passagemath-modules 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
- passagemath_modules-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_modules.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-23768756.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-7897025b.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-e34bb864.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-503f0c35.3.29.so +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-aarch64-linux-musl.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-aarch64-linux-musl.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-musl.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-aarch64-linux-musl.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-aarch64-linux-musl.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-aarch64-linux-musl.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-aarch64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-aarch64-linux-musl.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-aarch64-linux-musl.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-aarch64-linux-musl.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-aarch64-linux-musl.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,1354 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs sage.modules sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
Generic structures for linear codes of any metric
|
|
5
|
+
|
|
6
|
+
Class supporting methods available for linear codes over any metric (Hamming,
|
|
7
|
+
rank).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from copy import copy
|
|
11
|
+
|
|
12
|
+
from sage.coding.abstract_code import AbstractCode
|
|
13
|
+
from sage.modules.module import Module
|
|
14
|
+
from sage.categories.modules import Modules
|
|
15
|
+
from sage.modules.free_module import VectorSpace
|
|
16
|
+
from sage.coding.encoder import Encoder
|
|
17
|
+
from sage.misc.cachefunc import cached_method
|
|
18
|
+
from sage.rings.integer import Integer
|
|
19
|
+
from sage.structure.parent import Parent
|
|
20
|
+
from sage.rings.integer_ring import ZZ
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AbstractLinearCodeNoMetric(AbstractCode, Module):
|
|
24
|
+
r"""
|
|
25
|
+
Abstract class for linear codes of any metric.
|
|
26
|
+
|
|
27
|
+
This class contains all the methods that can be used on any linear code
|
|
28
|
+
of any metric. Every abstract class of linear codes over some metric (e.g.
|
|
29
|
+
abstract class for linear codes over the Hamming metric,
|
|
30
|
+
:class:`sage.coding.linear_code.AbstractLinearCode`) should inherit from
|
|
31
|
+
this class.
|
|
32
|
+
|
|
33
|
+
To create a new class of linear codes over some metrics, you need to:
|
|
34
|
+
|
|
35
|
+
- inherit from AbstractLinearCodeNoMetric
|
|
36
|
+
|
|
37
|
+
- call AbstractCode ``__init__`` method in the subclass constructor.
|
|
38
|
+
Example: ``super().__init__(length, "EncoderName",
|
|
39
|
+
"DecoderName", "metric")``.
|
|
40
|
+
|
|
41
|
+
- add the following two lines on the class level::
|
|
42
|
+
|
|
43
|
+
_registered_encoders = {}
|
|
44
|
+
_registered_decoders = {}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
- fill the dictionary of its encoders in ``sage.coding.__init__.py`` file.
|
|
48
|
+
Example: I want to link the encoder ``MyEncoderClass`` to ``MyNewCodeClass``
|
|
49
|
+
under the name ``MyEncoderName``.
|
|
50
|
+
All I need to do is to write this line in the ``__init__.py`` file:
|
|
51
|
+
``MyNewCodeClass._registered_encoders["NameOfMyEncoder"] = MyEncoderClass``
|
|
52
|
+
and all instances of ``MyNewCodeClass`` will be able to use instances of
|
|
53
|
+
``MyEncoderClass``.
|
|
54
|
+
|
|
55
|
+
- fill the dictionary of its decoders in ``sage.coding.__init__`` file.
|
|
56
|
+
Example: I want to link the encoder ``MyDecoderClass`` to ``MyNewCodeClass``
|
|
57
|
+
under the name ``MyDecoderName``.
|
|
58
|
+
All I need to do is to write this line in the ``__init__.py`` file:
|
|
59
|
+
``MyNewCodeClass._registered_decoders["NameOfMyDecoder"] = MyDecoderClass``
|
|
60
|
+
and all instances of ``MyNewCodeClass`` will be able to use instances of
|
|
61
|
+
``MyDecoderClass``.
|
|
62
|
+
|
|
63
|
+
- create a generic constructor representative of you abstract class. This
|
|
64
|
+
generic constructor is a class for unstructured linear codes given by some
|
|
65
|
+
generator and considered over the given metric. A good example of this is
|
|
66
|
+
:class:`sage.coding.linear_code.LinearCode`, which is a generic constructor
|
|
67
|
+
for :class:`sage.coding.linear_code.AbstractLinearCode`, an abstract class
|
|
68
|
+
for linear codes over the Hamming metric.
|
|
69
|
+
|
|
70
|
+
- set a private field in the ``__init__`` method specifying the generic
|
|
71
|
+
constructor, (e.g. ``MyAbstractCode._generic_constructor = MyCode``)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
It is assumed that the subclass codes are linear over ``base_field``. To
|
|
75
|
+
test this, it is recommended to add a test suite test to the generic
|
|
76
|
+
constructor. To do this, create a representative of your code `C` and run
|
|
77
|
+
``TestSuite(C).run()``. A good example of this is in
|
|
78
|
+
:class:`sage.coding.linear_code.LinearCode`.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
As the class :class:`AbstractLinearCodeNoMetric` is not designed to be
|
|
82
|
+
instantiated, it does not have any representation methods. You should
|
|
83
|
+
implement ``_repr_`` and ``_latex_`` methods in the subclass.
|
|
84
|
+
|
|
85
|
+
.. WARNING::
|
|
86
|
+
|
|
87
|
+
A lot of methods of the abstract class rely on the knowledge of a generator matrix.
|
|
88
|
+
It is thus strongly recommended to set an encoder with a generator matrix implemented
|
|
89
|
+
as a default encoder.
|
|
90
|
+
|
|
91
|
+
TESTS:
|
|
92
|
+
|
|
93
|
+
If the name of the default decoder is not known by the class, it will raise
|
|
94
|
+
a exception::
|
|
95
|
+
|
|
96
|
+
sage: from sage.coding.linear_code_no_metric import AbstractLinearCodeNoMetric
|
|
97
|
+
sage: class MyCodeFamily(AbstractLinearCodeNoMetric):
|
|
98
|
+
....: def __init__(self, field, length, dimension, generator_matrix):
|
|
99
|
+
....: AbstractLinearCodeNoMetric.__init__(self, field, length, "Systematic", "Fail", "MyMetric")
|
|
100
|
+
....: self._dimension = dimension
|
|
101
|
+
....: self._generator_matrix = generator_matrix
|
|
102
|
+
....: def generator_matrix(self):
|
|
103
|
+
....: return self._generator_matrix
|
|
104
|
+
....: def _repr_(self):
|
|
105
|
+
....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality())
|
|
106
|
+
|
|
107
|
+
sage: generator_matrix = matrix(GF(17), 5, 10,
|
|
108
|
+
....: {(i,i):1 for i in range(5)})
|
|
109
|
+
sage: C = MyCodeFamily(GF(17), 10, 5, generator_matrix)
|
|
110
|
+
Traceback (most recent call last):
|
|
111
|
+
...
|
|
112
|
+
ValueError: You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders
|
|
113
|
+
|
|
114
|
+
If the name of the default encoder is not known by the class, it will raise
|
|
115
|
+
an exception::
|
|
116
|
+
|
|
117
|
+
sage: class MyCodeFamily2(sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric):
|
|
118
|
+
....: def __init__(self, field, length, dimension, generator_matrix):
|
|
119
|
+
....: sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric.__init__(self, field, length, "Fail", "Syndrome", "MyMetric")
|
|
120
|
+
....: self._dimension = dimension
|
|
121
|
+
....: self._generator_matrix = generator_matrix
|
|
122
|
+
....: def generator_matrix(self):
|
|
123
|
+
....: return self._generator_matrix
|
|
124
|
+
....: def _repr_(self):
|
|
125
|
+
....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality())
|
|
126
|
+
|
|
127
|
+
sage: C = MyCodeFamily2(GF(17), 10, 5, generator_matrix)
|
|
128
|
+
Traceback (most recent call last):
|
|
129
|
+
...
|
|
130
|
+
ValueError: You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders
|
|
131
|
+
|
|
132
|
+
A ring instead of a field::
|
|
133
|
+
|
|
134
|
+
sage: MyCodeFamily2(IntegerModRing(4), 4, 4, matrix.ones(4))
|
|
135
|
+
Traceback (most recent call last):
|
|
136
|
+
...
|
|
137
|
+
ValueError: 'base_field' must be a field (and Ring of integers modulo 4 is not one)
|
|
138
|
+
"""
|
|
139
|
+
_registered_encoders = {}
|
|
140
|
+
_registered_decoders = {}
|
|
141
|
+
|
|
142
|
+
def __init__(self, base_field, length, default_encoder_name, default_decoder_name, metric='Hamming'):
|
|
143
|
+
"""
|
|
144
|
+
Initialize mandatory parameters that any linear code shares.
|
|
145
|
+
|
|
146
|
+
This method only exists for inheritance purposes as it initializes
|
|
147
|
+
parameters that need to be known by every linear code. The class
|
|
148
|
+
:class:`sage.coding.linear_code_no_metric.AbstractLinearCodeNoMetric`
|
|
149
|
+
should never be directly instantiated.
|
|
150
|
+
|
|
151
|
+
INPUT:
|
|
152
|
+
|
|
153
|
+
- ``base_field`` -- the base field of ``self``
|
|
154
|
+
|
|
155
|
+
- ``length`` -- the length of ``self`` (a Python int or a Sage Integer, must be > 0)
|
|
156
|
+
|
|
157
|
+
- ``default_encoder_name`` -- the name of the default encoder of ``self``
|
|
158
|
+
|
|
159
|
+
- ``default_decoder_name`` -- the name of the default decoder of ``self``
|
|
160
|
+
|
|
161
|
+
- ``metric`` -- (default: ``Hamming``) the metric of ``self``
|
|
162
|
+
|
|
163
|
+
EXAMPLES:
|
|
164
|
+
|
|
165
|
+
sage: from sage.coding.linear_code_no_metric import AbstractLinearCodeNoMetric
|
|
166
|
+
sage: from sage.coding.linear_code import LinearCodeSyndromeDecoder
|
|
167
|
+
sage: class MyLinearCode(AbstractLinearCodeNoMetric):
|
|
168
|
+
....: def __init__(self, field, length, dimension, generator_matrix):
|
|
169
|
+
....: self._registered_decoders['Syndrome'] = LinearCodeSyndromeDecoder
|
|
170
|
+
....: AbstractLinearCodeNoMetric.__init__(self, field, length, "Systematic", "Syndrome")
|
|
171
|
+
....: self._dimension = dimension
|
|
172
|
+
....: self._generator_matrix = generator_matrix
|
|
173
|
+
....: def generator_matrix(self):
|
|
174
|
+
....: return self._generator_matrix
|
|
175
|
+
....: def _repr_(self):
|
|
176
|
+
....: return "[%d, %d] dummy code over GF(%s)" % (self.length(), self.dimension(), self.base_field().cardinality())
|
|
177
|
+
sage: C = MyLinearCode(GF(2), 1, 1, matrix(GF(2), [1]))
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
self._registered_encoders['Systematic'] = LinearCodeSystematicEncoder
|
|
181
|
+
|
|
182
|
+
if not base_field.is_field():
|
|
183
|
+
raise ValueError("'base_field' must be a field (and {} is not one)".format(base_field))
|
|
184
|
+
if default_encoder_name not in self._registered_encoders:
|
|
185
|
+
raise ValueError("You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders")
|
|
186
|
+
if default_decoder_name not in self._registered_decoders:
|
|
187
|
+
raise ValueError("You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders")
|
|
188
|
+
|
|
189
|
+
# if not self.dimension() <= length:
|
|
190
|
+
# raise ValueError("The dimension of the code can be at most its length, {}".format(length))
|
|
191
|
+
|
|
192
|
+
super().__init__(length, default_encoder_name, default_decoder_name, metric)
|
|
193
|
+
cat = Modules(base_field).FiniteDimensional().WithBasis().Finite()
|
|
194
|
+
facade_for = VectorSpace(base_field, self._length)
|
|
195
|
+
self.Element = facade_for.Element
|
|
196
|
+
Parent.__init__(self, base=base_field, facade=facade_for, category=cat)
|
|
197
|
+
|
|
198
|
+
def base_field(self):
|
|
199
|
+
r"""
|
|
200
|
+
Return the base field of ``self``.
|
|
201
|
+
|
|
202
|
+
EXAMPLES::
|
|
203
|
+
|
|
204
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0], [1,0,0,1,1,0,0],
|
|
205
|
+
....: [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]])
|
|
206
|
+
sage: C = LinearCode(G)
|
|
207
|
+
sage: C.base_field()
|
|
208
|
+
Finite Field of size 2
|
|
209
|
+
"""
|
|
210
|
+
return self.base_ring()
|
|
211
|
+
|
|
212
|
+
def ambient_space(self):
|
|
213
|
+
r"""
|
|
214
|
+
Return the ambient vector space of ``self``.
|
|
215
|
+
|
|
216
|
+
EXAMPLES::
|
|
217
|
+
|
|
218
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
219
|
+
sage: C.ambient_space()
|
|
220
|
+
Vector space of dimension 7 over Finite Field of size 2
|
|
221
|
+
"""
|
|
222
|
+
return VectorSpace(self.base_ring(),self.length())
|
|
223
|
+
|
|
224
|
+
def generator_matrix(self, encoder_name=None, **kwargs):
|
|
225
|
+
r"""
|
|
226
|
+
Return a generator matrix of ``self``.
|
|
227
|
+
|
|
228
|
+
INPUT:
|
|
229
|
+
|
|
230
|
+
- ``encoder_name`` -- (default: ``None``) name of the encoder which will be
|
|
231
|
+
used to compute the generator matrix. The default encoder of ``self``
|
|
232
|
+
will be used if default value is kept.
|
|
233
|
+
|
|
234
|
+
- ``kwargs`` -- all additional arguments are forwarded to the construction of the
|
|
235
|
+
encoder that is used
|
|
236
|
+
|
|
237
|
+
EXAMPLES::
|
|
238
|
+
|
|
239
|
+
sage: G = matrix(GF(3), 2, [1,-1,1,-1,1,1])
|
|
240
|
+
sage: code = LinearCode(G)
|
|
241
|
+
sage: code.generator_matrix()
|
|
242
|
+
[1 2 1]
|
|
243
|
+
[2 1 1]
|
|
244
|
+
"""
|
|
245
|
+
E = self.encoder(encoder_name, **kwargs)
|
|
246
|
+
return E.generator_matrix()
|
|
247
|
+
|
|
248
|
+
def __eq__(self, other):
|
|
249
|
+
r"""
|
|
250
|
+
Test equality between two linear codes.
|
|
251
|
+
|
|
252
|
+
EXAMPLES::
|
|
253
|
+
|
|
254
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
255
|
+
sage: C1 = LinearCode(G)
|
|
256
|
+
sage: C1 == 5
|
|
257
|
+
False
|
|
258
|
+
sage: C2 = LinearCode(G)
|
|
259
|
+
sage: C1 == C2
|
|
260
|
+
True
|
|
261
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,1,1]])
|
|
262
|
+
sage: C2 = LinearCode(G)
|
|
263
|
+
sage: C1 == C2
|
|
264
|
+
False
|
|
265
|
+
sage: G = Matrix(GF(3), [[1,2,1,0,0,0,0]])
|
|
266
|
+
sage: C3 = LinearCode(G)
|
|
267
|
+
sage: C1 == C3
|
|
268
|
+
False
|
|
269
|
+
"""
|
|
270
|
+
# Fail without computing the generator matrix if possible:
|
|
271
|
+
if not (isinstance(other, AbstractLinearCodeNoMetric)
|
|
272
|
+
and self.length() == other.length()
|
|
273
|
+
and self.dimension() == other.dimension()
|
|
274
|
+
and self.base_ring() == other.base_ring()):
|
|
275
|
+
return False
|
|
276
|
+
# Check that basis elements of `other` are all in `self.`
|
|
277
|
+
# Since we're over a field and since the dimensions match, the codes
|
|
278
|
+
# must be equal.
|
|
279
|
+
# This implementation may avoid linear algebra altogether, if `self`
|
|
280
|
+
# implements an efficient way to obtain a parity check matrix, and in
|
|
281
|
+
# the worst case does only one system solving.
|
|
282
|
+
return all(c in self for c in other.gens())
|
|
283
|
+
|
|
284
|
+
def __ne__(self, other):
|
|
285
|
+
r"""
|
|
286
|
+
Test inequality of ``self`` and ``other``.
|
|
287
|
+
|
|
288
|
+
This is a generic implementation, which returns the inverse of
|
|
289
|
+
``__eq__`` for ``self``.
|
|
290
|
+
|
|
291
|
+
EXAMPLES::
|
|
292
|
+
|
|
293
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
294
|
+
sage: C1 = LinearCode(G)
|
|
295
|
+
sage: C2 = LinearCode(G)
|
|
296
|
+
sage: C1 != C2
|
|
297
|
+
False
|
|
298
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,1,1]])
|
|
299
|
+
sage: C2 = LinearCode(G)
|
|
300
|
+
sage: C1 != C2
|
|
301
|
+
True
|
|
302
|
+
"""
|
|
303
|
+
return not self == other
|
|
304
|
+
|
|
305
|
+
def dimension(self):
|
|
306
|
+
r"""
|
|
307
|
+
Return the dimension of this code.
|
|
308
|
+
|
|
309
|
+
EXAMPLES::
|
|
310
|
+
|
|
311
|
+
sage: G = matrix(GF(2), [[1,0,0], [1,1,0]])
|
|
312
|
+
sage: C = LinearCode(G)
|
|
313
|
+
sage: C.dimension()
|
|
314
|
+
2
|
|
315
|
+
|
|
316
|
+
TESTS:
|
|
317
|
+
|
|
318
|
+
Check that :issue:`21156` is fixed::
|
|
319
|
+
|
|
320
|
+
sage: from sage.coding.linear_code import AbstractLinearCode
|
|
321
|
+
sage: from sage.coding.encoder import Encoder
|
|
322
|
+
sage: class MonkeyCode(AbstractLinearCode):
|
|
323
|
+
....: _registered_encoders = {}
|
|
324
|
+
....: _registered_decoders = {}
|
|
325
|
+
....: def __init__(self):
|
|
326
|
+
....: super().__init__(GF(5), 10, "Monkey", "Syndrome")
|
|
327
|
+
....:
|
|
328
|
+
sage: class MonkeyEncoder(Encoder):
|
|
329
|
+
....: def __init__(self, code):
|
|
330
|
+
....: super().__init__(C)
|
|
331
|
+
....: @cached_method
|
|
332
|
+
....: def generator_matrix(self):
|
|
333
|
+
....: G = identity_matrix(GF(5), 5).augment(matrix(GF(5), 5, 7))
|
|
334
|
+
....: return G
|
|
335
|
+
....:
|
|
336
|
+
sage: MonkeyCode._registered_encoders["Monkey"] = MonkeyEncoder
|
|
337
|
+
sage: C = MonkeyCode()
|
|
338
|
+
sage: C.dimension()
|
|
339
|
+
5
|
|
340
|
+
"""
|
|
341
|
+
try:
|
|
342
|
+
return self._dimension
|
|
343
|
+
except AttributeError:
|
|
344
|
+
dimension = self.generator_matrix().nrows()
|
|
345
|
+
self._dimension = dimension
|
|
346
|
+
return self._dimension
|
|
347
|
+
|
|
348
|
+
def cardinality(self):
|
|
349
|
+
r"""
|
|
350
|
+
Return the size of this code.
|
|
351
|
+
|
|
352
|
+
EXAMPLES::
|
|
353
|
+
|
|
354
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
355
|
+
sage: C.cardinality()
|
|
356
|
+
16
|
|
357
|
+
sage: len(C)
|
|
358
|
+
16
|
|
359
|
+
"""
|
|
360
|
+
return self.base_ring().order()**self.dimension()
|
|
361
|
+
|
|
362
|
+
__len__ = cardinality
|
|
363
|
+
|
|
364
|
+
def rate(self):
|
|
365
|
+
r"""
|
|
366
|
+
Return the ratio of the number of information symbols to
|
|
367
|
+
the code length.
|
|
368
|
+
|
|
369
|
+
EXAMPLES::
|
|
370
|
+
|
|
371
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
372
|
+
sage: C.rate()
|
|
373
|
+
4/7
|
|
374
|
+
"""
|
|
375
|
+
return self.dimension() / self.length()
|
|
376
|
+
|
|
377
|
+
@cached_method
|
|
378
|
+
def gens(self) -> tuple:
|
|
379
|
+
r"""
|
|
380
|
+
Return the generators of this code as a tuple of vectors.
|
|
381
|
+
|
|
382
|
+
EXAMPLES::
|
|
383
|
+
|
|
384
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
385
|
+
sage: C.gens()
|
|
386
|
+
((1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1),
|
|
387
|
+
(0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1))
|
|
388
|
+
"""
|
|
389
|
+
return tuple(self.generator_matrix().rows())
|
|
390
|
+
|
|
391
|
+
def basis(self):
|
|
392
|
+
r"""
|
|
393
|
+
Return a basis of ``self``.
|
|
394
|
+
|
|
395
|
+
OUTPUT: ``Sequence`` -- an immutable sequence whose universe is ambient space of ``self``
|
|
396
|
+
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
400
|
+
sage: C.basis()
|
|
401
|
+
[(1, 0, 0, 0, 0, 1, 1),
|
|
402
|
+
(0, 1, 0, 0, 1, 0, 1),
|
|
403
|
+
(0, 0, 1, 0, 1, 1, 0),
|
|
404
|
+
(0, 0, 0, 1, 1, 1, 1)]
|
|
405
|
+
sage: C.basis().universe()
|
|
406
|
+
Vector space of dimension 7 over Finite Field of size 2
|
|
407
|
+
"""
|
|
408
|
+
gens = self.gens()
|
|
409
|
+
from sage.structure.sequence import Sequence
|
|
410
|
+
return Sequence(gens, universe=self.ambient_space(), check=False, immutable=True, cr=True)
|
|
411
|
+
|
|
412
|
+
@cached_method
|
|
413
|
+
def parity_check_matrix(self):
|
|
414
|
+
r"""
|
|
415
|
+
Return the parity check matrix of ``self``.
|
|
416
|
+
|
|
417
|
+
The parity check matrix of a linear code `C` corresponds to the
|
|
418
|
+
generator matrix of the dual code of `C`.
|
|
419
|
+
|
|
420
|
+
EXAMPLES::
|
|
421
|
+
|
|
422
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
423
|
+
sage: Cperp = C.dual_code()
|
|
424
|
+
sage: C; Cperp
|
|
425
|
+
[7, 4] Hamming Code over GF(2)
|
|
426
|
+
[7, 3] linear code over GF(2)
|
|
427
|
+
sage: C.generator_matrix()
|
|
428
|
+
[1 0 0 0 0 1 1]
|
|
429
|
+
[0 1 0 0 1 0 1]
|
|
430
|
+
[0 0 1 0 1 1 0]
|
|
431
|
+
[0 0 0 1 1 1 1]
|
|
432
|
+
sage: C.parity_check_matrix()
|
|
433
|
+
[1 0 1 0 1 0 1]
|
|
434
|
+
[0 1 1 0 0 1 1]
|
|
435
|
+
[0 0 0 1 1 1 1]
|
|
436
|
+
sage: Cperp.parity_check_matrix()
|
|
437
|
+
[1 0 0 0 0 1 1]
|
|
438
|
+
[0 1 0 0 1 0 1]
|
|
439
|
+
[0 0 1 0 1 1 0]
|
|
440
|
+
[0 0 0 1 1 1 1]
|
|
441
|
+
sage: Cperp.generator_matrix()
|
|
442
|
+
[1 0 1 0 1 0 1]
|
|
443
|
+
[0 1 1 0 0 1 1]
|
|
444
|
+
[0 0 0 1 1 1 1]
|
|
445
|
+
"""
|
|
446
|
+
G = self.generator_matrix()
|
|
447
|
+
H = G.right_kernel()
|
|
448
|
+
M = H.basis_matrix()
|
|
449
|
+
M.set_immutable()
|
|
450
|
+
return M
|
|
451
|
+
|
|
452
|
+
def syndrome(self, r):
|
|
453
|
+
r"""
|
|
454
|
+
Return the syndrome of ``r``.
|
|
455
|
+
|
|
456
|
+
The syndrome of ``r`` is the result of `H \times r` where `H` is
|
|
457
|
+
the parity check matrix of ``self``. If ``r`` belongs to ``self``,
|
|
458
|
+
its syndrome equals to the zero vector.
|
|
459
|
+
|
|
460
|
+
INPUT:
|
|
461
|
+
|
|
462
|
+
- ``r`` -- a vector of the same length as ``self``
|
|
463
|
+
|
|
464
|
+
OUTPUT: a column vector
|
|
465
|
+
|
|
466
|
+
EXAMPLES::
|
|
467
|
+
|
|
468
|
+
sage: MS = MatrixSpace(GF(2),4,7)
|
|
469
|
+
sage: G = MS([[1,1,1,0,0,0,0], [1,0,0,1,1,0,0], [0,1,0,1,0,1,0], [1,1,0,1,0,0,1]])
|
|
470
|
+
sage: C = LinearCode(G)
|
|
471
|
+
sage: r = vector(GF(2), (1,0,1,0,1,0,1))
|
|
472
|
+
sage: r in C
|
|
473
|
+
True
|
|
474
|
+
sage: C.syndrome(r)
|
|
475
|
+
(0, 0, 0)
|
|
476
|
+
|
|
477
|
+
If ``r`` is not a codeword, its syndrome is not equal to zero::
|
|
478
|
+
|
|
479
|
+
sage: r = vector(GF(2), (1,0,1,0,1,1,1))
|
|
480
|
+
sage: r in C
|
|
481
|
+
False
|
|
482
|
+
sage: C.syndrome(r)
|
|
483
|
+
(0, 1, 1)
|
|
484
|
+
|
|
485
|
+
Syndrome computation works fine on bigger fields::
|
|
486
|
+
|
|
487
|
+
sage: C = codes.random_linear_code(GF(59), 12, 4)
|
|
488
|
+
sage: c = C.random_element()
|
|
489
|
+
sage: C.syndrome(c)
|
|
490
|
+
(0, 0, 0, 0, 0, 0, 0, 0)
|
|
491
|
+
"""
|
|
492
|
+
return self.parity_check_matrix()*r
|
|
493
|
+
|
|
494
|
+
def __contains__(self, v):
|
|
495
|
+
r"""
|
|
496
|
+
Return ``True`` if `v` can be coerced into ``self``.
|
|
497
|
+
Otherwise, return ``False``.
|
|
498
|
+
|
|
499
|
+
EXAMPLES::
|
|
500
|
+
|
|
501
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
502
|
+
sage: vector((1, 0, 0, 0, 0, 1, 1)) in C # indirect doctest
|
|
503
|
+
True
|
|
504
|
+
sage: vector((1, 0, 0, 0, 2, 1, 1)) in C # indirect doctest
|
|
505
|
+
True
|
|
506
|
+
sage: vector((1, 0, 0, 0, 0, 1/2, 1)) in C # indirect doctest
|
|
507
|
+
False
|
|
508
|
+
"""
|
|
509
|
+
if v not in self.ambient_space() or len(v) != self.length():
|
|
510
|
+
return False
|
|
511
|
+
return self.syndrome(v) == 0
|
|
512
|
+
|
|
513
|
+
def systematic_generator_matrix(self, systematic_positions=None):
|
|
514
|
+
"""
|
|
515
|
+
Return a systematic generator matrix of the code.
|
|
516
|
+
|
|
517
|
+
A generator matrix of a code is called systematic if it contains
|
|
518
|
+
a set of columns forming an identity matrix.
|
|
519
|
+
|
|
520
|
+
INPUT:
|
|
521
|
+
|
|
522
|
+
- ``systematic_positions`` -- (default: ``None``) if supplied, the set
|
|
523
|
+
of systematic positions in the systematic generator matrix. See the
|
|
524
|
+
documentation for :class:`LinearCodeSystematicEncoder` details.
|
|
525
|
+
|
|
526
|
+
EXAMPLES::
|
|
527
|
+
|
|
528
|
+
sage: G = matrix(GF(3), [[ 1, 2, 1, 0],\
|
|
529
|
+
....: [ 2, 1, 1, 1]])
|
|
530
|
+
sage: C = LinearCode(G)
|
|
531
|
+
sage: C.generator_matrix()
|
|
532
|
+
[1 2 1 0]
|
|
533
|
+
[2 1 1 1]
|
|
534
|
+
sage: C.systematic_generator_matrix()
|
|
535
|
+
[1 2 0 1]
|
|
536
|
+
[0 0 1 2]
|
|
537
|
+
|
|
538
|
+
Specific systematic positions can also be requested::
|
|
539
|
+
|
|
540
|
+
sage: C.systematic_generator_matrix(systematic_positions=[3,2])
|
|
541
|
+
[1 2 0 1]
|
|
542
|
+
[1 2 1 0]
|
|
543
|
+
"""
|
|
544
|
+
systematic_positions = tuple(systematic_positions) if systematic_positions else None
|
|
545
|
+
return self.encoder("Systematic", systematic_positions=systematic_positions).generator_matrix()
|
|
546
|
+
|
|
547
|
+
def standard_form(self, return_permutation=True):
|
|
548
|
+
r"""
|
|
549
|
+
Return a linear code which is permutation-equivalent to ``self`` and
|
|
550
|
+
admits a generator matrix in standard form.
|
|
551
|
+
|
|
552
|
+
A generator matrix is in standard form if it is of the form `[I \vert
|
|
553
|
+
A]`, where `I` is the `k \times k` identity matrix. Any code admits a
|
|
554
|
+
generator matrix in systematic form, i.e. where a subset of the columns
|
|
555
|
+
form the identity matrix, but one might need to permute columns to allow
|
|
556
|
+
the identity matrix to be leading.
|
|
557
|
+
|
|
558
|
+
INPUT:
|
|
559
|
+
|
|
560
|
+
- ``return_permutation`` -- boolean (default: ``True``); if ``True``,
|
|
561
|
+
the column permutation which brings ``self`` into the returned code
|
|
562
|
+
is also returned
|
|
563
|
+
|
|
564
|
+
OUTPUT: a :class:`LinearCode` whose :meth:`systematic_generator_matrix`
|
|
565
|
+
is guaranteed to be of the form `[I \vert A]`.
|
|
566
|
+
|
|
567
|
+
EXAMPLES::
|
|
568
|
+
|
|
569
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
570
|
+
sage: C.generator_matrix()
|
|
571
|
+
[1 0 0 0 0 1 1]
|
|
572
|
+
[0 1 0 0 1 0 1]
|
|
573
|
+
[0 0 1 0 1 1 0]
|
|
574
|
+
[0 0 0 1 1 1 1]
|
|
575
|
+
sage: Cs,p = C.standard_form()
|
|
576
|
+
sage: p
|
|
577
|
+
[]
|
|
578
|
+
sage: Cs is C
|
|
579
|
+
True
|
|
580
|
+
sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\
|
|
581
|
+
....: [0,1,0,1,0,1,0],\
|
|
582
|
+
....: [0,0,0,0,0,0,1]]))
|
|
583
|
+
sage: Cs, p = C.standard_form()
|
|
584
|
+
sage: p
|
|
585
|
+
[1, 2, 7, 3, 4, 5, 6]
|
|
586
|
+
sage: Cs.generator_matrix()
|
|
587
|
+
[1 0 0 0 0 1 1]
|
|
588
|
+
[0 1 0 0 1 0 1]
|
|
589
|
+
[0 0 1 0 0 0 0]
|
|
590
|
+
"""
|
|
591
|
+
E = self.encoder("Systematic")
|
|
592
|
+
if E.systematic_positions() == tuple(range(self.dimension())):
|
|
593
|
+
from sage.combinat.permutation import Permutation
|
|
594
|
+
return self, Permutation([])
|
|
595
|
+
else:
|
|
596
|
+
perm = E.systematic_permutation()
|
|
597
|
+
return self.permuted_code(perm), perm
|
|
598
|
+
|
|
599
|
+
def redundancy_matrix(self):
|
|
600
|
+
r"""
|
|
601
|
+
Return the non-identity columns of a systematic generator matrix for
|
|
602
|
+
``self``.
|
|
603
|
+
|
|
604
|
+
A systematic generator matrix is a generator matrix such that a subset
|
|
605
|
+
of its columns forms the identity matrix. This method returns the
|
|
606
|
+
remaining part of the matrix.
|
|
607
|
+
|
|
608
|
+
For any given code, there can be many systematic generator matrices
|
|
609
|
+
(depending on which positions should form the identity). This method
|
|
610
|
+
will use the matrix returned by
|
|
611
|
+
:meth:`AbstractLinearCode.systematic_generator_matrix`.
|
|
612
|
+
|
|
613
|
+
OUTPUT:
|
|
614
|
+
|
|
615
|
+
- An `k \times (n-k)` matrix.
|
|
616
|
+
|
|
617
|
+
EXAMPLES::
|
|
618
|
+
|
|
619
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
620
|
+
sage: C.generator_matrix()
|
|
621
|
+
[1 0 0 0 0 1 1]
|
|
622
|
+
[0 1 0 0 1 0 1]
|
|
623
|
+
[0 0 1 0 1 1 0]
|
|
624
|
+
[0 0 0 1 1 1 1]
|
|
625
|
+
sage: C.redundancy_matrix()
|
|
626
|
+
[0 1 1]
|
|
627
|
+
[1 0 1]
|
|
628
|
+
[1 1 0]
|
|
629
|
+
[1 1 1]
|
|
630
|
+
sage: C = LinearCode(matrix(GF(3),2,[1,2,0,\
|
|
631
|
+
....: 2,1,1]))
|
|
632
|
+
sage: C.systematic_generator_matrix()
|
|
633
|
+
[1 2 0]
|
|
634
|
+
[0 0 1]
|
|
635
|
+
sage: C.redundancy_matrix()
|
|
636
|
+
[2]
|
|
637
|
+
[0]
|
|
638
|
+
"""
|
|
639
|
+
E = self.encoder("Systematic")
|
|
640
|
+
G = E.generator_matrix()
|
|
641
|
+
return G.delete_columns(E.systematic_positions())
|
|
642
|
+
|
|
643
|
+
@cached_method
|
|
644
|
+
def information_set(self):
|
|
645
|
+
"""
|
|
646
|
+
Return an information set of the code.
|
|
647
|
+
|
|
648
|
+
Return value of this method is cached.
|
|
649
|
+
|
|
650
|
+
A set of column positions of a generator matrix of a code
|
|
651
|
+
is called an information set if the corresponding columns
|
|
652
|
+
form a square matrix of full rank.
|
|
653
|
+
|
|
654
|
+
OUTPUT: information set of a systematic generator matrix of the code
|
|
655
|
+
|
|
656
|
+
EXAMPLES::
|
|
657
|
+
|
|
658
|
+
sage: G = matrix(GF(3),2,[1,2,0,
|
|
659
|
+
....: 2,1,1])
|
|
660
|
+
sage: code = LinearCode(G)
|
|
661
|
+
sage: code.systematic_generator_matrix()
|
|
662
|
+
[1 2 0]
|
|
663
|
+
[0 0 1]
|
|
664
|
+
sage: code.information_set()
|
|
665
|
+
(0, 2)
|
|
666
|
+
"""
|
|
667
|
+
return self.encoder("Systematic").systematic_positions()
|
|
668
|
+
|
|
669
|
+
def is_information_set(self, positions):
|
|
670
|
+
"""
|
|
671
|
+
Return whether the given positions form an information set.
|
|
672
|
+
|
|
673
|
+
INPUT:
|
|
674
|
+
|
|
675
|
+
- A list of positions, i.e. integers in the range 0 to `n-1` where `n`
|
|
676
|
+
is the length of ``self``.
|
|
677
|
+
|
|
678
|
+
OUTPUT: boolean indicating whether the positions form an information set
|
|
679
|
+
|
|
680
|
+
EXAMPLES::
|
|
681
|
+
|
|
682
|
+
sage: G = matrix(GF(3),2,[1,2,0,
|
|
683
|
+
....: 2,1,1])
|
|
684
|
+
sage: code = LinearCode(G)
|
|
685
|
+
sage: code.is_information_set([0,1])
|
|
686
|
+
False
|
|
687
|
+
sage: code.is_information_set([0,2])
|
|
688
|
+
True
|
|
689
|
+
"""
|
|
690
|
+
try:
|
|
691
|
+
self.encoder("Systematic", systematic_positions=tuple(positions))
|
|
692
|
+
return True
|
|
693
|
+
except ValueError:
|
|
694
|
+
return False
|
|
695
|
+
|
|
696
|
+
def __iter__(self):
|
|
697
|
+
"""
|
|
698
|
+
Return an iterator over the elements of this linear code.
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
703
|
+
sage: [list(c) for c in C if c.hamming_weight() < 4]
|
|
704
|
+
[[0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1],
|
|
705
|
+
[0, 1, 0, 0, 1, 0, 1], [0, 0, 1, 0, 1, 1, 0],
|
|
706
|
+
[1, 1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 1, 0, 0],
|
|
707
|
+
[0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 0, 0, 1]]
|
|
708
|
+
|
|
709
|
+
TESTS::
|
|
710
|
+
|
|
711
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
712
|
+
sage: L = list(C)
|
|
713
|
+
sage: L[10].is_immutable()
|
|
714
|
+
True
|
|
715
|
+
"""
|
|
716
|
+
from sage.modules.finite_submodule_iter import \
|
|
717
|
+
FiniteFieldsubspace_iterator
|
|
718
|
+
return FiniteFieldsubspace_iterator(self.generator_matrix(), immutable=True)
|
|
719
|
+
|
|
720
|
+
def __getitem__(self, i):
|
|
721
|
+
r"""
|
|
722
|
+
Return the `i`-th codeword of this code.
|
|
723
|
+
|
|
724
|
+
The implementation of this depends on the implementation of the
|
|
725
|
+
:meth:`.__iter__` method.
|
|
726
|
+
|
|
727
|
+
The implementation is as follows. Suppose that:
|
|
728
|
+
|
|
729
|
+
- the primitive element of the base_ring of this code is `a`,
|
|
730
|
+
- the prime subfield is `p`,
|
|
731
|
+
- the field has order `p^m`,
|
|
732
|
+
- the code has dimension `k`,
|
|
733
|
+
- and the generator matrix is `G`.
|
|
734
|
+
|
|
735
|
+
Then the :meth:`.__iter__` method returns the elements in this order:
|
|
736
|
+
|
|
737
|
+
1. first, the following ordered list is returned:
|
|
738
|
+
``[i*a^0 * G[0] for i in range(p)]``
|
|
739
|
+
2. Next, the following ordered list is returned:
|
|
740
|
+
``[i*a^0 * G[0] + a^1*G[0] for i in range(p)]``
|
|
741
|
+
3. This continues till we get
|
|
742
|
+
``[(i*a^0 +(p-1)*a^1 +...+ (p-1)*a^(m-1))*G[0] for i in range(p)]``
|
|
743
|
+
4. Then, we move to G[1]:
|
|
744
|
+
``[i*a^0 * G[0] + a^0*G[1] for i in range(p)]``,
|
|
745
|
+
|
|
746
|
+
and so on.
|
|
747
|
+
Hence the `i`-th element can be obtained by the `p`-adic expansion
|
|
748
|
+
of `i` as ``[i_0, i_1, ...,i_{m-1}, i_m, i_{m+1}, ..., i_{km-1}].``
|
|
749
|
+
|
|
750
|
+
The element that is generated is:
|
|
751
|
+
|
|
752
|
+
.. MATH::
|
|
753
|
+
|
|
754
|
+
\begin{aligned}
|
|
755
|
+
& (i_0 a^0 + i_1 a^1 + \cdots + i_{m-1} a^{m-1}) G[0] + \\
|
|
756
|
+
& (i_m a^0 + i_{m+1} a^1 + \cdots + i_{2m-1} a^{m-1}) G[1] + \\
|
|
757
|
+
& \vdots\\
|
|
758
|
+
& (i_{(k-1)m} a^0 + \cdots + i_{km-1} a^{m-1}) G[k-1]
|
|
759
|
+
\end{aligned}
|
|
760
|
+
|
|
761
|
+
EXAMPLES::
|
|
762
|
+
|
|
763
|
+
sage: G = Matrix(GF(3), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
764
|
+
sage: C = LinearCode(G)
|
|
765
|
+
sage: C[24]
|
|
766
|
+
(2, 2, 0, 1, 2, 2, 0)
|
|
767
|
+
sage: C[24] == C.list()[24]
|
|
768
|
+
True
|
|
769
|
+
|
|
770
|
+
TESTS::
|
|
771
|
+
|
|
772
|
+
sage: C = random_matrix(GF(25,'a'), 2, 7).row_space()
|
|
773
|
+
sage: C = LinearCode(C.basis_matrix())
|
|
774
|
+
sage: Clist = C.list()
|
|
775
|
+
sage: all(C[i] == Clist[i] for i in range(len(C)))
|
|
776
|
+
True
|
|
777
|
+
|
|
778
|
+
Check that only the indices less than the size of the code are
|
|
779
|
+
allowed::
|
|
780
|
+
|
|
781
|
+
sage: C[25**2]
|
|
782
|
+
Traceback (most recent call last):
|
|
783
|
+
...
|
|
784
|
+
IndexError: The value of the index 'i' (=625) must be between
|
|
785
|
+
0 and 'q^k -1' (=624), inclusive, where 'q' is the size of the
|
|
786
|
+
base field and 'k' is the dimension of the code.
|
|
787
|
+
|
|
788
|
+
Check that codewords are immutable. See :issue:`16338`::
|
|
789
|
+
|
|
790
|
+
sage: C[0].is_immutable()
|
|
791
|
+
True
|
|
792
|
+
"""
|
|
793
|
+
# IMPORTANT: If the __iter__() function implementation is changed
|
|
794
|
+
# then the implementation here must also be changed so that
|
|
795
|
+
# list(self)[i] and self[i] both return the same element.
|
|
796
|
+
|
|
797
|
+
F = self.base_ring()
|
|
798
|
+
maxindex = F.order()**self.dimension()-1
|
|
799
|
+
if i < 0 or i > maxindex:
|
|
800
|
+
raise IndexError("The value of the index 'i' (={}) must be between "
|
|
801
|
+
"0 and 'q^k -1' (={}), inclusive, where 'q' is "
|
|
802
|
+
"the size of the base field and 'k' is the "
|
|
803
|
+
"dimension of the code.".format(i, maxindex))
|
|
804
|
+
|
|
805
|
+
a = F.primitive_element()
|
|
806
|
+
m = F.degree()
|
|
807
|
+
p = F.prime_subfield().order()
|
|
808
|
+
A = [a ** k for k in range(m)]
|
|
809
|
+
G = self.generator_matrix()
|
|
810
|
+
N = self.dimension()*F.degree() # the total length of p-adic vector
|
|
811
|
+
ivec = Integer(i).digits(p, padto=N)
|
|
812
|
+
|
|
813
|
+
codeword = 0
|
|
814
|
+
row = 0
|
|
815
|
+
for g in G:
|
|
816
|
+
codeword += sum(ivec[j+row*m]*A[j] for j in range(m)) * g
|
|
817
|
+
row += 1
|
|
818
|
+
|
|
819
|
+
# The codewords for a specific code can not change. So, we set them
|
|
820
|
+
# to be immutable.
|
|
821
|
+
codeword.set_immutable()
|
|
822
|
+
return codeword
|
|
823
|
+
|
|
824
|
+
def __hash__(self):
|
|
825
|
+
r"""
|
|
826
|
+
Return the hash value of ``self``.
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
831
|
+
sage: C = LinearCode(G)
|
|
832
|
+
sage: hash(C) #random
|
|
833
|
+
9015017528451745710
|
|
834
|
+
|
|
835
|
+
If ``C1`` and ``C2`` are two codes which only differ by the
|
|
836
|
+
coefficients of their generator matrices, their hashes are
|
|
837
|
+
different (we check that the bug found in :issue:`18813` is
|
|
838
|
+
fixed)::
|
|
839
|
+
|
|
840
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
841
|
+
sage: C1 = LinearCode(G)
|
|
842
|
+
sage: G = Matrix(GF(2), [[1,0,0,1,0,1,0],[0,1,0,0,1,0,0],[0,0,1,1,0,1,0],[0,0,0,0,0,0,1]])
|
|
843
|
+
sage: C2 = LinearCode(G)
|
|
844
|
+
sage: hash(C1) != hash(C2)
|
|
845
|
+
True
|
|
846
|
+
"""
|
|
847
|
+
Str = str(self)
|
|
848
|
+
G = self.generator_matrix()
|
|
849
|
+
return hash((Str, G)) ^ hash(Str) ^ hash(G)
|
|
850
|
+
|
|
851
|
+
def is_subcode(self, other):
|
|
852
|
+
"""
|
|
853
|
+
Return ``True`` if ``self`` is a subcode of ``other``.
|
|
854
|
+
|
|
855
|
+
EXAMPLES::
|
|
856
|
+
|
|
857
|
+
sage: C1 = codes.HammingCode(GF(2), 3)
|
|
858
|
+
sage: G1 = C1.generator_matrix()
|
|
859
|
+
sage: G2 = G1.matrix_from_rows([0,1,2])
|
|
860
|
+
sage: C2 = LinearCode(G2)
|
|
861
|
+
sage: C2.is_subcode(C1)
|
|
862
|
+
True
|
|
863
|
+
sage: C1.is_subcode(C2)
|
|
864
|
+
False
|
|
865
|
+
sage: C3 = C1.extended_code()
|
|
866
|
+
sage: C1.is_subcode(C3)
|
|
867
|
+
False
|
|
868
|
+
sage: C4 = C1.punctured([1])
|
|
869
|
+
sage: C4.is_subcode(C1)
|
|
870
|
+
False
|
|
871
|
+
sage: C5 = C1.shortened([1])
|
|
872
|
+
sage: C5.is_subcode(C1)
|
|
873
|
+
False
|
|
874
|
+
sage: C1 = codes.HammingCode(GF(9,"z"), 3)
|
|
875
|
+
sage: G1 = C1.generator_matrix()
|
|
876
|
+
sage: G2 = G1.matrix_from_rows([0,1,2])
|
|
877
|
+
sage: C2 = LinearCode(G2)
|
|
878
|
+
sage: C2.is_subcode(C1)
|
|
879
|
+
True
|
|
880
|
+
"""
|
|
881
|
+
G = self.generator_matrix()
|
|
882
|
+
return all(r in other for r in G.rows())
|
|
883
|
+
|
|
884
|
+
def is_permutation_automorphism(self, g):
|
|
885
|
+
r"""
|
|
886
|
+
Return `1` if `g` is an element of `S_n` (`n` = length of ``self``) and
|
|
887
|
+
if `g` is an automorphism of ``self``.
|
|
888
|
+
|
|
889
|
+
EXAMPLES::
|
|
890
|
+
|
|
891
|
+
sage: # needs sage.groups
|
|
892
|
+
sage: C = codes.HammingCode(GF(3), 3)
|
|
893
|
+
sage: g = SymmetricGroup(13).random_element()
|
|
894
|
+
sage: C.is_permutation_automorphism(g)
|
|
895
|
+
0
|
|
896
|
+
sage: MS = MatrixSpace(GF(2),4,8)
|
|
897
|
+
sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0],
|
|
898
|
+
....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]])
|
|
899
|
+
sage: C = LinearCode(G)
|
|
900
|
+
sage: S8 = SymmetricGroup(8)
|
|
901
|
+
sage: g = S8("(2,3)")
|
|
902
|
+
sage: C.is_permutation_automorphism(g)
|
|
903
|
+
1
|
|
904
|
+
sage: g = S8("(1,2,3,4)")
|
|
905
|
+
sage: C.is_permutation_automorphism(g)
|
|
906
|
+
0
|
|
907
|
+
"""
|
|
908
|
+
basis = self.generator_matrix().rows()
|
|
909
|
+
H = self.parity_check_matrix()
|
|
910
|
+
V = H.column_space()
|
|
911
|
+
HGm = H*g.matrix()
|
|
912
|
+
for c in basis:
|
|
913
|
+
if HGm*c != V(0):
|
|
914
|
+
return False
|
|
915
|
+
return True
|
|
916
|
+
|
|
917
|
+
def permuted_code(self, p):
|
|
918
|
+
r"""
|
|
919
|
+
Return the permuted code, which is equivalent to ``self`` via the
|
|
920
|
+
column permutation ``p``.
|
|
921
|
+
|
|
922
|
+
EXAMPLES::
|
|
923
|
+
|
|
924
|
+
sage: # needs sage.groups
|
|
925
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
926
|
+
sage: G = C.permutation_automorphism_group(); G
|
|
927
|
+
Permutation Group with generators
|
|
928
|
+
[(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)]
|
|
929
|
+
sage: g = G("(2,3)(6,7)")
|
|
930
|
+
sage: Cg = C.permuted_code(g)
|
|
931
|
+
sage: Cg
|
|
932
|
+
[7, 4] linear code over GF(2)
|
|
933
|
+
sage: C.generator_matrix() == Cg.systematic_generator_matrix()
|
|
934
|
+
True
|
|
935
|
+
"""
|
|
936
|
+
if not hasattr(self, "_generic_constructor"):
|
|
937
|
+
raise NotImplementedError("Generic constructor not set for the class of codes")
|
|
938
|
+
G = copy(self.generator_matrix())
|
|
939
|
+
G.permute_columns(p)
|
|
940
|
+
return self._generic_constructor(G)
|
|
941
|
+
|
|
942
|
+
def dual_code(self):
|
|
943
|
+
r"""
|
|
944
|
+
Return the dual code `C^{\perp}` of the code `C`,
|
|
945
|
+
|
|
946
|
+
.. MATH::
|
|
947
|
+
|
|
948
|
+
C^{\perp} = \{ v \in V\ |\ v\cdot c = 0,\ \forall c \in C \}.
|
|
949
|
+
|
|
950
|
+
EXAMPLES::
|
|
951
|
+
|
|
952
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
953
|
+
sage: C.dual_code()
|
|
954
|
+
[7, 3] linear code over GF(2)
|
|
955
|
+
sage: C = codes.HammingCode(GF(4, 'a'), 3)
|
|
956
|
+
sage: C.dual_code()
|
|
957
|
+
[21, 3] linear code over GF(4)
|
|
958
|
+
"""
|
|
959
|
+
if not hasattr(self, "_generic_constructor"):
|
|
960
|
+
raise NotImplementedError("Generic constructor not set for the class of codes")
|
|
961
|
+
return self._generic_constructor(self.parity_check_matrix())
|
|
962
|
+
|
|
963
|
+
def is_self_dual(self) -> bool:
|
|
964
|
+
"""
|
|
965
|
+
Return ``True`` if the code is self-dual (in the usual Hamming inner
|
|
966
|
+
product) and ``False`` otherwise.
|
|
967
|
+
|
|
968
|
+
EXAMPLES::
|
|
969
|
+
|
|
970
|
+
sage: C = codes.GolayCode(GF(2))
|
|
971
|
+
sage: C.is_self_dual()
|
|
972
|
+
True
|
|
973
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
974
|
+
sage: C.is_self_dual()
|
|
975
|
+
False
|
|
976
|
+
"""
|
|
977
|
+
return self == self.dual_code()
|
|
978
|
+
|
|
979
|
+
def is_self_orthogonal(self):
|
|
980
|
+
"""
|
|
981
|
+
Return ``True`` if this code is self-orthogonal and ``False``
|
|
982
|
+
otherwise.
|
|
983
|
+
|
|
984
|
+
A code is self-orthogonal if it is a subcode of its dual.
|
|
985
|
+
|
|
986
|
+
EXAMPLES::
|
|
987
|
+
|
|
988
|
+
sage: C = codes.GolayCode(GF(2))
|
|
989
|
+
sage: C.is_self_orthogonal()
|
|
990
|
+
True
|
|
991
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
992
|
+
sage: C.is_self_orthogonal()
|
|
993
|
+
False
|
|
994
|
+
sage: C = codes.QuasiQuadraticResidueCode(11) # optional - gap_package_guava
|
|
995
|
+
sage: C.is_self_orthogonal() # optional - gap_package_guava
|
|
996
|
+
True
|
|
997
|
+
"""
|
|
998
|
+
return self.is_subcode(self.dual_code())
|
|
999
|
+
|
|
1000
|
+
@cached_method
|
|
1001
|
+
def zero(self):
|
|
1002
|
+
r"""
|
|
1003
|
+
Return the zero vector of ``self``.
|
|
1004
|
+
|
|
1005
|
+
EXAMPLES::
|
|
1006
|
+
|
|
1007
|
+
sage: C = codes.HammingCode(GF(2), 3)
|
|
1008
|
+
sage: C.zero()
|
|
1009
|
+
(0, 0, 0, 0, 0, 0, 0)
|
|
1010
|
+
sage: C.sum(()) # indirect doctest
|
|
1011
|
+
(0, 0, 0, 0, 0, 0, 0)
|
|
1012
|
+
sage: C.sum((C.gens())) # indirect doctest
|
|
1013
|
+
(1, 1, 1, 1, 1, 1, 1)
|
|
1014
|
+
"""
|
|
1015
|
+
return self.ambient_space().zero()
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
####################### encoders ###############################
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
class LinearCodeSystematicEncoder(Encoder):
|
|
1022
|
+
r"""
|
|
1023
|
+
Encoder based on a generator matrix in systematic form for Linear codes.
|
|
1024
|
+
|
|
1025
|
+
To encode an element of its message space, this encoder first builds a
|
|
1026
|
+
generator matrix in systematic form. What is called systematic form here
|
|
1027
|
+
is the reduced row echelon form of a matrix, which is not necessarily
|
|
1028
|
+
`[I \vert H]`, where `I` is the identity block and `H` the parity block.
|
|
1029
|
+
One can refer to :meth:`LinearCodeSystematicEncoder.generator_matrix`
|
|
1030
|
+
for a concrete example.
|
|
1031
|
+
Once such a matrix has been computed, it is used to encode any message
|
|
1032
|
+
into a codeword.
|
|
1033
|
+
|
|
1034
|
+
This encoder can also serve as the default encoder of a code defined by a
|
|
1035
|
+
parity check matrix: if the :class:`LinearCodeSystematicEncoder` detects
|
|
1036
|
+
that it is the default encoder, it computes a generator matrix as the
|
|
1037
|
+
reduced row echelon form of the right kernel of the parity check matrix.
|
|
1038
|
+
|
|
1039
|
+
INPUT:
|
|
1040
|
+
|
|
1041
|
+
- ``code`` -- the associated code of this encoder
|
|
1042
|
+
|
|
1043
|
+
- ``systematic_positions`` -- (default: ``None``) the positions in codewords that
|
|
1044
|
+
should correspond to the message symbols. A list of `k` distinct integers in
|
|
1045
|
+
the range 0 to `n-1` where `n` is the length of the code and `k` its
|
|
1046
|
+
dimension. The `0`-th symbol of a message will then be at position
|
|
1047
|
+
``systematic_positions[0]``, the 1st index at position
|
|
1048
|
+
``systematic_positions[1]``, etc. A :exc:`ValueError` is raised at
|
|
1049
|
+
construction time if the supplied indices do not form an information set.
|
|
1050
|
+
|
|
1051
|
+
EXAMPLES:
|
|
1052
|
+
|
|
1053
|
+
The following demonstrates the basic usage of :class:`LinearCodeSystematicEncoder`::
|
|
1054
|
+
|
|
1055
|
+
sage: LCSE = codes.encoders.LinearCodeSystematicEncoder
|
|
1056
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\
|
|
1057
|
+
....: [1,0,0,1,1,0,0,0],\
|
|
1058
|
+
....: [0,1,0,1,0,1,0,0],\
|
|
1059
|
+
....: [1,1,0,1,0,0,1,1]])
|
|
1060
|
+
sage: C = LinearCode(G)
|
|
1061
|
+
sage: E = LCSE(C)
|
|
1062
|
+
sage: E.generator_matrix()
|
|
1063
|
+
[1 0 0 0 0 1 1 1]
|
|
1064
|
+
[0 1 0 0 1 0 1 1]
|
|
1065
|
+
[0 0 1 0 1 1 0 0]
|
|
1066
|
+
[0 0 0 1 1 1 1 1]
|
|
1067
|
+
sage: E2 = LCSE(C, systematic_positions=[5,4,3,2])
|
|
1068
|
+
sage: E2.generator_matrix()
|
|
1069
|
+
[1 0 0 0 0 1 1 1]
|
|
1070
|
+
[0 1 0 0 1 0 1 1]
|
|
1071
|
+
[1 1 0 1 0 0 1 1]
|
|
1072
|
+
[1 1 1 0 0 0 0 0]
|
|
1073
|
+
|
|
1074
|
+
An error is raised if one specifies systematic positions which do not form
|
|
1075
|
+
an information set::
|
|
1076
|
+
|
|
1077
|
+
sage: E3 = LCSE(C, systematic_positions=[0,1,6,7])
|
|
1078
|
+
Traceback (most recent call last):
|
|
1079
|
+
...
|
|
1080
|
+
ValueError: systematic_positions are not an information set
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
We exemplify how to use :class:`LinearCodeSystematicEncoder` as the default
|
|
1084
|
+
encoder. The following class is the dual of the repetition code::
|
|
1085
|
+
|
|
1086
|
+
sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode):
|
|
1087
|
+
....: def __init__(self, field, length):
|
|
1088
|
+
....: super().__init__(field, length, "Systematic", "Syndrome")
|
|
1089
|
+
....:
|
|
1090
|
+
....: def parity_check_matrix(self):
|
|
1091
|
+
....: return Matrix(self.base_field(), [1]*self.length())
|
|
1092
|
+
....:
|
|
1093
|
+
....: def _repr_(self):
|
|
1094
|
+
....: return "Dual of the [%d, 1] Repetition Code over GF(%s)" % (self.length(), self.base_field().cardinality())
|
|
1095
|
+
....:
|
|
1096
|
+
sage: DualRepetitionCode(GF(3), 5).generator_matrix()
|
|
1097
|
+
[1 0 0 0 2]
|
|
1098
|
+
[0 1 0 0 2]
|
|
1099
|
+
[0 0 1 0 2]
|
|
1100
|
+
[0 0 0 1 2]
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
An exception is thrown if :class:`LinearCodeSystematicEncoder` is the default encoder but no
|
|
1104
|
+
parity check matrix has been specified for the code::
|
|
1105
|
+
|
|
1106
|
+
sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode):
|
|
1107
|
+
....: def __init__(self, field, length):
|
|
1108
|
+
....: super().__init__(field, length, "Systematic", "Syndrome")
|
|
1109
|
+
....:
|
|
1110
|
+
....: def _repr_(self):
|
|
1111
|
+
....: return "I am a badly defined code"
|
|
1112
|
+
....:
|
|
1113
|
+
sage: BadCodeFamily(GF(3), 5).generator_matrix()
|
|
1114
|
+
Traceback (most recent call last):
|
|
1115
|
+
...
|
|
1116
|
+
ValueError: a parity check matrix must be specified
|
|
1117
|
+
if LinearCodeSystematicEncoder is the default encoder
|
|
1118
|
+
"""
|
|
1119
|
+
|
|
1120
|
+
def __init__(self, code, systematic_positions=None):
|
|
1121
|
+
r"""
|
|
1122
|
+
EXAMPLES::
|
|
1123
|
+
|
|
1124
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
1125
|
+
sage: C = LinearCode(G)
|
|
1126
|
+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
|
|
1127
|
+
sage: E
|
|
1128
|
+
Systematic encoder for [7, 4] linear code over GF(2)
|
|
1129
|
+
"""
|
|
1130
|
+
super().__init__(code)
|
|
1131
|
+
self._systematic_positions = tuple(systematic_positions) if systematic_positions else None
|
|
1132
|
+
if systematic_positions:
|
|
1133
|
+
# Test that systematic_positions consists of integers in the right
|
|
1134
|
+
# range. We test that len(systematic_positions) = code.dimension()
|
|
1135
|
+
# in self.generator_matrix() to avoid possible infinite recursion.
|
|
1136
|
+
if (not all( e in ZZ and e >= 0 and e < code.length() for e in systematic_positions)) \
|
|
1137
|
+
or len(systematic_positions) != len(set(systematic_positions)):
|
|
1138
|
+
raise ValueError("systematic positions must be a tuple of distinct integers in the range 0 to n-1 where n is the length of the code")
|
|
1139
|
+
# Test that the systematic positions are an information set
|
|
1140
|
+
self.generator_matrix()
|
|
1141
|
+
|
|
1142
|
+
def __eq__(self, other):
|
|
1143
|
+
r"""
|
|
1144
|
+
Test equality between LinearCodeSystematicEncoder objects.
|
|
1145
|
+
|
|
1146
|
+
EXAMPLES::
|
|
1147
|
+
|
|
1148
|
+
sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]])
|
|
1149
|
+
sage: E1 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G))
|
|
1150
|
+
sage: E2 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G))
|
|
1151
|
+
sage: E1 == E2
|
|
1152
|
+
True
|
|
1153
|
+
sage: E1.systematic_positions()
|
|
1154
|
+
(0, 1, 2)
|
|
1155
|
+
sage: E3 = codes.encoders.LinearCodeSystematicEncoder(LinearCode(G), systematic_positions=(2,5,6))
|
|
1156
|
+
sage: E3.systematic_positions()
|
|
1157
|
+
(2, 5, 6)
|
|
1158
|
+
sage: E1 == E3
|
|
1159
|
+
False
|
|
1160
|
+
"""
|
|
1161
|
+
return isinstance(other, LinearCodeSystematicEncoder)\
|
|
1162
|
+
and self.code() == other.code()\
|
|
1163
|
+
and self.systematic_positions() == other.systematic_positions()
|
|
1164
|
+
|
|
1165
|
+
def _repr_(self):
|
|
1166
|
+
r"""
|
|
1167
|
+
Return a string representation of ``self``.
|
|
1168
|
+
|
|
1169
|
+
EXAMPLES::
|
|
1170
|
+
|
|
1171
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
1172
|
+
sage: C = LinearCode(G)
|
|
1173
|
+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
|
|
1174
|
+
sage: E
|
|
1175
|
+
Systematic encoder for [7, 4] linear code over GF(2)
|
|
1176
|
+
"""
|
|
1177
|
+
return "Systematic encoder for %s" % self.code()
|
|
1178
|
+
|
|
1179
|
+
def _latex_(self):
|
|
1180
|
+
r"""
|
|
1181
|
+
Return a latex representation of ``self``.
|
|
1182
|
+
|
|
1183
|
+
EXAMPLES::
|
|
1184
|
+
|
|
1185
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],[1,0,0,1,1,0,0],[0,1,0,1,0,1,0],[1,1,0,1,0,0,1]])
|
|
1186
|
+
sage: C = LinearCode(G)
|
|
1187
|
+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
|
|
1188
|
+
sage: latex(E)
|
|
1189
|
+
\textnormal{Systematic encoder for }[7, 4]\textnormal{ Linear code over }\Bold{F}_{2}
|
|
1190
|
+
"""
|
|
1191
|
+
return "\\textnormal{Systematic encoder for }%s" % self.code()._latex_()
|
|
1192
|
+
|
|
1193
|
+
@cached_method
|
|
1194
|
+
def generator_matrix(self):
|
|
1195
|
+
r"""
|
|
1196
|
+
Return a generator matrix in systematic form of the associated code of ``self``.
|
|
1197
|
+
|
|
1198
|
+
Systematic form here means that a subsets of the columns of the matrix
|
|
1199
|
+
forms the identity matrix.
|
|
1200
|
+
|
|
1201
|
+
.. NOTE::
|
|
1202
|
+
|
|
1203
|
+
The matrix returned by this method will not necessarily be `[I \vert H]`, where `I`
|
|
1204
|
+
is the identity block and `H` the parity block. If one wants to know which columns
|
|
1205
|
+
create the identity block, one can call :meth:`systematic_positions`
|
|
1206
|
+
|
|
1207
|
+
EXAMPLES::
|
|
1208
|
+
|
|
1209
|
+
sage: LCSE = codes.encoders.LinearCodeSystematicEncoder
|
|
1210
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\
|
|
1211
|
+
....: [1,0,0,1,1,0,0],\
|
|
1212
|
+
....: [0,1,0,1,0,1,0],\
|
|
1213
|
+
....: [1,1,0,1,0,0,1]])
|
|
1214
|
+
sage: C = LinearCode(G)
|
|
1215
|
+
sage: E = LCSE(C)
|
|
1216
|
+
sage: E.generator_matrix()
|
|
1217
|
+
[1 0 0 0 0 1 1]
|
|
1218
|
+
[0 1 0 0 1 0 1]
|
|
1219
|
+
[0 0 1 0 1 1 0]
|
|
1220
|
+
[0 0 0 1 1 1 1]
|
|
1221
|
+
|
|
1222
|
+
We can ask for different systematic positions::
|
|
1223
|
+
|
|
1224
|
+
sage: E2 = LCSE(C, systematic_positions=[5,4,3,2])
|
|
1225
|
+
sage: E2.generator_matrix()
|
|
1226
|
+
[1 0 0 0 0 1 1]
|
|
1227
|
+
[0 1 0 0 1 0 1]
|
|
1228
|
+
[1 1 0 1 0 0 1]
|
|
1229
|
+
[1 1 1 0 0 0 0]
|
|
1230
|
+
|
|
1231
|
+
Another example where there is no generator matrix of the form `[I \vert H]`::
|
|
1232
|
+
|
|
1233
|
+
sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\
|
|
1234
|
+
....: [1,1,0,0,1,0,0],\
|
|
1235
|
+
....: [0,0,1,0,0,1,0],\
|
|
1236
|
+
....: [0,0,1,0,1,0,1]])
|
|
1237
|
+
sage: C = LinearCode(G)
|
|
1238
|
+
sage: E = LCSE(C)
|
|
1239
|
+
sage: E.generator_matrix()
|
|
1240
|
+
[1 1 0 0 0 1 0]
|
|
1241
|
+
[0 0 1 0 0 1 0]
|
|
1242
|
+
[0 0 0 0 1 1 0]
|
|
1243
|
+
[0 0 0 0 0 0 1]
|
|
1244
|
+
"""
|
|
1245
|
+
C = self.code()
|
|
1246
|
+
# This if statement detects if this encoder is itself the default encoder.
|
|
1247
|
+
# In this case, attempt building the generator matrix from the parity
|
|
1248
|
+
# check matrix
|
|
1249
|
+
if hasattr(self, "_use_pc_matrix"):
|
|
1250
|
+
if self._use_pc_matrix == 1:
|
|
1251
|
+
self._use_pc_matrix = 2
|
|
1252
|
+
return C.parity_check_matrix().right_kernel_matrix()
|
|
1253
|
+
else:
|
|
1254
|
+
raise ValueError("a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder")
|
|
1255
|
+
else:
|
|
1256
|
+
self._use_pc_matrix = 1
|
|
1257
|
+
M = copy(C.generator_matrix())
|
|
1258
|
+
if not self._systematic_positions:
|
|
1259
|
+
M.echelonize()
|
|
1260
|
+
else:
|
|
1261
|
+
k = M.nrows() # it is important that k is *not* computed as C.dimension() to avoid possible cyclic dependency
|
|
1262
|
+
if len(self._systematic_positions) != k:
|
|
1263
|
+
raise ValueError("systematic_positions must be a tuple of length equal to the dimension of the code")
|
|
1264
|
+
# Permute the columns of M and bring to reduced row echelon formb
|
|
1265
|
+
perm = self.systematic_permutation()
|
|
1266
|
+
M.permute_columns(perm)
|
|
1267
|
+
M.echelonize()
|
|
1268
|
+
if M[:,:k].is_singular():
|
|
1269
|
+
raise ValueError("systematic_positions are not an information set")
|
|
1270
|
+
M.permute_columns(perm.inverse())
|
|
1271
|
+
M.set_immutable()
|
|
1272
|
+
return M
|
|
1273
|
+
|
|
1274
|
+
def systematic_permutation(self):
|
|
1275
|
+
r"""
|
|
1276
|
+
Return a permutation which would take the systematic positions into [0,..,k-1].
|
|
1277
|
+
|
|
1278
|
+
EXAMPLES::
|
|
1279
|
+
|
|
1280
|
+
sage: C = LinearCode(matrix(GF(2), [[1,0,0,0,1,1,0],\
|
|
1281
|
+
....: [0,1,0,1,0,1,0],\
|
|
1282
|
+
....: [0,0,0,0,0,0,1]]))
|
|
1283
|
+
sage: E = codes.encoders.LinearCodeSystematicEncoder(C)
|
|
1284
|
+
sage: E.systematic_positions()
|
|
1285
|
+
(0, 1, 6)
|
|
1286
|
+
sage: E.systematic_permutation()
|
|
1287
|
+
[1, 2, 7, 3, 4, 5, 6]
|
|
1288
|
+
"""
|
|
1289
|
+
n = self.code().length()
|
|
1290
|
+
systematic_positions = self.systematic_positions()
|
|
1291
|
+
k = len(systematic_positions)
|
|
1292
|
+
lp = [None] * n
|
|
1293
|
+
for (i, j) in zip(range(k), systematic_positions):
|
|
1294
|
+
lp[i] = j
|
|
1295
|
+
j = k
|
|
1296
|
+
set_sys_pos = set(systematic_positions)
|
|
1297
|
+
for i in range(n):
|
|
1298
|
+
if i not in set_sys_pos:
|
|
1299
|
+
lp[j] = i
|
|
1300
|
+
j += 1
|
|
1301
|
+
from sage.combinat.permutation import Permutation
|
|
1302
|
+
return Permutation([1 + e for e in lp])
|
|
1303
|
+
|
|
1304
|
+
def systematic_positions(self):
|
|
1305
|
+
r"""
|
|
1306
|
+
Return a tuple containing the indices of the columns which form an
|
|
1307
|
+
identity matrix when the generator matrix is in systematic form.
|
|
1308
|
+
|
|
1309
|
+
EXAMPLES::
|
|
1310
|
+
|
|
1311
|
+
sage: LCSE = codes.encoders.LinearCodeSystematicEncoder
|
|
1312
|
+
sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0],\
|
|
1313
|
+
....: [1,0,0,1,1,0,0],\
|
|
1314
|
+
....: [0,1,0,1,0,1,0],\
|
|
1315
|
+
....: [1,1,0,1,0,0,1]])
|
|
1316
|
+
sage: C = LinearCode(G)
|
|
1317
|
+
sage: E = LCSE(C)
|
|
1318
|
+
sage: E.systematic_positions()
|
|
1319
|
+
(0, 1, 2, 3)
|
|
1320
|
+
|
|
1321
|
+
We take another matrix with a less nice shape::
|
|
1322
|
+
|
|
1323
|
+
sage: G = Matrix(GF(2), [[1,1,0,0,1,0,1],\
|
|
1324
|
+
....: [1,1,0,0,1,0,0],\
|
|
1325
|
+
....: [0,0,1,0,0,1,0],\
|
|
1326
|
+
....: [0,0,1,0,1,0,1]])
|
|
1327
|
+
sage: C = LinearCode(G)
|
|
1328
|
+
sage: E = LCSE(C)
|
|
1329
|
+
sage: E.systematic_positions()
|
|
1330
|
+
(0, 2, 4, 6)
|
|
1331
|
+
|
|
1332
|
+
The systematic positions correspond to the positions which carry information in a codeword::
|
|
1333
|
+
|
|
1334
|
+
sage: MS = E.message_space()
|
|
1335
|
+
sage: m = MS.random_element()
|
|
1336
|
+
sage: c = m * E.generator_matrix()
|
|
1337
|
+
sage: pos = E.systematic_positions()
|
|
1338
|
+
sage: info = MS([c[i] for i in pos])
|
|
1339
|
+
sage: m == info
|
|
1340
|
+
True
|
|
1341
|
+
|
|
1342
|
+
When constructing a systematic encoder with specific systematic
|
|
1343
|
+
positions, then it is guaranteed that this method returns exactly those
|
|
1344
|
+
positions (even if another choice might also be systematic)::
|
|
1345
|
+
|
|
1346
|
+
sage: G = Matrix(GF(2), [[1,0,0,0],\
|
|
1347
|
+
....: [0,1,0,0],\
|
|
1348
|
+
....: [0,0,1,1]])
|
|
1349
|
+
sage: C = LinearCode(G)
|
|
1350
|
+
sage: E = LCSE(C, systematic_positions=[0,1,3])
|
|
1351
|
+
sage: E.systematic_positions()
|
|
1352
|
+
(0, 1, 3)
|
|
1353
|
+
"""
|
|
1354
|
+
return self._systematic_positions if self._systematic_positions else self.generator_matrix().pivots()
|