passagemath-modules 10.6.31rc3__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
- passagemath_modules-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-7f678fcf.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_modules.libs/libquadmath-2284e583.so.0.0.0 +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,3589 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
r"""
|
|
3
|
+
Free modules of finite rank
|
|
4
|
+
|
|
5
|
+
The class :class:`FiniteRankFreeModule` implements free modules of finite rank
|
|
6
|
+
over a commutative ring.
|
|
7
|
+
|
|
8
|
+
A *free module of finite rank* over a commutative ring `R` is a module `M` over
|
|
9
|
+
`R` that admits a *finite basis*, i.e. a finite family of linearly independent
|
|
10
|
+
generators. Since `R` is commutative, it has the invariant basis number
|
|
11
|
+
property, so that the rank of the free module `M` is defined uniquely, as the
|
|
12
|
+
cardinality of any basis of `M`.
|
|
13
|
+
|
|
14
|
+
No distinguished basis of `M` is assumed. On the contrary, many bases can be
|
|
15
|
+
introduced on the free module along with change-of-basis rules (as module
|
|
16
|
+
automorphisms). Each
|
|
17
|
+
module element has then various representations over the various bases.
|
|
18
|
+
|
|
19
|
+
.. NOTE::
|
|
20
|
+
|
|
21
|
+
The class :class:`FiniteRankFreeModule` does not inherit from
|
|
22
|
+
class :class:`~sage.modules.free_module.FreeModule_generic`
|
|
23
|
+
nor from class
|
|
24
|
+
:class:`~sage.combinat.free_module.CombinatorialFreeModule`, since
|
|
25
|
+
both classes deal with modules with a *distinguished basis* (see
|
|
26
|
+
details :ref:`below <diff-FreeModule>`). Accordingly, the class
|
|
27
|
+
:class:`FiniteRankFreeModule` inherits directly from the generic class
|
|
28
|
+
:class:`~sage.structure.parent.Parent` with the category set to
|
|
29
|
+
:class:`~sage.categories.modules.Modules` (and not to
|
|
30
|
+
:class:`~sage.categories.modules_with_basis.ModulesWithBasis`).
|
|
31
|
+
|
|
32
|
+
.. TODO::
|
|
33
|
+
|
|
34
|
+
- implement submodules
|
|
35
|
+
- create a FreeModules category (cf. the *TODO* statement in the
|
|
36
|
+
documentation of :class:`~sage.categories.modules.Modules`: *Implement
|
|
37
|
+
a ``FreeModules(R)`` category, when so prompted by a concrete use case*)
|
|
38
|
+
|
|
39
|
+
AUTHORS:
|
|
40
|
+
|
|
41
|
+
- Eric Gourgoulhon, Michal Bejger (2014-2015): initial version
|
|
42
|
+
- Travis Scrimshaw (2016): category set to ``Modules(ring).FiniteDimensional()``
|
|
43
|
+
(:issue:`20770`)
|
|
44
|
+
- Michael Jung (2019): improve treatment of the zero element
|
|
45
|
+
- Eric Gourgoulhon (2021): unicode symbols for tensor and exterior products
|
|
46
|
+
- Matthias Koeppe (2022): ``FiniteRankFreeModule_abstract``, symmetric powers
|
|
47
|
+
|
|
48
|
+
REFERENCES:
|
|
49
|
+
|
|
50
|
+
- Chap. 10 of R. Godement : *Algebra* [God1968]_
|
|
51
|
+
- Chap. 3 of S. Lang : *Algebra* [Lan2002]_
|
|
52
|
+
|
|
53
|
+
EXAMPLES:
|
|
54
|
+
|
|
55
|
+
Let us define a free module of rank 2 over `\ZZ`::
|
|
56
|
+
|
|
57
|
+
sage: M = FiniteRankFreeModule(ZZ, 2, name='M') ; M
|
|
58
|
+
Rank-2 free module M over the Integer Ring
|
|
59
|
+
sage: M.category()
|
|
60
|
+
Category of finite dimensional modules over Integer Ring
|
|
61
|
+
|
|
62
|
+
We introduce a first basis on ``M``::
|
|
63
|
+
|
|
64
|
+
sage: e = M.basis('e') ; e
|
|
65
|
+
Basis (e_0,e_1) on the Rank-2 free module M over the Integer Ring
|
|
66
|
+
|
|
67
|
+
The elements of the basis are of course module elements::
|
|
68
|
+
|
|
69
|
+
sage: e[0]
|
|
70
|
+
Element e_0 of the Rank-2 free module M over the Integer Ring
|
|
71
|
+
sage: e[1]
|
|
72
|
+
Element e_1 of the Rank-2 free module M over the Integer Ring
|
|
73
|
+
sage: e[0].parent()
|
|
74
|
+
Rank-2 free module M over the Integer Ring
|
|
75
|
+
|
|
76
|
+
We define a module element by its components w.r.t. basis ``e``::
|
|
77
|
+
|
|
78
|
+
sage: u = M([2,-3], basis=e, name='u')
|
|
79
|
+
sage: u.display(e)
|
|
80
|
+
u = 2 e_0 - 3 e_1
|
|
81
|
+
|
|
82
|
+
Module elements can be also be created by arithmetic expressions::
|
|
83
|
+
|
|
84
|
+
sage: v = -2*u + 4*e[0] ; v
|
|
85
|
+
Element of the Rank-2 free module M over the Integer Ring
|
|
86
|
+
sage: v.display(e)
|
|
87
|
+
6 e_1
|
|
88
|
+
sage: u == 2*e[0] - 3*e[1]
|
|
89
|
+
True
|
|
90
|
+
|
|
91
|
+
We define a second basis on ``M`` from a family of linearly independent
|
|
92
|
+
elements::
|
|
93
|
+
|
|
94
|
+
sage: f = M.basis('f', from_family=(e[0]-e[1], -2*e[0]+3*e[1])) ; f
|
|
95
|
+
Basis (f_0,f_1) on the Rank-2 free module M over the Integer Ring
|
|
96
|
+
sage: f[0].display(e)
|
|
97
|
+
f_0 = e_0 - e_1
|
|
98
|
+
sage: f[1].display(e)
|
|
99
|
+
f_1 = -2 e_0 + 3 e_1
|
|
100
|
+
|
|
101
|
+
We may of course express the elements of basis ``e`` in terms of basis ``f``::
|
|
102
|
+
|
|
103
|
+
sage: e[0].display(f)
|
|
104
|
+
e_0 = 3 f_0 + f_1
|
|
105
|
+
sage: e[1].display(f)
|
|
106
|
+
e_1 = 2 f_0 + f_1
|
|
107
|
+
|
|
108
|
+
as well as any module element::
|
|
109
|
+
|
|
110
|
+
sage: u.display(f)
|
|
111
|
+
u = -f_1
|
|
112
|
+
sage: v.display(f)
|
|
113
|
+
12 f_0 + 6 f_1
|
|
114
|
+
|
|
115
|
+
The two bases are related by a module automorphism::
|
|
116
|
+
|
|
117
|
+
sage: a = M.change_of_basis(e,f) ; a
|
|
118
|
+
Automorphism of the Rank-2 free module M over the Integer Ring
|
|
119
|
+
sage: a.parent()
|
|
120
|
+
General linear group of the Rank-2 free module M over the Integer Ring
|
|
121
|
+
sage: a.matrix(e)
|
|
122
|
+
[ 1 -2]
|
|
123
|
+
[-1 3]
|
|
124
|
+
|
|
125
|
+
Let us check that basis ``f`` is indeed the image of basis ``e`` by ``a``::
|
|
126
|
+
|
|
127
|
+
sage: f[0] == a(e[0])
|
|
128
|
+
True
|
|
129
|
+
sage: f[1] == a(e[1])
|
|
130
|
+
True
|
|
131
|
+
|
|
132
|
+
The reverse change of basis is of course the inverse automorphism::
|
|
133
|
+
|
|
134
|
+
sage: M.change_of_basis(f,e) == a^(-1)
|
|
135
|
+
True
|
|
136
|
+
|
|
137
|
+
We introduce a new module element via its components w.r.t. basis ``f``::
|
|
138
|
+
|
|
139
|
+
sage: v = M([2,4], basis=f, name='v')
|
|
140
|
+
sage: v.display(f)
|
|
141
|
+
v = 2 f_0 + 4 f_1
|
|
142
|
+
|
|
143
|
+
The sum of the two module elements ``u`` and ``v`` can be performed even if
|
|
144
|
+
they have been defined on different bases, thanks to the known relation
|
|
145
|
+
between the two bases::
|
|
146
|
+
|
|
147
|
+
sage: s = u + v ; s
|
|
148
|
+
Element u+v of the Rank-2 free module M over the Integer Ring
|
|
149
|
+
|
|
150
|
+
We can display the result in either basis::
|
|
151
|
+
|
|
152
|
+
sage: s.display(e)
|
|
153
|
+
u+v = -4 e_0 + 7 e_1
|
|
154
|
+
sage: s.display(f)
|
|
155
|
+
u+v = 2 f_0 + 3 f_1
|
|
156
|
+
|
|
157
|
+
Tensor products of elements are implemented::
|
|
158
|
+
|
|
159
|
+
sage: t = u*v ; t
|
|
160
|
+
Type-(2,0) tensor u⊗v on the Rank-2 free module M over the Integer Ring
|
|
161
|
+
sage: t.parent()
|
|
162
|
+
Free module of type-(2,0) tensors on the
|
|
163
|
+
Rank-2 free module M over the Integer Ring
|
|
164
|
+
sage: t.display(e)
|
|
165
|
+
u⊗v = -12 e_0⊗e_0 + 20 e_0⊗e_1 + 18 e_1⊗e_0 - 30 e_1⊗e_1
|
|
166
|
+
sage: t.display(f)
|
|
167
|
+
u⊗v = -2 f_1⊗f_0 - 4 f_1⊗f_1
|
|
168
|
+
|
|
169
|
+
We can access to tensor components w.r.t. to a given basis via the square
|
|
170
|
+
bracket operator::
|
|
171
|
+
|
|
172
|
+
sage: t[e,0,1]
|
|
173
|
+
20
|
|
174
|
+
sage: t[f,1,0]
|
|
175
|
+
-2
|
|
176
|
+
sage: u[e,0]
|
|
177
|
+
2
|
|
178
|
+
sage: u[e,:]
|
|
179
|
+
[2, -3]
|
|
180
|
+
sage: u[f,:]
|
|
181
|
+
[0, -1]
|
|
182
|
+
|
|
183
|
+
The parent of the automorphism ``a`` is the group `\mathrm{GL}(M)`, but
|
|
184
|
+
``a`` can also be considered as a tensor of type `(1,1)` on ``M``::
|
|
185
|
+
|
|
186
|
+
sage: a.parent()
|
|
187
|
+
General linear group of the Rank-2 free module M over the Integer Ring
|
|
188
|
+
sage: a.tensor_type()
|
|
189
|
+
(1, 1)
|
|
190
|
+
sage: a.display(e)
|
|
191
|
+
e_0⊗e^0 - 2 e_0⊗e^1 - e_1⊗e^0 + 3 e_1⊗e^1
|
|
192
|
+
sage: a.display(f)
|
|
193
|
+
f_0⊗f^0 - 2 f_0⊗f^1 - f_1⊗f^0 + 3 f_1⊗f^1
|
|
194
|
+
|
|
195
|
+
As such, we can form its tensor product with ``t``, yielding a tensor of
|
|
196
|
+
type `(3,1)`::
|
|
197
|
+
|
|
198
|
+
sage: t*a
|
|
199
|
+
Type-(3,1) tensor on the Rank-2 free module M over the Integer Ring
|
|
200
|
+
sage: (t*a).display(e)
|
|
201
|
+
-12 e_0⊗e_0⊗e_0⊗e^0 + 24 e_0⊗e_0⊗e_0⊗e^1 + 12 e_0⊗e_0⊗e_1⊗e^0
|
|
202
|
+
- 36 e_0⊗e_0⊗e_1⊗e^1 + 20 e_0⊗e_1⊗e_0⊗e^0 - 40 e_0⊗e_1⊗e_0⊗e^1
|
|
203
|
+
- 20 e_0⊗e_1⊗e_1⊗e^0 + 60 e_0⊗e_1⊗e_1⊗e^1 + 18 e_1⊗e_0⊗e_0⊗e^0
|
|
204
|
+
- 36 e_1⊗e_0⊗e_0⊗e^1 - 18 e_1⊗e_0⊗e_1⊗e^0 + 54 e_1⊗e_0⊗e_1⊗e^1
|
|
205
|
+
- 30 e_1⊗e_1⊗e_0⊗e^0 + 60 e_1⊗e_1⊗e_0⊗e^1 + 30 e_1⊗e_1⊗e_1⊗e^0
|
|
206
|
+
- 90 e_1⊗e_1⊗e_1⊗e^1
|
|
207
|
+
|
|
208
|
+
The parent of `t\otimes a` is itself a free module of finite rank over `\ZZ`::
|
|
209
|
+
|
|
210
|
+
sage: T = (t*a).parent() ; T
|
|
211
|
+
Free module of type-(3,1) tensors on the Rank-2 free module M over the
|
|
212
|
+
Integer Ring
|
|
213
|
+
sage: T.base_ring()
|
|
214
|
+
Integer Ring
|
|
215
|
+
sage: T.rank()
|
|
216
|
+
16
|
|
217
|
+
|
|
218
|
+
.. _diff-FreeModule:
|
|
219
|
+
|
|
220
|
+
.. RUBRIC:: Differences between ``FiniteRankFreeModule`` and ``FreeModule``
|
|
221
|
+
(or ``VectorSpace``)
|
|
222
|
+
|
|
223
|
+
To illustrate the differences, let us create two free modules of rank 3 over
|
|
224
|
+
`\ZZ`, one with ``FiniteRankFreeModule`` and the other one with
|
|
225
|
+
``FreeModule``::
|
|
226
|
+
|
|
227
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') ; M
|
|
228
|
+
Rank-3 free module M over the Integer Ring
|
|
229
|
+
sage: N = FreeModule(ZZ, 3) ; N
|
|
230
|
+
Ambient free module of rank 3 over the principal ideal domain Integer Ring
|
|
231
|
+
|
|
232
|
+
The main difference is that ``FreeModule`` returns a free module with a
|
|
233
|
+
distinguished basis, while ``FiniteRankFreeModule`` does not::
|
|
234
|
+
|
|
235
|
+
sage: N.basis()
|
|
236
|
+
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
|
|
237
|
+
sage: M.bases()
|
|
238
|
+
[]
|
|
239
|
+
sage: M.print_bases()
|
|
240
|
+
No basis has been defined on the Rank-3 free module M over the Integer Ring
|
|
241
|
+
|
|
242
|
+
This is also revealed by the category of each module::
|
|
243
|
+
|
|
244
|
+
sage: M.category()
|
|
245
|
+
Category of finite dimensional modules over Integer Ring
|
|
246
|
+
sage: N.category()
|
|
247
|
+
Category of finite dimensional modules with basis over
|
|
248
|
+
(Dedekind domains and euclidean domains and noetherian rings
|
|
249
|
+
and infinite enumerated sets and metric spaces)
|
|
250
|
+
|
|
251
|
+
In other words, the module created by ``FreeModule`` is actually `\ZZ^3`,
|
|
252
|
+
while, in the absence of any distinguished basis, no *canonical* isomorphism
|
|
253
|
+
relates the module created by ``FiniteRankFreeModule`` to `\ZZ^3`::
|
|
254
|
+
|
|
255
|
+
sage: N is ZZ^3
|
|
256
|
+
True
|
|
257
|
+
sage: M is ZZ^3
|
|
258
|
+
False
|
|
259
|
+
sage: M == ZZ^3
|
|
260
|
+
False
|
|
261
|
+
|
|
262
|
+
Because it is `\ZZ^3`, ``N`` is unique, while there may be various modules
|
|
263
|
+
of the same rank over the same ring created by ``FiniteRankFreeModule``;
|
|
264
|
+
they are then distinguished by their names (actually by the complete
|
|
265
|
+
sequence of arguments of ``FiniteRankFreeModule``)::
|
|
266
|
+
|
|
267
|
+
sage: N1 = FreeModule(ZZ, 3) ; N1
|
|
268
|
+
Ambient free module of rank 3 over the principal ideal domain Integer Ring
|
|
269
|
+
sage: N1 is N # FreeModule(ZZ, 3) is unique
|
|
270
|
+
True
|
|
271
|
+
sage: M1 = FiniteRankFreeModule(ZZ, 3, name='M_1') ; M1
|
|
272
|
+
Rank-3 free module M_1 over the Integer Ring
|
|
273
|
+
sage: M1 is M # M1 and M are different rank-3 modules over ZZ
|
|
274
|
+
False
|
|
275
|
+
sage: M1b = FiniteRankFreeModule(ZZ, 3, name='M_1') ; M1b
|
|
276
|
+
Rank-3 free module M_1 over the Integer Ring
|
|
277
|
+
sage: M1b is M1 # because M1b and M1 have the same name
|
|
278
|
+
True
|
|
279
|
+
|
|
280
|
+
As illustrated above, various bases can be introduced on the module created by
|
|
281
|
+
``FiniteRankFreeModule``::
|
|
282
|
+
|
|
283
|
+
sage: e = M.basis('e') ; e
|
|
284
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
285
|
+
sage: f = M.basis('f', from_family=(-e[0], e[1]-e[2], -2*e[1]+3*e[2])) ; f
|
|
286
|
+
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring
|
|
287
|
+
sage: M.bases()
|
|
288
|
+
[Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring,
|
|
289
|
+
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring]
|
|
290
|
+
|
|
291
|
+
Each element of a basis is accessible via its index::
|
|
292
|
+
|
|
293
|
+
sage: e[0]
|
|
294
|
+
Element e_0 of the Rank-3 free module M over the Integer Ring
|
|
295
|
+
sage: e[0].parent()
|
|
296
|
+
Rank-3 free module M over the Integer Ring
|
|
297
|
+
sage: f[1]
|
|
298
|
+
Element f_1 of the Rank-3 free module M over the Integer Ring
|
|
299
|
+
sage: f[1].parent()
|
|
300
|
+
Rank-3 free module M over the Integer Ring
|
|
301
|
+
|
|
302
|
+
while on module ``N``, the element of the (unique) basis is accessible
|
|
303
|
+
directly from the module symbol::
|
|
304
|
+
|
|
305
|
+
sage: N.0
|
|
306
|
+
(1, 0, 0)
|
|
307
|
+
sage: N.1
|
|
308
|
+
(0, 1, 0)
|
|
309
|
+
sage: N.0.parent()
|
|
310
|
+
Ambient free module of rank 3 over the principal ideal domain Integer Ring
|
|
311
|
+
|
|
312
|
+
The arithmetic of elements is similar; the difference lies in the display:
|
|
313
|
+
a basis has to be specified for elements of ``M``, while elements of ``N`` are
|
|
314
|
+
displayed directly as elements of `\ZZ^3`::
|
|
315
|
+
|
|
316
|
+
sage: u = 2*e[0] - 3*e[2] ; u
|
|
317
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
318
|
+
sage: u.display(e)
|
|
319
|
+
2 e_0 - 3 e_2
|
|
320
|
+
sage: u.display(f)
|
|
321
|
+
-2 f_0 - 6 f_1 - 3 f_2
|
|
322
|
+
sage: u[e,:]
|
|
323
|
+
[2, 0, -3]
|
|
324
|
+
sage: u[f,:]
|
|
325
|
+
[-2, -6, -3]
|
|
326
|
+
sage: v = 2*N.0 - 3*N.2 ; v
|
|
327
|
+
(2, 0, -3)
|
|
328
|
+
|
|
329
|
+
For the case of ``M``, in order to avoid to specify the basis if the user is
|
|
330
|
+
always working with the same basis (e.g. only one basis has been defined),
|
|
331
|
+
the concept of *default basis* has been introduced::
|
|
332
|
+
|
|
333
|
+
sage: M.default_basis()
|
|
334
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
335
|
+
sage: M.print_bases()
|
|
336
|
+
Bases defined on the Rank-3 free module M over the Integer Ring:
|
|
337
|
+
- (e_0,e_1,e_2) (default basis)
|
|
338
|
+
- (f_0,f_1,f_2)
|
|
339
|
+
|
|
340
|
+
This is different from the *distinguished basis* of ``N``: it simply means that
|
|
341
|
+
the mention of the basis can be omitted in function arguments::
|
|
342
|
+
|
|
343
|
+
sage: u.display() # equivalent to u.display(e)
|
|
344
|
+
2 e_0 - 3 e_2
|
|
345
|
+
sage: u[:] # equivalent to u[e,:]
|
|
346
|
+
[2, 0, -3]
|
|
347
|
+
|
|
348
|
+
At any time, the default basis can be changed::
|
|
349
|
+
|
|
350
|
+
sage: M.set_default_basis(f)
|
|
351
|
+
sage: u.display()
|
|
352
|
+
-2 f_0 - 6 f_1 - 3 f_2
|
|
353
|
+
|
|
354
|
+
Another difference between ``FiniteRankFreeModule`` and ``FreeModule`` is that
|
|
355
|
+
for the former the range of indices can be specified (by default, it starts
|
|
356
|
+
from 0)::
|
|
357
|
+
|
|
358
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1) ; M
|
|
359
|
+
Rank-3 free module M over the Integer Ring
|
|
360
|
+
sage: e = M.basis('e') ; e # compare with (e_0,e_1,e_2) above
|
|
361
|
+
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
|
|
362
|
+
sage: e[1], e[2], e[3]
|
|
363
|
+
(Element e_1 of the Rank-3 free module M over the Integer Ring,
|
|
364
|
+
Element e_2 of the Rank-3 free module M over the Integer Ring,
|
|
365
|
+
Element e_3 of the Rank-3 free module M over the Integer Ring)
|
|
366
|
+
|
|
367
|
+
All the above holds for ``VectorSpace`` instead of ``FreeModule``: the object
|
|
368
|
+
created by ``VectorSpace`` is actually a Cartesian power of the base field::
|
|
369
|
+
|
|
370
|
+
sage: V = VectorSpace(QQ,3) ; V
|
|
371
|
+
Vector space of dimension 3 over Rational Field
|
|
372
|
+
sage: V.category()
|
|
373
|
+
Category of finite dimensional vector spaces with basis
|
|
374
|
+
over (number fields and quotient fields and metric spaces)
|
|
375
|
+
sage: V is QQ^3
|
|
376
|
+
True
|
|
377
|
+
sage: V.basis()
|
|
378
|
+
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
|
|
379
|
+
|
|
380
|
+
To create a vector space without any distinguished basis, one has to use
|
|
381
|
+
``FiniteRankFreeModule``::
|
|
382
|
+
|
|
383
|
+
sage: V = FiniteRankFreeModule(QQ, 3, name='V') ; V
|
|
384
|
+
3-dimensional vector space V over the Rational Field
|
|
385
|
+
sage: V.category()
|
|
386
|
+
Category of finite dimensional vector spaces over Rational Field
|
|
387
|
+
sage: V.bases()
|
|
388
|
+
[]
|
|
389
|
+
sage: V.print_bases()
|
|
390
|
+
No basis has been defined on the 3-dimensional vector space V over the
|
|
391
|
+
Rational Field
|
|
392
|
+
|
|
393
|
+
The class :class:`FiniteRankFreeModule` has been created for the needs
|
|
394
|
+
of the `SageManifolds project <http://sagemanifolds.obspm.fr/>`_, where
|
|
395
|
+
free modules do not have any distinguished basis. Too kinds of free modules
|
|
396
|
+
occur in the context of differentiable manifolds (see
|
|
397
|
+
`here <http://sagemanifolds.obspm.fr/tensor_modules.html>`_ for more
|
|
398
|
+
details):
|
|
399
|
+
|
|
400
|
+
- the tangent vector space at any point of the manifold (cf.
|
|
401
|
+
:class:`~sage.manifolds.differentiable.tangent_space.TangentSpace`);
|
|
402
|
+
- the set of vector fields on a parallelizable open subset `U` of the manifold,
|
|
403
|
+
which is a free module over the algebra of scalar fields on `U` (cf.
|
|
404
|
+
:class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldFreeModule`).
|
|
405
|
+
|
|
406
|
+
For instance, without any specific coordinate choice, no basis can be
|
|
407
|
+
distinguished in a tangent space.
|
|
408
|
+
|
|
409
|
+
On the other side, the modules created by ``FreeModule`` have much more
|
|
410
|
+
algebraic functionalities than those created by ``FiniteRankFreeModule``. In
|
|
411
|
+
particular, submodules have not been implemented yet in
|
|
412
|
+
:class:`FiniteRankFreeModule`. Moreover, modules resulting from ``FreeModule``
|
|
413
|
+
are tailored to the specific kind of their base ring:
|
|
414
|
+
|
|
415
|
+
- free module over a commutative ring that is not an integral domain
|
|
416
|
+
(`\ZZ/6\ZZ`)::
|
|
417
|
+
|
|
418
|
+
sage: R = IntegerModRing(6) ; R
|
|
419
|
+
Ring of integers modulo 6
|
|
420
|
+
sage: FreeModule(R, 3)
|
|
421
|
+
Ambient free module of rank 3 over Ring of integers modulo 6
|
|
422
|
+
sage: type(FreeModule(R, 3))
|
|
423
|
+
<class 'sage.modules.free_module.FreeModule_ambient_with_category'>
|
|
424
|
+
|
|
425
|
+
- free module over an integral domain that is not principal (`\ZZ[X]`)::
|
|
426
|
+
|
|
427
|
+
sage: R.<X> = ZZ[] ; R
|
|
428
|
+
Univariate Polynomial Ring in X over Integer Ring
|
|
429
|
+
sage: FreeModule(R, 3)
|
|
430
|
+
Ambient free module of rank 3 over the integral domain Univariate
|
|
431
|
+
Polynomial Ring in X over Integer Ring
|
|
432
|
+
sage: type(FreeModule(R, 3))
|
|
433
|
+
<class 'sage.modules.free_module.FreeModule_ambient_domain_with_category'>
|
|
434
|
+
|
|
435
|
+
- free module over a principal ideal domain (`\ZZ`)::
|
|
436
|
+
|
|
437
|
+
sage: R = ZZ ; R
|
|
438
|
+
Integer Ring
|
|
439
|
+
sage: FreeModule(R,3)
|
|
440
|
+
Ambient free module of rank 3 over the principal ideal domain Integer Ring
|
|
441
|
+
sage: type(FreeModule(R, 3))
|
|
442
|
+
<class 'sage.modules.free_module.FreeModule_ambient_pid_with_category'>
|
|
443
|
+
|
|
444
|
+
On the contrary, all objects constructed with ``FiniteRankFreeModule`` belong
|
|
445
|
+
to the same class::
|
|
446
|
+
|
|
447
|
+
sage: R = IntegerModRing(6)
|
|
448
|
+
sage: type(FiniteRankFreeModule(R, 3))
|
|
449
|
+
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
|
|
450
|
+
sage: R.<X> = ZZ[]
|
|
451
|
+
sage: type(FiniteRankFreeModule(R, 3))
|
|
452
|
+
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
|
|
453
|
+
sage: R = ZZ
|
|
454
|
+
sage: type(FiniteRankFreeModule(R, 3))
|
|
455
|
+
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
.. RUBRIC:: Differences between ``FiniteRankFreeModule`` and
|
|
459
|
+
``CombinatorialFreeModule``
|
|
460
|
+
|
|
461
|
+
An alternative to construct free modules in Sage is
|
|
462
|
+
:class:`~sage.combinat.free_module.CombinatorialFreeModule`.
|
|
463
|
+
However, as ``FreeModule``, it leads to a module with a distinguished basis::
|
|
464
|
+
|
|
465
|
+
sage: N = CombinatorialFreeModule(ZZ, [1,2,3]) ; N
|
|
466
|
+
Free module generated by {1, 2, 3} over Integer Ring
|
|
467
|
+
sage: N.category()
|
|
468
|
+
Category of finite dimensional modules with basis over Integer Ring
|
|
469
|
+
|
|
470
|
+
The distinguished basis is returned by the method ``basis()``::
|
|
471
|
+
|
|
472
|
+
sage: b = N.basis() ; b
|
|
473
|
+
Finite family {1: B[1], 2: B[2], 3: B[3]}
|
|
474
|
+
sage: b[1]
|
|
475
|
+
B[1]
|
|
476
|
+
sage: b[1].parent()
|
|
477
|
+
Free module generated by {1, 2, 3} over Integer Ring
|
|
478
|
+
|
|
479
|
+
For the free module ``M`` created above with ``FiniteRankFreeModule``, the
|
|
480
|
+
method ``basis`` has at least one argument: the symbol string that
|
|
481
|
+
specifies which basis is required::
|
|
482
|
+
|
|
483
|
+
sage: e = M.basis('e') ; e
|
|
484
|
+
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
|
|
485
|
+
sage: e[1]
|
|
486
|
+
Element e_1 of the Rank-3 free module M over the Integer Ring
|
|
487
|
+
sage: e[1].parent()
|
|
488
|
+
Rank-3 free module M over the Integer Ring
|
|
489
|
+
|
|
490
|
+
The arithmetic of elements is similar::
|
|
491
|
+
|
|
492
|
+
sage: u = 2*e[1] - 5*e[3] ; u
|
|
493
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
494
|
+
sage: v = 2*b[1] - 5*b[3] ; v
|
|
495
|
+
2*B[1] - 5*B[3]
|
|
496
|
+
|
|
497
|
+
One notices that elements of ``N`` are displayed directly in terms of their
|
|
498
|
+
expansions on the distinguished basis. For elements of ``M``, one has to use
|
|
499
|
+
the method
|
|
500
|
+
:meth:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor.display`
|
|
501
|
+
in order to specify the basis::
|
|
502
|
+
|
|
503
|
+
sage: u.display(e)
|
|
504
|
+
2 e_1 - 5 e_3
|
|
505
|
+
|
|
506
|
+
The components on the basis are returned by the square bracket operator for
|
|
507
|
+
``M`` and by the method ``coefficient`` for ``N``::
|
|
508
|
+
|
|
509
|
+
sage: [u[e,i] for i in {1,2,3}]
|
|
510
|
+
[2, 0, -5]
|
|
511
|
+
sage: u[e,:] # a shortcut for the above
|
|
512
|
+
[2, 0, -5]
|
|
513
|
+
sage: [v.coefficient(i) for i in {1,2,3}]
|
|
514
|
+
[2, 0, -5]
|
|
515
|
+
"""
|
|
516
|
+
# ******************************************************************************
|
|
517
|
+
# Copyright (C) 2014-2021 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
|
|
518
|
+
# 2014-2016 Travis Scrimshaw <tscrimsh@umn.edu>
|
|
519
|
+
# 2015 Michal Bejger <bejger@camk.edu.pl>
|
|
520
|
+
# 2016 Frédéric Chapoton
|
|
521
|
+
# 2020 Michael Jung
|
|
522
|
+
# 2020-2022 Matthias Koeppe
|
|
523
|
+
#
|
|
524
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
525
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
526
|
+
# the License, or (at your option) any later version.
|
|
527
|
+
# https://www.gnu.org/licenses/
|
|
528
|
+
# ******************************************************************************
|
|
529
|
+
from __future__ import annotations
|
|
530
|
+
|
|
531
|
+
from typing import Optional
|
|
532
|
+
from collections.abc import Generator
|
|
533
|
+
|
|
534
|
+
from sage.categories.fields import Fields
|
|
535
|
+
from sage.categories.homset import Hom
|
|
536
|
+
from sage.categories.modules import Modules
|
|
537
|
+
from sage.categories.morphism import SetIsomorphism
|
|
538
|
+
from sage.categories.rings import Rings
|
|
539
|
+
from sage.misc.cachefunc import cached_method
|
|
540
|
+
from sage.rings.integer import Integer
|
|
541
|
+
from sage.sets.family import Family, TrivialFamily
|
|
542
|
+
from sage.structure.parent import Parent
|
|
543
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
544
|
+
from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm
|
|
545
|
+
from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement
|
|
546
|
+
from sage.tensor.modules.free_module_tensor import FreeModuleTensor
|
|
547
|
+
from sage.tensor.modules.reflexive_module import (
|
|
548
|
+
ReflexiveModule_abstract,
|
|
549
|
+
ReflexiveModule_base,
|
|
550
|
+
ReflexiveModule_dual,
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
class FiniteRankFreeModule_abstract(UniqueRepresentation, ReflexiveModule_abstract):
|
|
555
|
+
r"""
|
|
556
|
+
Abstract base class for free modules of finite rank over a commutative ring.
|
|
557
|
+
"""
|
|
558
|
+
|
|
559
|
+
def __init__(
|
|
560
|
+
self,
|
|
561
|
+
ring,
|
|
562
|
+
rank,
|
|
563
|
+
name=None,
|
|
564
|
+
latex_name=None,
|
|
565
|
+
category=None,
|
|
566
|
+
ambient=None,
|
|
567
|
+
):
|
|
568
|
+
r"""
|
|
569
|
+
See :class:`FiniteRankFreeModule` for documentation and examples.
|
|
570
|
+
|
|
571
|
+
TESTS::
|
|
572
|
+
|
|
573
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
574
|
+
sage: TestSuite(M).run()
|
|
575
|
+
sage: e = M.basis('e')
|
|
576
|
+
sage: TestSuite(M).run()
|
|
577
|
+
sage: f = M.basis('f')
|
|
578
|
+
sage: TestSuite(M).run()
|
|
579
|
+
"""
|
|
580
|
+
# This duplicates the normalization done in __classcall_private__,
|
|
581
|
+
# but it is needed for various subclasses.
|
|
582
|
+
if ring not in Rings().Commutative():
|
|
583
|
+
raise TypeError("the module base ring must be commutative")
|
|
584
|
+
category = Modules(ring).FiniteDimensional().or_subcategory(category)
|
|
585
|
+
Parent.__init__(self, base=ring, category=category)
|
|
586
|
+
self._ring = ring # same as self._base
|
|
587
|
+
if ambient is None:
|
|
588
|
+
self._ambient_module = self
|
|
589
|
+
else:
|
|
590
|
+
self._ambient_module = ambient
|
|
591
|
+
self._rank = rank
|
|
592
|
+
self._name = name
|
|
593
|
+
# This duplicates the normalization done in __classcall_private__,
|
|
594
|
+
# but it is needed for various subclasses.
|
|
595
|
+
if latex_name is None:
|
|
596
|
+
self._latex_name = self._name
|
|
597
|
+
else:
|
|
598
|
+
self._latex_name = latex_name
|
|
599
|
+
|
|
600
|
+
def _latex_(self):
|
|
601
|
+
r"""
|
|
602
|
+
LaTeX representation of ``self``.
|
|
603
|
+
|
|
604
|
+
EXAMPLES::
|
|
605
|
+
|
|
606
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
607
|
+
sage: M._latex_()
|
|
608
|
+
'M'
|
|
609
|
+
sage: latex(M)
|
|
610
|
+
M
|
|
611
|
+
sage: M1 = FiniteRankFreeModule(ZZ, 3, name='M', latex_name=r'\mathcal{M}')
|
|
612
|
+
sage: M1._latex_()
|
|
613
|
+
'\\mathcal{M}'
|
|
614
|
+
sage: latex(M1)
|
|
615
|
+
\mathcal{M}
|
|
616
|
+
"""
|
|
617
|
+
if self._latex_name is None:
|
|
618
|
+
return r'\mbox{' + str(self) + r'}'
|
|
619
|
+
else:
|
|
620
|
+
return self._latex_name
|
|
621
|
+
|
|
622
|
+
def rank(self) -> int:
|
|
623
|
+
r"""
|
|
624
|
+
Return the rank of the free module ``self``.
|
|
625
|
+
|
|
626
|
+
Since the ring over which ``self`` is built is assumed to be
|
|
627
|
+
commutative (and hence has the invariant basis number property), the
|
|
628
|
+
rank is defined uniquely, as the cardinality of any basis of ``self``.
|
|
629
|
+
|
|
630
|
+
EXAMPLES:
|
|
631
|
+
|
|
632
|
+
Rank of free modules over `\ZZ`::
|
|
633
|
+
|
|
634
|
+
sage: M = FiniteRankFreeModule(ZZ, 3)
|
|
635
|
+
sage: M.rank()
|
|
636
|
+
3
|
|
637
|
+
sage: M.tensor_module(0,1).rank()
|
|
638
|
+
3
|
|
639
|
+
sage: M.tensor_module(0,2).rank()
|
|
640
|
+
9
|
|
641
|
+
sage: M.tensor_module(1,0).rank()
|
|
642
|
+
3
|
|
643
|
+
sage: M.tensor_module(1,1).rank()
|
|
644
|
+
9
|
|
645
|
+
sage: M.tensor_module(1,2).rank()
|
|
646
|
+
27
|
|
647
|
+
sage: M.tensor_module(2,2).rank()
|
|
648
|
+
81
|
|
649
|
+
"""
|
|
650
|
+
return self._rank
|
|
651
|
+
|
|
652
|
+
@cached_method
|
|
653
|
+
def zero(self):
|
|
654
|
+
r"""
|
|
655
|
+
Return the zero element of ``self``.
|
|
656
|
+
|
|
657
|
+
EXAMPLES:
|
|
658
|
+
|
|
659
|
+
Zero elements of free modules over `\ZZ`::
|
|
660
|
+
|
|
661
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
662
|
+
sage: M.zero()
|
|
663
|
+
Element zero of the Rank-3 free module M over the Integer Ring
|
|
664
|
+
sage: M.zero().parent() is M
|
|
665
|
+
True
|
|
666
|
+
sage: M.zero() is M(0)
|
|
667
|
+
True
|
|
668
|
+
sage: T = M.tensor_module(1,1)
|
|
669
|
+
sage: T.zero()
|
|
670
|
+
Type-(1,1) tensor zero on the Rank-3 free module M over the Integer Ring
|
|
671
|
+
sage: T.zero().parent() is T
|
|
672
|
+
True
|
|
673
|
+
sage: T.zero() is T(0)
|
|
674
|
+
True
|
|
675
|
+
|
|
676
|
+
Components of the zero element with respect to some basis::
|
|
677
|
+
|
|
678
|
+
sage: e = M.basis('e')
|
|
679
|
+
sage: M.zero()[e,:]
|
|
680
|
+
[0, 0, 0]
|
|
681
|
+
sage: all(M.zero()[e,i] == M.base_ring().zero() for i in M.irange())
|
|
682
|
+
True
|
|
683
|
+
sage: T.zero()[e,:]
|
|
684
|
+
[0 0 0]
|
|
685
|
+
[0 0 0]
|
|
686
|
+
[0 0 0]
|
|
687
|
+
sage: M.tensor_module(1,2).zero()[e,:]
|
|
688
|
+
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
|
|
689
|
+
[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
|
|
690
|
+
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
|
|
691
|
+
"""
|
|
692
|
+
resu = self._element_constructor_(name='zero', latex_name='0')
|
|
693
|
+
for basis in self._known_bases:
|
|
694
|
+
resu._add_comp_unsafe(basis)
|
|
695
|
+
# (since new components are initialized to zero)
|
|
696
|
+
resu._is_zero = True # This element is certainly zero
|
|
697
|
+
resu.set_immutable()
|
|
698
|
+
return resu
|
|
699
|
+
|
|
700
|
+
def ambient_module(self): # compatible with sage.modules.free_module.FreeModule_generic
|
|
701
|
+
"""
|
|
702
|
+
Return the ambient module associated to this module.
|
|
703
|
+
|
|
704
|
+
EXAMPLES::
|
|
705
|
+
|
|
706
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
707
|
+
sage: M.ambient_module() is M
|
|
708
|
+
True
|
|
709
|
+
|
|
710
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
711
|
+
sage: Sym0123x45M = M.tensor_module(6, 0, sym=((0, 1, 2, 3), (4, 5)))
|
|
712
|
+
sage: T60M = M.tensor_module(6, 0)
|
|
713
|
+
sage: Sym0123x45M.ambient_module() is T60M
|
|
714
|
+
True
|
|
715
|
+
"""
|
|
716
|
+
return self._ambient_module
|
|
717
|
+
|
|
718
|
+
ambient = ambient_module # compatible with sage.modules.with_basis.subquotient.SubmoduleWithBasis
|
|
719
|
+
|
|
720
|
+
def is_submodule(self, other):
|
|
721
|
+
"""
|
|
722
|
+
Return ``True`` if ``self`` is a submodule of ``other``.
|
|
723
|
+
|
|
724
|
+
EXAMPLES::
|
|
725
|
+
|
|
726
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
727
|
+
sage: N = FiniteRankFreeModule(ZZ, 4, name='N')
|
|
728
|
+
sage: M.is_submodule(M)
|
|
729
|
+
True
|
|
730
|
+
sage: M.is_submodule(N)
|
|
731
|
+
False
|
|
732
|
+
"""
|
|
733
|
+
return self == other or self.ambient_module() == other
|
|
734
|
+
|
|
735
|
+
def isomorphism_with_fixed_basis(self, basis=None, codomain=None):
|
|
736
|
+
r"""
|
|
737
|
+
Construct the canonical isomorphism from the free module ``self``
|
|
738
|
+
to a free module in which ``basis`` of ``self`` is mapped to the
|
|
739
|
+
distinguished basis of ``codomain``.
|
|
740
|
+
|
|
741
|
+
INPUT:
|
|
742
|
+
|
|
743
|
+
- ``basis`` -- (default: ``None``) the basis of ``self`` which
|
|
744
|
+
should be mapped to the distinguished basis on ``codomain``;
|
|
745
|
+
if ``None``, the default basis is assumed.
|
|
746
|
+
- ``codomain`` -- (default: ``None``) the codomain of the
|
|
747
|
+
isomorphism represented by a free module within the category
|
|
748
|
+
:class:`~sage.categories.modules_with_basis.ModulesWithBasis` with
|
|
749
|
+
the same rank and base ring as ``self``; if ``None``, a free module
|
|
750
|
+
represented by
|
|
751
|
+
:class:`~sage.combinat.free_module.CombinatorialFreeModule` is
|
|
752
|
+
constructed
|
|
753
|
+
|
|
754
|
+
OUTPUT:
|
|
755
|
+
|
|
756
|
+
- a module isomorphism represented by
|
|
757
|
+
:class:`~sage.categories.morphism.SetIsomorphism`
|
|
758
|
+
|
|
759
|
+
EXAMPLES::
|
|
760
|
+
|
|
761
|
+
sage: V = FiniteRankFreeModule(QQ, 3, start_index=1); V
|
|
762
|
+
3-dimensional vector space over the Rational Field
|
|
763
|
+
sage: basis = e = V.basis("e"); basis
|
|
764
|
+
Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the
|
|
765
|
+
Rational Field
|
|
766
|
+
sage: phi_e = V.isomorphism_with_fixed_basis(basis); phi_e
|
|
767
|
+
Generic morphism:
|
|
768
|
+
From: 3-dimensional vector space over the Rational Field
|
|
769
|
+
To: Free module generated by {1, 2, 3} over Rational Field
|
|
770
|
+
sage: phi_e.codomain().category()
|
|
771
|
+
Category of finite dimensional vector spaces with basis over
|
|
772
|
+
Rational Field
|
|
773
|
+
sage: phi_e(e[1] + 2 * e[2])
|
|
774
|
+
e[1] + 2*e[2]
|
|
775
|
+
|
|
776
|
+
sage: abc = V.basis(['a', 'b', 'c'], symbol_dual=['d', 'e', 'f']); abc
|
|
777
|
+
Basis (a,b,c) on the 3-dimensional vector space over the Rational Field
|
|
778
|
+
sage: phi_abc = V.isomorphism_with_fixed_basis(abc); phi_abc
|
|
779
|
+
Generic morphism:
|
|
780
|
+
From: 3-dimensional vector space over the Rational Field
|
|
781
|
+
To: Free module generated by {1, 2, 3} over Rational Field
|
|
782
|
+
sage: phi_abc(abc[1] + 2 * abc[2])
|
|
783
|
+
B[1] + 2*B[2]
|
|
784
|
+
|
|
785
|
+
Providing a codomain::
|
|
786
|
+
|
|
787
|
+
sage: W = CombinatorialFreeModule(QQ, ['a', 'b', 'c'])
|
|
788
|
+
sage: phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW
|
|
789
|
+
Generic morphism:
|
|
790
|
+
From: 3-dimensional vector space over the Rational Field
|
|
791
|
+
To: Free module generated by {'a', 'b', 'c'} over Rational Field
|
|
792
|
+
sage: phi_eW(e[1] + 2 * e[2])
|
|
793
|
+
B['a'] + 2*B['b']
|
|
794
|
+
sage: ~phi_eW
|
|
795
|
+
Generic morphism:
|
|
796
|
+
From: Free module generated by {'a', 'b', 'c'} over Rational Field
|
|
797
|
+
To: 3-dimensional vector space over the Rational Field
|
|
798
|
+
sage: (~phi_eW)(W.basis()['b']).display()
|
|
799
|
+
e_2
|
|
800
|
+
|
|
801
|
+
Providing a :class:`~sage.modules.free_module.Module_free_ambient` as the codomain::
|
|
802
|
+
|
|
803
|
+
sage: W = QQ^3
|
|
804
|
+
sage: phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW
|
|
805
|
+
Generic morphism:
|
|
806
|
+
From: 3-dimensional vector space over the Rational Field
|
|
807
|
+
To: Vector space of dimension 3 over Rational Field
|
|
808
|
+
sage: phi_eW(e[1] + 2 * e[2])
|
|
809
|
+
(1, 2, 0)
|
|
810
|
+
|
|
811
|
+
Sending (1,1)-tensors to matrices::
|
|
812
|
+
|
|
813
|
+
sage: T11 = V.tensor_module(1, 1); T11
|
|
814
|
+
Free module of type-(1,1) tensors on the
|
|
815
|
+
3-dimensional vector space over the Rational Field
|
|
816
|
+
sage: e_T11 = T11.basis("e"); e_T11
|
|
817
|
+
Standard basis on the
|
|
818
|
+
Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field
|
|
819
|
+
induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field
|
|
820
|
+
sage: W = MatrixSpace(QQ, 3)
|
|
821
|
+
sage: phi_e_T11 = T11.isomorphism_with_fixed_basis(e_T11, codomain=W); phi_e_T11
|
|
822
|
+
Generic morphism:
|
|
823
|
+
From: Free module of type-(1,1) tensors on the
|
|
824
|
+
3-dimensional vector space over the Rational Field
|
|
825
|
+
To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field
|
|
826
|
+
sage: t = T11.an_element(); t.display()
|
|
827
|
+
1/2 e_1⊗e^1
|
|
828
|
+
sage: phi_e_T11(t)
|
|
829
|
+
[1/2 0 0]
|
|
830
|
+
[ 0 0 0]
|
|
831
|
+
[ 0 0 0]
|
|
832
|
+
sage: ~phi_e_T11
|
|
833
|
+
Generic morphism:
|
|
834
|
+
From: Full MatrixSpace of 3 by 3 dense matrices over Rational Field
|
|
835
|
+
To: Free module of type-(1,1) tensors on the
|
|
836
|
+
3-dimensional vector space over the Rational Field
|
|
837
|
+
sage: (~phi_e_T11)(W([[0, 1/2, 1/3],
|
|
838
|
+
....: [-1/2, 0, 0],
|
|
839
|
+
....: [-1/3, 0, 0]])).display()
|
|
840
|
+
1/2 e_1⊗e^2 + 1/3 e_1⊗e^3 - 1/2 e_2⊗e^1 - 1/3 e_3⊗e^1
|
|
841
|
+
|
|
842
|
+
Sending symmetric bilinear forms to matrices (note that they are currently elements
|
|
843
|
+
of `T^{(0,2)}(M)`, not the symmetric power of `M`)::
|
|
844
|
+
|
|
845
|
+
sage: T02 = V.tensor_module(0, 2); T02
|
|
846
|
+
Free module of type-(0,2) tensors on the
|
|
847
|
+
3-dimensional vector space over the Rational Field
|
|
848
|
+
sage: e_T02 = T02.basis("e"); e_T02
|
|
849
|
+
Standard basis on the
|
|
850
|
+
Free module of type-(0,2) tensors on the
|
|
851
|
+
3-dimensional vector space over the Rational Field
|
|
852
|
+
induced by Basis (e_1,e_2,e_3) on the
|
|
853
|
+
3-dimensional vector space over the Rational Field
|
|
854
|
+
sage: W = MatrixSpace(QQ, 3)
|
|
855
|
+
sage: phi_e_T02 = T02.isomorphism_with_fixed_basis(e_T02, codomain=W); phi_e_T02
|
|
856
|
+
Generic morphism:
|
|
857
|
+
From: Free module of type-(0,2) tensors on the
|
|
858
|
+
3-dimensional vector space over the Rational Field
|
|
859
|
+
To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field
|
|
860
|
+
|
|
861
|
+
sage: a = V.sym_bilinear_form()
|
|
862
|
+
sage: a[1,1], a[1,2], a[1,3] = 1, 2, 3
|
|
863
|
+
sage: a[2,2], a[2,3] = 4, 5
|
|
864
|
+
sage: a[3,3] = 6
|
|
865
|
+
sage: a.display()
|
|
866
|
+
e^1⊗e^1 + 2 e^1⊗e^2 + 3 e^1⊗e^3 + 2 e^2⊗e^1 + 4 e^2⊗e^2 + 5 e^2⊗e^3
|
|
867
|
+
+ 3 e^3⊗e^1 + 5 e^3⊗e^2 + 6 e^3⊗e^3
|
|
868
|
+
sage: phi_e_T02(a)
|
|
869
|
+
[1 2 3]
|
|
870
|
+
[2 4 5]
|
|
871
|
+
[3 5 6]
|
|
872
|
+
|
|
873
|
+
Same but explicitly in the subspace of symmetric bilinear forms::
|
|
874
|
+
|
|
875
|
+
sage: Sym2Vdual = V.dual_symmetric_power(2); Sym2Vdual
|
|
876
|
+
Free module of fully symmetric type-(0,2) tensors on the
|
|
877
|
+
3-dimensional vector space over the Rational Field
|
|
878
|
+
sage: Sym2Vdual.is_submodule(T02)
|
|
879
|
+
True
|
|
880
|
+
sage: Sym2Vdual.rank()
|
|
881
|
+
6
|
|
882
|
+
sage: e_Sym2Vdual = Sym2Vdual.basis("e"); e_Sym2Vdual
|
|
883
|
+
Standard basis on the
|
|
884
|
+
Free module of fully symmetric type-(0,2) tensors on the
|
|
885
|
+
3-dimensional vector space over the Rational Field
|
|
886
|
+
induced by Basis (e_1,e_2,e_3) on the
|
|
887
|
+
3-dimensional vector space over the Rational Field
|
|
888
|
+
sage: W_basis = [phi_e_T02(b) for b in e_Sym2Vdual]; W_basis
|
|
889
|
+
[
|
|
890
|
+
[1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0]
|
|
891
|
+
[0 0 0] [1 0 0] [0 0 0] [0 1 0] [0 0 1] [0 0 0]
|
|
892
|
+
[0 0 0], [0 0 0], [1 0 0], [0 0 0], [0 1 0], [0 0 1]
|
|
893
|
+
]
|
|
894
|
+
sage: W = MatrixSpace(QQ, 3).submodule(W_basis); W
|
|
895
|
+
Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field
|
|
896
|
+
sage: phi_e_Sym2Vdual = Sym2Vdual.isomorphism_with_fixed_basis(e_Sym2Vdual,
|
|
897
|
+
....: codomain=W)
|
|
898
|
+
sage: phi_e_Sym2Vdual
|
|
899
|
+
Generic morphism:
|
|
900
|
+
From: Free module of fully symmetric type-(0,2) tensors on the
|
|
901
|
+
3-dimensional vector space over the Rational Field
|
|
902
|
+
To: Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field
|
|
903
|
+
|
|
904
|
+
Sending tensors to elements of the tensor square of :class:`CombinatorialFreeModule`::
|
|
905
|
+
|
|
906
|
+
sage: T20 = V.tensor_module(2, 0); T20
|
|
907
|
+
Free module of type-(2,0) tensors on the
|
|
908
|
+
3-dimensional vector space over the Rational Field
|
|
909
|
+
sage: e_T20 = T02.basis("e"); e_T20
|
|
910
|
+
Standard basis on the
|
|
911
|
+
Free module of type-(0,2) tensors on the
|
|
912
|
+
3-dimensional vector space over the Rational Field
|
|
913
|
+
induced by Basis (e_1,e_2,e_3) on the
|
|
914
|
+
3-dimensional vector space over the Rational Field
|
|
915
|
+
sage: W = CombinatorialFreeModule(QQ, [1, 2, 3]).tensor_square(); W
|
|
916
|
+
Free module generated by {1, 2, 3} over Rational Field
|
|
917
|
+
# Free module generated by {1, 2, 3} over Rational Field
|
|
918
|
+
sage: phi_e_T20 = T20.isomorphism_with_fixed_basis(e_T20, codomain=W); phi_e_T20
|
|
919
|
+
Generic morphism:
|
|
920
|
+
From: Free module of type-(2,0) tensors on the
|
|
921
|
+
3-dimensional vector space over the Rational Field
|
|
922
|
+
To: Free module generated by {1, 2, 3} over Rational Field
|
|
923
|
+
# Free module generated by {1, 2, 3} over Rational Field
|
|
924
|
+
sage: t = T20.an_element(); t.display()
|
|
925
|
+
1/2 e_1⊗e_1
|
|
926
|
+
sage: phi_e_T20(t)
|
|
927
|
+
1/2*B[1] # B[1]
|
|
928
|
+
|
|
929
|
+
TESTS::
|
|
930
|
+
|
|
931
|
+
sage: V = FiniteRankFreeModule(QQ, 3); V
|
|
932
|
+
3-dimensional vector space over the Rational Field
|
|
933
|
+
sage: e = V.basis("e")
|
|
934
|
+
sage: V.isomorphism_with_fixed_basis(e, codomain=QQ^42)
|
|
935
|
+
Traceback (most recent call last):
|
|
936
|
+
...
|
|
937
|
+
ValueError: domain and codomain must have the same rank
|
|
938
|
+
sage: V.isomorphism_with_fixed_basis(e, codomain=RR^3)
|
|
939
|
+
Traceback (most recent call last):
|
|
940
|
+
...
|
|
941
|
+
ValueError: domain and codomain must have the same base ring
|
|
942
|
+
"""
|
|
943
|
+
base_ring = self.base_ring()
|
|
944
|
+
if basis is None:
|
|
945
|
+
basis = self.default_basis()
|
|
946
|
+
if codomain is None:
|
|
947
|
+
from sage.combinat.free_module import CombinatorialFreeModule
|
|
948
|
+
if isinstance(basis._symbol, str):
|
|
949
|
+
prefix = basis._symbol
|
|
950
|
+
else:
|
|
951
|
+
prefix = None
|
|
952
|
+
codomain = CombinatorialFreeModule(base_ring, basis.keys(),
|
|
953
|
+
prefix=prefix)
|
|
954
|
+
else:
|
|
955
|
+
try:
|
|
956
|
+
codomain_rank = codomain.rank()
|
|
957
|
+
except AttributeError:
|
|
958
|
+
# https://github.com/sagemath/sage/issues/34445: MatrixSpace does not have rank
|
|
959
|
+
codomain_rank = codomain.dimension()
|
|
960
|
+
if codomain_rank != self.rank():
|
|
961
|
+
raise ValueError("domain and codomain must have the same rank")
|
|
962
|
+
if codomain.base_ring() != base_ring:
|
|
963
|
+
raise ValueError("domain and codomain must have the same "
|
|
964
|
+
"base ring")
|
|
965
|
+
|
|
966
|
+
codomain_basis = Family(codomain.basis())
|
|
967
|
+
if isinstance(codomain_basis, TrivialFamily):
|
|
968
|
+
# assume that codomain basis keys are to be ignored;
|
|
969
|
+
# need them several times, can't keep as generators
|
|
970
|
+
key_pairs = tuple(enumerate(basis.keys()))
|
|
971
|
+
basis_by_codomain_key = basis
|
|
972
|
+
else:
|
|
973
|
+
# assume that the keys of the codomain should be used
|
|
974
|
+
# need them several times, can't keep as generators
|
|
975
|
+
key_pairs = tuple(zip(codomain_basis.keys(), basis.keys()))
|
|
976
|
+
basis_by_codomain_key = {}
|
|
977
|
+
for codomain_key, domain_key in key_pairs:
|
|
978
|
+
basis_by_codomain_key[codomain_key] = basis[domain_key]
|
|
979
|
+
|
|
980
|
+
def _isomorphism(x):
|
|
981
|
+
r"""
|
|
982
|
+
Concrete isomorphism from ``self`` to ``codomain``.
|
|
983
|
+
"""
|
|
984
|
+
return codomain.sum(x[basis, domain_key] * codomain_basis[codomain_key]
|
|
985
|
+
for codomain_key, domain_key in key_pairs)
|
|
986
|
+
|
|
987
|
+
def _inverse(y):
|
|
988
|
+
r"""
|
|
989
|
+
Concrete isomorphism from ``codomain`` to ``self``.
|
|
990
|
+
"""
|
|
991
|
+
return self.linear_combination(
|
|
992
|
+
(basis_by_codomain_key[codomain_key], coefficient)
|
|
993
|
+
for codomain_key, coefficient in y.monomial_coefficients().items())
|
|
994
|
+
|
|
995
|
+
category = Modules(self.base_ring())
|
|
996
|
+
homset = Hom(self, codomain, category)
|
|
997
|
+
isomorphism = SetIsomorphism(homset, _isomorphism)
|
|
998
|
+
inverse = SetIsomorphism(homset.reversed(), _inverse)
|
|
999
|
+
isomorphism._set_inverse(inverse)
|
|
1000
|
+
inverse._set_inverse(isomorphism)
|
|
1001
|
+
return isomorphism
|
|
1002
|
+
|
|
1003
|
+
def _test_isomorphism_with_fixed_basis(self, **options):
|
|
1004
|
+
r"""
|
|
1005
|
+
Test that the method ``isomorphism_with_fixed_basis`` works correctly.
|
|
1006
|
+
|
|
1007
|
+
EXAMPLES::
|
|
1008
|
+
|
|
1009
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1010
|
+
sage: M._test_isomorphism_with_fixed_basis()
|
|
1011
|
+
"""
|
|
1012
|
+
tester = self._tester(**options)
|
|
1013
|
+
try:
|
|
1014
|
+
basis = self.basis('test')
|
|
1015
|
+
except AttributeError:
|
|
1016
|
+
return
|
|
1017
|
+
morphism = self.isomorphism_with_fixed_basis(basis)
|
|
1018
|
+
tester.assertEqual(morphism.codomain().rank(), self.rank())
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
class FiniteRankFreeModule(ReflexiveModule_base, FiniteRankFreeModule_abstract):
|
|
1022
|
+
r"""
|
|
1023
|
+
Free module of finite rank over a commutative ring.
|
|
1024
|
+
|
|
1025
|
+
A *free module of finite rank* over a commutative ring `R` is a module `M`
|
|
1026
|
+
over `R` that admits a *finite basis*, i.e. a finite family of linearly
|
|
1027
|
+
independent generators. Since `R` is commutative, it has the invariant
|
|
1028
|
+
basis number property, so that the rank of the free module `M` is defined
|
|
1029
|
+
uniquely, as the cardinality of any basis of `M`.
|
|
1030
|
+
|
|
1031
|
+
No distinguished basis of `M` is assumed. On the contrary, many bases can be
|
|
1032
|
+
introduced on the free module along with change-of-basis rules (as module
|
|
1033
|
+
automorphisms). Each
|
|
1034
|
+
module element has then various representations over the various bases.
|
|
1035
|
+
|
|
1036
|
+
.. NOTE::
|
|
1037
|
+
|
|
1038
|
+
The class :class:`FiniteRankFreeModule` does not inherit from
|
|
1039
|
+
class :class:`~sage.modules.free_module.FreeModule_generic`
|
|
1040
|
+
nor from class
|
|
1041
|
+
:class:`~sage.combinat.free_module.CombinatorialFreeModule`, since
|
|
1042
|
+
both classes deal with modules with a *distinguished basis* (see
|
|
1043
|
+
details :ref:`above <diff-FreeModule>`).
|
|
1044
|
+
Moreover, following the recommendation exposed in :issue:`16427`
|
|
1045
|
+
the class :class:`FiniteRankFreeModule` inherits directly from
|
|
1046
|
+
:class:`~sage.structure.parent.Parent` (with the category set to
|
|
1047
|
+
:class:`~sage.categories.modules.Modules`) and not from the Cython
|
|
1048
|
+
class :class:`~sage.modules.module.Module`.
|
|
1049
|
+
|
|
1050
|
+
The class :class:`FiniteRankFreeModule` is a Sage *parent* class,
|
|
1051
|
+
the corresponding *element* class being
|
|
1052
|
+
:class:`~sage.tensor.modules.free_module_element.FiniteRankFreeModuleElement`.
|
|
1053
|
+
|
|
1054
|
+
INPUT:
|
|
1055
|
+
|
|
1056
|
+
- ``ring`` -- commutative ring `R` over which the free module is
|
|
1057
|
+
constructed
|
|
1058
|
+
- ``rank`` -- positive integer; rank of the free module
|
|
1059
|
+
- ``name`` -- (default: ``None``) string; name given to the free module
|
|
1060
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
|
|
1061
|
+
the freemodule; if none is provided, it is set to ``name``
|
|
1062
|
+
- ``start_index`` -- (default: 0) integer; lower bound of the range of
|
|
1063
|
+
indices in bases defined on the free module
|
|
1064
|
+
- ``output_formatter`` -- (default: ``None``) function or unbound
|
|
1065
|
+
method called to format the output of the tensor components;
|
|
1066
|
+
``output_formatter`` must take 1 or 2 arguments: the first argument
|
|
1067
|
+
must be an element of the ring `R` and the second one, if any, some
|
|
1068
|
+
format specification
|
|
1069
|
+
|
|
1070
|
+
EXAMPLES:
|
|
1071
|
+
|
|
1072
|
+
Free module of rank 3 over `\ZZ`::
|
|
1073
|
+
|
|
1074
|
+
sage: FiniteRankFreeModule._clear_cache_() # for doctests only
|
|
1075
|
+
sage: M = FiniteRankFreeModule(ZZ, 3) ; M
|
|
1076
|
+
Rank-3 free module over the Integer Ring
|
|
1077
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') ; M # declaration with a name
|
|
1078
|
+
Rank-3 free module M over the Integer Ring
|
|
1079
|
+
sage: M.category()
|
|
1080
|
+
Category of finite dimensional modules over Integer Ring
|
|
1081
|
+
sage: M.base_ring()
|
|
1082
|
+
Integer Ring
|
|
1083
|
+
sage: M.rank()
|
|
1084
|
+
3
|
|
1085
|
+
|
|
1086
|
+
If the base ring is a field, the free module is in the category of vector
|
|
1087
|
+
spaces::
|
|
1088
|
+
|
|
1089
|
+
sage: V = FiniteRankFreeModule(QQ, 3, name='V') ; V
|
|
1090
|
+
3-dimensional vector space V over the Rational Field
|
|
1091
|
+
sage: V.category()
|
|
1092
|
+
Category of finite dimensional vector spaces over Rational Field
|
|
1093
|
+
|
|
1094
|
+
The LaTeX output is adjusted via the parameter ``latex_name``::
|
|
1095
|
+
|
|
1096
|
+
sage: latex(M) # the default is the symbol provided in the string ``name``
|
|
1097
|
+
M
|
|
1098
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M', latex_name=r'\mathcal{M}')
|
|
1099
|
+
sage: latex(M)
|
|
1100
|
+
\mathcal{M}
|
|
1101
|
+
|
|
1102
|
+
The free module M has no distinguished basis::
|
|
1103
|
+
|
|
1104
|
+
sage: M in ModulesWithBasis(ZZ)
|
|
1105
|
+
False
|
|
1106
|
+
sage: M in Modules(ZZ)
|
|
1107
|
+
True
|
|
1108
|
+
|
|
1109
|
+
In particular, no basis is initialized at the module construction::
|
|
1110
|
+
|
|
1111
|
+
sage: M.print_bases()
|
|
1112
|
+
No basis has been defined on the Rank-3 free module M over the Integer Ring
|
|
1113
|
+
sage: M.bases()
|
|
1114
|
+
[]
|
|
1115
|
+
|
|
1116
|
+
Bases have to be introduced by means of the method :meth:`basis`,
|
|
1117
|
+
the first defined basis being considered as the *default basis*, meaning
|
|
1118
|
+
it can be skipped in function arguments required a basis (this can
|
|
1119
|
+
be changed by means of the method :meth:`set_default_basis`)::
|
|
1120
|
+
|
|
1121
|
+
sage: e = M.basis('e') ; e
|
|
1122
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
1123
|
+
sage: M.default_basis()
|
|
1124
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
1125
|
+
|
|
1126
|
+
A second basis can be created from a family of linearly independent
|
|
1127
|
+
elements expressed in terms of basis ``e``::
|
|
1128
|
+
|
|
1129
|
+
sage: f = M.basis('f', from_family=(-e[0], e[1]+e[2], 2*e[1]+3*e[2]))
|
|
1130
|
+
sage: f
|
|
1131
|
+
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring
|
|
1132
|
+
sage: M.print_bases()
|
|
1133
|
+
Bases defined on the Rank-3 free module M over the Integer Ring:
|
|
1134
|
+
- (e_0,e_1,e_2) (default basis)
|
|
1135
|
+
- (f_0,f_1,f_2)
|
|
1136
|
+
sage: M.bases()
|
|
1137
|
+
[Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring,
|
|
1138
|
+
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring]
|
|
1139
|
+
|
|
1140
|
+
M is a *parent* object, whose elements are instances of
|
|
1141
|
+
:class:`~sage.tensor.modules.free_module_element.FiniteRankFreeModuleElement`
|
|
1142
|
+
(actually a dynamically generated subclass of it)::
|
|
1143
|
+
|
|
1144
|
+
sage: v = M.an_element() ; v
|
|
1145
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
1146
|
+
sage: from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement
|
|
1147
|
+
sage: isinstance(v, FiniteRankFreeModuleElement)
|
|
1148
|
+
True
|
|
1149
|
+
sage: v in M
|
|
1150
|
+
True
|
|
1151
|
+
sage: M.is_parent_of(v)
|
|
1152
|
+
True
|
|
1153
|
+
sage: v.display() # expansion w.r.t. the default basis (e)
|
|
1154
|
+
e_0 + e_1 + e_2
|
|
1155
|
+
sage: v.display(f)
|
|
1156
|
+
-f_0 + f_1
|
|
1157
|
+
|
|
1158
|
+
The test suite of the category of modules is passed::
|
|
1159
|
+
|
|
1160
|
+
sage: TestSuite(M).run()
|
|
1161
|
+
|
|
1162
|
+
Constructing an element of ``M`` from (the integer) 0 yields
|
|
1163
|
+
the zero element of ``M``::
|
|
1164
|
+
|
|
1165
|
+
sage: M(0)
|
|
1166
|
+
Element zero of the Rank-3 free module M over the Integer Ring
|
|
1167
|
+
sage: M(0) is M.zero()
|
|
1168
|
+
True
|
|
1169
|
+
|
|
1170
|
+
Non-zero elements are constructed by providing their components in
|
|
1171
|
+
a given basis::
|
|
1172
|
+
|
|
1173
|
+
sage: v = M([-1,0,3]) ; v # components in the default basis (e)
|
|
1174
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
1175
|
+
sage: v.display() # expansion w.r.t. the default basis (e)
|
|
1176
|
+
-e_0 + 3 e_2
|
|
1177
|
+
sage: v.display(f)
|
|
1178
|
+
f_0 - 6 f_1 + 3 f_2
|
|
1179
|
+
sage: v = M([-1,0,3], basis=f) ; v # components in a specific basis
|
|
1180
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
1181
|
+
sage: v.display(f)
|
|
1182
|
+
-f_0 + 3 f_2
|
|
1183
|
+
sage: v.display()
|
|
1184
|
+
e_0 + 6 e_1 + 9 e_2
|
|
1185
|
+
sage: v = M([-1,0,3], basis=f, name='v') ; v
|
|
1186
|
+
Element v of the Rank-3 free module M over the Integer Ring
|
|
1187
|
+
sage: v.display(f)
|
|
1188
|
+
v = -f_0 + 3 f_2
|
|
1189
|
+
sage: v.display()
|
|
1190
|
+
v = e_0 + 6 e_1 + 9 e_2
|
|
1191
|
+
|
|
1192
|
+
An alternative is to construct the element from an empty list of
|
|
1193
|
+
componentsand to set the nonzero components afterwards::
|
|
1194
|
+
|
|
1195
|
+
sage: v = M([], name='v')
|
|
1196
|
+
sage: v[e,0] = -1
|
|
1197
|
+
sage: v[e,2] = 3
|
|
1198
|
+
sage: v.display(e)
|
|
1199
|
+
v = -e_0 + 3 e_2
|
|
1200
|
+
|
|
1201
|
+
Indices on the free module, such as indices labelling the element of a
|
|
1202
|
+
basis, are provided by the generator method :meth:`irange`. By default,
|
|
1203
|
+
they range from 0 to the module's rank minus one::
|
|
1204
|
+
|
|
1205
|
+
sage: list(M.irange())
|
|
1206
|
+
[0, 1, 2]
|
|
1207
|
+
|
|
1208
|
+
This can be changed via the parameter ``start_index`` in the module
|
|
1209
|
+
construction::
|
|
1210
|
+
|
|
1211
|
+
sage: M1 = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1)
|
|
1212
|
+
sage: list(M1.irange())
|
|
1213
|
+
[1, 2, 3]
|
|
1214
|
+
|
|
1215
|
+
The parameter ``output_formatter`` in the constructor of the free module
|
|
1216
|
+
is used to set the output format of tensor components::
|
|
1217
|
+
|
|
1218
|
+
sage: N = FiniteRankFreeModule(QQ, 3, output_formatter=Rational.numerical_approx)
|
|
1219
|
+
sage: e = N.basis('e')
|
|
1220
|
+
sage: v = N([1/3, 0, -2], basis=e)
|
|
1221
|
+
sage: v[e,:]
|
|
1222
|
+
[0.333333333333333, 0.000000000000000, -2.00000000000000]
|
|
1223
|
+
sage: v.display(e) # default format (53 bits of precision)
|
|
1224
|
+
0.333333333333333 e_0 - 2.00000000000000 e_2
|
|
1225
|
+
sage: v.display(e, format_spec=10) # 10 bits of precision
|
|
1226
|
+
0.33 e_0 - 2.0 e_2
|
|
1227
|
+
"""
|
|
1228
|
+
|
|
1229
|
+
Element = FiniteRankFreeModuleElement
|
|
1230
|
+
_sindex: int
|
|
1231
|
+
|
|
1232
|
+
@staticmethod
|
|
1233
|
+
def __classcall_private__(cls, ring, rank, name=None, latex_name=None, start_index=0,
|
|
1234
|
+
output_formatter=None, category=None, ambient=None):
|
|
1235
|
+
r"""
|
|
1236
|
+
Normalize init arguments for ``UniqueRepresentation``.
|
|
1237
|
+
|
|
1238
|
+
TESTS::
|
|
1239
|
+
|
|
1240
|
+
sage: FiniteRankFreeModule(QQ, 3) is FiniteRankFreeModule(QQ, 3, name=None)
|
|
1241
|
+
True
|
|
1242
|
+
sage: FiniteRankFreeModule(QQ, 3, name='M') is FiniteRankFreeModule(QQ, 3, name='M', latex_name='M')
|
|
1243
|
+
True
|
|
1244
|
+
sage: FiniteRankFreeModule(QQ, 3) is FiniteRankFreeModule(QQ, 3, start_index=0)
|
|
1245
|
+
True
|
|
1246
|
+
sage: FiniteRankFreeModule(QQ, 3) is FiniteRankFreeModule(QQ, 3, output_formatter=None)
|
|
1247
|
+
True
|
|
1248
|
+
sage: FiniteRankFreeModule(QQ, 3) is FiniteRankFreeModule(QQ, 3, category=Modules(QQ).FiniteDimensional())
|
|
1249
|
+
True
|
|
1250
|
+
"""
|
|
1251
|
+
if ring not in Rings().Commutative():
|
|
1252
|
+
raise TypeError("the module base ring must be commutative")
|
|
1253
|
+
category = Modules(ring).FiniteDimensional().or_subcategory(category)
|
|
1254
|
+
if latex_name is None:
|
|
1255
|
+
latex_name = name
|
|
1256
|
+
return super().__classcall__(
|
|
1257
|
+
cls, ring, rank, name, latex_name, start_index, output_formatter, category, ambient)
|
|
1258
|
+
|
|
1259
|
+
def __init__(
|
|
1260
|
+
self,
|
|
1261
|
+
ring,
|
|
1262
|
+
rank,
|
|
1263
|
+
name=None,
|
|
1264
|
+
latex_name=None,
|
|
1265
|
+
start_index: int = 0,
|
|
1266
|
+
output_formatter=None,
|
|
1267
|
+
category=None,
|
|
1268
|
+
ambient=None,
|
|
1269
|
+
):
|
|
1270
|
+
r"""
|
|
1271
|
+
See :class:`FiniteRankFreeModule` for documentation and examples.
|
|
1272
|
+
|
|
1273
|
+
TESTS::
|
|
1274
|
+
|
|
1275
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1276
|
+
sage: TestSuite(M).run()
|
|
1277
|
+
sage: e = M.basis('e')
|
|
1278
|
+
sage: TestSuite(M).run()
|
|
1279
|
+
sage: f = M.basis('f')
|
|
1280
|
+
sage: TestSuite(M).run()
|
|
1281
|
+
"""
|
|
1282
|
+
super().__init__(ring, rank, name=name, latex_name=latex_name,
|
|
1283
|
+
category=category, ambient=ambient)
|
|
1284
|
+
self._sindex = start_index
|
|
1285
|
+
self._output_formatter = output_formatter
|
|
1286
|
+
# Dictionary of the tensor modules built on self
|
|
1287
|
+
# (keys = (k,l) --the tensor type)
|
|
1288
|
+
# This dictionary is to be extended on need by the method tensor_module
|
|
1289
|
+
self._tensor_modules = {}
|
|
1290
|
+
# Dictionaries of exterior powers of self and of its dual
|
|
1291
|
+
# (keys = p --the power degree)
|
|
1292
|
+
# These dictionaries are to be extended on need by the methods
|
|
1293
|
+
# exterior_power and dual_exterior_power
|
|
1294
|
+
self._exterior_powers = {}
|
|
1295
|
+
self._dual_exterior_powers = {}
|
|
1296
|
+
# Set of all modules (tensor powers, exterior powers)
|
|
1297
|
+
# that depend on self's bases:
|
|
1298
|
+
self._all_modules = {self}
|
|
1299
|
+
# List of known bases on the free module:
|
|
1300
|
+
self._known_bases = []
|
|
1301
|
+
self._def_basis = None # default basis
|
|
1302
|
+
self._basis_changes = {} # Dictionary of the changes of bases
|
|
1303
|
+
# Identity automorphism:
|
|
1304
|
+
self._identity_map = None # to be set by self.identity_map()
|
|
1305
|
+
# General linear group:
|
|
1306
|
+
self._general_linear_group = None # to be set by
|
|
1307
|
+
# self.general_linear_group()
|
|
1308
|
+
|
|
1309
|
+
def construction(self):
|
|
1310
|
+
"""
|
|
1311
|
+
The construction functor and base ring for ``self``.
|
|
1312
|
+
|
|
1313
|
+
EXAMPLES::
|
|
1314
|
+
|
|
1315
|
+
sage: FiniteRankFreeModule._clear_cache_() # for doctests only
|
|
1316
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1317
|
+
sage: M.construction()
|
|
1318
|
+
(VectorFunctor, Integer Ring)
|
|
1319
|
+
sage: N = FiniteRankFreeModule(ZZ, 3, name='N', start_index=17)
|
|
1320
|
+
sage: N.construction()
|
|
1321
|
+
(VectorFunctor, Integer Ring)
|
|
1322
|
+
"""
|
|
1323
|
+
# Try to take it from the category
|
|
1324
|
+
c = super().construction()
|
|
1325
|
+
if c is not None:
|
|
1326
|
+
return c
|
|
1327
|
+
# Implementation restrictions:
|
|
1328
|
+
if self._output_formatter:
|
|
1329
|
+
return None
|
|
1330
|
+
from sage.categories.pushout import VectorFunctor
|
|
1331
|
+
kwds = dict(is_sparse=False,
|
|
1332
|
+
inner_product_matrix=None,
|
|
1333
|
+
with_basis=None,
|
|
1334
|
+
name_mapping={self.base_ring(): self._name} if self._name else None,
|
|
1335
|
+
latex_name_mapping={self.base_ring(): self._latex_name} if self._latex_name else None)
|
|
1336
|
+
if self._sindex:
|
|
1337
|
+
return (VectorFunctor(basis_keys=list(self.irange()), **kwds),
|
|
1338
|
+
self.base_ring())
|
|
1339
|
+
return (VectorFunctor(n=self.rank(), **kwds),
|
|
1340
|
+
self.base_ring())
|
|
1341
|
+
|
|
1342
|
+
#### Parent methods
|
|
1343
|
+
|
|
1344
|
+
def _element_constructor_(self, comp=[], basis=None, name=None,
|
|
1345
|
+
latex_name=None):
|
|
1346
|
+
r"""
|
|
1347
|
+
Construct an element of ``self``.
|
|
1348
|
+
|
|
1349
|
+
EXAMPLES::
|
|
1350
|
+
|
|
1351
|
+
sage: FiniteRankFreeModule._clear_cache_() # for doctests only
|
|
1352
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1353
|
+
sage: e = M.basis('e')
|
|
1354
|
+
sage: v = M._element_constructor_(comp=[1,0,-2], basis=e, name='v') ; v
|
|
1355
|
+
Element v of the Rank-3 free module M over the Integer Ring
|
|
1356
|
+
sage: v.display()
|
|
1357
|
+
v = e_0 - 2 e_2
|
|
1358
|
+
sage: v == M([1,0,-2])
|
|
1359
|
+
True
|
|
1360
|
+
sage: v = M._element_constructor_(0) ; v
|
|
1361
|
+
Element zero of the Rank-3 free module M over the Integer Ring
|
|
1362
|
+
sage: v = M._element_constructor_() ; v
|
|
1363
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
1364
|
+
"""
|
|
1365
|
+
if isinstance(comp, (int, Integer)) and comp == 0:
|
|
1366
|
+
return self.zero()
|
|
1367
|
+
resu = self.element_class(self, name=name, latex_name=latex_name)
|
|
1368
|
+
if comp:
|
|
1369
|
+
resu.set_comp(basis)[:] = comp
|
|
1370
|
+
return resu
|
|
1371
|
+
|
|
1372
|
+
def _an_element_(self):
|
|
1373
|
+
r"""
|
|
1374
|
+
Construct some (unnamed) element of ``self``.
|
|
1375
|
+
|
|
1376
|
+
EXAMPLES::
|
|
1377
|
+
|
|
1378
|
+
sage: FiniteRankFreeModule._clear_cache_() # for doctests only
|
|
1379
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1380
|
+
sage: v = M._an_element_(); v
|
|
1381
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
1382
|
+
sage: v.display()
|
|
1383
|
+
e_0 + e_1 + e_2
|
|
1384
|
+
sage: v == M.an_element()
|
|
1385
|
+
True
|
|
1386
|
+
sage: v.parent()
|
|
1387
|
+
Rank-3 free module M over the Integer Ring
|
|
1388
|
+
"""
|
|
1389
|
+
if self._def_basis is None:
|
|
1390
|
+
self.basis('e')
|
|
1391
|
+
resu = self.element_class(self)
|
|
1392
|
+
resu.set_comp()[:] = [self._ring.an_element() for i in range(self._rank)]
|
|
1393
|
+
return resu
|
|
1394
|
+
|
|
1395
|
+
#### End of parent methods
|
|
1396
|
+
|
|
1397
|
+
#### Methods to be redefined by derived classes ####
|
|
1398
|
+
|
|
1399
|
+
def _repr_(self):
|
|
1400
|
+
r"""
|
|
1401
|
+
Return a string representation of ``self``.
|
|
1402
|
+
|
|
1403
|
+
EXAMPLES::
|
|
1404
|
+
|
|
1405
|
+
sage: FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1406
|
+
Rank-3 free module M over the Integer Ring
|
|
1407
|
+
"""
|
|
1408
|
+
if self._ring in Fields():
|
|
1409
|
+
description = "{}-dimensional vector space ".format(self._rank)
|
|
1410
|
+
else:
|
|
1411
|
+
description = "Rank-{} free module ".format(self._rank)
|
|
1412
|
+
if self._name is not None:
|
|
1413
|
+
description += self._name + " "
|
|
1414
|
+
description += "over the {}".format(self._ring)
|
|
1415
|
+
return description
|
|
1416
|
+
|
|
1417
|
+
def _Hom_(self, other, category=None):
|
|
1418
|
+
r"""
|
|
1419
|
+
Construct the set of homomorphisms ``self`` --> ``other``.
|
|
1420
|
+
|
|
1421
|
+
INPUT:
|
|
1422
|
+
|
|
1423
|
+
- ``other`` -- another free module of finite rank over the same ring
|
|
1424
|
+
as ``self``
|
|
1425
|
+
- ``category`` -- (default: ``None``) not used here (to ensure
|
|
1426
|
+
compatibility with generic hook ``_Hom_``)
|
|
1427
|
+
|
|
1428
|
+
OUTPUT:
|
|
1429
|
+
|
|
1430
|
+
- the hom-set Hom(M,N), where M is ``self`` and N is ``other``
|
|
1431
|
+
|
|
1432
|
+
EXAMPLES::
|
|
1433
|
+
|
|
1434
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1435
|
+
sage: N = FiniteRankFreeModule(ZZ, 2, name='N')
|
|
1436
|
+
sage: H = M._Hom_(N) ; H
|
|
1437
|
+
Set of Morphisms from Rank-3 free module M over the Integer Ring
|
|
1438
|
+
to Rank-2 free module N over the Integer Ring
|
|
1439
|
+
in Category of finite dimensional modules over Integer Ring
|
|
1440
|
+
sage: H = Hom(M,N) ; H # indirect doctest
|
|
1441
|
+
Set of Morphisms from Rank-3 free module M over the Integer Ring
|
|
1442
|
+
to Rank-2 free module N over the Integer Ring
|
|
1443
|
+
in Category of finite dimensional modules over Integer Ring
|
|
1444
|
+
"""
|
|
1445
|
+
from .free_module_homset import FreeModuleHomset
|
|
1446
|
+
return FreeModuleHomset(self, other)
|
|
1447
|
+
|
|
1448
|
+
def tensor_module(self, k, l, *, sym=None, antisym=None):
|
|
1449
|
+
r"""
|
|
1450
|
+
Return the free module of all tensors of type `(k, l)` defined on
|
|
1451
|
+
``self``.
|
|
1452
|
+
|
|
1453
|
+
INPUT:
|
|
1454
|
+
|
|
1455
|
+
- ``k`` -- nonnegative integer; the contravariant rank, the tensor
|
|
1456
|
+
type being `(k, l)`
|
|
1457
|
+
- ``l`` -- nonnegative integer; the covariant rank, the tensor type
|
|
1458
|
+
being `(k, l)`
|
|
1459
|
+
- ``sym`` -- (default: ``None``) a symmetry or a list of symmetries
|
|
1460
|
+
among the tensor arguments: each symmetry is described by a tuple
|
|
1461
|
+
containing the positions of the involved arguments, with the
|
|
1462
|
+
convention ``position = 0`` for the first argument. For instance:
|
|
1463
|
+
|
|
1464
|
+
* ``sym = (0,1)`` for a symmetry between the 1st and 2nd arguments
|
|
1465
|
+
* ``sym = [(0,2), (1,3,4)]`` for a symmetry between the 1st and 3rd
|
|
1466
|
+
arguments and a symmetry between the 2nd, 4th and 5th arguments.
|
|
1467
|
+
|
|
1468
|
+
- ``antisym`` -- (default: ``None``) antisymmetry or list of
|
|
1469
|
+
antisymmetries among the arguments, with the same convention
|
|
1470
|
+
as for ``sym``
|
|
1471
|
+
|
|
1472
|
+
OUTPUT:
|
|
1473
|
+
|
|
1474
|
+
- instance of
|
|
1475
|
+
:class:`~sage.tensor.modules.tensor_free_module.TensorFreeModule`
|
|
1476
|
+
representing the free module
|
|
1477
|
+
`T^{(k,l)}(M)` of type-`(k,l)` tensors on the free module ``self``
|
|
1478
|
+
|
|
1479
|
+
EXAMPLES:
|
|
1480
|
+
|
|
1481
|
+
Tensor modules over a free module over `\ZZ`::
|
|
1482
|
+
|
|
1483
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1484
|
+
sage: T = M.tensor_module(1,2) ; T
|
|
1485
|
+
Free module of type-(1,2) tensors on the Rank-3 free module M
|
|
1486
|
+
over the Integer Ring
|
|
1487
|
+
sage: T.an_element()
|
|
1488
|
+
Type-(1,2) tensor on the Rank-3 free module M over the Integer Ring
|
|
1489
|
+
|
|
1490
|
+
Tensor modules are unique::
|
|
1491
|
+
|
|
1492
|
+
sage: M.tensor_module(1,2) is T
|
|
1493
|
+
True
|
|
1494
|
+
|
|
1495
|
+
The module of type-`(1,0)` tensors is the base module itself::
|
|
1496
|
+
|
|
1497
|
+
sage: M.tensor_module(1,0) is M
|
|
1498
|
+
True
|
|
1499
|
+
|
|
1500
|
+
while the module of type-`(0,1)` tensors is the dual of the base module::
|
|
1501
|
+
|
|
1502
|
+
sage: M.tensor_module(0, 1) is M.dual()
|
|
1503
|
+
True
|
|
1504
|
+
|
|
1505
|
+
By using the arguments ``sym`` and ``antisym``, submodules of a full tensor
|
|
1506
|
+
module can be constructed::
|
|
1507
|
+
|
|
1508
|
+
sage: T = M.tensor_module(4, 4, sym=((0, 1)), antisym=((4, 5))); T
|
|
1509
|
+
Free module of type-(4,4) tensors on the Rank-3 free module M over the Integer Ring,
|
|
1510
|
+
with symmetry on the index positions (0, 1),
|
|
1511
|
+
with antisymmetry on the index positions (4, 5)
|
|
1512
|
+
sage: T._name
|
|
1513
|
+
'T^{2,3}(M)⊗T^{6,7}(M*)⊗Sym^{0,1}(M)⊗ASym^{4,5}(M*)'
|
|
1514
|
+
sage: latex(T)
|
|
1515
|
+
T^{\{2,3\}}(M) \otimes T^{\{6,7\}}(M^*) \otimes \mathrm{Sym}^{\{0,1\}}(M) \otimes \mathrm{ASym}^{\{4,5\}}(M^*)
|
|
1516
|
+
|
|
1517
|
+
See :class:`~sage.tensor.modules.tensor_free_module.TensorFreeModule`
|
|
1518
|
+
and :class:`~sage.tensor.modules.tensor_free_module.TensorFreeSubmodule_sym`
|
|
1519
|
+
for more documentation.
|
|
1520
|
+
|
|
1521
|
+
TESTS::
|
|
1522
|
+
|
|
1523
|
+
sage: M = FiniteRankFreeModule(ZZ, 2)
|
|
1524
|
+
sage: M.tensor_module(2, 0, sym=(0,1)) is M.symmetric_power(2)
|
|
1525
|
+
True
|
|
1526
|
+
"""
|
|
1527
|
+
from .comp import CompWithSym
|
|
1528
|
+
|
|
1529
|
+
sym, antisym = CompWithSym._canonicalize_sym_antisym(k + l, sym, antisym)
|
|
1530
|
+
if sym or antisym:
|
|
1531
|
+
key = (k, l, sym, antisym)
|
|
1532
|
+
else:
|
|
1533
|
+
key = (k, l)
|
|
1534
|
+
try:
|
|
1535
|
+
return self._tensor_modules[key]
|
|
1536
|
+
except KeyError:
|
|
1537
|
+
if key == (1, 0):
|
|
1538
|
+
T = self
|
|
1539
|
+
elif key == (0, 1):
|
|
1540
|
+
T = self.dual()
|
|
1541
|
+
elif sym or antisym:
|
|
1542
|
+
from sage.tensor.modules.tensor_free_submodule import TensorFreeSubmodule_sym
|
|
1543
|
+
T = TensorFreeSubmodule_sym(self, (k, l), sym=sym, antisym=antisym)
|
|
1544
|
+
else:
|
|
1545
|
+
from sage.tensor.modules.tensor_free_module import TensorFreeModule
|
|
1546
|
+
T = TensorFreeModule(self, (k, l))
|
|
1547
|
+
self._tensor_modules[key] = T
|
|
1548
|
+
return T
|
|
1549
|
+
|
|
1550
|
+
def symmetric_power(self, p):
|
|
1551
|
+
r"""
|
|
1552
|
+
Return the `p`-th symmetric power of ``self``.
|
|
1553
|
+
|
|
1554
|
+
EXAMPLES:
|
|
1555
|
+
|
|
1556
|
+
Symmetric powers of a free `\ZZ`-module of rank 3::
|
|
1557
|
+
|
|
1558
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1559
|
+
sage: e = M.basis('e')
|
|
1560
|
+
sage: M.symmetric_power(0)
|
|
1561
|
+
Free module of type-(0,0) tensors on the Rank-3 free module M over the Integer Ring
|
|
1562
|
+
sage: M.symmetric_power(1) # return the module itself
|
|
1563
|
+
Rank-3 free module M over the Integer Ring
|
|
1564
|
+
sage: M.symmetric_power(1) is M
|
|
1565
|
+
True
|
|
1566
|
+
sage: M.symmetric_power(2)
|
|
1567
|
+
Free module of fully symmetric type-(2,0) tensors
|
|
1568
|
+
on the Rank-3 free module M over the Integer Ring
|
|
1569
|
+
sage: M.symmetric_power(2).an_element()
|
|
1570
|
+
Type-(2,0) tensor on the Rank-3 free module M over the Integer Ring
|
|
1571
|
+
sage: M.symmetric_power(2).an_element().display()
|
|
1572
|
+
e_0⊗e_0
|
|
1573
|
+
sage: M.symmetric_power(3)
|
|
1574
|
+
Free module of fully symmetric type-(3,0) tensors
|
|
1575
|
+
on the Rank-3 free module M over the Integer Ring
|
|
1576
|
+
sage: M.symmetric_power(3).an_element()
|
|
1577
|
+
Type-(3,0) tensor on the Rank-3 free module M over the Integer Ring
|
|
1578
|
+
sage: M.symmetric_power(3).an_element().display()
|
|
1579
|
+
e_0⊗e_0⊗e_0
|
|
1580
|
+
"""
|
|
1581
|
+
if p <= 1:
|
|
1582
|
+
return self.tensor_module(p, 0)
|
|
1583
|
+
return self.tensor_module(p, 0, sym=(tuple(range(p)),))
|
|
1584
|
+
|
|
1585
|
+
def dual_symmetric_power(self, p):
|
|
1586
|
+
r"""
|
|
1587
|
+
Return the `p`-th symmetric power of the dual of ``self``.
|
|
1588
|
+
|
|
1589
|
+
EXAMPLES:
|
|
1590
|
+
|
|
1591
|
+
Symmetric powers of the dual of a free `\ZZ`-module of rank 3::
|
|
1592
|
+
|
|
1593
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1594
|
+
sage: e = M.basis('e')
|
|
1595
|
+
sage: M.dual_symmetric_power(0)
|
|
1596
|
+
Free module of type-(0,0) tensors on the Rank-3 free module M over the Integer Ring
|
|
1597
|
+
sage: M.dual_symmetric_power(1) # return the dual module
|
|
1598
|
+
Dual of the Rank-3 free module M over the Integer Ring
|
|
1599
|
+
sage: M.dual_symmetric_power(2)
|
|
1600
|
+
Free module of fully symmetric type-(0,2) tensors
|
|
1601
|
+
on the Rank-3 free module M over the Integer Ring
|
|
1602
|
+
sage: M.dual_symmetric_power(2).an_element()
|
|
1603
|
+
Symmetric bilinear form on the Rank-3 free module M over the Integer Ring
|
|
1604
|
+
sage: M.dual_symmetric_power(2).an_element().display()
|
|
1605
|
+
e^0⊗e^0
|
|
1606
|
+
sage: M.dual_symmetric_power(3)
|
|
1607
|
+
Free module of fully symmetric type-(0,3) tensors
|
|
1608
|
+
on the Rank-3 free module M over the Integer Ring
|
|
1609
|
+
sage: M.dual_symmetric_power(3).an_element()
|
|
1610
|
+
Type-(0,3) tensor on the Rank-3 free module M over the Integer Ring
|
|
1611
|
+
sage: M.dual_symmetric_power(3).an_element().display()
|
|
1612
|
+
e^0⊗e^0⊗e^0
|
|
1613
|
+
"""
|
|
1614
|
+
if p <= 1:
|
|
1615
|
+
return self.tensor_module(0, p)
|
|
1616
|
+
return self.tensor_module(0, p, sym=(tuple(range(p)),))
|
|
1617
|
+
|
|
1618
|
+
def exterior_power(self, p):
|
|
1619
|
+
r"""
|
|
1620
|
+
Return the `p`-th exterior power of ``self``.
|
|
1621
|
+
|
|
1622
|
+
If `M` stands for the free module ``self``, the *p-th exterior
|
|
1623
|
+
power of* `M` is the set `\Lambda^p(M)` of all *alternating
|
|
1624
|
+
contravariant tensors* of rank `p`, i.e. of all multilinear maps
|
|
1625
|
+
|
|
1626
|
+
.. MATH::
|
|
1627
|
+
|
|
1628
|
+
\underbrace{M^*\times\cdots\times M^*}_{p\ \; \mbox{times}}
|
|
1629
|
+
\longrightarrow R
|
|
1630
|
+
|
|
1631
|
+
that vanish whenever any of two of their arguments are equal.
|
|
1632
|
+
`\Lambda^p(M)` is a free module of rank `\binom{n}{p}`
|
|
1633
|
+
over the same ring as `M`, where `n` is the rank of `M`.
|
|
1634
|
+
|
|
1635
|
+
INPUT:
|
|
1636
|
+
|
|
1637
|
+
- ``p`` -- nonnegative integer
|
|
1638
|
+
|
|
1639
|
+
OUTPUT:
|
|
1640
|
+
|
|
1641
|
+
- for `p=0`, the base ring `R`
|
|
1642
|
+
- for `p=1`, the free module `M`, since `\Lambda^1(M)=M`
|
|
1643
|
+
- for `p\geq 2`, instance of
|
|
1644
|
+
:class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerFreeModule`
|
|
1645
|
+
representing the free module `\Lambda^p(M)`
|
|
1646
|
+
|
|
1647
|
+
EXAMPLES:
|
|
1648
|
+
|
|
1649
|
+
Exterior powers of a free `\ZZ`-module of rank 3::
|
|
1650
|
+
|
|
1651
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1652
|
+
sage: e = M.basis('e')
|
|
1653
|
+
sage: M.exterior_power(0) # return the base ring
|
|
1654
|
+
Integer Ring
|
|
1655
|
+
sage: M.exterior_power(1) # return the module itself
|
|
1656
|
+
Rank-3 free module M over the Integer Ring
|
|
1657
|
+
sage: M.exterior_power(1) is M
|
|
1658
|
+
True
|
|
1659
|
+
sage: M.exterior_power(2)
|
|
1660
|
+
2nd exterior power of the Rank-3 free module M over the Integer Ring
|
|
1661
|
+
sage: M.exterior_power(2).an_element()
|
|
1662
|
+
Alternating contravariant tensor of degree 2 on the Rank-3
|
|
1663
|
+
free module M over the Integer Ring
|
|
1664
|
+
sage: M.exterior_power(2).an_element().display()
|
|
1665
|
+
e_0∧e_1
|
|
1666
|
+
sage: M.exterior_power(3)
|
|
1667
|
+
3rd exterior power of the Rank-3 free module M over the Integer Ring
|
|
1668
|
+
sage: M.exterior_power(3).an_element()
|
|
1669
|
+
Alternating contravariant tensor of degree 3 on the Rank-3
|
|
1670
|
+
free module M over the Integer Ring
|
|
1671
|
+
sage: M.exterior_power(3).an_element().display()
|
|
1672
|
+
e_0∧e_1∧e_2
|
|
1673
|
+
|
|
1674
|
+
See
|
|
1675
|
+
:class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerFreeModule`
|
|
1676
|
+
for more documentation.
|
|
1677
|
+
"""
|
|
1678
|
+
try:
|
|
1679
|
+
return self._exterior_powers[p]
|
|
1680
|
+
except KeyError:
|
|
1681
|
+
if p == 0:
|
|
1682
|
+
L = self._ring
|
|
1683
|
+
elif p == 1:
|
|
1684
|
+
L = self
|
|
1685
|
+
else:
|
|
1686
|
+
from sage.tensor.modules.ext_pow_free_module import ExtPowerFreeModule
|
|
1687
|
+
L = ExtPowerFreeModule(self, p)
|
|
1688
|
+
self._exterior_powers[p] = L
|
|
1689
|
+
return L
|
|
1690
|
+
|
|
1691
|
+
def dual_exterior_power(self, p):
|
|
1692
|
+
r"""
|
|
1693
|
+
Return the `p`-th exterior power of the dual of ``self``.
|
|
1694
|
+
|
|
1695
|
+
If `M` stands for the free module ``self``, the *p-th exterior
|
|
1696
|
+
power of the dual of* `M` is the set `\Lambda^p(M^*)` of all
|
|
1697
|
+
*alternating forms of degree* `p` on `M`, i.e. of all
|
|
1698
|
+
multilinear maps
|
|
1699
|
+
|
|
1700
|
+
.. MATH::
|
|
1701
|
+
|
|
1702
|
+
\underbrace{M\times\cdots\times M}_{p\ \; \mbox{times}}
|
|
1703
|
+
\longrightarrow R
|
|
1704
|
+
|
|
1705
|
+
that vanish whenever any of two of their arguments are equal.
|
|
1706
|
+
`\Lambda^p(M^*)` is a free module of rank `\binom{n}{p}`
|
|
1707
|
+
over the same ring as `M`, where `n` is the rank of `M`.
|
|
1708
|
+
|
|
1709
|
+
INPUT:
|
|
1710
|
+
|
|
1711
|
+
- ``p`` -- nonnegative integer
|
|
1712
|
+
|
|
1713
|
+
OUTPUT:
|
|
1714
|
+
|
|
1715
|
+
- for `p=0`, the base ring `R`
|
|
1716
|
+
- for `p=1`, instance of
|
|
1717
|
+
:class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankDualFreeModule`
|
|
1718
|
+
representing the dual `M^*`
|
|
1719
|
+
- for `p\geq 1`, instance of
|
|
1720
|
+
:class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerDualFreeModule`
|
|
1721
|
+
representing the free module `\Lambda^p(M^*)`
|
|
1722
|
+
|
|
1723
|
+
EXAMPLES:
|
|
1724
|
+
|
|
1725
|
+
Exterior powers of the dual of a free `\ZZ`-module of rank 3::
|
|
1726
|
+
|
|
1727
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1728
|
+
sage: e = M.basis('e')
|
|
1729
|
+
sage: M.dual_exterior_power(0) # return the base ring
|
|
1730
|
+
Integer Ring
|
|
1731
|
+
sage: M.dual_exterior_power(1) # return the dual module
|
|
1732
|
+
Dual of the Rank-3 free module M over the Integer Ring
|
|
1733
|
+
sage: M.dual_exterior_power(1) is M.dual()
|
|
1734
|
+
True
|
|
1735
|
+
sage: M.dual_exterior_power(2)
|
|
1736
|
+
2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring
|
|
1737
|
+
sage: M.dual_exterior_power(2).an_element()
|
|
1738
|
+
Alternating form of degree 2 on the Rank-3 free module M over the Integer Ring
|
|
1739
|
+
sage: M.dual_exterior_power(2).an_element().display()
|
|
1740
|
+
e^0∧e^1
|
|
1741
|
+
sage: M.dual_exterior_power(3)
|
|
1742
|
+
3rd exterior power of the dual of the Rank-3 free module M over the Integer Ring
|
|
1743
|
+
sage: M.dual_exterior_power(3).an_element()
|
|
1744
|
+
Alternating form of degree 3 on the Rank-3 free module M over the Integer Ring
|
|
1745
|
+
sage: M.dual_exterior_power(3).an_element().display()
|
|
1746
|
+
e^0∧e^1∧e^2
|
|
1747
|
+
|
|
1748
|
+
See
|
|
1749
|
+
:class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerDualFreeModule`
|
|
1750
|
+
for more documentation.
|
|
1751
|
+
"""
|
|
1752
|
+
try:
|
|
1753
|
+
return self._dual_exterior_powers[p]
|
|
1754
|
+
except KeyError:
|
|
1755
|
+
if p == 0:
|
|
1756
|
+
L = self._ring
|
|
1757
|
+
elif p == 1:
|
|
1758
|
+
L = FiniteRankDualFreeModule(self)
|
|
1759
|
+
else:
|
|
1760
|
+
from sage.tensor.modules.ext_pow_free_module import ExtPowerDualFreeModule
|
|
1761
|
+
L = ExtPowerDualFreeModule(self, p)
|
|
1762
|
+
self._dual_exterior_powers[p] = L
|
|
1763
|
+
return L
|
|
1764
|
+
|
|
1765
|
+
def general_linear_group(self):
|
|
1766
|
+
r"""
|
|
1767
|
+
Return the general linear group of ``self``.
|
|
1768
|
+
|
|
1769
|
+
If ``self`` is the free module `M`, the *general linear group* is the
|
|
1770
|
+
group `\mathrm{GL}(M)` of automorphisms of `M`.
|
|
1771
|
+
|
|
1772
|
+
OUTPUT:
|
|
1773
|
+
|
|
1774
|
+
- instance of class
|
|
1775
|
+
:class:`~sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup`
|
|
1776
|
+
representing `\mathrm{GL}(M)`
|
|
1777
|
+
|
|
1778
|
+
EXAMPLES:
|
|
1779
|
+
|
|
1780
|
+
The general linear group of a rank-3 free module::
|
|
1781
|
+
|
|
1782
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1783
|
+
sage: e = M.basis('e')
|
|
1784
|
+
sage: GL = M.general_linear_group() ; GL
|
|
1785
|
+
General linear group of the Rank-3 free module M over the Integer Ring
|
|
1786
|
+
sage: GL.category()
|
|
1787
|
+
Category of groups
|
|
1788
|
+
sage: type(GL)
|
|
1789
|
+
<class 'sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup_with_category'>
|
|
1790
|
+
|
|
1791
|
+
There is a unique instance of the general linear group::
|
|
1792
|
+
|
|
1793
|
+
sage: M.general_linear_group() is GL
|
|
1794
|
+
True
|
|
1795
|
+
|
|
1796
|
+
The group identity element::
|
|
1797
|
+
|
|
1798
|
+
sage: GL.one()
|
|
1799
|
+
Identity map of the Rank-3 free module M over the Integer Ring
|
|
1800
|
+
sage: GL.one().matrix(e)
|
|
1801
|
+
[1 0 0]
|
|
1802
|
+
[0 1 0]
|
|
1803
|
+
[0 0 1]
|
|
1804
|
+
|
|
1805
|
+
An element::
|
|
1806
|
+
|
|
1807
|
+
sage: GL.an_element()
|
|
1808
|
+
Automorphism of the Rank-3 free module M over the Integer Ring
|
|
1809
|
+
sage: GL.an_element().matrix(e)
|
|
1810
|
+
[ 1 0 0]
|
|
1811
|
+
[ 0 -1 0]
|
|
1812
|
+
[ 0 0 1]
|
|
1813
|
+
|
|
1814
|
+
See
|
|
1815
|
+
:class:`~sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup`
|
|
1816
|
+
for more documentation.
|
|
1817
|
+
"""
|
|
1818
|
+
from sage.tensor.modules.free_module_linear_group import \
|
|
1819
|
+
FreeModuleLinearGroup
|
|
1820
|
+
if self._general_linear_group is None:
|
|
1821
|
+
self._general_linear_group = FreeModuleLinearGroup(self)
|
|
1822
|
+
return self._general_linear_group
|
|
1823
|
+
|
|
1824
|
+
def basis(self, symbol, latex_symbol=None, from_family=None,
|
|
1825
|
+
indices=None, latex_indices=None, symbol_dual=None,
|
|
1826
|
+
latex_symbol_dual=None):
|
|
1827
|
+
r"""
|
|
1828
|
+
Define or return a basis of the free module ``self``.
|
|
1829
|
+
|
|
1830
|
+
Let `M` denotes the free module ``self`` and `n` its rank.
|
|
1831
|
+
|
|
1832
|
+
The basis can be defined from a set of `n` linearly independent
|
|
1833
|
+
elements of `M` by means of the argument ``from_family``.
|
|
1834
|
+
If ``from_family`` is not specified, the basis is created from
|
|
1835
|
+
scratch and, at this stage, is unrelated to bases that could have been
|
|
1836
|
+
defined previously on `M`. It can be related afterwards by means of
|
|
1837
|
+
the method :meth:`set_change_of_basis`.
|
|
1838
|
+
|
|
1839
|
+
If the basis specified by the given symbol already exists, it is
|
|
1840
|
+
simply returned, whatever the value of the arguments ``latex_symbol``
|
|
1841
|
+
or ``from_family``.
|
|
1842
|
+
|
|
1843
|
+
Note that another way to construct a basis of ``self`` is to use
|
|
1844
|
+
the method
|
|
1845
|
+
:meth:`~sage.tensor.modules.free_module_basis.FreeModuleBasis.new_basis`
|
|
1846
|
+
on an existing basis, with the automorphism relating the two bases as
|
|
1847
|
+
an argument.
|
|
1848
|
+
|
|
1849
|
+
INPUT:
|
|
1850
|
+
|
|
1851
|
+
- ``symbol`` -- either a string, to be used as a common base for the
|
|
1852
|
+
symbols of the elements of the basis, or a list/tuple of strings,
|
|
1853
|
+
representing the individual symbols of the elements of the basis
|
|
1854
|
+
- ``latex_symbol`` -- (default: ``None``) either a string, to be used
|
|
1855
|
+
as a common base for the LaTeX symbols of the elements of the basis,
|
|
1856
|
+
or a list/tuple of strings, representing the individual LaTeX symbols
|
|
1857
|
+
of the elements of the basis; if ``None``, ``symbol`` is used in
|
|
1858
|
+
place of ``latex_symbol``
|
|
1859
|
+
- ``from_family`` -- (default: ``None``) tuple or list of `n` linearly
|
|
1860
|
+
independent elements of the free module ``self`` (`n` being the
|
|
1861
|
+
rank of ``self``)
|
|
1862
|
+
- ``indices`` -- (default: ``None``; used only if ``symbol`` is a
|
|
1863
|
+
single string) list/tuple of strings representing the indices
|
|
1864
|
+
labelling the elements of the basis; if ``None``, the indices will be
|
|
1865
|
+
generated as integers within the range declared on ``self``
|
|
1866
|
+
- ``latex_indices`` -- (default: ``None``) list/tuple of strings
|
|
1867
|
+
representing the indices for the LaTeX symbols of the elements of
|
|
1868
|
+
the basis; if ``None``, ``indices`` is used instead
|
|
1869
|
+
- ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
|
|
1870
|
+
dual basis; if ``None``, ``symbol`` must be a string and is used
|
|
1871
|
+
for the common base of the symbols of the elements of the dual basis
|
|
1872
|
+
- ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
|
|
1873
|
+
but for the dual basis
|
|
1874
|
+
|
|
1875
|
+
OUTPUT:
|
|
1876
|
+
|
|
1877
|
+
- instance of
|
|
1878
|
+
:class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`
|
|
1879
|
+
representing a basis on ``self``
|
|
1880
|
+
|
|
1881
|
+
EXAMPLES:
|
|
1882
|
+
|
|
1883
|
+
Bases on a rank-3 free module::
|
|
1884
|
+
|
|
1885
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
1886
|
+
sage: e = M.basis('e') ; e
|
|
1887
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
1888
|
+
sage: e[0]
|
|
1889
|
+
Element e_0 of the Rank-3 free module M over the Integer Ring
|
|
1890
|
+
sage: latex(e)
|
|
1891
|
+
\left(e_{0},e_{1},e_{2}\right)
|
|
1892
|
+
|
|
1893
|
+
The LaTeX symbol can be set explicitly::
|
|
1894
|
+
|
|
1895
|
+
sage: eps = M.basis('eps', latex_symbol=r'\epsilon') ; eps
|
|
1896
|
+
Basis (eps_0,eps_1,eps_2) on the Rank-3 free module M
|
|
1897
|
+
over the Integer Ring
|
|
1898
|
+
sage: latex(eps)
|
|
1899
|
+
\left(\epsilon_{0},\epsilon_{1},\epsilon_{2}\right)
|
|
1900
|
+
|
|
1901
|
+
The indices can be customized::
|
|
1902
|
+
|
|
1903
|
+
sage: f = M.basis('f', indices=('x', 'y', 'z')); f
|
|
1904
|
+
Basis (f_x,f_y,f_z) on the Rank-3 free module M over the Integer Ring
|
|
1905
|
+
sage: latex(f[1])
|
|
1906
|
+
f_{y}
|
|
1907
|
+
|
|
1908
|
+
By providing a list or a tuple for the argument ``symbol``, one can
|
|
1909
|
+
have a different symbol for each element of the basis; it is then
|
|
1910
|
+
mandatory to specify some symbols for the dual basis::
|
|
1911
|
+
|
|
1912
|
+
sage: g = M.basis(('a', 'b', 'c'), symbol_dual=('A', 'B', 'C')); g
|
|
1913
|
+
Basis (a,b,c) on the Rank-3 free module M over the Integer Ring
|
|
1914
|
+
sage: g.dual_basis()
|
|
1915
|
+
Dual basis (A,B,C) on the Rank-3 free module M over the Integer Ring
|
|
1916
|
+
|
|
1917
|
+
If the provided symbol and indices are that of an already defined
|
|
1918
|
+
basis, the latter is returned (no new basis is created)::
|
|
1919
|
+
|
|
1920
|
+
sage: M.basis('e') is e
|
|
1921
|
+
True
|
|
1922
|
+
sage: M.basis('eps') is eps
|
|
1923
|
+
True
|
|
1924
|
+
sage: M.basis('e', indices=['x', 'y', 'z']) is e
|
|
1925
|
+
False
|
|
1926
|
+
sage: M.basis('e', indices=['x', 'y', 'z']) is \
|
|
1927
|
+
....: M.basis('e', indices=['x', 'y', 'z'])
|
|
1928
|
+
True
|
|
1929
|
+
|
|
1930
|
+
The individual elements of the basis are labelled according the
|
|
1931
|
+
parameter ``start_index`` provided at the free module construction::
|
|
1932
|
+
|
|
1933
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1)
|
|
1934
|
+
sage: e = M.basis('e') ; e
|
|
1935
|
+
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
|
|
1936
|
+
sage: e[1]
|
|
1937
|
+
Element e_1 of the Rank-3 free module M over the Integer Ring
|
|
1938
|
+
|
|
1939
|
+
Construction of a basis from a spanning family of linearly independent
|
|
1940
|
+
module elements::
|
|
1941
|
+
|
|
1942
|
+
sage: f1 = -e[2]
|
|
1943
|
+
sage: f2 = 4*e[1] + 3*e[3]
|
|
1944
|
+
sage: f3 = 7*e[1] + 5*e[3]
|
|
1945
|
+
sage: f = M.basis('f', from_family=(f1,f2,f3))
|
|
1946
|
+
sage: f[1].display()
|
|
1947
|
+
f_1 = -e_2
|
|
1948
|
+
sage: f[2].display()
|
|
1949
|
+
f_2 = 4 e_1 + 3 e_3
|
|
1950
|
+
sage: f[3].display()
|
|
1951
|
+
f_3 = 7 e_1 + 5 e_3
|
|
1952
|
+
|
|
1953
|
+
The change-of-basis automorphisms have been registered::
|
|
1954
|
+
|
|
1955
|
+
sage: M.change_of_basis(e,f).matrix(e)
|
|
1956
|
+
[ 0 4 7]
|
|
1957
|
+
[-1 0 0]
|
|
1958
|
+
[ 0 3 5]
|
|
1959
|
+
sage: M.change_of_basis(f,e).matrix(e)
|
|
1960
|
+
[ 0 -1 0]
|
|
1961
|
+
[-5 0 7]
|
|
1962
|
+
[ 3 0 -4]
|
|
1963
|
+
sage: M.change_of_basis(f,e) == M.change_of_basis(e,f).inverse()
|
|
1964
|
+
True
|
|
1965
|
+
|
|
1966
|
+
Check of the change-of-basis e --> f::
|
|
1967
|
+
|
|
1968
|
+
sage: a = M.change_of_basis(e,f) ; a
|
|
1969
|
+
Automorphism of the Rank-3 free module M over the Integer Ring
|
|
1970
|
+
sage: all( f[i] == a(e[i]) for i in M.irange() )
|
|
1971
|
+
True
|
|
1972
|
+
|
|
1973
|
+
Providing a family of module elements that are not linearly independent
|
|
1974
|
+
raise an error::
|
|
1975
|
+
|
|
1976
|
+
sage: g = M.basis('g', from_family=(f1, f2, f1+f2))
|
|
1977
|
+
Traceback (most recent call last):
|
|
1978
|
+
...
|
|
1979
|
+
ValueError: the provided module elements are not linearly
|
|
1980
|
+
independent
|
|
1981
|
+
|
|
1982
|
+
For more documentation on bases see
|
|
1983
|
+
:class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`.
|
|
1984
|
+
"""
|
|
1985
|
+
from .free_module_basis import FreeModuleBasis
|
|
1986
|
+
for other in self._known_bases:
|
|
1987
|
+
if symbol == other._symbol and indices == other._indices:
|
|
1988
|
+
return other
|
|
1989
|
+
resu = FreeModuleBasis(self, symbol, latex_symbol=latex_symbol,
|
|
1990
|
+
indices=indices, latex_indices=latex_indices,
|
|
1991
|
+
symbol_dual=symbol_dual,
|
|
1992
|
+
latex_symbol_dual=latex_symbol_dual)
|
|
1993
|
+
if from_family:
|
|
1994
|
+
try:
|
|
1995
|
+
resu._init_from_family(from_family)
|
|
1996
|
+
except ZeroDivisionError:
|
|
1997
|
+
raise ValueError("the provided module elements are not "
|
|
1998
|
+
"linearly independent")
|
|
1999
|
+
return resu
|
|
2000
|
+
|
|
2001
|
+
def _test_basis(self, tester=None, **options):
|
|
2002
|
+
r"""
|
|
2003
|
+
Test that the ``basis`` method works correctly.
|
|
2004
|
+
|
|
2005
|
+
EXAMPLES::
|
|
2006
|
+
|
|
2007
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2008
|
+
sage: M._test_basis(verbose=True)
|
|
2009
|
+
<BLANKLINE>
|
|
2010
|
+
Running the test suite of self.basis('test')
|
|
2011
|
+
running ._test_an_element() . . . pass
|
|
2012
|
+
running ._test_cardinality() . . . pass
|
|
2013
|
+
running ._test_category() . . . pass
|
|
2014
|
+
running ._test_construction() . . . pass
|
|
2015
|
+
running ._test_elements() . . .
|
|
2016
|
+
Running the test suite of self.an_element()
|
|
2017
|
+
running ._test_category() . . . pass
|
|
2018
|
+
running ._test_eq() . . . pass
|
|
2019
|
+
running ._test_new() . . . pass
|
|
2020
|
+
running ._test_nonzero_equal() . . . pass
|
|
2021
|
+
running ._test_not_implemented_methods() . . . pass
|
|
2022
|
+
running ._test_pickling() . . . pass
|
|
2023
|
+
pass
|
|
2024
|
+
running ._test_elements_eq_reflexive() . . . pass
|
|
2025
|
+
running ._test_elements_eq_symmetric() . . . pass
|
|
2026
|
+
running ._test_elements_eq_transitive() . . . pass
|
|
2027
|
+
running ._test_elements_neq() . . . pass
|
|
2028
|
+
running ._test_enumerated_set_contains() . . . pass
|
|
2029
|
+
running ._test_enumerated_set_iter_cardinality() . . . pass
|
|
2030
|
+
running ._test_enumerated_set_iter_list() . . . pass
|
|
2031
|
+
running ._test_eq() . . . pass
|
|
2032
|
+
running ._test_iter_len() . . . pass
|
|
2033
|
+
running ._test_new() . . . pass
|
|
2034
|
+
running ._test_not_implemented_methods() . . . pass
|
|
2035
|
+
running ._test_pickling() . . . pass
|
|
2036
|
+
running ._test_some_elements() . . . pass
|
|
2037
|
+
"""
|
|
2038
|
+
from sage.misc.sage_unittest import TestSuite
|
|
2039
|
+
# The intention is to raise an exception only if this is
|
|
2040
|
+
# run as a sub-testsuite of a larger testsuite.
|
|
2041
|
+
# (from _test_elements)
|
|
2042
|
+
is_sub_testsuite = (tester is not None)
|
|
2043
|
+
tester = self._tester(tester=tester, **options)
|
|
2044
|
+
try:
|
|
2045
|
+
b = self.basis('test')
|
|
2046
|
+
except NotImplementedError:
|
|
2047
|
+
return
|
|
2048
|
+
# Test uniqueness
|
|
2049
|
+
b_again = self.basis('test')
|
|
2050
|
+
tester.assertTrue(b is b_again)
|
|
2051
|
+
# Test rank
|
|
2052
|
+
tester.assertEqual(len(b), self.rank())
|
|
2053
|
+
indices = list(self.irange())
|
|
2054
|
+
tester.assertEqual(len(b), len(indices))
|
|
2055
|
+
# Test basis indexing
|
|
2056
|
+
for index, element in zip(indices, b):
|
|
2057
|
+
tester.assertTrue(element is b[index])
|
|
2058
|
+
# Run test suite of the basis object (similar to _test_elements)
|
|
2059
|
+
tester.info("\n Running the test suite of self.basis('test')")
|
|
2060
|
+
TestSuite(b).run(verbose=tester._verbose, prefix=tester._prefix + " ",
|
|
2061
|
+
raise_on_failure=is_sub_testsuite)
|
|
2062
|
+
|
|
2063
|
+
def _tensor(self, tensor_type, name=None, latex_name=None, sym=None,
|
|
2064
|
+
antisym=None):
|
|
2065
|
+
r"""
|
|
2066
|
+
Construct a tensor on the free module ``self``.
|
|
2067
|
+
|
|
2068
|
+
INPUT:
|
|
2069
|
+
|
|
2070
|
+
- ``tensor_type`` -- pair ``(k, l)`` with ``k`` being the
|
|
2071
|
+
contravariant rank and ``l`` the covariant rank
|
|
2072
|
+
|
|
2073
|
+
- ``name`` -- (default: ``None``) string; name given to the tensor
|
|
2074
|
+
|
|
2075
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2076
|
+
denote the tensor; if none is provided, the LaTeX symbol is set
|
|
2077
|
+
to ``name``
|
|
2078
|
+
|
|
2079
|
+
- ``sym`` -- (default: ``None``) a symmetry or an iterable of symmetries
|
|
2080
|
+
among the tensor arguments: each symmetry is described by a tuple
|
|
2081
|
+
containing the positions of the involved arguments, with the
|
|
2082
|
+
convention ``position = 0`` for the first argument. For instance:
|
|
2083
|
+
|
|
2084
|
+
* ``sym = (0,1)`` for a symmetry between the 1st and 2nd arguments
|
|
2085
|
+
* ``sym = [(0,2), (1,3,4)]`` for a symmetry between the 1st and 3rd
|
|
2086
|
+
arguments and a symmetry between the 2nd, 4th and 5th arguments.
|
|
2087
|
+
|
|
2088
|
+
- ``antisym`` -- (default: ``None``) antisymmetry or iterable of
|
|
2089
|
+
antisymmetries among the arguments, with the same convention
|
|
2090
|
+
as for ``sym``
|
|
2091
|
+
|
|
2092
|
+
OUTPUT:
|
|
2093
|
+
|
|
2094
|
+
- instance of
|
|
2095
|
+
:class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`
|
|
2096
|
+
representing the tensor defined on ``self`` with the provided
|
|
2097
|
+
characteristics
|
|
2098
|
+
|
|
2099
|
+
EXAMPLES:
|
|
2100
|
+
|
|
2101
|
+
Tensors on a rank-3 free module::
|
|
2102
|
+
|
|
2103
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2104
|
+
sage: t = M._tensor((1,0), name='t') ; t
|
|
2105
|
+
Element t of the Rank-3 free module M over the Integer Ring
|
|
2106
|
+
"""
|
|
2107
|
+
from .comp import CompWithSym
|
|
2108
|
+
sym, antisym = CompWithSym._canonicalize_sym_antisym(
|
|
2109
|
+
tensor_type[0] + tensor_type[1], sym, antisym)
|
|
2110
|
+
# Special cases:
|
|
2111
|
+
if tensor_type == (1,0):
|
|
2112
|
+
return self.element_class(self, name=name, latex_name=latex_name)
|
|
2113
|
+
elif tensor_type == (0,1):
|
|
2114
|
+
return self.linear_form(name=name, latex_name=latex_name)
|
|
2115
|
+
elif tensor_type[0] == 0 and tensor_type[1] > 1 and antisym:
|
|
2116
|
+
if len(antisym[0]) == tensor_type[1]:
|
|
2117
|
+
return self.alternating_form(tensor_type[1], name=name,
|
|
2118
|
+
latex_name=latex_name)
|
|
2119
|
+
elif tensor_type[0] > 1 and tensor_type[1] == 0 and antisym:
|
|
2120
|
+
if len(antisym[0]) == tensor_type[0]:
|
|
2121
|
+
return self.alternating_contravariant_tensor(tensor_type[0],
|
|
2122
|
+
name=name, latex_name=latex_name)
|
|
2123
|
+
# Generic case:
|
|
2124
|
+
return self.tensor_module(*tensor_type).element_class(self,
|
|
2125
|
+
tensor_type, name=name, latex_name=latex_name,
|
|
2126
|
+
sym=sym, antisym=antisym)
|
|
2127
|
+
|
|
2128
|
+
def tensor(self, *args, **kwds):
|
|
2129
|
+
r"""
|
|
2130
|
+
Construct a tensor on the free module ``self`` or a tensor product with other modules.
|
|
2131
|
+
|
|
2132
|
+
If ``args`` consist of other parents, just delegate to :meth:`tensor_product`.
|
|
2133
|
+
|
|
2134
|
+
Otherwise, construct a tensor from the following input.
|
|
2135
|
+
|
|
2136
|
+
INPUT:
|
|
2137
|
+
|
|
2138
|
+
- ``tensor_type`` -- pair ``(k, l)`` with ``k`` being the
|
|
2139
|
+
contravariant rank and ``l`` the covariant rank
|
|
2140
|
+
|
|
2141
|
+
- ``name`` -- (default: ``None``) string; name given to the tensor
|
|
2142
|
+
|
|
2143
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2144
|
+
denote the tensor; if none is provided, the LaTeX symbol is set
|
|
2145
|
+
to ``name``
|
|
2146
|
+
|
|
2147
|
+
- ``sym`` -- (default: ``None``) a symmetry or an iterable of symmetries
|
|
2148
|
+
among the tensor arguments: each symmetry is described by a tuple
|
|
2149
|
+
containing the positions of the involved arguments, with the
|
|
2150
|
+
convention ``position = 0`` for the first argument. For instance:
|
|
2151
|
+
|
|
2152
|
+
* ``sym = (0,1)`` for a symmetry between the 1st and 2nd arguments
|
|
2153
|
+
* ``sym = [(0,2), (1,3,4)]`` for a symmetry between the 1st and 3rd
|
|
2154
|
+
arguments and a symmetry between the 2nd, 4th and 5th arguments.
|
|
2155
|
+
|
|
2156
|
+
- ``antisym`` -- (default: ``None``) antisymmetry or iterable of
|
|
2157
|
+
antisymmetries among the arguments, with the same convention
|
|
2158
|
+
as for ``sym``
|
|
2159
|
+
|
|
2160
|
+
OUTPUT:
|
|
2161
|
+
|
|
2162
|
+
- instance of
|
|
2163
|
+
:class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`
|
|
2164
|
+
representing the tensor defined on ``self`` with the provided
|
|
2165
|
+
characteristics
|
|
2166
|
+
|
|
2167
|
+
EXAMPLES:
|
|
2168
|
+
|
|
2169
|
+
Tensors on a rank-3 free module::
|
|
2170
|
+
|
|
2171
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2172
|
+
sage: t = M.tensor((1,0), name='t') ; t
|
|
2173
|
+
Element t of the Rank-3 free module M over the Integer Ring
|
|
2174
|
+
sage: t = M.tensor((0,1), name='t') ; t
|
|
2175
|
+
Linear form t on the Rank-3 free module M over the Integer Ring
|
|
2176
|
+
sage: t = M.tensor((1,1), name='t') ; t
|
|
2177
|
+
Type-(1,1) tensor t on the Rank-3 free module M over the Integer Ring
|
|
2178
|
+
sage: t = M.tensor((0,2), name='t', sym=(0,1)) ; t
|
|
2179
|
+
Symmetric bilinear form t on the
|
|
2180
|
+
Rank-3 free module M over the Integer Ring
|
|
2181
|
+
sage: t = M.tensor((0,2), name='t', antisym=(0,1)) ; t
|
|
2182
|
+
Alternating form t of degree 2 on the
|
|
2183
|
+
Rank-3 free module M over the Integer Ring
|
|
2184
|
+
sage: t = M.tensor((1,2), name='t') ; t
|
|
2185
|
+
Type-(1,2) tensor t on the Rank-3 free module M over the Integer Ring
|
|
2186
|
+
|
|
2187
|
+
See :class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`
|
|
2188
|
+
for more examples and documentation.
|
|
2189
|
+
|
|
2190
|
+
TESTS:
|
|
2191
|
+
|
|
2192
|
+
Trivial symmetries in the list of symmetries or antisymmetries are silently
|
|
2193
|
+
ignored::
|
|
2194
|
+
|
|
2195
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2196
|
+
sage: M.tensor((3,0), sym=[[1]])
|
|
2197
|
+
Type-(3,0) tensor on the Rank-3 free module M over the Integer Ring
|
|
2198
|
+
sage: M.tensor((3,0), antisym=[[]])
|
|
2199
|
+
Type-(3,0) tensor on the Rank-3 free module M over the Integer Ring
|
|
2200
|
+
"""
|
|
2201
|
+
# Until https://github.com/sagemath/sage/issues/30373 is done,
|
|
2202
|
+
# TensorProductFunctor._functor_name is "tensor", so this method
|
|
2203
|
+
# also needs to double as the tensor product construction
|
|
2204
|
+
if isinstance(args[0], Parent):
|
|
2205
|
+
return self.tensor_product(*args, **kwds)
|
|
2206
|
+
return self._tensor(*args, **kwds)
|
|
2207
|
+
|
|
2208
|
+
def tensor_from_comp(self, tensor_type, comp, name=None, latex_name=None):
|
|
2209
|
+
r"""
|
|
2210
|
+
Construct a tensor on ``self`` from a set of components.
|
|
2211
|
+
|
|
2212
|
+
The tensor symmetries are deduced from those of the components.
|
|
2213
|
+
|
|
2214
|
+
INPUT:
|
|
2215
|
+
|
|
2216
|
+
- ``tensor_type`` -- pair ``(k, l)`` with ``k`` being the
|
|
2217
|
+
contravariant rank and ``l`` the covariant rank
|
|
2218
|
+
- ``comp`` -- instance of :class:`~sage.tensor.modules.comp.Components`
|
|
2219
|
+
representing the tensor components in a given basis
|
|
2220
|
+
- ``name`` -- (default: ``None``) string; name given to the tensor
|
|
2221
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
|
|
2222
|
+
the tensor; if none is provided, the LaTeX symbol is set to ``name``
|
|
2223
|
+
|
|
2224
|
+
OUTPUT:
|
|
2225
|
+
|
|
2226
|
+
- instance of
|
|
2227
|
+
:class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`
|
|
2228
|
+
representing the tensor defined on ``self`` with the provided
|
|
2229
|
+
characteristics.
|
|
2230
|
+
|
|
2231
|
+
EXAMPLES:
|
|
2232
|
+
|
|
2233
|
+
Construction of a tensor of rank 1::
|
|
2234
|
+
|
|
2235
|
+
sage: from sage.tensor.modules.comp import Components, CompWithSym, CompFullySym, CompFullyAntiSym
|
|
2236
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2237
|
+
sage: e = M.basis('e') ; e
|
|
2238
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
2239
|
+
sage: c = Components(ZZ, e, 1)
|
|
2240
|
+
sage: c[:]
|
|
2241
|
+
[0, 0, 0]
|
|
2242
|
+
sage: c[:] = [-1,4,2]
|
|
2243
|
+
sage: t = M.tensor_from_comp((1,0), c)
|
|
2244
|
+
sage: t
|
|
2245
|
+
Element of the Rank-3 free module M over the Integer Ring
|
|
2246
|
+
sage: t.display(e)
|
|
2247
|
+
-e_0 + 4 e_1 + 2 e_2
|
|
2248
|
+
sage: t = M.tensor_from_comp((0,1), c) ; t
|
|
2249
|
+
Linear form on the Rank-3 free module M over the Integer Ring
|
|
2250
|
+
sage: t.display(e)
|
|
2251
|
+
-e^0 + 4 e^1 + 2 e^2
|
|
2252
|
+
|
|
2253
|
+
Construction of a tensor of rank 2::
|
|
2254
|
+
|
|
2255
|
+
sage: c = CompFullySym(ZZ, e, 2)
|
|
2256
|
+
sage: c[0,0], c[1,2] = 4, 5
|
|
2257
|
+
sage: t = M.tensor_from_comp((0,2), c) ; t
|
|
2258
|
+
Symmetric bilinear form on the
|
|
2259
|
+
Rank-3 free module M over the Integer Ring
|
|
2260
|
+
sage: t.symmetries()
|
|
2261
|
+
symmetry: (0, 1); no antisymmetry
|
|
2262
|
+
sage: t.display(e)
|
|
2263
|
+
4 e^0⊗e^0 + 5 e^1⊗e^2 + 5 e^2⊗e^1
|
|
2264
|
+
sage: c = CompFullyAntiSym(ZZ, e, 2)
|
|
2265
|
+
sage: c[0,1], c[1,2] = 4, 5
|
|
2266
|
+
sage: t = M.tensor_from_comp((0,2), c) ; t
|
|
2267
|
+
Alternating form of degree 2 on the
|
|
2268
|
+
Rank-3 free module M over the Integer Ring
|
|
2269
|
+
sage: t.display(e)
|
|
2270
|
+
4 e^0∧e^1 + 5 e^1∧e^2
|
|
2271
|
+
"""
|
|
2272
|
+
from .comp import CompWithSym, CompFullyAntiSym
|
|
2273
|
+
|
|
2274
|
+
# 0/ Compatibility checks:
|
|
2275
|
+
if comp._ring is not self._ring:
|
|
2276
|
+
raise TypeError("the components are not defined on the same"
|
|
2277
|
+
" ring as the module")
|
|
2278
|
+
if comp._frame not in self._known_bases:
|
|
2279
|
+
raise TypeError("the components are not defined on a basis of"
|
|
2280
|
+
" the module")
|
|
2281
|
+
if comp._nid != tensor_type[0] + tensor_type[1]:
|
|
2282
|
+
raise TypeError("number of component indices not compatible with "
|
|
2283
|
+
" the tensor type")
|
|
2284
|
+
|
|
2285
|
+
# 1/ Construction of the tensor:
|
|
2286
|
+
if tensor_type == (1, 0):
|
|
2287
|
+
resu = self.element_class(self, name=name, latex_name=latex_name)
|
|
2288
|
+
elif tensor_type == (0, 1):
|
|
2289
|
+
resu = self.linear_form(name=name, latex_name=latex_name)
|
|
2290
|
+
elif tensor_type[0] == 0 and tensor_type[1] > 1 and \
|
|
2291
|
+
isinstance(comp, CompFullyAntiSym):
|
|
2292
|
+
resu = self.alternating_form(tensor_type[1], name=name,
|
|
2293
|
+
latex_name=latex_name)
|
|
2294
|
+
elif tensor_type[0] > 1 and tensor_type[1] == 0 and \
|
|
2295
|
+
isinstance(comp, CompFullyAntiSym):
|
|
2296
|
+
resu = self.alternating_contravariant_tensor(tensor_type[0],
|
|
2297
|
+
name=name,
|
|
2298
|
+
latex_name=latex_name)
|
|
2299
|
+
else:
|
|
2300
|
+
resu = self.tensor_module(*tensor_type).element_class(self,
|
|
2301
|
+
tensor_type, name=name, latex_name=latex_name)
|
|
2302
|
+
# Tensor symmetries deduced from those of comp:
|
|
2303
|
+
if isinstance(comp, CompWithSym):
|
|
2304
|
+
resu._sym = comp._sym
|
|
2305
|
+
resu._antisym = comp._antisym
|
|
2306
|
+
|
|
2307
|
+
# 2/ Tensor components set to comp:
|
|
2308
|
+
resu._components[comp._frame] = comp
|
|
2309
|
+
|
|
2310
|
+
return resu
|
|
2311
|
+
|
|
2312
|
+
def alternating_contravariant_tensor(self, degree, name=None,
|
|
2313
|
+
latex_name=None):
|
|
2314
|
+
r"""
|
|
2315
|
+
Construct an alternating contravariant tensor on the free module.
|
|
2316
|
+
|
|
2317
|
+
INPUT:
|
|
2318
|
+
|
|
2319
|
+
- ``degree`` -- degree of the alternating contravariant tensor
|
|
2320
|
+
(i.e. its tensor rank)
|
|
2321
|
+
- ``name`` -- (default: ``None``) string; name given to the
|
|
2322
|
+
alternating contravariant tensor
|
|
2323
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2324
|
+
denote the alternating contravariant tensor; if none is
|
|
2325
|
+
provided, the LaTeX symbol is set to ``name``
|
|
2326
|
+
|
|
2327
|
+
OUTPUT:
|
|
2328
|
+
|
|
2329
|
+
- instance of
|
|
2330
|
+
:class:`~sage.tensor.modules.alternating_contr_tensor.AlternatingContrTensor`
|
|
2331
|
+
|
|
2332
|
+
EXAMPLES:
|
|
2333
|
+
|
|
2334
|
+
Alternating contravariant tensor on a rank-3 module::
|
|
2335
|
+
|
|
2336
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2337
|
+
sage: a = M.alternating_contravariant_tensor(2, 'a') ; a
|
|
2338
|
+
Alternating contravariant tensor a of degree 2 on the
|
|
2339
|
+
Rank-3 free module M over the Integer Ring
|
|
2340
|
+
|
|
2341
|
+
The nonzero components in a given basis have to be set in a second
|
|
2342
|
+
step, thereby fully specifying the alternating form::
|
|
2343
|
+
|
|
2344
|
+
sage: e = M.basis('e') ; e
|
|
2345
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
2346
|
+
sage: a.set_comp(e)[0,1] = 2
|
|
2347
|
+
sage: a.set_comp(e)[1,2] = -3
|
|
2348
|
+
sage: a.display(e)
|
|
2349
|
+
a = 2 e_0∧e_1 - 3 e_1∧e_2
|
|
2350
|
+
|
|
2351
|
+
An alternating contravariant tensor of degree 1 is simply
|
|
2352
|
+
an element of the module::
|
|
2353
|
+
|
|
2354
|
+
sage: a = M.alternating_contravariant_tensor(1, 'a') ; a
|
|
2355
|
+
Element a of the Rank-3 free module M over the Integer Ring
|
|
2356
|
+
|
|
2357
|
+
See
|
|
2358
|
+
:class:`~sage.tensor.modules.alternating_contr_tensor.AlternatingContrTensor`
|
|
2359
|
+
for more documentation.
|
|
2360
|
+
"""
|
|
2361
|
+
if degree == 1:
|
|
2362
|
+
return self.element_class(self, name=name,
|
|
2363
|
+
latex_name=latex_name)
|
|
2364
|
+
return self.exterior_power(degree).element_class(self, degree,
|
|
2365
|
+
name=name, latex_name=latex_name)
|
|
2366
|
+
|
|
2367
|
+
def alternating_form(self, degree, name=None, latex_name=None):
|
|
2368
|
+
r"""
|
|
2369
|
+
Construct an alternating form on the free module.
|
|
2370
|
+
|
|
2371
|
+
INPUT:
|
|
2372
|
+
|
|
2373
|
+
- ``degree`` -- the degree of the alternating form (i.e. its
|
|
2374
|
+
tensor rank)
|
|
2375
|
+
- ``name`` -- (default: ``None``) string; name given to the
|
|
2376
|
+
alternating form
|
|
2377
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2378
|
+
denote the alternating form; if none is provided, the LaTeX symbol
|
|
2379
|
+
is set to ``name``
|
|
2380
|
+
|
|
2381
|
+
OUTPUT:
|
|
2382
|
+
|
|
2383
|
+
- instance of
|
|
2384
|
+
:class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`
|
|
2385
|
+
|
|
2386
|
+
EXAMPLES:
|
|
2387
|
+
|
|
2388
|
+
Alternating forms on a rank-3 module::
|
|
2389
|
+
|
|
2390
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2391
|
+
sage: a = M.alternating_form(2, 'a') ; a
|
|
2392
|
+
Alternating form a of degree 2 on the
|
|
2393
|
+
Rank-3 free module M over the Integer Ring
|
|
2394
|
+
|
|
2395
|
+
The nonzero components in a given basis have to be set in a second
|
|
2396
|
+
step, thereby fully specifying the alternating form::
|
|
2397
|
+
|
|
2398
|
+
sage: e = M.basis('e') ; e
|
|
2399
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
2400
|
+
sage: a.set_comp(e)[0,1] = 2
|
|
2401
|
+
sage: a.set_comp(e)[1,2] = -3
|
|
2402
|
+
sage: a.display(e)
|
|
2403
|
+
a = 2 e^0∧e^1 - 3 e^1∧e^2
|
|
2404
|
+
|
|
2405
|
+
An alternating form of degree 1 is a linear form::
|
|
2406
|
+
|
|
2407
|
+
sage: a = M.alternating_form(1, 'a') ; a
|
|
2408
|
+
Linear form a on the Rank-3 free module M over the Integer Ring
|
|
2409
|
+
|
|
2410
|
+
To construct such a form, it is preferable to call the method
|
|
2411
|
+
:meth:`linear_form` instead::
|
|
2412
|
+
|
|
2413
|
+
sage: a = M.linear_form('a') ; a
|
|
2414
|
+
Linear form a on the Rank-3 free module M over the Integer Ring
|
|
2415
|
+
|
|
2416
|
+
See
|
|
2417
|
+
:class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`
|
|
2418
|
+
for more documentation.
|
|
2419
|
+
"""
|
|
2420
|
+
if degree == 0:
|
|
2421
|
+
try:
|
|
2422
|
+
return self._ring.element_class(self._ring, name=name,
|
|
2423
|
+
latex_name=latex_name)
|
|
2424
|
+
except (KeyError, AttributeError):
|
|
2425
|
+
raise NotImplementedError('{} apparently '.format(self._ring) +
|
|
2426
|
+
'does not provide generic elements')
|
|
2427
|
+
return self.dual_exterior_power(degree).element_class(self, degree,
|
|
2428
|
+
name=name, latex_name=latex_name)
|
|
2429
|
+
|
|
2430
|
+
def linear_form(self, name=None, latex_name=None):
|
|
2431
|
+
r"""
|
|
2432
|
+
Construct a linear form on the free module ``self``.
|
|
2433
|
+
|
|
2434
|
+
A *linear form* on a free module `M` over a ring `R` is a map
|
|
2435
|
+
`M \rightarrow R` that is linear. It can be viewed as a tensor of type
|
|
2436
|
+
`(0,1)` on `M`.
|
|
2437
|
+
|
|
2438
|
+
INPUT:
|
|
2439
|
+
|
|
2440
|
+
- ``name`` -- (default: ``None``) string; name given to the linear
|
|
2441
|
+
form
|
|
2442
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2443
|
+
denote the linear form; if none is provided, the LaTeX symbol
|
|
2444
|
+
is set to ``name``
|
|
2445
|
+
|
|
2446
|
+
OUTPUT:
|
|
2447
|
+
|
|
2448
|
+
- instance of
|
|
2449
|
+
:class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`
|
|
2450
|
+
|
|
2451
|
+
EXAMPLES:
|
|
2452
|
+
|
|
2453
|
+
Linear form on a rank-3 free module::
|
|
2454
|
+
|
|
2455
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2456
|
+
sage: e = M.basis('e')
|
|
2457
|
+
sage: a = M.linear_form('A') ; a
|
|
2458
|
+
Linear form A on the Rank-3 free module M over the Integer Ring
|
|
2459
|
+
sage: a[:] = [2,-1,3] # components w.r.t. the module's default basis (e)
|
|
2460
|
+
sage: a.display()
|
|
2461
|
+
A = 2 e^0 - e^1 + 3 e^2
|
|
2462
|
+
|
|
2463
|
+
A linear form maps module elements to ring elements::
|
|
2464
|
+
|
|
2465
|
+
sage: v = M([1,1,1])
|
|
2466
|
+
sage: a(v)
|
|
2467
|
+
4
|
|
2468
|
+
|
|
2469
|
+
Test of linearity::
|
|
2470
|
+
|
|
2471
|
+
sage: u = M([-5,-2,7])
|
|
2472
|
+
sage: a(3*u - 4*v) == 3*a(u) - 4*a(v)
|
|
2473
|
+
True
|
|
2474
|
+
|
|
2475
|
+
See
|
|
2476
|
+
:class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`
|
|
2477
|
+
for more documentation.
|
|
2478
|
+
"""
|
|
2479
|
+
return self.dual_exterior_power(1).element_class(self, 1, name=name,
|
|
2480
|
+
latex_name=latex_name)
|
|
2481
|
+
|
|
2482
|
+
def automorphism(self, matrix=None, basis=None, name=None,
|
|
2483
|
+
latex_name=None):
|
|
2484
|
+
r"""
|
|
2485
|
+
Construct a module automorphism of ``self``.
|
|
2486
|
+
|
|
2487
|
+
Denoting ``self`` by `M`, an automorphism of ``self`` is an element
|
|
2488
|
+
of the general linear group `\mathrm{GL}(M)`.
|
|
2489
|
+
|
|
2490
|
+
INPUT:
|
|
2491
|
+
|
|
2492
|
+
- ``matrix`` -- (default: ``None``) matrix of size rank(M)*rank(M)
|
|
2493
|
+
representing the automorphism with respect to ``basis``;
|
|
2494
|
+
this entry can actually be any material from which a matrix of
|
|
2495
|
+
elements of ``self`` base ring can be constructed; the *columns* of
|
|
2496
|
+
``matrix`` must be the components w.r.t. ``basis`` of
|
|
2497
|
+
the images of the elements of ``basis``. If ``matrix`` is ``None``,
|
|
2498
|
+
the automorphism has to be initialized afterwards by
|
|
2499
|
+
method :meth:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor.set_comp`
|
|
2500
|
+
or via the operator [].
|
|
2501
|
+
- ``basis`` -- (default: ``None``) basis of ``self`` defining the
|
|
2502
|
+
matrix representation; if ``None`` the default basis of ``self`` is
|
|
2503
|
+
assumed.
|
|
2504
|
+
- ``name`` -- (default: ``None``) string; name given to the
|
|
2505
|
+
automorphism
|
|
2506
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2507
|
+
denote the automorphism; if none is provided, the LaTeX symbol
|
|
2508
|
+
is set to ``name``
|
|
2509
|
+
|
|
2510
|
+
OUTPUT:
|
|
2511
|
+
|
|
2512
|
+
- instance of
|
|
2513
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
2514
|
+
|
|
2515
|
+
EXAMPLES:
|
|
2516
|
+
|
|
2517
|
+
Automorphism of a rank-2 free `\ZZ`-module::
|
|
2518
|
+
|
|
2519
|
+
sage: M = FiniteRankFreeModule(ZZ, 2, name='M')
|
|
2520
|
+
sage: e = M.basis('e')
|
|
2521
|
+
sage: a = M.automorphism(matrix=[[1,2],[1,3]], basis=e, name='a') ; a
|
|
2522
|
+
Automorphism a of the Rank-2 free module M over the Integer Ring
|
|
2523
|
+
sage: a.parent()
|
|
2524
|
+
General linear group of the Rank-2 free module M over the Integer Ring
|
|
2525
|
+
sage: a.matrix(e)
|
|
2526
|
+
[1 2]
|
|
2527
|
+
[1 3]
|
|
2528
|
+
|
|
2529
|
+
An automorphism is a tensor of type (1,1)::
|
|
2530
|
+
|
|
2531
|
+
sage: a.tensor_type()
|
|
2532
|
+
(1, 1)
|
|
2533
|
+
sage: a.display(e)
|
|
2534
|
+
a = e_0⊗e^0 + 2 e_0⊗e^1 + e_1⊗e^0 + 3 e_1⊗e^1
|
|
2535
|
+
|
|
2536
|
+
The automorphism components can be specified in a second step, as
|
|
2537
|
+
components of a type-`(1,1)` tensor::
|
|
2538
|
+
|
|
2539
|
+
sage: a1 = M.automorphism(name='a')
|
|
2540
|
+
sage: a1[e,:] = [[1,2],[1,3]]
|
|
2541
|
+
sage: a1.matrix(e)
|
|
2542
|
+
[1 2]
|
|
2543
|
+
[1 3]
|
|
2544
|
+
sage: a1 == a
|
|
2545
|
+
True
|
|
2546
|
+
|
|
2547
|
+
Component by component specification::
|
|
2548
|
+
|
|
2549
|
+
sage: a2 = M.automorphism(name='a')
|
|
2550
|
+
sage: a2[0,0] = 1 # component set in the module's default basis (e)
|
|
2551
|
+
sage: a2[0,1] = 2
|
|
2552
|
+
sage: a2[1,0] = 1
|
|
2553
|
+
sage: a2[1,1] = 3
|
|
2554
|
+
sage: a2.matrix(e)
|
|
2555
|
+
[1 2]
|
|
2556
|
+
[1 3]
|
|
2557
|
+
sage: a2 == a
|
|
2558
|
+
True
|
|
2559
|
+
|
|
2560
|
+
See
|
|
2561
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
2562
|
+
for more documentation.
|
|
2563
|
+
"""
|
|
2564
|
+
resu = self.general_linear_group().element_class(self, name=name,
|
|
2565
|
+
latex_name=latex_name)
|
|
2566
|
+
if matrix:
|
|
2567
|
+
if basis is None:
|
|
2568
|
+
basis = self.default_basis()
|
|
2569
|
+
resu.set_comp(basis)[:] = matrix
|
|
2570
|
+
return resu
|
|
2571
|
+
|
|
2572
|
+
def sym_bilinear_form(self, name=None, latex_name=None):
|
|
2573
|
+
r"""
|
|
2574
|
+
Construct a symmetric bilinear form on the free module ``self``.
|
|
2575
|
+
|
|
2576
|
+
INPUT:
|
|
2577
|
+
|
|
2578
|
+
- ``name`` -- (default: ``None``) string; name given to the symmetric
|
|
2579
|
+
bilinear form
|
|
2580
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
2581
|
+
denote the symmetric bilinear form; if none is provided, the LaTeX
|
|
2582
|
+
symbol is set to ``name``
|
|
2583
|
+
|
|
2584
|
+
OUTPUT:
|
|
2585
|
+
|
|
2586
|
+
- instance of
|
|
2587
|
+
:class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`
|
|
2588
|
+
of tensor type `(0,2)` and symmetric
|
|
2589
|
+
|
|
2590
|
+
EXAMPLES:
|
|
2591
|
+
|
|
2592
|
+
Symmetric bilinear form on a rank-3 free module::
|
|
2593
|
+
|
|
2594
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2595
|
+
sage: a = M.sym_bilinear_form('A') ; a
|
|
2596
|
+
Symmetric bilinear form A on the
|
|
2597
|
+
Rank-3 free module M over the Integer Ring
|
|
2598
|
+
|
|
2599
|
+
A symmetric bilinear form is a type-`(0,2)` tensor that is symmetric::
|
|
2600
|
+
|
|
2601
|
+
sage: a.parent()
|
|
2602
|
+
Free module of type-(0,2) tensors on the
|
|
2603
|
+
Rank-3 free module M over the Integer Ring
|
|
2604
|
+
sage: a.tensor_type()
|
|
2605
|
+
(0, 2)
|
|
2606
|
+
sage: a.tensor_rank()
|
|
2607
|
+
2
|
|
2608
|
+
sage: a.symmetries()
|
|
2609
|
+
symmetry: (0, 1); no antisymmetry
|
|
2610
|
+
|
|
2611
|
+
Components with respect to a given basis::
|
|
2612
|
+
|
|
2613
|
+
sage: e = M.basis('e')
|
|
2614
|
+
sage: a[0,0], a[0,1], a[0,2] = 1, 2, 3
|
|
2615
|
+
sage: a[1,1], a[1,2] = 4, 5
|
|
2616
|
+
sage: a[2,2] = 6
|
|
2617
|
+
|
|
2618
|
+
Only independent components have been set; the other ones are
|
|
2619
|
+
deduced by symmetry::
|
|
2620
|
+
|
|
2621
|
+
sage: a[1,0], a[2,0], a[2,1]
|
|
2622
|
+
(2, 3, 5)
|
|
2623
|
+
sage: a[:]
|
|
2624
|
+
[1 2 3]
|
|
2625
|
+
[2 4 5]
|
|
2626
|
+
[3 5 6]
|
|
2627
|
+
|
|
2628
|
+
A symmetric bilinear form acts on pairs of module elements::
|
|
2629
|
+
|
|
2630
|
+
sage: u = M([2,-1,3]) ; v = M([-2,4,1])
|
|
2631
|
+
sage: a(u,v)
|
|
2632
|
+
61
|
|
2633
|
+
sage: a(v,u) == a(u,v)
|
|
2634
|
+
True
|
|
2635
|
+
|
|
2636
|
+
The sum of two symmetric bilinear forms is another symmetric bilinear
|
|
2637
|
+
form::
|
|
2638
|
+
|
|
2639
|
+
sage: b = M.sym_bilinear_form('B')
|
|
2640
|
+
sage: b[0,0], b[0,1], b[1,2] = -2, 1, -3
|
|
2641
|
+
sage: s = a + b ; s
|
|
2642
|
+
Symmetric bilinear form A+B on the
|
|
2643
|
+
Rank-3 free module M over the Integer Ring
|
|
2644
|
+
sage: a[:], b[:], s[:]
|
|
2645
|
+
(
|
|
2646
|
+
[1 2 3] [-2 1 0] [-1 3 3]
|
|
2647
|
+
[2 4 5] [ 1 0 -3] [ 3 4 2]
|
|
2648
|
+
[3 5 6], [ 0 -3 0], [ 3 2 6]
|
|
2649
|
+
)
|
|
2650
|
+
|
|
2651
|
+
Adding a symmetric bilinear from with a non-symmetric one results in a
|
|
2652
|
+
generic type-`(0,2)` tensor::
|
|
2653
|
+
|
|
2654
|
+
sage: c = M.tensor((0,2), name='C')
|
|
2655
|
+
sage: c[0,1] = 4
|
|
2656
|
+
sage: s = a + c ; s
|
|
2657
|
+
Type-(0,2) tensor A+C on the Rank-3 free module M over the Integer Ring
|
|
2658
|
+
sage: s.symmetries()
|
|
2659
|
+
no symmetry; no antisymmetry
|
|
2660
|
+
sage: s[:]
|
|
2661
|
+
[1 6 3]
|
|
2662
|
+
[2 4 5]
|
|
2663
|
+
[3 5 6]
|
|
2664
|
+
|
|
2665
|
+
See :class:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor`
|
|
2666
|
+
for more documentation.
|
|
2667
|
+
"""
|
|
2668
|
+
return self.tensor_module(0,2).element_class(self, (0,2), name=name,
|
|
2669
|
+
latex_name=latex_name, sym=(0,1))
|
|
2670
|
+
|
|
2671
|
+
#### End of methods to be redefined by derived classes ####
|
|
2672
|
+
|
|
2673
|
+
def dual(self):
|
|
2674
|
+
r"""
|
|
2675
|
+
Return the dual module of ``self``.
|
|
2676
|
+
|
|
2677
|
+
EXAMPLES:
|
|
2678
|
+
|
|
2679
|
+
Dual of a free module over `\ZZ`::
|
|
2680
|
+
|
|
2681
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
2682
|
+
sage: M.dual()
|
|
2683
|
+
Dual of the Rank-3 free module M over the Integer Ring
|
|
2684
|
+
sage: latex(M.dual())
|
|
2685
|
+
M^*
|
|
2686
|
+
|
|
2687
|
+
The dual is a free module of the same rank as M::
|
|
2688
|
+
|
|
2689
|
+
sage: from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule_abstract
|
|
2690
|
+
sage: isinstance(M.dual(), FiniteRankFreeModule_abstract)
|
|
2691
|
+
True
|
|
2692
|
+
sage: M.dual().rank()
|
|
2693
|
+
3
|
|
2694
|
+
|
|
2695
|
+
It is formed by alternating forms of degree 1, i.e. linear forms::
|
|
2696
|
+
|
|
2697
|
+
sage: M.dual() is M.dual_exterior_power(1)
|
|
2698
|
+
True
|
|
2699
|
+
sage: M.dual().an_element()
|
|
2700
|
+
Linear form on the Rank-3 free module M over the Integer Ring
|
|
2701
|
+
sage: a = M.linear_form()
|
|
2702
|
+
sage: a in M.dual()
|
|
2703
|
+
True
|
|
2704
|
+
|
|
2705
|
+
The elements of a dual basis belong of course to the dual module::
|
|
2706
|
+
|
|
2707
|
+
sage: e = M.basis('e')
|
|
2708
|
+
sage: e.dual_basis()[0] in M.dual()
|
|
2709
|
+
True
|
|
2710
|
+
"""
|
|
2711
|
+
return self.dual_exterior_power(1)
|
|
2712
|
+
|
|
2713
|
+
def irange(self, start: int | None = None) -> Generator[int, None, None]:
|
|
2714
|
+
r"""
|
|
2715
|
+
Single index generator, labelling the elements of a basis of ``self``.
|
|
2716
|
+
|
|
2717
|
+
INPUT:
|
|
2718
|
+
|
|
2719
|
+
- ``start`` -- (default: ``None``) integer; initial value of the
|
|
2720
|
+
index; if none is provided, ``self._sindex`` is assumed
|
|
2721
|
+
|
|
2722
|
+
OUTPUT:
|
|
2723
|
+
|
|
2724
|
+
- an iterable index, starting from ``start`` and ending at
|
|
2725
|
+
``self._sindex + self.rank() - 1``
|
|
2726
|
+
|
|
2727
|
+
EXAMPLES:
|
|
2728
|
+
|
|
2729
|
+
Index range on a rank-3 module::
|
|
2730
|
+
|
|
2731
|
+
sage: M = FiniteRankFreeModule(ZZ, 3)
|
|
2732
|
+
sage: list(M.irange())
|
|
2733
|
+
[0, 1, 2]
|
|
2734
|
+
sage: list(M.irange(start=1))
|
|
2735
|
+
[1, 2]
|
|
2736
|
+
|
|
2737
|
+
The default starting value corresponds to the parameter ``start_index``
|
|
2738
|
+
provided at the module construction (the default value being 0)::
|
|
2739
|
+
|
|
2740
|
+
sage: M1 = FiniteRankFreeModule(ZZ, 3, start_index=1)
|
|
2741
|
+
sage: list(M1.irange())
|
|
2742
|
+
[1, 2, 3]
|
|
2743
|
+
sage: M2 = FiniteRankFreeModule(ZZ, 3, start_index=-4)
|
|
2744
|
+
sage: list(M2.irange())
|
|
2745
|
+
[-4, -3, -2]
|
|
2746
|
+
"""
|
|
2747
|
+
si = self._sindex
|
|
2748
|
+
imax = self._rank + si
|
|
2749
|
+
if start is None:
|
|
2750
|
+
i = si
|
|
2751
|
+
else:
|
|
2752
|
+
i = start
|
|
2753
|
+
while i < imax:
|
|
2754
|
+
yield i
|
|
2755
|
+
i += 1
|
|
2756
|
+
|
|
2757
|
+
def default_basis(self):
|
|
2758
|
+
r"""
|
|
2759
|
+
Return the default basis of the free module ``self``.
|
|
2760
|
+
|
|
2761
|
+
The *default basis* is simply a basis whose name can be skipped in
|
|
2762
|
+
methods requiring a basis as an argument. By default, it is the first
|
|
2763
|
+
basis introduced on the module. It can be changed by the method
|
|
2764
|
+
:meth:`set_default_basis`.
|
|
2765
|
+
|
|
2766
|
+
OUTPUT:
|
|
2767
|
+
|
|
2768
|
+
- instance of
|
|
2769
|
+
:class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`
|
|
2770
|
+
|
|
2771
|
+
EXAMPLES:
|
|
2772
|
+
|
|
2773
|
+
At the module construction, no default basis is assumed::
|
|
2774
|
+
|
|
2775
|
+
sage: M = FiniteRankFreeModule(ZZ, 2, name='M', start_index=1)
|
|
2776
|
+
sage: M.default_basis()
|
|
2777
|
+
No default basis has been defined on the
|
|
2778
|
+
Rank-2 free module M over the Integer Ring
|
|
2779
|
+
|
|
2780
|
+
The first defined basis becomes the default one::
|
|
2781
|
+
|
|
2782
|
+
sage: e = M.basis('e') ; e
|
|
2783
|
+
Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring
|
|
2784
|
+
sage: M.default_basis()
|
|
2785
|
+
Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring
|
|
2786
|
+
sage: f = M.basis('f') ; f
|
|
2787
|
+
Basis (f_1,f_2) on the Rank-2 free module M over the Integer Ring
|
|
2788
|
+
sage: M.default_basis()
|
|
2789
|
+
Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring
|
|
2790
|
+
"""
|
|
2791
|
+
if self._def_basis is None:
|
|
2792
|
+
print("No default basis has been defined on the {}".format(self))
|
|
2793
|
+
return self._def_basis
|
|
2794
|
+
|
|
2795
|
+
def set_default_basis(self, basis):
|
|
2796
|
+
r"""
|
|
2797
|
+
Set the default basis of ``self``.
|
|
2798
|
+
|
|
2799
|
+
The *default basis* is simply a basis whose name can be skipped in
|
|
2800
|
+
methods requiring a basis as an argument. By default, it is the first
|
|
2801
|
+
basis introduced on the module.
|
|
2802
|
+
|
|
2803
|
+
INPUT:
|
|
2804
|
+
|
|
2805
|
+
- ``basis`` -- instance of
|
|
2806
|
+
:class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`
|
|
2807
|
+
representing a basis on ``self``
|
|
2808
|
+
|
|
2809
|
+
EXAMPLES:
|
|
2810
|
+
|
|
2811
|
+
Changing the default basis on a rank-3 free module::
|
|
2812
|
+
|
|
2813
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1)
|
|
2814
|
+
sage: e = M.basis('e') ; e
|
|
2815
|
+
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
|
|
2816
|
+
sage: f = M.basis('f') ; f
|
|
2817
|
+
Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring
|
|
2818
|
+
sage: M.default_basis()
|
|
2819
|
+
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
|
|
2820
|
+
sage: M.set_default_basis(f)
|
|
2821
|
+
sage: M.default_basis()
|
|
2822
|
+
Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring
|
|
2823
|
+
"""
|
|
2824
|
+
from .free_module_basis import FreeModuleBasis
|
|
2825
|
+
if not isinstance(basis, FreeModuleBasis):
|
|
2826
|
+
raise TypeError("the argument is not a free module basis")
|
|
2827
|
+
if basis._fmodule is not self:
|
|
2828
|
+
raise ValueError("the basis is not defined on the current module")
|
|
2829
|
+
self._def_basis = basis
|
|
2830
|
+
|
|
2831
|
+
def print_bases(self):
|
|
2832
|
+
r"""
|
|
2833
|
+
Display the bases that have been defined on the free module ``self``.
|
|
2834
|
+
|
|
2835
|
+
Use the method :meth:`bases` to get the raw list of bases.
|
|
2836
|
+
|
|
2837
|
+
EXAMPLES:
|
|
2838
|
+
|
|
2839
|
+
Bases on a rank-4 free module::
|
|
2840
|
+
|
|
2841
|
+
sage: M = FiniteRankFreeModule(ZZ, 4, name='M', start_index=1)
|
|
2842
|
+
sage: M.print_bases()
|
|
2843
|
+
No basis has been defined on the
|
|
2844
|
+
Rank-4 free module M over the Integer Ring
|
|
2845
|
+
sage: e = M.basis('e')
|
|
2846
|
+
sage: M.print_bases()
|
|
2847
|
+
Bases defined on the Rank-4 free module M over the Integer Ring:
|
|
2848
|
+
- (e_1,e_2,e_3,e_4) (default basis)
|
|
2849
|
+
sage: f = M.basis('f')
|
|
2850
|
+
sage: M.print_bases()
|
|
2851
|
+
Bases defined on the Rank-4 free module M over the Integer Ring:
|
|
2852
|
+
- (e_1,e_2,e_3,e_4) (default basis)
|
|
2853
|
+
- (f_1,f_2,f_3,f_4)
|
|
2854
|
+
sage: M.set_default_basis(f)
|
|
2855
|
+
sage: M.print_bases()
|
|
2856
|
+
Bases defined on the Rank-4 free module M over the Integer Ring:
|
|
2857
|
+
- (e_1,e_2,e_3,e_4)
|
|
2858
|
+
- (f_1,f_2,f_3,f_4) (default basis)
|
|
2859
|
+
|
|
2860
|
+
"""
|
|
2861
|
+
if not self._known_bases:
|
|
2862
|
+
print("No basis has been defined on the {}".format(self))
|
|
2863
|
+
else:
|
|
2864
|
+
print("Bases defined on the {}:".format(self))
|
|
2865
|
+
for basis in self._known_bases:
|
|
2866
|
+
item = " - " + basis._name
|
|
2867
|
+
if basis is self._def_basis:
|
|
2868
|
+
item += " (default basis)"
|
|
2869
|
+
print(item)
|
|
2870
|
+
|
|
2871
|
+
def bases(self):
|
|
2872
|
+
r"""
|
|
2873
|
+
Return the list of bases that have been defined on the free module
|
|
2874
|
+
``self``.
|
|
2875
|
+
|
|
2876
|
+
Use the method :meth:`print_bases` to get a formatted output with more
|
|
2877
|
+
information.
|
|
2878
|
+
|
|
2879
|
+
OUTPUT:
|
|
2880
|
+
|
|
2881
|
+
- list of instances of class
|
|
2882
|
+
:class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`
|
|
2883
|
+
|
|
2884
|
+
EXAMPLES:
|
|
2885
|
+
|
|
2886
|
+
Bases on a rank-3 free module::
|
|
2887
|
+
|
|
2888
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M_3', start_index=1)
|
|
2889
|
+
sage: M.bases()
|
|
2890
|
+
[]
|
|
2891
|
+
sage: e = M.basis('e')
|
|
2892
|
+
sage: M.bases()
|
|
2893
|
+
[Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring]
|
|
2894
|
+
sage: f = M.basis('f')
|
|
2895
|
+
sage: M.bases()
|
|
2896
|
+
[Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring,
|
|
2897
|
+
Basis (f_1,f_2,f_3) on the Rank-3 free module M_3 over the Integer Ring]
|
|
2898
|
+
"""
|
|
2899
|
+
return list(self._known_bases)
|
|
2900
|
+
|
|
2901
|
+
def change_of_basis(self, basis1, basis2):
|
|
2902
|
+
r"""
|
|
2903
|
+
Return a module automorphism linking two bases defined on the free
|
|
2904
|
+
module ``self``.
|
|
2905
|
+
|
|
2906
|
+
If the automorphism has not been recorded yet (in the internal
|
|
2907
|
+
dictionary ``self._basis_changes``), it is computed by transitivity,
|
|
2908
|
+
i.e. by performing products of recorded changes of basis.
|
|
2909
|
+
|
|
2910
|
+
INPUT:
|
|
2911
|
+
|
|
2912
|
+
- ``basis1`` -- a basis of ``self``, denoted `(e_i)` below
|
|
2913
|
+
- ``basis2`` -- a basis of ``self``, denoted `(f_i)` below
|
|
2914
|
+
|
|
2915
|
+
OUTPUT:
|
|
2916
|
+
|
|
2917
|
+
- instance of
|
|
2918
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
2919
|
+
describing the automorphism `P` that relates the basis `(e_i)` to the
|
|
2920
|
+
basis `(f_i)` according to `f_i = P(e_i)`
|
|
2921
|
+
|
|
2922
|
+
EXAMPLES:
|
|
2923
|
+
|
|
2924
|
+
Changes of basis on a rank-2 free module::
|
|
2925
|
+
|
|
2926
|
+
sage: FiniteRankFreeModule._clear_cache_() # for doctests only
|
|
2927
|
+
sage: M = FiniteRankFreeModule(ZZ, 2, name='M', start_index=1)
|
|
2928
|
+
sage: e = M.basis('e')
|
|
2929
|
+
sage: f = M.basis('f', from_family=(e[1]+2*e[2], e[1]+3*e[2]))
|
|
2930
|
+
sage: P = M.change_of_basis(e,f) ; P
|
|
2931
|
+
Automorphism of the Rank-2 free module M over the Integer Ring
|
|
2932
|
+
sage: P.matrix(e)
|
|
2933
|
+
[1 1]
|
|
2934
|
+
[2 3]
|
|
2935
|
+
|
|
2936
|
+
Note that the columns of this matrix contain the components of the
|
|
2937
|
+
elements of basis ``f`` w.r.t. to basis ``e``::
|
|
2938
|
+
|
|
2939
|
+
sage: f[1].display(e)
|
|
2940
|
+
f_1 = e_1 + 2 e_2
|
|
2941
|
+
sage: f[2].display(e)
|
|
2942
|
+
f_2 = e_1 + 3 e_2
|
|
2943
|
+
|
|
2944
|
+
The change of basis is cached::
|
|
2945
|
+
|
|
2946
|
+
sage: P is M.change_of_basis(e,f)
|
|
2947
|
+
True
|
|
2948
|
+
|
|
2949
|
+
Check of the change-of-basis automorphism::
|
|
2950
|
+
|
|
2951
|
+
sage: f[1] == P(e[1])
|
|
2952
|
+
True
|
|
2953
|
+
sage: f[2] == P(e[2])
|
|
2954
|
+
True
|
|
2955
|
+
|
|
2956
|
+
Check of the reverse change of basis::
|
|
2957
|
+
|
|
2958
|
+
sage: M.change_of_basis(f,e) == P^(-1)
|
|
2959
|
+
True
|
|
2960
|
+
|
|
2961
|
+
We have of course::
|
|
2962
|
+
|
|
2963
|
+
sage: M.change_of_basis(e,e)
|
|
2964
|
+
Identity map of the Rank-2 free module M over the Integer Ring
|
|
2965
|
+
sage: M.change_of_basis(e,e) is M.identity_map()
|
|
2966
|
+
True
|
|
2967
|
+
|
|
2968
|
+
Let us introduce a third basis on ``M``::
|
|
2969
|
+
|
|
2970
|
+
sage: h = M.basis('h', from_family=(3*e[1]+4*e[2], 5*e[1]+7*e[2]))
|
|
2971
|
+
|
|
2972
|
+
The change of basis ``e`` --> ``h`` has been recorded directly from the
|
|
2973
|
+
definition of ``h``::
|
|
2974
|
+
|
|
2975
|
+
sage: Q = M.change_of_basis(e,h) ; Q.matrix(e)
|
|
2976
|
+
[3 5]
|
|
2977
|
+
[4 7]
|
|
2978
|
+
|
|
2979
|
+
The change of basis ``f`` --> ``h`` is computed by transitivity, i.e.
|
|
2980
|
+
from the changes of basis ``f`` --> ``e`` and ``e`` --> ``h``::
|
|
2981
|
+
|
|
2982
|
+
sage: R = M.change_of_basis(f,h) ; R
|
|
2983
|
+
Automorphism of the Rank-2 free module M over the Integer Ring
|
|
2984
|
+
sage: R.matrix(e)
|
|
2985
|
+
[-1 2]
|
|
2986
|
+
[-2 3]
|
|
2987
|
+
sage: R.matrix(f)
|
|
2988
|
+
[ 5 8]
|
|
2989
|
+
[-2 -3]
|
|
2990
|
+
|
|
2991
|
+
Let us check that ``R`` is indeed the change of basis ``f`` --> ``h``::
|
|
2992
|
+
|
|
2993
|
+
sage: h[1] == R(f[1])
|
|
2994
|
+
True
|
|
2995
|
+
sage: h[2] == R(f[2])
|
|
2996
|
+
True
|
|
2997
|
+
|
|
2998
|
+
A related check is::
|
|
2999
|
+
|
|
3000
|
+
sage: R == Q*P^(-1)
|
|
3001
|
+
True
|
|
3002
|
+
"""
|
|
3003
|
+
if basis1 == basis2:
|
|
3004
|
+
return self.identity_map()
|
|
3005
|
+
bc = self._basis_changes
|
|
3006
|
+
if (basis1, basis2) not in bc:
|
|
3007
|
+
if basis1 not in self._known_bases:
|
|
3008
|
+
raise TypeError("{} is not a basis of the {}".format(basis1,
|
|
3009
|
+
self))
|
|
3010
|
+
if basis2 not in self._known_bases:
|
|
3011
|
+
raise TypeError("{} is not a basis of the {}".format(basis2,
|
|
3012
|
+
self))
|
|
3013
|
+
# Is the inverse already registered ?
|
|
3014
|
+
if (basis2, basis1) in bc:
|
|
3015
|
+
inv = bc[(basis2, basis1)].inverse()
|
|
3016
|
+
bc[(basis1, basis2)] = inv
|
|
3017
|
+
return inv
|
|
3018
|
+
# Search for a third basis, basis say, such that either the changes
|
|
3019
|
+
# basis1 --> basis and basis --> basis2
|
|
3020
|
+
# or
|
|
3021
|
+
# basis2 --> basis and basis --> basis1
|
|
3022
|
+
# are known:
|
|
3023
|
+
for basis in self._known_bases:
|
|
3024
|
+
if (basis1, basis) in bc and (basis, basis2) in bc:
|
|
3025
|
+
transf = bc[(basis, basis2)] * bc[(basis1, basis)]
|
|
3026
|
+
bc[(basis1, basis2)] = transf
|
|
3027
|
+
bc[(basis2, basis1)] = transf.inverse()
|
|
3028
|
+
break
|
|
3029
|
+
if (basis2, basis) in bc and (basis, basis1) in bc:
|
|
3030
|
+
inv = bc[(basis, basis1)] * bc[(basis2, basis)]
|
|
3031
|
+
bc[(basis2, basis1)] = inv
|
|
3032
|
+
bc[(basis1, basis2)] = inv.inverse()
|
|
3033
|
+
break
|
|
3034
|
+
else:
|
|
3035
|
+
raise ValueError(("the change of basis from '{!r}' to '{!r}'"
|
|
3036
|
+
+ " cannot be computed"
|
|
3037
|
+
).format(basis1, basis2))
|
|
3038
|
+
return bc[(basis1, basis2)]
|
|
3039
|
+
|
|
3040
|
+
def set_change_of_basis(self, basis1, basis2, change_of_basis,
|
|
3041
|
+
compute_inverse=True):
|
|
3042
|
+
r"""
|
|
3043
|
+
Relates two bases by an automorphism of ``self``.
|
|
3044
|
+
|
|
3045
|
+
This updates the internal dictionary ``self._basis_changes``.
|
|
3046
|
+
|
|
3047
|
+
INPUT:
|
|
3048
|
+
|
|
3049
|
+
- ``basis1`` -- basis 1, denoted `(e_i)` below
|
|
3050
|
+
- ``basis2`` -- basis 2, denoted `(f_i)` below
|
|
3051
|
+
- ``change_of_basis`` -- instance of class
|
|
3052
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
3053
|
+
describing the automorphism `P` that relates the basis `(e_i)` to
|
|
3054
|
+
the basis `(f_i)` according to `f_i = P(e_i)`
|
|
3055
|
+
- ``compute_inverse`` -- boolean (default: ``True``); if set to ``True``,
|
|
3056
|
+
the inverse automorphism is computed and the change from basis `(f_i)`
|
|
3057
|
+
to `(e_i)` is set to it in the internal dictionary
|
|
3058
|
+
``self._basis_changes``
|
|
3059
|
+
|
|
3060
|
+
EXAMPLES:
|
|
3061
|
+
|
|
3062
|
+
Defining a change of basis on a rank-2 free module::
|
|
3063
|
+
|
|
3064
|
+
sage: M = FiniteRankFreeModule(QQ, 2, name='M')
|
|
3065
|
+
sage: e = M.basis('e')
|
|
3066
|
+
sage: f = M.basis('f')
|
|
3067
|
+
sage: a = M.automorphism()
|
|
3068
|
+
sage: a[:] = [[1, 2], [-1, 3]]
|
|
3069
|
+
sage: M.set_change_of_basis(e, f, a)
|
|
3070
|
+
|
|
3071
|
+
The change of basis and its inverse have been recorded::
|
|
3072
|
+
|
|
3073
|
+
sage: M.change_of_basis(e,f).matrix(e)
|
|
3074
|
+
[ 1 2]
|
|
3075
|
+
[-1 3]
|
|
3076
|
+
sage: M.change_of_basis(f,e).matrix(e)
|
|
3077
|
+
[ 3/5 -2/5]
|
|
3078
|
+
[ 1/5 1/5]
|
|
3079
|
+
|
|
3080
|
+
and are effective::
|
|
3081
|
+
|
|
3082
|
+
sage: f[0].display(e)
|
|
3083
|
+
f_0 = e_0 - e_1
|
|
3084
|
+
sage: e[0].display(f)
|
|
3085
|
+
e_0 = 3/5 f_0 + 1/5 f_1
|
|
3086
|
+
"""
|
|
3087
|
+
if basis1 not in self._known_bases:
|
|
3088
|
+
raise TypeError("{} is not a basis of the {}".format(basis1,
|
|
3089
|
+
self))
|
|
3090
|
+
if basis2 not in self._known_bases:
|
|
3091
|
+
raise TypeError("{} is not a basis of the {}".format(basis2,
|
|
3092
|
+
self))
|
|
3093
|
+
if change_of_basis not in self.general_linear_group():
|
|
3094
|
+
raise TypeError("{} is not an automorphism of the {}".format(
|
|
3095
|
+
change_of_basis, self))
|
|
3096
|
+
self._basis_changes[(basis1, basis2)] = change_of_basis
|
|
3097
|
+
if compute_inverse:
|
|
3098
|
+
self._basis_changes[(basis2, basis1)] = change_of_basis.inverse()
|
|
3099
|
+
|
|
3100
|
+
def hom(self, codomain, matrix_rep, bases=None, name=None,
|
|
3101
|
+
latex_name=None):
|
|
3102
|
+
r"""
|
|
3103
|
+
Homomorphism from ``self`` to a free module.
|
|
3104
|
+
|
|
3105
|
+
Define a module homomorphism
|
|
3106
|
+
|
|
3107
|
+
.. MATH::
|
|
3108
|
+
|
|
3109
|
+
\phi:\ M \longrightarrow N,
|
|
3110
|
+
|
|
3111
|
+
where `M` is ``self`` and `N` is a free module of finite rank
|
|
3112
|
+
over the same ring `R` as ``self``.
|
|
3113
|
+
|
|
3114
|
+
.. NOTE::
|
|
3115
|
+
|
|
3116
|
+
This method is a redefinition of
|
|
3117
|
+
:meth:`sage.structure.parent.Parent.hom` because the latter assumes
|
|
3118
|
+
that ``self`` has some privileged generators, while an instance of
|
|
3119
|
+
:class:`FiniteRankFreeModule` has no privileged basis.
|
|
3120
|
+
|
|
3121
|
+
INPUT:
|
|
3122
|
+
|
|
3123
|
+
- ``codomain`` -- the target module `N`
|
|
3124
|
+
- ``matrix_rep`` -- matrix of size rank(N)*rank(M) representing the
|
|
3125
|
+
homomorphism with respect to the pair of bases defined by ``bases``;
|
|
3126
|
+
this entry can actually be any material from which a matrix of
|
|
3127
|
+
elements of `R` can be constructed; the *columns* of
|
|
3128
|
+
``matrix_rep`` must be the components w.r.t. ``basis_N`` of
|
|
3129
|
+
the images of the elements of ``basis_M``.
|
|
3130
|
+
- ``bases`` -- (default: ``None``) pair ``(basis_M, basis_N)`` defining
|
|
3131
|
+
the matrix representation, ``basis_M`` being a basis of ``self`` and
|
|
3132
|
+
``basis_N`` a basis of module `N` ; if None the pair formed by the
|
|
3133
|
+
default bases of each module is assumed.
|
|
3134
|
+
- ``name`` -- (default: ``None``) string; name given to the
|
|
3135
|
+
homomorphism
|
|
3136
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
|
|
3137
|
+
the homomorphism. If ``None``, ``name`` will be used.
|
|
3138
|
+
|
|
3139
|
+
OUTPUT:
|
|
3140
|
+
|
|
3141
|
+
- the homomorphism `\phi: M \rightarrow N` corresponding to the given
|
|
3142
|
+
specifications, as an instance of
|
|
3143
|
+
:class:`~sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism`
|
|
3144
|
+
|
|
3145
|
+
EXAMPLES:
|
|
3146
|
+
|
|
3147
|
+
Homomorphism between two free modules over `\ZZ`::
|
|
3148
|
+
|
|
3149
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
3150
|
+
sage: N = FiniteRankFreeModule(ZZ, 2, name='N')
|
|
3151
|
+
sage: e = M.basis('e')
|
|
3152
|
+
sage: f = N.basis('f')
|
|
3153
|
+
sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) ; phi
|
|
3154
|
+
Generic morphism:
|
|
3155
|
+
From: Rank-3 free module M over the Integer Ring
|
|
3156
|
+
To: Rank-2 free module N over the Integer Ring
|
|
3157
|
+
|
|
3158
|
+
Homomorphism defined by a matrix w.r.t. bases that are not the
|
|
3159
|
+
default ones::
|
|
3160
|
+
|
|
3161
|
+
sage: ep = M.basis('ep', latex_symbol=r"e'")
|
|
3162
|
+
sage: fp = N.basis('fp', latex_symbol=r"f'")
|
|
3163
|
+
sage: phi = M.hom(N, [[3,2,1], [1,2,3]], bases=(ep, fp)) ; phi
|
|
3164
|
+
Generic morphism:
|
|
3165
|
+
From: Rank-3 free module M over the Integer Ring
|
|
3166
|
+
To: Rank-2 free module N over the Integer Ring
|
|
3167
|
+
|
|
3168
|
+
Call with all arguments specified::
|
|
3169
|
+
|
|
3170
|
+
sage: phi = M.hom(N, [[3,2,1], [1,2,3]], bases=(ep, fp),
|
|
3171
|
+
....: name='phi', latex_name=r'\phi')
|
|
3172
|
+
|
|
3173
|
+
The parent::
|
|
3174
|
+
|
|
3175
|
+
sage: phi.parent() is Hom(M,N)
|
|
3176
|
+
True
|
|
3177
|
+
|
|
3178
|
+
See class
|
|
3179
|
+
:class:`~sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism`
|
|
3180
|
+
for more documentation.
|
|
3181
|
+
"""
|
|
3182
|
+
homset = Hom(self, codomain)
|
|
3183
|
+
return homset(matrix_rep, bases=bases, name=name,
|
|
3184
|
+
latex_name=latex_name)
|
|
3185
|
+
|
|
3186
|
+
def endomorphism(self, matrix_rep, basis=None, name=None, latex_name=None):
|
|
3187
|
+
r"""
|
|
3188
|
+
Construct an endomorphism of the free module ``self``.
|
|
3189
|
+
|
|
3190
|
+
The returned object is a module morphism `\phi: M \rightarrow M`,
|
|
3191
|
+
where `M` is ``self``.
|
|
3192
|
+
|
|
3193
|
+
INPUT:
|
|
3194
|
+
|
|
3195
|
+
- ``matrix_rep`` -- matrix of size rank(M)*rank(M) representing the
|
|
3196
|
+
endomorphism with respect to ``basis``;
|
|
3197
|
+
this entry can actually be any material from which a matrix of
|
|
3198
|
+
elements of ``self`` base ring can be constructed; the *columns* of
|
|
3199
|
+
``matrix_rep`` must be the components w.r.t. ``basis`` of
|
|
3200
|
+
the images of the elements of ``basis``.
|
|
3201
|
+
- ``basis`` -- (default: ``None``) basis of ``self`` defining the
|
|
3202
|
+
matrix representation; if None the default basis of ``self`` is
|
|
3203
|
+
assumed.
|
|
3204
|
+
- ``name`` -- (default: ``None``) string; name given to the
|
|
3205
|
+
endomorphism
|
|
3206
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
|
|
3207
|
+
the endomorphism. If none is provided, ``name`` will be used.
|
|
3208
|
+
|
|
3209
|
+
OUTPUT:
|
|
3210
|
+
|
|
3211
|
+
- the endomorphism `\phi: M \rightarrow M` corresponding to the given
|
|
3212
|
+
specifications, as an instance of
|
|
3213
|
+
:class:`~sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism`
|
|
3214
|
+
|
|
3215
|
+
EXAMPLES:
|
|
3216
|
+
|
|
3217
|
+
Construction of an endomorphism with minimal data (module's default
|
|
3218
|
+
basis and no name)::
|
|
3219
|
+
|
|
3220
|
+
sage: M = FiniteRankFreeModule(ZZ, 2, name='M')
|
|
3221
|
+
sage: e = M.basis('e')
|
|
3222
|
+
sage: phi = M.endomorphism([[1,-2], [-3,4]]) ; phi
|
|
3223
|
+
Generic endomorphism of Rank-2 free module M over the Integer Ring
|
|
3224
|
+
sage: phi.matrix() # matrix w.r.t the default basis
|
|
3225
|
+
[ 1 -2]
|
|
3226
|
+
[-3 4]
|
|
3227
|
+
|
|
3228
|
+
Construction with full list of arguments (matrix given a basis
|
|
3229
|
+
different from the default one)::
|
|
3230
|
+
|
|
3231
|
+
sage: a = M.automorphism() ; a[0,1], a[1,0] = 1, -1
|
|
3232
|
+
sage: ep = e.new_basis(a, 'ep', latex_symbol="e'")
|
|
3233
|
+
sage: phi = M.endomorphism([[1,-2], [-3,4]], basis=ep, name='phi',
|
|
3234
|
+
....: latex_name=r'\phi')
|
|
3235
|
+
sage: phi
|
|
3236
|
+
Generic endomorphism of Rank-2 free module M over the Integer Ring
|
|
3237
|
+
sage: phi.matrix(ep) # the input matrix
|
|
3238
|
+
[ 1 -2]
|
|
3239
|
+
[-3 4]
|
|
3240
|
+
sage: phi.matrix() # matrix w.r.t the default basis
|
|
3241
|
+
[4 3]
|
|
3242
|
+
[2 1]
|
|
3243
|
+
|
|
3244
|
+
See :class:`~sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism`
|
|
3245
|
+
for more documentation.
|
|
3246
|
+
"""
|
|
3247
|
+
from sage.categories.homset import End
|
|
3248
|
+
if basis is None:
|
|
3249
|
+
basis = self.default_basis()
|
|
3250
|
+
return End(self)(matrix_rep, bases=(basis,basis), name=name,
|
|
3251
|
+
latex_name=latex_name)
|
|
3252
|
+
|
|
3253
|
+
def identity_map(self, name='Id', latex_name=None):
|
|
3254
|
+
r"""
|
|
3255
|
+
Return the identity map of the free module ``self``.
|
|
3256
|
+
|
|
3257
|
+
INPUT:
|
|
3258
|
+
|
|
3259
|
+
- ``name`` -- (string; default: 'Id') name given to the identity
|
|
3260
|
+
identity map
|
|
3261
|
+
- ``latex_name`` -- (string; default: ``None``) LaTeX symbol to denote
|
|
3262
|
+
the identity map; if none is provided, the LaTeX symbol is set to
|
|
3263
|
+
'\mathrm{Id}' if ``name`` is 'Id' and to ``name`` otherwise
|
|
3264
|
+
|
|
3265
|
+
OUTPUT:
|
|
3266
|
+
|
|
3267
|
+
- the identity map of ``self`` as an instance of
|
|
3268
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
3269
|
+
|
|
3270
|
+
EXAMPLES:
|
|
3271
|
+
|
|
3272
|
+
Identity map of a rank-3 `\ZZ`-module::
|
|
3273
|
+
|
|
3274
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
3275
|
+
sage: e = M.basis('e')
|
|
3276
|
+
sage: Id = M.identity_map() ; Id
|
|
3277
|
+
Identity map of the Rank-3 free module M over the Integer Ring
|
|
3278
|
+
sage: Id.parent()
|
|
3279
|
+
General linear group of the Rank-3 free module M over the Integer Ring
|
|
3280
|
+
sage: Id.matrix(e)
|
|
3281
|
+
[1 0 0]
|
|
3282
|
+
[0 1 0]
|
|
3283
|
+
[0 0 1]
|
|
3284
|
+
|
|
3285
|
+
The default LaTeX symbol::
|
|
3286
|
+
|
|
3287
|
+
sage: latex(Id)
|
|
3288
|
+
\mathrm{Id}
|
|
3289
|
+
|
|
3290
|
+
It can be changed by means of the method
|
|
3291
|
+
:meth:`~sage.tensor.modules.free_module_tensor.FreeModuleTensor.set_name`::
|
|
3292
|
+
|
|
3293
|
+
sage: Id.set_name(latex_name=r'\mathrm{1}_M')
|
|
3294
|
+
sage: latex(Id)
|
|
3295
|
+
\mathrm{1}_M
|
|
3296
|
+
|
|
3297
|
+
The identity map is actually the identity element of GL(M)::
|
|
3298
|
+
|
|
3299
|
+
sage: Id is M.general_linear_group().one()
|
|
3300
|
+
True
|
|
3301
|
+
|
|
3302
|
+
It is also a tensor of type-`(1,1)` on M::
|
|
3303
|
+
|
|
3304
|
+
sage: Id.tensor_type()
|
|
3305
|
+
(1, 1)
|
|
3306
|
+
sage: Id.comp(e)
|
|
3307
|
+
Kronecker delta of size 3x3
|
|
3308
|
+
sage: Id[:]
|
|
3309
|
+
[1 0 0]
|
|
3310
|
+
[0 1 0]
|
|
3311
|
+
[0 0 1]
|
|
3312
|
+
|
|
3313
|
+
Example with a LaTeX symbol different from the default one and set
|
|
3314
|
+
at the creation of the object::
|
|
3315
|
+
|
|
3316
|
+
sage: N = FiniteRankFreeModule(ZZ, 3, name='N')
|
|
3317
|
+
sage: f = N.basis('f')
|
|
3318
|
+
sage: Id = N.identity_map(name='Id_N', latex_name=r'\mathrm{Id}_N')
|
|
3319
|
+
sage: Id
|
|
3320
|
+
Identity map of the Rank-3 free module N over the Integer Ring
|
|
3321
|
+
sage: latex(Id)
|
|
3322
|
+
\mathrm{Id}_N
|
|
3323
|
+
"""
|
|
3324
|
+
if self._identity_map is None:
|
|
3325
|
+
self._identity_map = self.general_linear_group().one()
|
|
3326
|
+
if name != 'Id':
|
|
3327
|
+
if latex_name is None:
|
|
3328
|
+
latex_name = name
|
|
3329
|
+
self._identity_map.set_name(name=name, latex_name=latex_name)
|
|
3330
|
+
return self._identity_map
|
|
3331
|
+
|
|
3332
|
+
|
|
3333
|
+
class FiniteRankDualFreeModule(ReflexiveModule_dual, FiniteRankFreeModule_abstract):
|
|
3334
|
+
r"""
|
|
3335
|
+
Dual of a free module of finite rank over a commutative ring.
|
|
3336
|
+
|
|
3337
|
+
Given a free module `M` of finite rank over a commutative ring `R`,
|
|
3338
|
+
the *dual of* `M` is the set `M^*` of all linear forms on `M`,
|
|
3339
|
+
i.e., linear maps
|
|
3340
|
+
|
|
3341
|
+
.. MATH::
|
|
3342
|
+
|
|
3343
|
+
M \longrightarrow R
|
|
3344
|
+
|
|
3345
|
+
This is a Sage *parent* class, whose *element* class is
|
|
3346
|
+
:class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`.
|
|
3347
|
+
|
|
3348
|
+
INPUT:
|
|
3349
|
+
|
|
3350
|
+
- ``fmodule`` -- free module `M` of finite rank, as an instance of
|
|
3351
|
+
:class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule`
|
|
3352
|
+
- ``name`` -- (default: ``None``) string; name given to `M^*`
|
|
3353
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote `M^*`
|
|
3354
|
+
|
|
3355
|
+
EXAMPLES::
|
|
3356
|
+
|
|
3357
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
3358
|
+
sage: e = M.basis('e')
|
|
3359
|
+
sage: A = M.dual(); A
|
|
3360
|
+
Dual of the Rank-3 free module M over the Integer Ring
|
|
3361
|
+
|
|
3362
|
+
``A`` is a module (actually a free module) over `\ZZ`::
|
|
3363
|
+
|
|
3364
|
+
sage: A.category()
|
|
3365
|
+
Category of finite dimensional modules over Integer Ring
|
|
3366
|
+
sage: A in Modules(ZZ)
|
|
3367
|
+
True
|
|
3368
|
+
sage: A.rank()
|
|
3369
|
+
3
|
|
3370
|
+
sage: A.base_ring()
|
|
3371
|
+
Integer Ring
|
|
3372
|
+
sage: A.base_module()
|
|
3373
|
+
Rank-3 free module M over the Integer Ring
|
|
3374
|
+
|
|
3375
|
+
``A`` is a *parent* object, whose elements are linear forms,
|
|
3376
|
+
represented by instances of the class
|
|
3377
|
+
:class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`::
|
|
3378
|
+
|
|
3379
|
+
sage: a = A.an_element() ; a
|
|
3380
|
+
Linear form on the Rank-3 free module M over the Integer Ring
|
|
3381
|
+
sage: a.display() # expansion with respect to M's default basis (e)
|
|
3382
|
+
e^0
|
|
3383
|
+
sage: from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm
|
|
3384
|
+
sage: isinstance(a, FreeModuleAltForm)
|
|
3385
|
+
True
|
|
3386
|
+
sage: a in A
|
|
3387
|
+
True
|
|
3388
|
+
sage: A.is_parent_of(a)
|
|
3389
|
+
True
|
|
3390
|
+
|
|
3391
|
+
Elements can be constructed from ``A``. In particular, 0 yields
|
|
3392
|
+
the zero element of ``A``::
|
|
3393
|
+
|
|
3394
|
+
sage: A(0)
|
|
3395
|
+
Linear form zero on the Rank-3 free module M over the Integer Ring
|
|
3396
|
+
sage: A(0) is A.zero()
|
|
3397
|
+
True
|
|
3398
|
+
|
|
3399
|
+
while nonzero elements are constructed by providing their components in a
|
|
3400
|
+
given basis::
|
|
3401
|
+
|
|
3402
|
+
sage: e
|
|
3403
|
+
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
|
|
3404
|
+
sage: comp = [0,3,-1]
|
|
3405
|
+
sage: a = A(comp, basis=e, name='a') ; a
|
|
3406
|
+
Linear form a on the Rank-3 free module M over the Integer Ring
|
|
3407
|
+
sage: a.display(e)
|
|
3408
|
+
a = 3 e^1 - e^2
|
|
3409
|
+
|
|
3410
|
+
An alternative is to construct the alternating form from an empty list of
|
|
3411
|
+
components and to set the nonzero components afterwards::
|
|
3412
|
+
|
|
3413
|
+
sage: a = A([], name='a')
|
|
3414
|
+
sage: a.set_comp(e)[0] = 3
|
|
3415
|
+
sage: a.set_comp(e)[1] = -1
|
|
3416
|
+
sage: a.set_comp(e)[2] = 4
|
|
3417
|
+
sage: a.display(e)
|
|
3418
|
+
a = 3 e^0 - e^1 + 4 e^2
|
|
3419
|
+
|
|
3420
|
+
The dual is unique::
|
|
3421
|
+
|
|
3422
|
+
sage: A is M.dual()
|
|
3423
|
+
True
|
|
3424
|
+
|
|
3425
|
+
The exterior power `\Lambda^1(M^*)` is nothing but `M^*`::
|
|
3426
|
+
|
|
3427
|
+
sage: M.dual_exterior_power(1) is M.dual()
|
|
3428
|
+
True
|
|
3429
|
+
|
|
3430
|
+
It also coincides with the module of type-`(0,1)` tensors::
|
|
3431
|
+
|
|
3432
|
+
sage: M.dual_exterior_power(1) is M.tensor_module(0,1)
|
|
3433
|
+
True
|
|
3434
|
+
"""
|
|
3435
|
+
|
|
3436
|
+
Element = FreeModuleAltForm
|
|
3437
|
+
|
|
3438
|
+
def __init__(self, fmodule, name=None, latex_name=None):
|
|
3439
|
+
r"""
|
|
3440
|
+
TESTS::
|
|
3441
|
+
|
|
3442
|
+
sage: from sage.tensor.modules.finite_rank_free_module import FiniteRankDualFreeModule
|
|
3443
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
3444
|
+
sage: e = M.basis('e')
|
|
3445
|
+
sage: A = FiniteRankDualFreeModule(M) ; A
|
|
3446
|
+
Dual of the Rank-3 free module M over the Integer Ring
|
|
3447
|
+
sage: TestSuite(A).run()
|
|
3448
|
+
"""
|
|
3449
|
+
self._fmodule = fmodule
|
|
3450
|
+
rank = fmodule._rank
|
|
3451
|
+
if name is None and fmodule._name is not None:
|
|
3452
|
+
name = fmodule._name + '*'
|
|
3453
|
+
if latex_name is None and fmodule._latex_name is not None:
|
|
3454
|
+
latex_name = fmodule._latex_name + r'^*'
|
|
3455
|
+
super().__init__(fmodule._ring, rank, name=name,
|
|
3456
|
+
latex_name=latex_name)
|
|
3457
|
+
fmodule._all_modules.add(self)
|
|
3458
|
+
|
|
3459
|
+
#### Parent methods
|
|
3460
|
+
|
|
3461
|
+
def _element_constructor_(self, comp=[], basis=None, name=None,
|
|
3462
|
+
latex_name=None):
|
|
3463
|
+
r"""
|
|
3464
|
+
Construct a linear form.
|
|
3465
|
+
|
|
3466
|
+
EXAMPLES::
|
|
3467
|
+
|
|
3468
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
3469
|
+
sage: e = M.basis('e')
|
|
3470
|
+
sage: A = M.dual()
|
|
3471
|
+
sage: a = A._element_constructor_(0) ; a
|
|
3472
|
+
Linear form zero on the Rank-3 free module M over the Integer Ring
|
|
3473
|
+
sage: a = A._element_constructor_([2,0,-1], name='a') ; a
|
|
3474
|
+
Linear form a on the Rank-3 free module M over the Integer Ring
|
|
3475
|
+
sage: a.display()
|
|
3476
|
+
a = 2 e^0 - e^2
|
|
3477
|
+
"""
|
|
3478
|
+
if isinstance(comp, (int, Integer)) and comp == 0:
|
|
3479
|
+
return self.zero()
|
|
3480
|
+
if isinstance(comp, FreeModuleTensor):
|
|
3481
|
+
# coercion of a tensor of type (0,1) to a linear form
|
|
3482
|
+
tensor = comp # for readability
|
|
3483
|
+
if tensor.tensor_type() == (0,1) and self._degree == 1 and \
|
|
3484
|
+
tensor.base_module() is self._fmodule:
|
|
3485
|
+
resu = self.element_class(self._fmodule, 1, name=tensor._name,
|
|
3486
|
+
latex_name=tensor._latex_name)
|
|
3487
|
+
for basis, comp in tensor._components.items():
|
|
3488
|
+
resu._components[basis] = comp.copy()
|
|
3489
|
+
return resu
|
|
3490
|
+
else:
|
|
3491
|
+
raise TypeError("cannot coerce the {} ".format(tensor) +
|
|
3492
|
+
"to an element of {}".format(self))
|
|
3493
|
+
# standard construction
|
|
3494
|
+
resu = self.element_class(self._fmodule, 1, name=name, latex_name=latex_name)
|
|
3495
|
+
if comp:
|
|
3496
|
+
resu.set_comp(basis)[:] = comp
|
|
3497
|
+
return resu
|
|
3498
|
+
|
|
3499
|
+
def _an_element_(self):
|
|
3500
|
+
r"""
|
|
3501
|
+
Construct some (unnamed) alternating form.
|
|
3502
|
+
|
|
3503
|
+
EXAMPLES::
|
|
3504
|
+
|
|
3505
|
+
sage: M = FiniteRankFreeModule(QQ, 4, name='M')
|
|
3506
|
+
sage: e = M.basis('e')
|
|
3507
|
+
sage: a = M.dual()._an_element_() ; a
|
|
3508
|
+
Linear form on the 4-dimensional vector space M over the Rational
|
|
3509
|
+
Field
|
|
3510
|
+
sage: a.display()
|
|
3511
|
+
1/2 e^0
|
|
3512
|
+
|
|
3513
|
+
TESTS:
|
|
3514
|
+
|
|
3515
|
+
When the base module has no default basis, a default
|
|
3516
|
+
basis will be set for it::
|
|
3517
|
+
|
|
3518
|
+
sage: M2 = FiniteRankFreeModule(QQ, 4, name='M2')
|
|
3519
|
+
sage: a = M2.dual()._an_element_(); a
|
|
3520
|
+
Linear form on the 4-dimensional vector space M2 over the Rational Field
|
|
3521
|
+
sage: a + a
|
|
3522
|
+
Linear form on the 4-dimensional vector space M2 over the Rational Field
|
|
3523
|
+
sage: M2.default_basis()
|
|
3524
|
+
Basis (e_0,e_1,e_2,e_3) on the 4-dimensional vector space M2 over the Rational Field
|
|
3525
|
+
"""
|
|
3526
|
+
resu = self.element_class(self._fmodule, 1)
|
|
3527
|
+
# Make sure that the base module has a default basis
|
|
3528
|
+
self._fmodule.an_element()
|
|
3529
|
+
sindex = self._fmodule._sindex
|
|
3530
|
+
ind = [sindex + i for i in range(resu._tensor_rank)]
|
|
3531
|
+
resu.set_comp()[ind] = self._fmodule._ring.an_element()
|
|
3532
|
+
return resu
|
|
3533
|
+
|
|
3534
|
+
#### End of parent methods
|
|
3535
|
+
|
|
3536
|
+
@cached_method
|
|
3537
|
+
def zero(self):
|
|
3538
|
+
r"""
|
|
3539
|
+
Return the zero of ``self``.
|
|
3540
|
+
|
|
3541
|
+
EXAMPLES::
|
|
3542
|
+
|
|
3543
|
+
sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
|
|
3544
|
+
sage: e = M.basis('e')
|
|
3545
|
+
sage: A = M.dual()
|
|
3546
|
+
sage: A.zero()
|
|
3547
|
+
Linear form zero on the Rank-3 free module M over the Integer Ring
|
|
3548
|
+
sage: A(0) is A.zero()
|
|
3549
|
+
True
|
|
3550
|
+
"""
|
|
3551
|
+
resu = self._element_constructor_(name='zero', latex_name='0')
|
|
3552
|
+
for basis in self._fmodule._known_bases:
|
|
3553
|
+
resu._components[basis] = resu._new_comp(basis)
|
|
3554
|
+
# (since new components are initialized to zero)
|
|
3555
|
+
resu._is_zero = True # This element is certainly zero
|
|
3556
|
+
resu.set_immutable()
|
|
3557
|
+
return resu
|
|
3558
|
+
|
|
3559
|
+
def _repr_(self):
|
|
3560
|
+
r"""
|
|
3561
|
+
Return a string representation of ``self``.
|
|
3562
|
+
|
|
3563
|
+
EXAMPLES::
|
|
3564
|
+
|
|
3565
|
+
sage: M = FiniteRankFreeModule(ZZ, 5, name='M')
|
|
3566
|
+
sage: M.dual_exterior_power(1)._repr_()
|
|
3567
|
+
'Dual of the Rank-5 free module M over the Integer Ring'
|
|
3568
|
+
"""
|
|
3569
|
+
return "Dual of the {}".format(self._fmodule)
|
|
3570
|
+
|
|
3571
|
+
def base_module(self):
|
|
3572
|
+
r"""
|
|
3573
|
+
Return the free module on which ``self`` is constructed.
|
|
3574
|
+
|
|
3575
|
+
OUTPUT:
|
|
3576
|
+
|
|
3577
|
+
- instance of :class:`FiniteRankFreeModule` representing the free
|
|
3578
|
+
module on which the dual is defined.
|
|
3579
|
+
|
|
3580
|
+
EXAMPLES::
|
|
3581
|
+
|
|
3582
|
+
sage: M = FiniteRankFreeModule(ZZ, 5, name='M')
|
|
3583
|
+
sage: A = M.dual()
|
|
3584
|
+
sage: A.base_module()
|
|
3585
|
+
Rank-5 free module M over the Integer Ring
|
|
3586
|
+
sage: A.base_module() is M
|
|
3587
|
+
True
|
|
3588
|
+
"""
|
|
3589
|
+
return self._fmodule
|