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,2639 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings sage.schemes
|
|
3
|
+
r"""
|
|
4
|
+
Decoders for AG codes
|
|
5
|
+
|
|
6
|
+
This module implements decoders for evaluation and differential AG codes.
|
|
7
|
+
|
|
8
|
+
The implemented algorithm for unique decoding of AG codes, named K, is from
|
|
9
|
+
[LBO2014]_ and [Lee2016]_.
|
|
10
|
+
|
|
11
|
+
EXAMPLES::
|
|
12
|
+
|
|
13
|
+
sage: F.<a> = GF(9)
|
|
14
|
+
sage: A2.<x,y> = AffineSpace(F, 2)
|
|
15
|
+
sage: C = Curve(y^3 + y - x^4)
|
|
16
|
+
sage: Q, = C.places_at_infinity()
|
|
17
|
+
sage: O = C(0,0).place()
|
|
18
|
+
sage: pls = C.places()
|
|
19
|
+
sage: pls.remove(Q)
|
|
20
|
+
sage: pls.remove(O)
|
|
21
|
+
sage: G = -O + 18*Q
|
|
22
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
23
|
+
sage: code # long time
|
|
24
|
+
[26, 15] evaluation AG code over GF(9)
|
|
25
|
+
sage: decoder = code.decoder('K') # long time
|
|
26
|
+
sage: tau = decoder.decoding_radius() # long time
|
|
27
|
+
sage: tau # long time
|
|
28
|
+
4
|
|
29
|
+
|
|
30
|
+
The ``decoder`` is now ready for correcting vectors received from a noisy
|
|
31
|
+
channel::
|
|
32
|
+
|
|
33
|
+
sage: # long time
|
|
34
|
+
sage: channel = channels.StaticErrorRateChannel(code.ambient_space(), tau)
|
|
35
|
+
sage: message_space = decoder.message_space()
|
|
36
|
+
sage: message = message_space.random_element()
|
|
37
|
+
sage: encoder = decoder.connected_encoder()
|
|
38
|
+
sage: sent_codeword = encoder.encode(message)
|
|
39
|
+
sage: received_vector = channel(sent_codeword)
|
|
40
|
+
sage: (received_vector - sent_codeword).hamming_weight()
|
|
41
|
+
4
|
|
42
|
+
sage: decoder.decode_to_code(received_vector) == sent_codeword
|
|
43
|
+
True
|
|
44
|
+
sage: decoder.decode_to_message(received_vector) == message
|
|
45
|
+
True
|
|
46
|
+
|
|
47
|
+
AUTHORS:
|
|
48
|
+
|
|
49
|
+
- Kwankyu Lee (2019-03): initial version
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
# ****************************************************************************
|
|
53
|
+
# Copyright (C) 2019 Kwankyu Lee <kwankyu@gmail.com>
|
|
54
|
+
#
|
|
55
|
+
# This program is free software: you can redistribute it and/or modify
|
|
56
|
+
# it under the terms of the GNU General Public License as published by
|
|
57
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
58
|
+
# (at your option) any later version.
|
|
59
|
+
# https://www.gnu.org/licenses/
|
|
60
|
+
# ****************************************************************************
|
|
61
|
+
|
|
62
|
+
cimport cython
|
|
63
|
+
|
|
64
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
65
|
+
from sage.rings.function_field.constructor import FunctionField
|
|
66
|
+
|
|
67
|
+
from sage.modules.free_module_element import vector
|
|
68
|
+
from sage.matrix.constructor import matrix
|
|
69
|
+
|
|
70
|
+
from sage.coding.encoder import Encoder
|
|
71
|
+
from sage.coding.decoder import Decoder, DecodingError
|
|
72
|
+
|
|
73
|
+
from sage.modules.free_module_element cimport FreeModuleElement
|
|
74
|
+
from sage.matrix.matrix cimport Matrix
|
|
75
|
+
from sage.rings.polynomial.polynomial_element cimport Polynomial
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class EvaluationAGCodeEncoder(Encoder):
|
|
79
|
+
"""
|
|
80
|
+
Encoder of an evaluation AG code.
|
|
81
|
+
|
|
82
|
+
INPUT:
|
|
83
|
+
|
|
84
|
+
- ``code`` -- an evaluation AG code
|
|
85
|
+
|
|
86
|
+
- ``decoder`` -- a decoder of the code
|
|
87
|
+
|
|
88
|
+
EXAMPLES::
|
|
89
|
+
|
|
90
|
+
sage: F.<a> = GF(4)
|
|
91
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
92
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
93
|
+
sage: F = C.function_field()
|
|
94
|
+
sage: pls = F.places()
|
|
95
|
+
sage: p = C([0,0])
|
|
96
|
+
sage: Q, = p.places()
|
|
97
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
98
|
+
sage: G = 5*Q
|
|
99
|
+
sage: code = codes.EvaluationAGCode(D, G)
|
|
100
|
+
sage: dec = code.decoder('K', Q)
|
|
101
|
+
sage: enc = dec.connected_encoder()
|
|
102
|
+
sage: enc
|
|
103
|
+
Encoder for [8, 5] evaluation AG code over GF(4)
|
|
104
|
+
"""
|
|
105
|
+
def __init__(self, code, decoder=None):
|
|
106
|
+
"""
|
|
107
|
+
Initialize.
|
|
108
|
+
|
|
109
|
+
TESTS::
|
|
110
|
+
|
|
111
|
+
sage: F.<a> = GF(4)
|
|
112
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
113
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
114
|
+
sage: F = C.function_field()
|
|
115
|
+
sage: pls = F.places()
|
|
116
|
+
sage: p = C([0,0])
|
|
117
|
+
sage: Q, = p.places()
|
|
118
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
119
|
+
sage: G = 5*Q
|
|
120
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
121
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
122
|
+
sage: enc = dec.connected_encoder() # long time
|
|
123
|
+
sage: TestSuite(enc).run(skip='_test_pickling') # long time
|
|
124
|
+
"""
|
|
125
|
+
super().__init__(code)
|
|
126
|
+
|
|
127
|
+
if decoder is None:
|
|
128
|
+
decoder = code.decoder('K')
|
|
129
|
+
|
|
130
|
+
self._decoder = decoder
|
|
131
|
+
self._encode = decoder._encode
|
|
132
|
+
self._unencode = decoder._decode
|
|
133
|
+
|
|
134
|
+
def __hash__(self):
|
|
135
|
+
"""
|
|
136
|
+
Return the hash of ``self``.
|
|
137
|
+
|
|
138
|
+
TESTS::
|
|
139
|
+
|
|
140
|
+
sage: F.<a> = GF(4)
|
|
141
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
142
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
143
|
+
sage: F = C.function_field()
|
|
144
|
+
sage: pls = F.places()
|
|
145
|
+
sage: p = C([0,0])
|
|
146
|
+
sage: Q, = p.places()
|
|
147
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
148
|
+
sage: G = 5*Q
|
|
149
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
150
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
151
|
+
sage: enc = dec.connected_encoder() # long time
|
|
152
|
+
sage: {enc: 1} # long time
|
|
153
|
+
{Encoder for [8, 5] evaluation AG code over GF(4): 1}
|
|
154
|
+
"""
|
|
155
|
+
return hash((self.code(), self._encode))
|
|
156
|
+
|
|
157
|
+
def __eq__(self, other):
|
|
158
|
+
"""
|
|
159
|
+
Test equality.
|
|
160
|
+
|
|
161
|
+
TESTS::
|
|
162
|
+
|
|
163
|
+
sage: F.<a> = GF(4)
|
|
164
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
165
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
166
|
+
sage: F = C.function_field()
|
|
167
|
+
sage: pls = F.places()
|
|
168
|
+
sage: p = C([0,0])
|
|
169
|
+
sage: Q, = p.places()
|
|
170
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
171
|
+
sage: G = 5*Q
|
|
172
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
173
|
+
sage: dec1 = code.decoder('K', Q) # long time
|
|
174
|
+
sage: enc1 = dec1.connected_encoder() # long time
|
|
175
|
+
sage: dec2 = code.decoder('K', Q) # long time
|
|
176
|
+
sage: enc2 = dec2.connected_encoder() # long time
|
|
177
|
+
sage: enc1 == enc2 # long time
|
|
178
|
+
True
|
|
179
|
+
"""
|
|
180
|
+
if self is other:
|
|
181
|
+
return True
|
|
182
|
+
|
|
183
|
+
if not isinstance(other, EvaluationAGCodeEncoder):
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
return self.code() == other.code() and self._decoder == other._decoder
|
|
187
|
+
|
|
188
|
+
def _repr_(self):
|
|
189
|
+
r"""
|
|
190
|
+
Return the string representation of ``self``.
|
|
191
|
+
|
|
192
|
+
TESTS::
|
|
193
|
+
|
|
194
|
+
sage: F.<a> = GF(4)
|
|
195
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
196
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
197
|
+
sage: F = C.function_field()
|
|
198
|
+
sage: pls = F.places()
|
|
199
|
+
sage: p = C([0,0])
|
|
200
|
+
sage: Q, = p.places()
|
|
201
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
202
|
+
sage: G = 5*Q
|
|
203
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
204
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
205
|
+
sage: enc = dec.connected_encoder() # long time
|
|
206
|
+
sage: enc # long time
|
|
207
|
+
Encoder for [8, 5] evaluation AG code over GF(4)
|
|
208
|
+
"""
|
|
209
|
+
return "Encoder for {}".format(self.code())
|
|
210
|
+
|
|
211
|
+
def _latex_(self):
|
|
212
|
+
r"""
|
|
213
|
+
Return the latex representation of ``self``.
|
|
214
|
+
|
|
215
|
+
TESTS::
|
|
216
|
+
|
|
217
|
+
sage: F.<a> = GF(4)
|
|
218
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
219
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
220
|
+
sage: F = C.function_field()
|
|
221
|
+
sage: pls = F.places()
|
|
222
|
+
sage: p = C([0,0])
|
|
223
|
+
sage: Q, = p.places()
|
|
224
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
225
|
+
sage: G = 5*Q
|
|
226
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
227
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
228
|
+
sage: enc = dec.connected_encoder() # long time
|
|
229
|
+
sage: latex(enc) # long time
|
|
230
|
+
\text{Encoder for }[8, 5]\text{ evaluation AG code over }\Bold{F}_{2^{2}}
|
|
231
|
+
"""
|
|
232
|
+
return r"\text{{Encoder for }}{}".format(self.code()._latex_())
|
|
233
|
+
|
|
234
|
+
def encode(self, message):
|
|
235
|
+
"""
|
|
236
|
+
Return the codeword encoded from the message.
|
|
237
|
+
|
|
238
|
+
INPUT:
|
|
239
|
+
|
|
240
|
+
- ``message`` -- a vector in the message space
|
|
241
|
+
|
|
242
|
+
EXAMPLES::
|
|
243
|
+
|
|
244
|
+
sage: F.<a> = GF(4)
|
|
245
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
246
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
247
|
+
sage: F = C.function_field()
|
|
248
|
+
sage: pls = F.places()
|
|
249
|
+
sage: p = C([0,0])
|
|
250
|
+
sage: Q, = p.places()
|
|
251
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
252
|
+
sage: G = 5*Q
|
|
253
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
254
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
255
|
+
sage: enc = dec.connected_encoder() # long time
|
|
256
|
+
sage: msg = enc.message_space().random_element() # long time
|
|
257
|
+
sage: codeword = enc.encode(msg) # long time
|
|
258
|
+
sage: enc.unencode(codeword) == msg # long time
|
|
259
|
+
True
|
|
260
|
+
"""
|
|
261
|
+
return self._encode(message)
|
|
262
|
+
|
|
263
|
+
def unencode_nocheck(self, codeword):
|
|
264
|
+
"""
|
|
265
|
+
Return the message unencoded from ``codeword``.
|
|
266
|
+
|
|
267
|
+
INPUT:
|
|
268
|
+
|
|
269
|
+
- ``codeword`` -- a vector in the code
|
|
270
|
+
|
|
271
|
+
EXAMPLES::
|
|
272
|
+
|
|
273
|
+
sage: F.<a> = GF(4)
|
|
274
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
275
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
276
|
+
sage: F = C.function_field()
|
|
277
|
+
sage: pls = F.places()
|
|
278
|
+
sage: p = C([0,0])
|
|
279
|
+
sage: Q, = p.places()
|
|
280
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
281
|
+
sage: G = 5*Q
|
|
282
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
283
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
284
|
+
sage: enc = dec.connected_encoder() # long time
|
|
285
|
+
sage: msg = enc.message_space().random_element() # long time
|
|
286
|
+
sage: codeword = enc.encode(msg) # long time
|
|
287
|
+
sage: enc.unencode(codeword) in enc.message_space() # long time, indirect doctest
|
|
288
|
+
True
|
|
289
|
+
"""
|
|
290
|
+
return self._unencode(codeword)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class DifferentialAGCodeEncoder(Encoder):
|
|
294
|
+
"""
|
|
295
|
+
Encoder of a differential AG code.
|
|
296
|
+
|
|
297
|
+
INPUT:
|
|
298
|
+
|
|
299
|
+
- ``code`` -- a differential AG code
|
|
300
|
+
|
|
301
|
+
- ``decoder`` -- a decoder of the code
|
|
302
|
+
|
|
303
|
+
EXAMPLES::
|
|
304
|
+
|
|
305
|
+
sage: F.<a> = GF(4)
|
|
306
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
307
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
308
|
+
sage: F = C.function_field()
|
|
309
|
+
sage: pls = F.places()
|
|
310
|
+
sage: p = C([0,0])
|
|
311
|
+
sage: Q, = p.places()
|
|
312
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
313
|
+
sage: G = 5*Q
|
|
314
|
+
sage: code = codes.DifferentialAGCode(D, G)
|
|
315
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
316
|
+
sage: enc = dec.connected_encoder(); enc # long time
|
|
317
|
+
Encoder for [8, 3] differential AG code over GF(4)
|
|
318
|
+
"""
|
|
319
|
+
def __init__(self, code, decoder=None):
|
|
320
|
+
"""
|
|
321
|
+
Initialize.
|
|
322
|
+
|
|
323
|
+
TESTS::
|
|
324
|
+
|
|
325
|
+
sage: F.<a> = GF(4)
|
|
326
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
327
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
328
|
+
sage: F = C.function_field()
|
|
329
|
+
sage: pls = F.places()
|
|
330
|
+
sage: p = C([0,0])
|
|
331
|
+
sage: Q, = p.places()
|
|
332
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
333
|
+
sage: G = 5*Q
|
|
334
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
335
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
336
|
+
sage: enc = dec.connected_encoder() # long time
|
|
337
|
+
sage: TestSuite(enc).run(skip='_test_pickling') # long time
|
|
338
|
+
"""
|
|
339
|
+
super().__init__(code)
|
|
340
|
+
|
|
341
|
+
if decoder is None:
|
|
342
|
+
decoder = code.decoder('K')
|
|
343
|
+
|
|
344
|
+
self._decoder = decoder
|
|
345
|
+
self._encode = decoder._encode
|
|
346
|
+
self._unencode = decoder._decode
|
|
347
|
+
|
|
348
|
+
def __hash__(self):
|
|
349
|
+
"""
|
|
350
|
+
Return the hash of ``self``.
|
|
351
|
+
|
|
352
|
+
TESTS::
|
|
353
|
+
|
|
354
|
+
sage: F.<a> = GF(4)
|
|
355
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
356
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
357
|
+
sage: F = C.function_field()
|
|
358
|
+
sage: pls = F.places()
|
|
359
|
+
sage: p = C([0,0])
|
|
360
|
+
sage: Q, = p.places()
|
|
361
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
362
|
+
sage: G = 5*Q
|
|
363
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
364
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
365
|
+
sage: enc = dec.connected_encoder() # long time
|
|
366
|
+
sage: {enc: 1} # long time
|
|
367
|
+
{Encoder for [8, 3] differential AG code over GF(4): 1}
|
|
368
|
+
"""
|
|
369
|
+
return hash((self.code(), self._encode))
|
|
370
|
+
|
|
371
|
+
def __eq__(self, other):
|
|
372
|
+
"""
|
|
373
|
+
Test equality.
|
|
374
|
+
|
|
375
|
+
TESTS::
|
|
376
|
+
|
|
377
|
+
sage: F.<a> = GF(4)
|
|
378
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
379
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
380
|
+
sage: F = C.function_field()
|
|
381
|
+
sage: pls = F.places()
|
|
382
|
+
sage: p = C([0,0])
|
|
383
|
+
sage: Q, = p.places()
|
|
384
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
385
|
+
sage: G = 5*Q
|
|
386
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
387
|
+
sage: dec1 = code.decoder('K', Q) # long time
|
|
388
|
+
sage: enc1 = dec1.connected_encoder() # long time
|
|
389
|
+
sage: dec2 = code.decoder('K', Q) # long time
|
|
390
|
+
sage: enc2 = dec2.connected_encoder() # long time
|
|
391
|
+
sage: enc1 == enc2 # long time
|
|
392
|
+
True
|
|
393
|
+
"""
|
|
394
|
+
if self is other:
|
|
395
|
+
return True
|
|
396
|
+
|
|
397
|
+
if not isinstance(other, DifferentialAGCodeEncoder):
|
|
398
|
+
return False
|
|
399
|
+
|
|
400
|
+
return self.code() == other.code() and self._decoder == other._decoder
|
|
401
|
+
|
|
402
|
+
def _repr_(self):
|
|
403
|
+
r"""
|
|
404
|
+
Return the string representation of ``self``.
|
|
405
|
+
|
|
406
|
+
TESTS::
|
|
407
|
+
|
|
408
|
+
sage: F.<a> = GF(4)
|
|
409
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
410
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
411
|
+
sage: F = C.function_field()
|
|
412
|
+
sage: pls = F.places()
|
|
413
|
+
sage: p = C([0,0])
|
|
414
|
+
sage: Q, = p.places()
|
|
415
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
416
|
+
sage: G = 5*Q
|
|
417
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
418
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
419
|
+
sage: enc = dec.connected_encoder() # long time
|
|
420
|
+
sage: enc # long time
|
|
421
|
+
Encoder for [8, 3] differential AG code over GF(4)
|
|
422
|
+
"""
|
|
423
|
+
return "Encoder for {}".format(self.code())
|
|
424
|
+
|
|
425
|
+
def _latex_(self):
|
|
426
|
+
r"""
|
|
427
|
+
Return the latex representation of ``self``.
|
|
428
|
+
|
|
429
|
+
TESTS::
|
|
430
|
+
|
|
431
|
+
sage: F.<a> = GF(4)
|
|
432
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
433
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
434
|
+
sage: F = C.function_field()
|
|
435
|
+
sage: pls = F.places()
|
|
436
|
+
sage: p = C([0,0])
|
|
437
|
+
sage: Q, = p.places()
|
|
438
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
439
|
+
sage: G = 5*Q
|
|
440
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
441
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
442
|
+
sage: enc = dec.connected_encoder() # long time
|
|
443
|
+
sage: latex(enc) # long time
|
|
444
|
+
\text{Encoder for }[8, 3]\text{ differential AG code over }\Bold{F}_{2^{2}}
|
|
445
|
+
"""
|
|
446
|
+
return r"\text{{Encoder for }}{}".format(self.code()._latex_())
|
|
447
|
+
|
|
448
|
+
def encode(self, message):
|
|
449
|
+
"""
|
|
450
|
+
Return the codeword encoded from the message.
|
|
451
|
+
|
|
452
|
+
INPUT:
|
|
453
|
+
|
|
454
|
+
- ``message`` -- a vector in the message space
|
|
455
|
+
|
|
456
|
+
EXAMPLES::
|
|
457
|
+
|
|
458
|
+
sage: F.<a> = GF(4)
|
|
459
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
460
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
461
|
+
sage: F = C.function_field()
|
|
462
|
+
sage: pls = F.places()
|
|
463
|
+
sage: p = C([0,0])
|
|
464
|
+
sage: Q, = p.places()
|
|
465
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
466
|
+
sage: G = 5*Q
|
|
467
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
468
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
469
|
+
sage: enc = dec.connected_encoder() # long time
|
|
470
|
+
sage: msg = enc.message_space().random_element() # long time
|
|
471
|
+
sage: codeword = enc.encode(msg) # long time
|
|
472
|
+
sage: enc.unencode(codeword) == msg # long time
|
|
473
|
+
True
|
|
474
|
+
"""
|
|
475
|
+
return self._encode(message)
|
|
476
|
+
|
|
477
|
+
def unencode_nocheck(self, codeword):
|
|
478
|
+
"""
|
|
479
|
+
Return the message unencoded from ``codeword``.
|
|
480
|
+
|
|
481
|
+
INPUT:
|
|
482
|
+
|
|
483
|
+
- ``codeword`` -- a vector in the code
|
|
484
|
+
|
|
485
|
+
EXAMPLES::
|
|
486
|
+
|
|
487
|
+
sage: F.<a> = GF(4)
|
|
488
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
489
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
490
|
+
sage: F = C.function_field()
|
|
491
|
+
sage: pls = F.places()
|
|
492
|
+
sage: p = C([0,0])
|
|
493
|
+
sage: Q, = p.places()
|
|
494
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
495
|
+
sage: G = 5*Q
|
|
496
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
497
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
498
|
+
sage: enc = dec.connected_encoder() # long time
|
|
499
|
+
sage: msg = enc.message_space().random_element() # long time
|
|
500
|
+
sage: codeword = enc.encode(msg) # long time
|
|
501
|
+
sage: enc.unencode(codeword) in enc.message_space() # indirect doctest, long time
|
|
502
|
+
True
|
|
503
|
+
"""
|
|
504
|
+
return self._unencode(codeword)
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
class EvaluationAGCodeUniqueDecoder(Decoder):
|
|
508
|
+
"""
|
|
509
|
+
Unique decoder for evaluation AG codes.
|
|
510
|
+
|
|
511
|
+
INPUT:
|
|
512
|
+
|
|
513
|
+
- ``code`` -- an evaluation AG code
|
|
514
|
+
|
|
515
|
+
- ``Q`` -- (optional) a place, not one of the places supporting the code
|
|
516
|
+
|
|
517
|
+
- ``basis`` -- (optional) a basis of the space of functions to evaluate
|
|
518
|
+
|
|
519
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
520
|
+
|
|
521
|
+
EXAMPLES::
|
|
522
|
+
|
|
523
|
+
sage: k.<a> = GF(4)
|
|
524
|
+
sage: P.<x,y> = AffineSpace(k, 2);
|
|
525
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
526
|
+
sage: F = C.function_field()
|
|
527
|
+
sage: pls = F.places()
|
|
528
|
+
sage: p = C(0,0)
|
|
529
|
+
sage: Q, = p.places()
|
|
530
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
531
|
+
sage: G = 5*Q
|
|
532
|
+
sage: code = codes.EvaluationAGCode(D, G)
|
|
533
|
+
sage: dec = code.decoder('K', Q)
|
|
534
|
+
sage: enc = dec.connected_encoder()
|
|
535
|
+
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 1)
|
|
536
|
+
sage: rv = chan.transmit(code.random_element())
|
|
537
|
+
sage: enc.encode(dec.decode_to_message(rv)) in code
|
|
538
|
+
True
|
|
539
|
+
|
|
540
|
+
If ``basis`` is given, that defines the associated evaluation encoding map::
|
|
541
|
+
|
|
542
|
+
sage: basis = tuple(G.basis_function_space())
|
|
543
|
+
sage: dec2 = code.decoder('K', Q, basis)
|
|
544
|
+
sage: enc2 = dec2.connected_encoder()
|
|
545
|
+
sage: f = basis[0]
|
|
546
|
+
sage: cw = vector(f.evaluate(p) for p in D)
|
|
547
|
+
sage: enc2.unencode(cw)
|
|
548
|
+
(1, 0, 0, 0, 0)
|
|
549
|
+
sage: enc2.encode(_) == cw
|
|
550
|
+
True
|
|
551
|
+
sage: f = basis[1]
|
|
552
|
+
sage: cw = vector(f.evaluate(p) for p in D)
|
|
553
|
+
sage: enc2.unencode(cw)
|
|
554
|
+
(0, 1, 0, 0, 0)
|
|
555
|
+
sage: enc2.encode(_) == cw
|
|
556
|
+
True
|
|
557
|
+
|
|
558
|
+
The default ``basis`` is given by ``code.basis_functions()``.
|
|
559
|
+
"""
|
|
560
|
+
_decoder_type = {'always-succeed'}
|
|
561
|
+
|
|
562
|
+
def __init__(self, code, Q=None, basis=None, verbose=False):
|
|
563
|
+
"""
|
|
564
|
+
Initialize.
|
|
565
|
+
|
|
566
|
+
TESTS::
|
|
567
|
+
|
|
568
|
+
sage: F.<a> = GF(4)
|
|
569
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
570
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
571
|
+
sage: F = C.function_field()
|
|
572
|
+
sage: pls = F.places()
|
|
573
|
+
sage: p = C([0,0])
|
|
574
|
+
sage: Q, = p.places()
|
|
575
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
576
|
+
sage: G = 5*Q
|
|
577
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
578
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
579
|
+
sage: TestSuite(dec).run() # long time
|
|
580
|
+
"""
|
|
581
|
+
if not code.dimension() > 0:
|
|
582
|
+
raise ValueError("no decoder for degenerate codes")
|
|
583
|
+
|
|
584
|
+
F = code.base_function_field()
|
|
585
|
+
K = F.constant_base_field()
|
|
586
|
+
|
|
587
|
+
if Q is None:
|
|
588
|
+
# try to get a rational place not in the support of the AG code
|
|
589
|
+
deg = 1
|
|
590
|
+
for p in F.places(deg):
|
|
591
|
+
if p not in code._pls:
|
|
592
|
+
Q = p
|
|
593
|
+
break
|
|
594
|
+
if Q is None: # if none, then take a nonrational place
|
|
595
|
+
while Q is None:
|
|
596
|
+
deg += 1
|
|
597
|
+
Q = F.get_place(deg)
|
|
598
|
+
elif Q in code._pls:
|
|
599
|
+
raise ValueError("Q is one of the places defining the code")
|
|
600
|
+
|
|
601
|
+
if verbose:
|
|
602
|
+
print('auxiliary place: {} of degree {}'.format(Q, Q.degree()))
|
|
603
|
+
|
|
604
|
+
super().__init__(code, code.ambient_space(), connected_encoder_name='evaluation')
|
|
605
|
+
|
|
606
|
+
if Q.degree() > 1:
|
|
607
|
+
circuit = EvaluationAGCodeDecoder_K_extension(code._pls, code._G, Q,
|
|
608
|
+
verbose=verbose)
|
|
609
|
+
else:
|
|
610
|
+
circuit = EvaluationAGCodeDecoder_K(code._pls, code._G, Q,
|
|
611
|
+
verbose=verbose)
|
|
612
|
+
|
|
613
|
+
if basis is None:
|
|
614
|
+
basis = code._basis_functions
|
|
615
|
+
|
|
616
|
+
C = matrix([circuit.decode(vector(K,
|
|
617
|
+
[f.evaluate(p) for p in code._pls]))
|
|
618
|
+
for f in basis])
|
|
619
|
+
|
|
620
|
+
self._extension = Q.degree() > 1
|
|
621
|
+
self._K = K
|
|
622
|
+
self._basis = tuple(basis)
|
|
623
|
+
self._C = C
|
|
624
|
+
self._Cinv = C.inverse()
|
|
625
|
+
|
|
626
|
+
self._circuit = circuit
|
|
627
|
+
self._info = circuit.info
|
|
628
|
+
self._Q = Q
|
|
629
|
+
|
|
630
|
+
def __hash__(self):
|
|
631
|
+
"""
|
|
632
|
+
Return the hash of ``self``.
|
|
633
|
+
|
|
634
|
+
EXAMPLES::
|
|
635
|
+
|
|
636
|
+
sage: F.<a> = GF(4)
|
|
637
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
638
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
639
|
+
sage: F = C.function_field()
|
|
640
|
+
sage: pls = F.places()
|
|
641
|
+
sage: p = C([0,0])
|
|
642
|
+
sage: Q, = p.places()
|
|
643
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
644
|
+
sage: G = 5*Q
|
|
645
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
646
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
647
|
+
sage: {dec: 1} # long time
|
|
648
|
+
{Unique decoder for [8, 5] evaluation AG code over GF(4): 1}
|
|
649
|
+
"""
|
|
650
|
+
return hash((self.code(), self._Q))
|
|
651
|
+
|
|
652
|
+
def __eq__(self, other) -> bool:
|
|
653
|
+
"""
|
|
654
|
+
Check whether ``other`` equals ``self``.
|
|
655
|
+
|
|
656
|
+
EXAMPLES::
|
|
657
|
+
|
|
658
|
+
sage: F.<a> = GF(4)
|
|
659
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
660
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
661
|
+
sage: F = C.function_field()
|
|
662
|
+
sage: pls = F.places()
|
|
663
|
+
sage: p = C([0,0])
|
|
664
|
+
sage: Q, = p.places()
|
|
665
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
666
|
+
sage: G = 5*Q
|
|
667
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
668
|
+
sage: dec1 = code.decoder('K', Q) # long time
|
|
669
|
+
sage: dec2 = code.decoder('K', Q) # long time
|
|
670
|
+
sage: dec1 == dec2 # long time
|
|
671
|
+
True
|
|
672
|
+
"""
|
|
673
|
+
if self is other:
|
|
674
|
+
return True
|
|
675
|
+
|
|
676
|
+
if not isinstance(other, type(self)):
|
|
677
|
+
return False
|
|
678
|
+
|
|
679
|
+
return (self.code() == other.code() and self._Q == other._Q
|
|
680
|
+
and self._basis == other._basis)
|
|
681
|
+
|
|
682
|
+
def _repr_(self) -> str:
|
|
683
|
+
r"""
|
|
684
|
+
Return the string representation of ``self``.
|
|
685
|
+
|
|
686
|
+
EXAMPLES::
|
|
687
|
+
|
|
688
|
+
sage: F.<a> = GF(4)
|
|
689
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
690
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
691
|
+
sage: F = C.function_field()
|
|
692
|
+
sage: pls = F.places()
|
|
693
|
+
sage: p = C([0,0])
|
|
694
|
+
sage: Q, = p.places()
|
|
695
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
696
|
+
sage: G = 5*Q
|
|
697
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
698
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
699
|
+
sage: dec # long time
|
|
700
|
+
Unique decoder for [8, 5] evaluation AG code over GF(4)
|
|
701
|
+
"""
|
|
702
|
+
return "Unique decoder for {}".format(self.code())
|
|
703
|
+
|
|
704
|
+
def _latex_(self) -> str:
|
|
705
|
+
r"""
|
|
706
|
+
Return the latex representation of ``self``.
|
|
707
|
+
|
|
708
|
+
EXAMPLES::
|
|
709
|
+
|
|
710
|
+
sage: F.<a> = GF(4)
|
|
711
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
712
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
713
|
+
sage: F = C.function_field()
|
|
714
|
+
sage: pls = F.places()
|
|
715
|
+
sage: p = C([0,0])
|
|
716
|
+
sage: Q, = p.places()
|
|
717
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
718
|
+
sage: G = 5*Q
|
|
719
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
720
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
721
|
+
sage: latex(dec) # long time
|
|
722
|
+
\text{Unique decoder for }[8, 5]\text{ evaluation AG code over }\Bold{F}_{2^{2}}
|
|
723
|
+
"""
|
|
724
|
+
return r"\text{{Unique decoder for }}{}".format(self.code()._latex_())
|
|
725
|
+
|
|
726
|
+
def _encode(self, message):
|
|
727
|
+
r"""
|
|
728
|
+
Return the codeword encoded from ``message``.
|
|
729
|
+
|
|
730
|
+
INPUT:
|
|
731
|
+
|
|
732
|
+
- ``message`` -- a vector to be encoded to a codeword
|
|
733
|
+
|
|
734
|
+
TESTS::
|
|
735
|
+
|
|
736
|
+
sage: F.<a> = GF(4)
|
|
737
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
738
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
739
|
+
sage: F = C.function_field()
|
|
740
|
+
sage: pls = F.places()
|
|
741
|
+
sage: p = C([0,0])
|
|
742
|
+
sage: Q, = p.places()
|
|
743
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
744
|
+
sage: G = 5*Q
|
|
745
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
746
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
747
|
+
sage: enc = dec.connected_encoder() # long time
|
|
748
|
+
sage: msg = enc.message_space().random_element() # long time
|
|
749
|
+
sage: dec._decode(dec._encode(msg)) == msg # long time
|
|
750
|
+
True
|
|
751
|
+
"""
|
|
752
|
+
K = self._K
|
|
753
|
+
C = self._C
|
|
754
|
+
circuit = self._circuit
|
|
755
|
+
|
|
756
|
+
if self._extension:
|
|
757
|
+
internal_message = circuit._lift(vector(K, message)) * C
|
|
758
|
+
return circuit._pull_back(circuit.encode(internal_message))
|
|
759
|
+
else:
|
|
760
|
+
return circuit.encode(vector(K, message) * C)
|
|
761
|
+
|
|
762
|
+
def _decode(self, vect, **kwargs):
|
|
763
|
+
r"""
|
|
764
|
+
Return the message decoded from the vector ``vect``.
|
|
765
|
+
|
|
766
|
+
INPUT:
|
|
767
|
+
|
|
768
|
+
- ``vect`` -- a vector to be decoded to a message
|
|
769
|
+
|
|
770
|
+
TESTS::
|
|
771
|
+
|
|
772
|
+
sage: F.<a> = GF(4)
|
|
773
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
774
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
775
|
+
sage: F = C.function_field()
|
|
776
|
+
sage: pls = F.places()
|
|
777
|
+
sage: p = C([0,0])
|
|
778
|
+
sage: Q, = p.places()
|
|
779
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
780
|
+
sage: G = 5*Q
|
|
781
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
782
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
783
|
+
sage: code = dec.code() # long time
|
|
784
|
+
sage: cw = code.random_element() # long time
|
|
785
|
+
sage: dec._encode(dec._decode(cw)) == cw # long time
|
|
786
|
+
True
|
|
787
|
+
"""
|
|
788
|
+
Cinv = self._Cinv
|
|
789
|
+
circuit = self._circuit
|
|
790
|
+
|
|
791
|
+
if self._extension:
|
|
792
|
+
internal_message = circuit.decode(circuit._lift(vect), **kwargs) * Cinv
|
|
793
|
+
return circuit._pull_back(internal_message)
|
|
794
|
+
|
|
795
|
+
return circuit.decode(vect, **kwargs) * Cinv
|
|
796
|
+
|
|
797
|
+
def connected_encoder(self, *args, **kwargs):
|
|
798
|
+
r"""
|
|
799
|
+
Return the connected encoder for this decoder.
|
|
800
|
+
|
|
801
|
+
INPUT:
|
|
802
|
+
|
|
803
|
+
- ``args``, ``kwargs`` -- all additional arguments are forwarded to the
|
|
804
|
+
constructor of the connected encoder
|
|
805
|
+
|
|
806
|
+
EXAMPLES::
|
|
807
|
+
|
|
808
|
+
sage: F.<a> = GF(4)
|
|
809
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
810
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
811
|
+
sage: F = C.function_field()
|
|
812
|
+
sage: pls = F.places()
|
|
813
|
+
sage: p = C([0,0])
|
|
814
|
+
sage: Q, = p.places()
|
|
815
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
816
|
+
sage: G = 5*Q
|
|
817
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
818
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
819
|
+
sage: dec.connected_encoder() # long time
|
|
820
|
+
Encoder for [8, 5] evaluation AG code over GF(4)
|
|
821
|
+
"""
|
|
822
|
+
return self.code().encoder(self._connected_encoder_name, self, *args, **kwargs)
|
|
823
|
+
|
|
824
|
+
def decoding_radius(self):
|
|
825
|
+
r"""
|
|
826
|
+
Return the decoding radius of the decoder.
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: F.<a> = GF(4)
|
|
831
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
832
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
833
|
+
sage: F = C.function_field()
|
|
834
|
+
sage: pls = F.places()
|
|
835
|
+
sage: p = C([0,0])
|
|
836
|
+
sage: Q, = p.places()
|
|
837
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
838
|
+
sage: G = 5*Q
|
|
839
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
840
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
841
|
+
sage: dec.decoding_radius() # long time
|
|
842
|
+
1
|
|
843
|
+
"""
|
|
844
|
+
return self._info['decoding_radius']
|
|
845
|
+
|
|
846
|
+
def decode_to_message(self, received_vector, **kwargs):
|
|
847
|
+
r"""
|
|
848
|
+
Return the message decoded from ``received_vector``.
|
|
849
|
+
|
|
850
|
+
INPUT:
|
|
851
|
+
|
|
852
|
+
- ``received_vector`` -- a vector in the ambient space of the code
|
|
853
|
+
|
|
854
|
+
- ``verbose`` -- boolean; if ``True``, verbose information on the decoding process
|
|
855
|
+
is printed
|
|
856
|
+
|
|
857
|
+
EXAMPLES::
|
|
858
|
+
|
|
859
|
+
sage: F.<a> = GF(4)
|
|
860
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
861
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
862
|
+
sage: F = C.function_field()
|
|
863
|
+
sage: pls = F.places()
|
|
864
|
+
sage: p = C([0,0])
|
|
865
|
+
sage: Q, = p.places()
|
|
866
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
867
|
+
sage: G = 5*Q
|
|
868
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
869
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
870
|
+
sage: enc = dec.connected_encoder() # long time
|
|
871
|
+
sage: code = dec.code() # long time
|
|
872
|
+
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 1) # long time
|
|
873
|
+
sage: rv = chan.transmit(code.random_element()) # long time
|
|
874
|
+
sage: msg = dec.decode_to_message(rv) # long time
|
|
875
|
+
sage: cw = enc.encode(msg) # long time
|
|
876
|
+
sage: (cw - rv).hamming_weight() == 1 # long time
|
|
877
|
+
True
|
|
878
|
+
"""
|
|
879
|
+
return self._decode(received_vector, **kwargs)
|
|
880
|
+
|
|
881
|
+
def decode_to_code(self, received_vector, **kwargs):
|
|
882
|
+
r"""
|
|
883
|
+
Return the codeword decoded from ``received_vector``.
|
|
884
|
+
|
|
885
|
+
INPUT:
|
|
886
|
+
|
|
887
|
+
- ``received_vector`` -- a vector in the ambient space of the code
|
|
888
|
+
|
|
889
|
+
- ``verbose`` -- boolean; if ``True``, verbose information on the decoding process
|
|
890
|
+
is printed
|
|
891
|
+
|
|
892
|
+
EXAMPLES::
|
|
893
|
+
|
|
894
|
+
sage: F.<a> = GF(4)
|
|
895
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
896
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
897
|
+
sage: F = C.function_field()
|
|
898
|
+
sage: pls = F.places()
|
|
899
|
+
sage: p = C([0,0])
|
|
900
|
+
sage: Q, = p.places()
|
|
901
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
902
|
+
sage: G = 5*Q
|
|
903
|
+
sage: code = codes.EvaluationAGCode(D, G) # long time
|
|
904
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
905
|
+
sage: code = dec.code() # long time
|
|
906
|
+
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 1) # long time
|
|
907
|
+
sage: rv = chan.transmit(code.random_element()) # long time
|
|
908
|
+
sage: cw = dec.decode_to_code(rv) # long time
|
|
909
|
+
sage: (cw - rv).hamming_weight() == 1 # long time
|
|
910
|
+
True
|
|
911
|
+
"""
|
|
912
|
+
return self._encode(self._decode(received_vector, **kwargs))
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
class DifferentialAGCodeUniqueDecoder(Decoder):
|
|
916
|
+
"""
|
|
917
|
+
Unique decoder for a differential AG codes.
|
|
918
|
+
|
|
919
|
+
INPUT:
|
|
920
|
+
|
|
921
|
+
- ``code`` -- an evaluation AG code
|
|
922
|
+
|
|
923
|
+
- ``Q`` -- (optional) a place, not one of the places supporting the code
|
|
924
|
+
|
|
925
|
+
- ``basis`` -- (optional) a basis of the space of differentials to take residues
|
|
926
|
+
|
|
927
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
928
|
+
|
|
929
|
+
EXAMPLES::
|
|
930
|
+
|
|
931
|
+
sage: F.<a> = GF(4)
|
|
932
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
933
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
934
|
+
sage: F = C.function_field()
|
|
935
|
+
sage: pls = F.places()
|
|
936
|
+
sage: p = C(0,0)
|
|
937
|
+
sage: Q, = p.places()
|
|
938
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
939
|
+
sage: G = 5*Q
|
|
940
|
+
sage: code = codes.DifferentialAGCode(D, G)
|
|
941
|
+
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 2)
|
|
942
|
+
sage: rv = chan.transmit(code.random_element()) # long time
|
|
943
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
944
|
+
sage: enc = dec.connected_encoder() # long time
|
|
945
|
+
sage: enc.encode(dec.decode_to_message(rv)) in code # long time
|
|
946
|
+
True
|
|
947
|
+
|
|
948
|
+
If ``basis`` is given, that defines the associated residue encoding map::
|
|
949
|
+
|
|
950
|
+
sage: basis = tuple((G - sum(D)).basis_differential_space())
|
|
951
|
+
sage: w = basis[0]
|
|
952
|
+
sage: cw = vector(w.residue(p) for p in D)
|
|
953
|
+
sage: dec2 = code.decoder('K', Q, basis) # long time
|
|
954
|
+
sage: enc2 = dec2.connected_encoder() # long time
|
|
955
|
+
sage: temp = enc2.unencode(cw); temp # long time
|
|
956
|
+
(1, 0, 0)
|
|
957
|
+
sage: enc2.encode(temp) == cw # long time
|
|
958
|
+
True
|
|
959
|
+
sage: w = basis[1]
|
|
960
|
+
sage: cw = vector(w.residue(p) for p in D)
|
|
961
|
+
sage: temp = enc2.unencode(cw); temp # long time
|
|
962
|
+
(0, 1, 0)
|
|
963
|
+
sage: enc2.encode(temp) == cw # long time
|
|
964
|
+
True
|
|
965
|
+
|
|
966
|
+
The default ``basis`` is given by ``code.basis_differentials()``.
|
|
967
|
+
"""
|
|
968
|
+
_decoder_type = {'always-succeed'}
|
|
969
|
+
|
|
970
|
+
def __init__(self, code, Q=None, basis=None, verbose=False):
|
|
971
|
+
"""
|
|
972
|
+
Initialize.
|
|
973
|
+
|
|
974
|
+
TESTS::
|
|
975
|
+
|
|
976
|
+
sage: F.<a> = GF(4)
|
|
977
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
978
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
979
|
+
sage: F = C.function_field()
|
|
980
|
+
sage: pls = F.places()
|
|
981
|
+
sage: p = C([0,0])
|
|
982
|
+
sage: Q, = p.places()
|
|
983
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
984
|
+
sage: G = 5*Q
|
|
985
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
986
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
987
|
+
sage: TestSuite(dec).run() # long time
|
|
988
|
+
"""
|
|
989
|
+
if not code.dimension() > 0:
|
|
990
|
+
raise ValueError("no decoder for degenerate codes")
|
|
991
|
+
|
|
992
|
+
F = code.base_function_field()
|
|
993
|
+
K = F.constant_base_field()
|
|
994
|
+
|
|
995
|
+
if Q is None:
|
|
996
|
+
# try to get a rational place not in the support of the AG code
|
|
997
|
+
deg = 1
|
|
998
|
+
for p in F.places(deg):
|
|
999
|
+
if p not in code._pls:
|
|
1000
|
+
Q = p
|
|
1001
|
+
break
|
|
1002
|
+
if Q is None: # then take a nonrational place
|
|
1003
|
+
while Q is None:
|
|
1004
|
+
deg += 1
|
|
1005
|
+
Q = F.get_place(deg)
|
|
1006
|
+
elif Q in code._pls:
|
|
1007
|
+
raise ValueError("Q is one of the places defining the code")
|
|
1008
|
+
|
|
1009
|
+
if verbose:
|
|
1010
|
+
print('auxiliary place: {} of degree {}'.format(Q, Q.degree()))
|
|
1011
|
+
|
|
1012
|
+
super().__init__(code, code.ambient_space(), connected_encoder_name='residue')
|
|
1013
|
+
|
|
1014
|
+
if Q.degree() > 1:
|
|
1015
|
+
circuit = DifferentialAGCodeDecoder_K_extension(code._pls, code._G, Q,
|
|
1016
|
+
verbose=verbose)
|
|
1017
|
+
else:
|
|
1018
|
+
circuit = DifferentialAGCodeDecoder_K(code._pls, code._G, Q,
|
|
1019
|
+
verbose=verbose)
|
|
1020
|
+
|
|
1021
|
+
if basis is None:
|
|
1022
|
+
basis = code._basis_differentials
|
|
1023
|
+
|
|
1024
|
+
C = matrix([circuit.decode(vector(K, [b.residue(p) for p in code._pls]))
|
|
1025
|
+
for b in basis])
|
|
1026
|
+
|
|
1027
|
+
self._extension = Q.degree() > 1
|
|
1028
|
+
self._K = K
|
|
1029
|
+
self._basis = tuple(basis)
|
|
1030
|
+
self._C = C
|
|
1031
|
+
self._Cinv = C.inverse()
|
|
1032
|
+
|
|
1033
|
+
self._circuit = circuit
|
|
1034
|
+
self._info = circuit.info
|
|
1035
|
+
self._Q = Q
|
|
1036
|
+
|
|
1037
|
+
def __hash__(self):
|
|
1038
|
+
"""
|
|
1039
|
+
Return the hash of ``self``.
|
|
1040
|
+
|
|
1041
|
+
TESTS::
|
|
1042
|
+
|
|
1043
|
+
sage: F.<a> = GF(4)
|
|
1044
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1045
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1046
|
+
sage: F = C.function_field()
|
|
1047
|
+
sage: pls = F.places()
|
|
1048
|
+
sage: p = C([0,0])
|
|
1049
|
+
sage: Q, = p.places()
|
|
1050
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1051
|
+
sage: G = 5*Q
|
|
1052
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1053
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1054
|
+
sage: {dec: 1} # long time
|
|
1055
|
+
{Unique decoder for [8, 3] differential AG code over GF(4): 1}
|
|
1056
|
+
"""
|
|
1057
|
+
return hash((self.code(), self._Q))
|
|
1058
|
+
|
|
1059
|
+
def __eq__(self, other) -> bool:
|
|
1060
|
+
"""
|
|
1061
|
+
Check whether ``other`` equals ``self``.
|
|
1062
|
+
|
|
1063
|
+
TESTS::
|
|
1064
|
+
|
|
1065
|
+
sage: F.<a> = GF(4)
|
|
1066
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1067
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1068
|
+
sage: F = C.function_field()
|
|
1069
|
+
sage: pls = F.places()
|
|
1070
|
+
sage: p = C([0,0])
|
|
1071
|
+
sage: Q, = p.places()
|
|
1072
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1073
|
+
sage: G = 5*Q
|
|
1074
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1075
|
+
sage: dec1 = code.decoder('K', Q) # long time
|
|
1076
|
+
sage: dec2 = code.decoder('K', Q) # long time
|
|
1077
|
+
sage: dec1 == dec2 # long time
|
|
1078
|
+
True
|
|
1079
|
+
"""
|
|
1080
|
+
if self is other:
|
|
1081
|
+
return True
|
|
1082
|
+
|
|
1083
|
+
if not isinstance(other, type(self)):
|
|
1084
|
+
return False
|
|
1085
|
+
|
|
1086
|
+
return (self.code() == other.code() and self._Q == other._Q
|
|
1087
|
+
and self._basis == other._basis)
|
|
1088
|
+
|
|
1089
|
+
def _repr_(self) -> str:
|
|
1090
|
+
r"""
|
|
1091
|
+
Return the string representation of ``self``.
|
|
1092
|
+
|
|
1093
|
+
TESTS::
|
|
1094
|
+
|
|
1095
|
+
sage: F.<a> = GF(4)
|
|
1096
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1097
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1098
|
+
sage: F = C.function_field()
|
|
1099
|
+
sage: pls = F.places()
|
|
1100
|
+
sage: p = C([0,0])
|
|
1101
|
+
sage: Q, = p.places()
|
|
1102
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1103
|
+
sage: G = 5*Q
|
|
1104
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1105
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1106
|
+
sage: dec # long time
|
|
1107
|
+
Unique decoder for [8, 3] differential AG code over GF(4)
|
|
1108
|
+
"""
|
|
1109
|
+
return "Unique decoder for {}".format(self.code())
|
|
1110
|
+
|
|
1111
|
+
def _latex_(self) -> str:
|
|
1112
|
+
r"""
|
|
1113
|
+
Return the latex representation of ``self``.
|
|
1114
|
+
|
|
1115
|
+
TESTS::
|
|
1116
|
+
|
|
1117
|
+
sage: F.<a> = GF(4)
|
|
1118
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1119
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1120
|
+
sage: F = C.function_field()
|
|
1121
|
+
sage: pls = F.places()
|
|
1122
|
+
sage: p = C([0,0])
|
|
1123
|
+
sage: Q, = p.places()
|
|
1124
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1125
|
+
sage: G = 5*Q
|
|
1126
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1127
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1128
|
+
sage: latex(dec) # long time
|
|
1129
|
+
\text{Unique decoder for }[8, 3]\text{ differential AG code over }\Bold{F}_{2^{2}}
|
|
1130
|
+
"""
|
|
1131
|
+
return r"\text{{Unique decoder for }}{}".format(self.code()._latex_())
|
|
1132
|
+
|
|
1133
|
+
def _encode(self, message):
|
|
1134
|
+
r"""
|
|
1135
|
+
Return the codeword encoded from ``message``.
|
|
1136
|
+
|
|
1137
|
+
INPUT:
|
|
1138
|
+
|
|
1139
|
+
- ``message`` -- a vector to be encoded to a codeword
|
|
1140
|
+
|
|
1141
|
+
TESTS::
|
|
1142
|
+
|
|
1143
|
+
sage: F.<a> = GF(4)
|
|
1144
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1145
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1146
|
+
sage: F = C.function_field()
|
|
1147
|
+
sage: pls = F.places()
|
|
1148
|
+
sage: p = C([0,0])
|
|
1149
|
+
sage: Q, = p.places()
|
|
1150
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1151
|
+
sage: G = 5*Q
|
|
1152
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1153
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1154
|
+
sage: enc = dec.connected_encoder() # long time
|
|
1155
|
+
sage: msg = enc.message_space().random_element() # long time
|
|
1156
|
+
sage: dec._decode(dec._encode(msg)) == msg # long time
|
|
1157
|
+
True
|
|
1158
|
+
"""
|
|
1159
|
+
K = self._K
|
|
1160
|
+
C = self._C
|
|
1161
|
+
circuit = self._circuit
|
|
1162
|
+
|
|
1163
|
+
if self._extension:
|
|
1164
|
+
internal_message = circuit._lift(vector(K, message)) * C
|
|
1165
|
+
return circuit._pull_back(circuit.encode(internal_message))
|
|
1166
|
+
else:
|
|
1167
|
+
return circuit.encode(vector(K, message) * C)
|
|
1168
|
+
|
|
1169
|
+
def _decode(self, vect, **kwargs):
|
|
1170
|
+
r"""
|
|
1171
|
+
Return the message decoded from the vector ``vect``.
|
|
1172
|
+
|
|
1173
|
+
INPUT:
|
|
1174
|
+
|
|
1175
|
+
- ``vect`` -- a vector to be decoded to a message
|
|
1176
|
+
|
|
1177
|
+
TESTS::
|
|
1178
|
+
|
|
1179
|
+
sage: F.<a> = GF(4)
|
|
1180
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1181
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1182
|
+
sage: F = C.function_field()
|
|
1183
|
+
sage: pls = F.places()
|
|
1184
|
+
sage: p = C([0,0])
|
|
1185
|
+
sage: Q, = p.places()
|
|
1186
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1187
|
+
sage: G = 5*Q
|
|
1188
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1189
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1190
|
+
sage: code = dec.code() # long time
|
|
1191
|
+
sage: cw = code.random_element() # long time
|
|
1192
|
+
sage: dec._encode(dec._decode(cw)) == cw # long time
|
|
1193
|
+
True
|
|
1194
|
+
"""
|
|
1195
|
+
Cinv = self._Cinv
|
|
1196
|
+
circuit = self._circuit
|
|
1197
|
+
|
|
1198
|
+
if self._extension:
|
|
1199
|
+
internal_message = circuit.decode(circuit._lift(vect), **kwargs) * Cinv
|
|
1200
|
+
return circuit._pull_back(internal_message)
|
|
1201
|
+
|
|
1202
|
+
return circuit.decode(vect, **kwargs) * Cinv
|
|
1203
|
+
|
|
1204
|
+
def connected_encoder(self, *args, **kwargs):
|
|
1205
|
+
r"""
|
|
1206
|
+
Return the connected encoder for this decoder.
|
|
1207
|
+
|
|
1208
|
+
INPUT:
|
|
1209
|
+
|
|
1210
|
+
- ``args``, ``kwargs`` -- all additional arguments are forwarded to the
|
|
1211
|
+
constructor of the connected encoder
|
|
1212
|
+
|
|
1213
|
+
EXAMPLES::
|
|
1214
|
+
|
|
1215
|
+
sage: F.<a> = GF(4)
|
|
1216
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1217
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1218
|
+
sage: F = C.function_field()
|
|
1219
|
+
sage: pls = F.places()
|
|
1220
|
+
sage: p = C([0,0])
|
|
1221
|
+
sage: Q, = p.places()
|
|
1222
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1223
|
+
sage: G = 5*Q
|
|
1224
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1225
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1226
|
+
sage: dec.connected_encoder() # long time
|
|
1227
|
+
Encoder for [8, 3] differential AG code over GF(4)
|
|
1228
|
+
"""
|
|
1229
|
+
return self.code().encoder(self._connected_encoder_name, self, *args, **kwargs)
|
|
1230
|
+
|
|
1231
|
+
def decoding_radius(self):
|
|
1232
|
+
r"""
|
|
1233
|
+
Return the decoding radius of the decoder.
|
|
1234
|
+
|
|
1235
|
+
EXAMPLES::
|
|
1236
|
+
|
|
1237
|
+
sage: F.<a> = GF(4)
|
|
1238
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1239
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1240
|
+
sage: F = C.function_field()
|
|
1241
|
+
sage: pls = F.places()
|
|
1242
|
+
sage: p = C([0,0])
|
|
1243
|
+
sage: Q, = p.places()
|
|
1244
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1245
|
+
sage: G = 5*Q
|
|
1246
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1247
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1248
|
+
sage: dec.decoding_radius() # long time
|
|
1249
|
+
2
|
|
1250
|
+
"""
|
|
1251
|
+
return self._info['decoding_radius']
|
|
1252
|
+
|
|
1253
|
+
def decode_to_message(self, received_vector, **kwargs):
|
|
1254
|
+
r"""
|
|
1255
|
+
Return the message decoded from ``received_vector``.
|
|
1256
|
+
|
|
1257
|
+
INPUT:
|
|
1258
|
+
|
|
1259
|
+
- ``received_vector`` -- a vector in the ambient space of the code
|
|
1260
|
+
|
|
1261
|
+
- ``verbose`` -- boolean; if ``True``, verbose information on
|
|
1262
|
+
the decoding process is printed
|
|
1263
|
+
|
|
1264
|
+
EXAMPLES::
|
|
1265
|
+
|
|
1266
|
+
sage: F.<a> = GF(4)
|
|
1267
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1268
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1269
|
+
sage: F = C.function_field()
|
|
1270
|
+
sage: pls = F.places()
|
|
1271
|
+
sage: p = C([0,0])
|
|
1272
|
+
sage: Q, = p.places()
|
|
1273
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1274
|
+
sage: G = 5*Q
|
|
1275
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1276
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1277
|
+
sage: enc = dec.connected_encoder() # long time
|
|
1278
|
+
sage: code = dec.code() # long time
|
|
1279
|
+
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 2) # long time
|
|
1280
|
+
sage: rv = chan.transmit(code.random_element()) # long time
|
|
1281
|
+
sage: msg = dec.decode_to_message(rv) # long time
|
|
1282
|
+
sage: cw = enc.encode(msg) # long time
|
|
1283
|
+
sage: (cw - rv).hamming_weight() == 2 # long time
|
|
1284
|
+
True
|
|
1285
|
+
"""
|
|
1286
|
+
return self._decode(received_vector, **kwargs)
|
|
1287
|
+
|
|
1288
|
+
def decode_to_code(self, received_vector, **kwargs):
|
|
1289
|
+
r"""
|
|
1290
|
+
Return the codeword decoded from ``received_vector``.
|
|
1291
|
+
|
|
1292
|
+
INPUT:
|
|
1293
|
+
|
|
1294
|
+
- ``received_vector`` -- a vector in the ambient space of the code
|
|
1295
|
+
|
|
1296
|
+
- ``verbose`` -- boolean; if ``True``, verbose information on
|
|
1297
|
+
the decoding process is printed
|
|
1298
|
+
|
|
1299
|
+
EXAMPLES::
|
|
1300
|
+
|
|
1301
|
+
sage: F.<a> = GF(4)
|
|
1302
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1303
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1304
|
+
sage: F = C.function_field()
|
|
1305
|
+
sage: pls = F.places()
|
|
1306
|
+
sage: p = C([0,0])
|
|
1307
|
+
sage: Q, = p.places()
|
|
1308
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1309
|
+
sage: G = 5*Q
|
|
1310
|
+
sage: code = codes.DifferentialAGCode(D, G) # long time
|
|
1311
|
+
sage: dec = code.decoder('K', Q) # long time
|
|
1312
|
+
sage: enc = dec.connected_encoder() # long time
|
|
1313
|
+
sage: code = dec.code() # long time
|
|
1314
|
+
sage: chan = channels.StaticErrorRateChannel(code.ambient_space(), 2) # long time
|
|
1315
|
+
sage: rv = chan.transmit(code.random_element()) # long time
|
|
1316
|
+
sage: cw = dec.decode_to_code(rv) # long time
|
|
1317
|
+
sage: (cw - rv).hamming_weight() == 2 # long time
|
|
1318
|
+
True
|
|
1319
|
+
"""
|
|
1320
|
+
return self._encode(self._decode(received_vector, **kwargs))
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
cdef inline int pos_mod(int a, int b) noexcept:
|
|
1324
|
+
"""
|
|
1325
|
+
Return ``a % b`` such that the result is positive.
|
|
1326
|
+
|
|
1327
|
+
C modulus can be negative as ``a == (a / b) * b + (a % b)``.
|
|
1328
|
+
"""
|
|
1329
|
+
cdef int m = a % b
|
|
1330
|
+
if m < 0:
|
|
1331
|
+
m += b
|
|
1332
|
+
return m
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
cdef class Decoder_K():
|
|
1336
|
+
"""
|
|
1337
|
+
Common base class for the implementation of decoding algorithm K
|
|
1338
|
+
for AG codes.
|
|
1339
|
+
|
|
1340
|
+
EXAMPLES::
|
|
1341
|
+
|
|
1342
|
+
sage: F.<a> = GF(4)
|
|
1343
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1344
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1345
|
+
sage: pls = C.places()
|
|
1346
|
+
sage: p = C([0,0])
|
|
1347
|
+
sage: Q, = p.places()
|
|
1348
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1349
|
+
sage: G = 5*Q
|
|
1350
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K
|
|
1351
|
+
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q)
|
|
1352
|
+
"""
|
|
1353
|
+
cdef bint is_differential
|
|
1354
|
+
cdef int code_length, designed_distance, gamma, s0, tau
|
|
1355
|
+
cdef list code_basis, message_index, hvecs, eta_vecs
|
|
1356
|
+
cdef list dR, dRbar
|
|
1357
|
+
cdef list mul_mat
|
|
1358
|
+
cdef Matrix coeff_mat
|
|
1359
|
+
cdef object W, x
|
|
1360
|
+
|
|
1361
|
+
cdef readonly dict info
|
|
1362
|
+
|
|
1363
|
+
def encode(self, message):
|
|
1364
|
+
"""
|
|
1365
|
+
Encode ``message`` to a codeword.
|
|
1366
|
+
|
|
1367
|
+
TESTS::
|
|
1368
|
+
|
|
1369
|
+
sage: F.<a> = GF(4)
|
|
1370
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1371
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1372
|
+
sage: pls = C.places()
|
|
1373
|
+
sage: p = C([0,0])
|
|
1374
|
+
sage: Q, = p.places()
|
|
1375
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1376
|
+
sage: G = 5*Q
|
|
1377
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K
|
|
1378
|
+
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q) # long time
|
|
1379
|
+
sage: F.<a> = GF(4) # long time
|
|
1380
|
+
sage: rv = vector([0, 0, 0, a, 0, a, a + 1, 0]) # long time
|
|
1381
|
+
sage: msg = circuit.decode(rv) # long time
|
|
1382
|
+
sage: circuit.decode(circuit.encode(msg)) == msg # long time
|
|
1383
|
+
True
|
|
1384
|
+
"""
|
|
1385
|
+
code_basis = self.code_basis
|
|
1386
|
+
message_index = self.message_index
|
|
1387
|
+
return vector(sum([message[i]*code_basis[i] for i in range(len(message_index))]))
|
|
1388
|
+
|
|
1389
|
+
cdef inline int _degree(self, Polynomial f) noexcept:
|
|
1390
|
+
"""
|
|
1391
|
+
Return the degree of polynomial ``f``
|
|
1392
|
+
|
|
1393
|
+
For zero polynomial, return a negative integer to effect as -infinity.
|
|
1394
|
+
"""
|
|
1395
|
+
if f.is_zero():
|
|
1396
|
+
return -0b1000000000000000000000000 # -16777216
|
|
1397
|
+
else:
|
|
1398
|
+
return f.degree()
|
|
1399
|
+
|
|
1400
|
+
cdef void _exponents(self, int s, int *sk, int *si) noexcept:
|
|
1401
|
+
"""
|
|
1402
|
+
Compute the exponents of the monomial with weighted degree ``s``.
|
|
1403
|
+
|
|
1404
|
+
This sets the result in ``sk`` and ``si``.
|
|
1405
|
+
"""
|
|
1406
|
+
cdef int i, d, gamma
|
|
1407
|
+
cdef list dRbar
|
|
1408
|
+
|
|
1409
|
+
gamma = self.gamma
|
|
1410
|
+
dRbar = self.dRbar # dWbar for differential AG code
|
|
1411
|
+
|
|
1412
|
+
i = pos_mod(s, gamma)
|
|
1413
|
+
d = dRbar[i]
|
|
1414
|
+
sk[0] = (s - d) // gamma
|
|
1415
|
+
si[0] = i
|
|
1416
|
+
|
|
1417
|
+
@cython.wraparound(False)
|
|
1418
|
+
@cython.boundscheck(False)
|
|
1419
|
+
cdef void _substitution(self, FreeModuleElement vec, w, int k, Py_ssize_t i) noexcept:
|
|
1420
|
+
r"""
|
|
1421
|
+
Substitute ``z`` with ``(z + w*phi_s)``.
|
|
1422
|
+
|
|
1423
|
+
.. WARNING::
|
|
1424
|
+
|
|
1425
|
+
This modified the ``vec`` input.
|
|
1426
|
+
"""
|
|
1427
|
+
cdef Py_ssize_t j, m
|
|
1428
|
+
cdef list a, s
|
|
1429
|
+
cdef FreeModuleElement temp
|
|
1430
|
+
cdef Polynomial c
|
|
1431
|
+
|
|
1432
|
+
cdef int gamma = self.gamma
|
|
1433
|
+
cdef list mul_mat = self.mul_mat
|
|
1434
|
+
|
|
1435
|
+
W = self.W
|
|
1436
|
+
x = self.x
|
|
1437
|
+
|
|
1438
|
+
# optimizing this part is crucial for the speed of the decoder
|
|
1439
|
+
a = [vec.get_unsafe(j) for j in range(gamma, 2*gamma)]
|
|
1440
|
+
c = w * x**k
|
|
1441
|
+
s = [W.zero()] * gamma
|
|
1442
|
+
for j in range(gamma):
|
|
1443
|
+
temp = <FreeModuleElement> (<list> mul_mat[j])[i]
|
|
1444
|
+
for m in range(gamma):
|
|
1445
|
+
s[m] += a[j] * temp.get_unsafe(m)
|
|
1446
|
+
for j in range(gamma):
|
|
1447
|
+
vec.set_unsafe(j, c * s[j] + vec.get_unsafe(j))
|
|
1448
|
+
|
|
1449
|
+
def decode(self, received_vector, bint verbose=False,
|
|
1450
|
+
bint detect_decoding_failure=True,
|
|
1451
|
+
bint detect_Q_polynomial=True):
|
|
1452
|
+
"""
|
|
1453
|
+
Return the message vector that corresponds to the corrected codeword
|
|
1454
|
+
from the received vector.
|
|
1455
|
+
|
|
1456
|
+
INPUT:
|
|
1457
|
+
|
|
1458
|
+
- ``received_vector`` -- a received vector in the ambient space of the
|
|
1459
|
+
code
|
|
1460
|
+
|
|
1461
|
+
- ``verbose`` -- boolean; if ``True``, verbose information is printed
|
|
1462
|
+
|
|
1463
|
+
- ``detect_decoding_failure`` -- boolean; if ``True``, early failure
|
|
1464
|
+
detection is activated
|
|
1465
|
+
|
|
1466
|
+
- ``detect_Q_polynomial`` -- boolean; if ``True``, a Q-polynomial is
|
|
1467
|
+
detected for fast decoding
|
|
1468
|
+
|
|
1469
|
+
If decoding fails for some reason, :exc:`DecodingError` is raised. The
|
|
1470
|
+
message contained in the exception indicates the type of the decoding
|
|
1471
|
+
failure.
|
|
1472
|
+
|
|
1473
|
+
TESTS::
|
|
1474
|
+
|
|
1475
|
+
sage: F.<a> = GF(4)
|
|
1476
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1477
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1478
|
+
sage: pls = C.places()
|
|
1479
|
+
sage: p = C([0,0])
|
|
1480
|
+
sage: Q, = p.places()
|
|
1481
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1482
|
+
sage: G = 5*Q
|
|
1483
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K # long time
|
|
1484
|
+
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q) # long time
|
|
1485
|
+
sage: rv = vector(F, [1, a, 1, a + 1, a + 1, a + 1, 1, a + 1]) # long time
|
|
1486
|
+
sage: circuit.decode(rv) # long time
|
|
1487
|
+
(1, 0, a + 1, a + 1, a)
|
|
1488
|
+
"""
|
|
1489
|
+
cdef int s, sk, si, i, j, c, cbar, posQs, posQi
|
|
1490
|
+
cdef int k, ip, count, delta, dlt, wlt, pos, wd_hvec
|
|
1491
|
+
cdef list mat, nu, mu, message
|
|
1492
|
+
cdef list i_k, i_prime, i_value, i_count, voting_value, voting_count
|
|
1493
|
+
cdef list std
|
|
1494
|
+
cdef FreeModuleElement row, hvec, row_i, row_ip, nrow_i, nrow_ip
|
|
1495
|
+
cdef Matrix coeff_mat
|
|
1496
|
+
cdef Polynomial t
|
|
1497
|
+
cdef bint found_Q
|
|
1498
|
+
|
|
1499
|
+
cdef int code_length = self.code_length
|
|
1500
|
+
cdef int designed_distance = self.designed_distance
|
|
1501
|
+
|
|
1502
|
+
cdef int gamma = self.gamma
|
|
1503
|
+
cdef list dR = self.dR
|
|
1504
|
+
cdef list dRbar = self.dRbar # dWbar for differential AG code
|
|
1505
|
+
|
|
1506
|
+
cdef list hvecs = self.hvecs
|
|
1507
|
+
cdef list eta_vecs = self.eta_vecs
|
|
1508
|
+
cdef list mul_mat = self.mul_mat
|
|
1509
|
+
coeff_mat = self.coeff_mat
|
|
1510
|
+
|
|
1511
|
+
cdef list message_index = self.message_index
|
|
1512
|
+
|
|
1513
|
+
cdef int s0 = self.s0
|
|
1514
|
+
cdef int tau = self.tau
|
|
1515
|
+
|
|
1516
|
+
W = self.W
|
|
1517
|
+
x = self.x
|
|
1518
|
+
|
|
1519
|
+
K = W.base_ring()
|
|
1520
|
+
|
|
1521
|
+
if verbose:
|
|
1522
|
+
width = 7 * (K.degree() + 2)
|
|
1523
|
+
|
|
1524
|
+
# auxiliary function for verbose printing
|
|
1525
|
+
def vprint_g(g, s):
|
|
1526
|
+
if verbose > 1:
|
|
1527
|
+
print(g)
|
|
1528
|
+
else:
|
|
1529
|
+
print('[', end='')
|
|
1530
|
+
for i in reversed(range(gamma)):
|
|
1531
|
+
t = g[gamma + i]
|
|
1532
|
+
wd = gamma * self._degree(t) + <int> dR[i] + s
|
|
1533
|
+
s1 = '{} y{}z'.format(0 if t == 0 else t.lt(), i)
|
|
1534
|
+
if t != 0:
|
|
1535
|
+
s2 = '{:<4}'.format('({})'.format(wd))
|
|
1536
|
+
else:
|
|
1537
|
+
s2 = '(-) '
|
|
1538
|
+
print(('{:>' + str(width) + '} ').format(s1 + s2), end='')
|
|
1539
|
+
for i in reversed(range(gamma)):
|
|
1540
|
+
t = g[i]
|
|
1541
|
+
wd = gamma * self._degree(t) + <int> dRbar[i]
|
|
1542
|
+
s1 = '{} w{}' if self.is_differential else '{} Y{}'
|
|
1543
|
+
s1 = s1.format(0 if t == 0 else t.lt(), i)
|
|
1544
|
+
if t != 0:
|
|
1545
|
+
s2 = '{:<4}'.format('({})'.format(wd))
|
|
1546
|
+
else:
|
|
1547
|
+
s2 = '(-) '
|
|
1548
|
+
print(('{:>' + str(width) + '} ').format(s1 + s2), end='')
|
|
1549
|
+
print(']')
|
|
1550
|
+
|
|
1551
|
+
message = []
|
|
1552
|
+
|
|
1553
|
+
# construct the initial generators of the interpolation module
|
|
1554
|
+
hvec = sum(received_vector[i] * hvecs[i] for i in range(code_length))
|
|
1555
|
+
|
|
1556
|
+
# weighted degree of hvec
|
|
1557
|
+
wd_hvec = max(gamma * self._degree(hvec[i]) + <int> dRbar[i] for i in range(gamma))
|
|
1558
|
+
|
|
1559
|
+
if wd_hvec <= 0:
|
|
1560
|
+
if verbose:
|
|
1561
|
+
print("no error")
|
|
1562
|
+
|
|
1563
|
+
for s in message_index:
|
|
1564
|
+
self._exponents(s, &sk, &si)
|
|
1565
|
+
message.append(hvec[si][sk])
|
|
1566
|
+
else:
|
|
1567
|
+
mat = []
|
|
1568
|
+
for i in range(gamma):
|
|
1569
|
+
row = vector(eta_vecs[i].list(copy=False) + [W.zero() for j in range(gamma)])
|
|
1570
|
+
mat.append(row)
|
|
1571
|
+
for i in range(gamma):
|
|
1572
|
+
std = [W.zero() for j in range(gamma)]
|
|
1573
|
+
std[i] = W.one()
|
|
1574
|
+
row = vector(sum(-hvec[j] * mul_mat[i][j] for j in range(gamma)).list(copy=False) + std)
|
|
1575
|
+
mat.append(row)
|
|
1576
|
+
|
|
1577
|
+
nu = []
|
|
1578
|
+
for i in range(gamma):
|
|
1579
|
+
nu.append((<FreeModuleElement> mat[i]).get_unsafe(i).lc())
|
|
1580
|
+
|
|
1581
|
+
found_Q = False
|
|
1582
|
+
s = wd_hvec
|
|
1583
|
+
|
|
1584
|
+
while s >= s0:
|
|
1585
|
+
if verbose:
|
|
1586
|
+
print("# s = {}".format(s))
|
|
1587
|
+
print("generators (leading terms):")
|
|
1588
|
+
for i in reversed(range(gamma)):
|
|
1589
|
+
g = mat[gamma + i]
|
|
1590
|
+
print("F{} ".format(i), end='')
|
|
1591
|
+
vprint_g(g, s)
|
|
1592
|
+
for i in reversed(range(gamma)):
|
|
1593
|
+
g = mat[i]
|
|
1594
|
+
print("G{} ".format(i), end='')
|
|
1595
|
+
vprint_g(g, s)
|
|
1596
|
+
|
|
1597
|
+
self._exponents(s, &sk, &si)
|
|
1598
|
+
delta = 0
|
|
1599
|
+
mu = []
|
|
1600
|
+
i_k = []
|
|
1601
|
+
i_prime = []
|
|
1602
|
+
i_value = []
|
|
1603
|
+
i_count = []
|
|
1604
|
+
voting_value = []
|
|
1605
|
+
voting_count = []
|
|
1606
|
+
for i in range(gamma):
|
|
1607
|
+
# detect decoding failure
|
|
1608
|
+
dlt = self._degree((<FreeModuleElement> mat[gamma + i]).get_unsafe(gamma + i))
|
|
1609
|
+
delta += dlt
|
|
1610
|
+
if detect_decoding_failure and delta > tau:
|
|
1611
|
+
# more errors than tau; declare failure
|
|
1612
|
+
if verbose:
|
|
1613
|
+
print("detected decoding failure")
|
|
1614
|
+
raise DecodingError("more errors than decoding radius")
|
|
1615
|
+
|
|
1616
|
+
# detect Q-polynomial
|
|
1617
|
+
wlt = gamma * dlt + <int> dR[i]
|
|
1618
|
+
if detect_Q_polynomial and wlt + s + tau < designed_distance:
|
|
1619
|
+
found_Q = True
|
|
1620
|
+
posQs = s
|
|
1621
|
+
posQi = i
|
|
1622
|
+
break
|
|
1623
|
+
|
|
1624
|
+
self._exponents(wlt + s, &k, &ip)
|
|
1625
|
+
count = self._degree((<FreeModuleElement> mat[ip]).get_unsafe(ip)) - k
|
|
1626
|
+
i_k.append(k)
|
|
1627
|
+
i_prime.append(ip)
|
|
1628
|
+
i_count.append(count)
|
|
1629
|
+
|
|
1630
|
+
if found_Q:
|
|
1631
|
+
break
|
|
1632
|
+
|
|
1633
|
+
if s > 0 or sk < 0: # not s in message_index
|
|
1634
|
+
for i in range(gamma):
|
|
1635
|
+
k = i_k[i]
|
|
1636
|
+
ip = i_prime[i]
|
|
1637
|
+
|
|
1638
|
+
if k < 0:
|
|
1639
|
+
value = K.zero()
|
|
1640
|
+
else:
|
|
1641
|
+
value = -(<FreeModuleElement> mat[gamma + i]).get_unsafe(ip)[k]
|
|
1642
|
+
|
|
1643
|
+
mu.append(1)
|
|
1644
|
+
i_value.append(value)
|
|
1645
|
+
winner = 0
|
|
1646
|
+
else:
|
|
1647
|
+
for i in range(gamma):
|
|
1648
|
+
k = i_k[i]
|
|
1649
|
+
ip = i_prime[i]
|
|
1650
|
+
|
|
1651
|
+
mui = (<FreeModuleElement> mat[gamma + i]).get_unsafe(gamma + i).lc() * coeff_mat[i, si]
|
|
1652
|
+
value = -(<FreeModuleElement> mat[gamma + i]).get_unsafe(ip)[k] / mui
|
|
1653
|
+
|
|
1654
|
+
mu.append(mui)
|
|
1655
|
+
i_value.append(value)
|
|
1656
|
+
|
|
1657
|
+
cbar = max(i_count[i], 0)
|
|
1658
|
+
try:
|
|
1659
|
+
pos = voting_value.index(value)
|
|
1660
|
+
voting_count[pos] += cbar
|
|
1661
|
+
except ValueError:
|
|
1662
|
+
voting_value.append(value)
|
|
1663
|
+
voting_count.append(cbar)
|
|
1664
|
+
|
|
1665
|
+
# voting
|
|
1666
|
+
c = -1
|
|
1667
|
+
for i in range(len(voting_value)):
|
|
1668
|
+
if c < voting_count[i]:
|
|
1669
|
+
c = voting_count[i]
|
|
1670
|
+
winner = voting_value[i]
|
|
1671
|
+
|
|
1672
|
+
if verbose:
|
|
1673
|
+
print("i_prime:", i_prime)
|
|
1674
|
+
print("i_count:", i_count)
|
|
1675
|
+
print("i_value:", i_value)
|
|
1676
|
+
|
|
1677
|
+
if s <= 0 and sk >= 0: # s in message_index
|
|
1678
|
+
print("voting:", list(zip(voting_value, voting_count)))
|
|
1679
|
+
|
|
1680
|
+
for i in range(gamma):
|
|
1681
|
+
row_i = <FreeModuleElement> mat[gamma + i]
|
|
1682
|
+
row_ip = <FreeModuleElement> mat[i_prime[i]]
|
|
1683
|
+
if winner != 0:
|
|
1684
|
+
self._substitution(row_i, winner, sk, si)
|
|
1685
|
+
self._substitution(row_ip, winner, sk, si)
|
|
1686
|
+
if i_value[i] == winner:
|
|
1687
|
+
nrow_ip = row_ip
|
|
1688
|
+
nrow_i = row_i
|
|
1689
|
+
else:
|
|
1690
|
+
nnu = mu[i] * (winner - i_value[i])
|
|
1691
|
+
if i_count[i] > 0:
|
|
1692
|
+
nrow_ip = row_i
|
|
1693
|
+
nrow_i = x**i_count[i] * row_i - nnu / nu[i_prime[i]] * row_ip
|
|
1694
|
+
nu[i_prime[i]] = nnu
|
|
1695
|
+
else:
|
|
1696
|
+
nrow_ip = row_ip
|
|
1697
|
+
nrow_i = row_i - nnu / nu[i_prime[i]] * x**(-i_count[i]) * row_ip
|
|
1698
|
+
mat[i_prime[i]] = nrow_ip
|
|
1699
|
+
mat[gamma + i] = nrow_i
|
|
1700
|
+
|
|
1701
|
+
if s <= 0 and sk >= 0: # s in message_index
|
|
1702
|
+
if verbose:
|
|
1703
|
+
print("message symbol:", winner)
|
|
1704
|
+
message.append(winner)
|
|
1705
|
+
|
|
1706
|
+
s -= 1
|
|
1707
|
+
|
|
1708
|
+
if found_Q:
|
|
1709
|
+
s = posQs
|
|
1710
|
+
i = posQi
|
|
1711
|
+
if verbose:
|
|
1712
|
+
print("found a Q-polynomial at s = {}, F{}".format(s, i))
|
|
1713
|
+
dlt = gamma * self._degree((<FreeModuleElement> mat[gamma + i]).get_unsafe(gamma + i)) + <int> dR[i]
|
|
1714
|
+
|
|
1715
|
+
while s >= s0:
|
|
1716
|
+
if verbose:
|
|
1717
|
+
print("# s = {}".format(s))
|
|
1718
|
+
print("F{} ".format(i), end='')
|
|
1719
|
+
vprint_g(mat[gamma + i], s)
|
|
1720
|
+
self._exponents(s, &sk, &si)
|
|
1721
|
+
if s <= 0 and sk >= 0: # s in message_index
|
|
1722
|
+
self._exponents(dlt + s, &k, &ip)
|
|
1723
|
+
mui = (<FreeModuleElement> mat[gamma + i]).get_unsafe(gamma + i).lc() * coeff_mat[i, si]
|
|
1724
|
+
value = -(<FreeModuleElement> mat[gamma + i]).get_unsafe(ip)[k] / mui
|
|
1725
|
+
if not value.is_zero():
|
|
1726
|
+
self._substitution(<FreeModuleElement> mat[gamma+i], value, sk, si)
|
|
1727
|
+
if verbose:
|
|
1728
|
+
print("message symbol:", value)
|
|
1729
|
+
message.append(value)
|
|
1730
|
+
s -= 1
|
|
1731
|
+
|
|
1732
|
+
for j in range(gamma):
|
|
1733
|
+
if not (<FreeModuleElement> mat[gamma + i]).get_unsafe(j).is_zero():
|
|
1734
|
+
if verbose:
|
|
1735
|
+
print("detected decoding failure at division")
|
|
1736
|
+
raise DecodingError("decoding failed")
|
|
1737
|
+
|
|
1738
|
+
message.reverse()
|
|
1739
|
+
|
|
1740
|
+
return vector(K, message)
|
|
1741
|
+
|
|
1742
|
+
@cython.wraparound(False)
|
|
1743
|
+
@cython.boundscheck(False)
|
|
1744
|
+
cdef inline int _next(self, int s) noexcept:
|
|
1745
|
+
"""
|
|
1746
|
+
Return the next value after ``s`` in dRbar(dWbar).
|
|
1747
|
+
"""
|
|
1748
|
+
cdef int i, d, gamma
|
|
1749
|
+
cdef list dRbar = self.dRbar
|
|
1750
|
+
gamma = self.gamma
|
|
1751
|
+
i = pos_mod(s, gamma)
|
|
1752
|
+
while True:
|
|
1753
|
+
s += 1
|
|
1754
|
+
i = (i + 1) % gamma # equals s % gamma
|
|
1755
|
+
d = dRbar[i]
|
|
1756
|
+
if s >= d:
|
|
1757
|
+
return s
|
|
1758
|
+
|
|
1759
|
+
@cython.wraparound(False)
|
|
1760
|
+
@cython.boundscheck(False)
|
|
1761
|
+
cdef inline void _get_eta_basis(self, list basis, list vecs, int s0, mon_func) noexcept:
|
|
1762
|
+
"""
|
|
1763
|
+
Compute a basis of J and h-functions via FGLM algorithm.
|
|
1764
|
+
|
|
1765
|
+
This sets ``basis`` with the basis of J and ``vecs`` with the h-functions.
|
|
1766
|
+
"""
|
|
1767
|
+
cdef int s, sk, si, i, j, num
|
|
1768
|
+
cdef Matrix mat, matinv
|
|
1769
|
+
cdef list gen, delta, h
|
|
1770
|
+
cdef tuple t
|
|
1771
|
+
|
|
1772
|
+
cdef int gamma = self.gamma
|
|
1773
|
+
cdef int code_length = self.code_length
|
|
1774
|
+
x = self.x
|
|
1775
|
+
W = self.W
|
|
1776
|
+
s = s0
|
|
1777
|
+
self._exponents(s, &sk, &si)
|
|
1778
|
+
delta = [(sk, si)]
|
|
1779
|
+
mat = matrix(mon_func(sk, si))
|
|
1780
|
+
num = 0
|
|
1781
|
+
while num < gamma:
|
|
1782
|
+
s = self._next(s)
|
|
1783
|
+
self._exponents(s, &sk, &si)
|
|
1784
|
+
if basis[si] is None:
|
|
1785
|
+
v = mon_func(sk, si)
|
|
1786
|
+
try:
|
|
1787
|
+
sol = mat.solve_left(v)
|
|
1788
|
+
gen = [W.zero() for i in range(gamma)]
|
|
1789
|
+
for i in range(len(delta)):
|
|
1790
|
+
t = delta[i]
|
|
1791
|
+
gen[<Py_ssize_t> t[1]] += -sol[i] * x**(<int> t[0])
|
|
1792
|
+
gen[si] += x**sk
|
|
1793
|
+
basis[si] = vector(gen)
|
|
1794
|
+
num += 1
|
|
1795
|
+
except ValueError:
|
|
1796
|
+
mat = mat.stack(matrix(v))
|
|
1797
|
+
delta.append((sk, si))
|
|
1798
|
+
|
|
1799
|
+
matinv = mat.inverse()
|
|
1800
|
+
for i in range(code_length):
|
|
1801
|
+
h = [W.zero() for k in range(gamma)]
|
|
1802
|
+
for j in range(code_length):
|
|
1803
|
+
t = delta[j]
|
|
1804
|
+
h[<Py_ssize_t> t[1]] += matinv[i, j] * x**(<int> t[0])
|
|
1805
|
+
vecs[i] = vector(h)
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
@cython.auto_pickle(True)
|
|
1809
|
+
cdef class EvaluationAGCodeDecoder_K(Decoder_K):
|
|
1810
|
+
"""
|
|
1811
|
+
This class implements the decoding algorithm K for evaluation AG codes.
|
|
1812
|
+
|
|
1813
|
+
INPUT:
|
|
1814
|
+
|
|
1815
|
+
- ``pls`` -- list of places of a function field
|
|
1816
|
+
|
|
1817
|
+
- ``G`` -- a divisor of the function field
|
|
1818
|
+
|
|
1819
|
+
- ``Q`` -- a rational place not in ``pls``
|
|
1820
|
+
|
|
1821
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
1822
|
+
|
|
1823
|
+
EXAMPLES::
|
|
1824
|
+
|
|
1825
|
+
sage: F.<a> = GF(4)
|
|
1826
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
1827
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1828
|
+
sage: pls = C.places()
|
|
1829
|
+
sage: p = C([0,0])
|
|
1830
|
+
sage: Q, = p.places()
|
|
1831
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1832
|
+
sage: G = 5*Q
|
|
1833
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K
|
|
1834
|
+
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q)
|
|
1835
|
+
sage: rv = vector([a, 0, 0, a, 1, 1, a + 1, 0])
|
|
1836
|
+
sage: cw = circuit.encode(circuit.decode(rv))
|
|
1837
|
+
sage: rv - cw
|
|
1838
|
+
(a + 1, 0, 0, 0, 0, 0, 0, 0)
|
|
1839
|
+
sage: circuit.info['designed_distance']
|
|
1840
|
+
3
|
|
1841
|
+
sage: circuit.info['decoding_radius']
|
|
1842
|
+
1
|
|
1843
|
+
"""
|
|
1844
|
+
def __init__(self, pls, G, Q, verbose=False):
|
|
1845
|
+
"""
|
|
1846
|
+
Initialize.
|
|
1847
|
+
|
|
1848
|
+
TESTS::
|
|
1849
|
+
|
|
1850
|
+
sage: F.<a> = GF(4)
|
|
1851
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
1852
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
1853
|
+
sage: pls = C.places()
|
|
1854
|
+
sage: p = C([0,0])
|
|
1855
|
+
sage: Q, = p.places()
|
|
1856
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
1857
|
+
sage: G = 5*Q
|
|
1858
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K
|
|
1859
|
+
sage: circuit = EvaluationAGCodeDecoder_K(D, G, Q) # long time
|
|
1860
|
+
sage: TestSuite(circuit).run(skip='_test_pickling') # long time
|
|
1861
|
+
"""
|
|
1862
|
+
cdef int i, j, s, s0, sk, si, n, r, d
|
|
1863
|
+
cdef int code_length, genus, gamma, dLO, tau
|
|
1864
|
+
cdef list gaps, dR, yR, dRbar, yRbar, evyRbar, nus, mul_mat
|
|
1865
|
+
cdef list message_index, code_basis
|
|
1866
|
+
cdef FreeModuleElement evxR
|
|
1867
|
+
cdef set temp
|
|
1868
|
+
|
|
1869
|
+
D = sum(pls)
|
|
1870
|
+
F = D.parent().function_field()
|
|
1871
|
+
K = F.constant_base_field()
|
|
1872
|
+
W = PolynomialRing(K, name='x') # working polynomial ring
|
|
1873
|
+
x = W.gen()
|
|
1874
|
+
|
|
1875
|
+
# length of the code
|
|
1876
|
+
code_length = len(pls)
|
|
1877
|
+
|
|
1878
|
+
# compute gamma
|
|
1879
|
+
gamma = 1
|
|
1880
|
+
while True:
|
|
1881
|
+
if Q.divisor(gamma).dimension() > 1:
|
|
1882
|
+
break
|
|
1883
|
+
gamma += 1
|
|
1884
|
+
|
|
1885
|
+
# compute xR
|
|
1886
|
+
for f in Q.divisor(gamma).basis_function_space():
|
|
1887
|
+
if f.valuation(Q) == -gamma:
|
|
1888
|
+
xR = f
|
|
1889
|
+
break
|
|
1890
|
+
|
|
1891
|
+
# Apéry R
|
|
1892
|
+
dR = [0 for i in range(gamma)]
|
|
1893
|
+
yR = [None for i in range(gamma)]
|
|
1894
|
+
s = 0
|
|
1895
|
+
n = 0
|
|
1896
|
+
while n < gamma:
|
|
1897
|
+
g = 0
|
|
1898
|
+
for b in Q.divisor(s).basis_function_space():
|
|
1899
|
+
if b.valuation(Q) == -s:
|
|
1900
|
+
g = b
|
|
1901
|
+
break
|
|
1902
|
+
r = pos_mod(s, gamma)
|
|
1903
|
+
if g != 0 and not yR[r]:
|
|
1904
|
+
dR[r] = s
|
|
1905
|
+
yR[r] = g
|
|
1906
|
+
n += 1
|
|
1907
|
+
s += 1
|
|
1908
|
+
|
|
1909
|
+
# gaps of L
|
|
1910
|
+
temp = set()
|
|
1911
|
+
for d in dR:
|
|
1912
|
+
temp.update([d - gamma*(i+1) for i in range(d // gamma)])
|
|
1913
|
+
gaps = list(temp)
|
|
1914
|
+
del temp
|
|
1915
|
+
|
|
1916
|
+
# genus of L
|
|
1917
|
+
genus = len(gaps)
|
|
1918
|
+
|
|
1919
|
+
# Apéry Rbar
|
|
1920
|
+
dRbar = [0 for i in range(gamma)]
|
|
1921
|
+
yRbar = [None for i in range(gamma)]
|
|
1922
|
+
s = -G.degree()
|
|
1923
|
+
n = 0
|
|
1924
|
+
while n < gamma:
|
|
1925
|
+
B = (Q.divisor(s) + G).basis_function_space()
|
|
1926
|
+
g = 0
|
|
1927
|
+
for b in B:
|
|
1928
|
+
if b.valuation(Q) + G.multiplicity(Q) == -s:
|
|
1929
|
+
g = b
|
|
1930
|
+
break
|
|
1931
|
+
r = pos_mod(s, gamma)
|
|
1932
|
+
if g != 0 and not yRbar[r]:
|
|
1933
|
+
dRbar[r] = s
|
|
1934
|
+
yRbar[r] = g
|
|
1935
|
+
n += 1
|
|
1936
|
+
s += 1
|
|
1937
|
+
|
|
1938
|
+
if verbose:
|
|
1939
|
+
print("gamma:", gamma)
|
|
1940
|
+
print("x = {}".format(xR))
|
|
1941
|
+
print("Apéry system of R")
|
|
1942
|
+
for i in range(gamma):
|
|
1943
|
+
print(" {}: {}, y{} = {}".format(i, dR[i], i, yR[i]))
|
|
1944
|
+
print("Apéry system of Rbar")
|
|
1945
|
+
for i in range(gamma):
|
|
1946
|
+
print(" {}: {}, Y{} = {}".format(i, dRbar[i], i, yRbar[i]))
|
|
1947
|
+
|
|
1948
|
+
# ev map for the monomial whose weighted degree is s
|
|
1949
|
+
evxR = vector(K, [xR.evaluate(p) for p in pls])
|
|
1950
|
+
evyRbar = [vector(K, [yRbar[i].evaluate(p) for p in pls]) for i in range(gamma)]
|
|
1951
|
+
|
|
1952
|
+
self.is_differential = False
|
|
1953
|
+
self.code_length = code_length
|
|
1954
|
+
self.designed_distance = code_length - G.degree()
|
|
1955
|
+
self.gamma = gamma
|
|
1956
|
+
self.dR = dR
|
|
1957
|
+
self.dRbar = dRbar
|
|
1958
|
+
self.W = W
|
|
1959
|
+
self.x = x
|
|
1960
|
+
|
|
1961
|
+
def ev_mon(int sk, int si):
|
|
1962
|
+
cdef int i
|
|
1963
|
+
return vector([evxR.get_unsafe(i)**sk * evyRbar[si][i] for i in range(code_length)])
|
|
1964
|
+
|
|
1965
|
+
# minimum of nongaps of Rbar
|
|
1966
|
+
s0 = self._next(-G.degree() - 1)
|
|
1967
|
+
|
|
1968
|
+
# basis of the code ev(L(G))
|
|
1969
|
+
message_index = []
|
|
1970
|
+
code_basis = []
|
|
1971
|
+
s = s0
|
|
1972
|
+
self._exponents(s, &sk, &si)
|
|
1973
|
+
v = ev_mon(sk, si)
|
|
1974
|
+
V = v.parent()
|
|
1975
|
+
while s <= 0:
|
|
1976
|
+
if not V.are_linearly_dependent(code_basis + [v]):
|
|
1977
|
+
message_index.append(s)
|
|
1978
|
+
code_basis.append(v)
|
|
1979
|
+
s = self._next(s)
|
|
1980
|
+
self._exponents(s, &sk, &si)
|
|
1981
|
+
v = ev_mon(sk, si)
|
|
1982
|
+
|
|
1983
|
+
# compute a basis of J and h-functions via FGLM algorithm
|
|
1984
|
+
eta_vecs = [None for i in range(gamma)]
|
|
1985
|
+
hvecs = [None for i in range(code_length)]
|
|
1986
|
+
|
|
1987
|
+
self._get_eta_basis(eta_vecs, hvecs, s0, ev_mon)
|
|
1988
|
+
|
|
1989
|
+
if verbose:
|
|
1990
|
+
print("message indices:", message_index)
|
|
1991
|
+
print("eta basis:", eta_vecs)
|
|
1992
|
+
print("Lagrange polynomials")
|
|
1993
|
+
for i in range(code_length):
|
|
1994
|
+
print("h{} = {}".format(i, hvecs[i]))
|
|
1995
|
+
|
|
1996
|
+
# Lee-O'Sullivan bound
|
|
1997
|
+
def nu(int s):
|
|
1998
|
+
cdef int i, sk, si, m = 0
|
|
1999
|
+
for i in range(gamma):
|
|
2000
|
+
self._exponents(s + <int> dR[i], &sk, &si)
|
|
2001
|
+
m += max(0, self._degree(eta_vecs[si][si]) - sk)
|
|
2002
|
+
return m
|
|
2003
|
+
|
|
2004
|
+
nus = [nu(s) for s in message_index]
|
|
2005
|
+
dLO = min(nus)
|
|
2006
|
+
tau = (dLO - 1) // 2
|
|
2007
|
+
|
|
2008
|
+
if verbose:
|
|
2009
|
+
print("gaps:", gaps)
|
|
2010
|
+
print("genus:", genus)
|
|
2011
|
+
print("nus:", nus)
|
|
2012
|
+
print("dLO:", dLO)
|
|
2013
|
+
print("tau:", tau)
|
|
2014
|
+
|
|
2015
|
+
# the vector form corresponding to f in Rbar
|
|
2016
|
+
def vec_form(f):
|
|
2017
|
+
r = f
|
|
2018
|
+
cdef list l = [W.zero() for i in range(gamma)]
|
|
2019
|
+
while r != 0:
|
|
2020
|
+
s = -r.valuation(Q) - G.multiplicity(Q)
|
|
2021
|
+
self._exponents(s, &sk, &si)
|
|
2022
|
+
mon = xR**sk * yRbar[si]
|
|
2023
|
+
c = (r / mon).evaluate(Q)
|
|
2024
|
+
l[si] += c * x**sk
|
|
2025
|
+
r -= c*mon
|
|
2026
|
+
return vector(l)
|
|
2027
|
+
|
|
2028
|
+
# the matrix of the leading coefficient of y_i*ybar_j and the product
|
|
2029
|
+
coeff_mat = matrix.zero(K, gamma, gamma)
|
|
2030
|
+
mul_mat = [[None for j in range(gamma)] for i in range(gamma)]
|
|
2031
|
+
for i in range(gamma):
|
|
2032
|
+
for j in range(gamma):
|
|
2033
|
+
f = yR[i] * yRbar[j]
|
|
2034
|
+
v = vec_form(f)
|
|
2035
|
+
self._exponents((<int> dR[i]) + (<int> dRbar[j]), &sk, &si)
|
|
2036
|
+
coeff_mat[i, j] = v[si][sk]
|
|
2037
|
+
(<list> mul_mat[i])[j] = v
|
|
2038
|
+
|
|
2039
|
+
if verbose:
|
|
2040
|
+
print("multiplication table")
|
|
2041
|
+
for i in range(gamma):
|
|
2042
|
+
for j in range(gamma):
|
|
2043
|
+
print("y{} * Y{}:".format(i, j), mul_mat[i][j])
|
|
2044
|
+
print("coefficient array")
|
|
2045
|
+
print(coeff_mat)
|
|
2046
|
+
|
|
2047
|
+
self.code_basis = code_basis
|
|
2048
|
+
self.message_index = message_index
|
|
2049
|
+
self.hvecs = hvecs
|
|
2050
|
+
self.eta_vecs = eta_vecs
|
|
2051
|
+
self.mul_mat = mul_mat
|
|
2052
|
+
self.coeff_mat = coeff_mat
|
|
2053
|
+
self.s0 = s0
|
|
2054
|
+
self.tau = tau
|
|
2055
|
+
|
|
2056
|
+
cdef dict info = {}
|
|
2057
|
+
info['designed_distance'] = dLO
|
|
2058
|
+
info['decoding_radius'] = tau
|
|
2059
|
+
|
|
2060
|
+
self.info = info
|
|
2061
|
+
|
|
2062
|
+
|
|
2063
|
+
@cython.auto_pickle(True)
|
|
2064
|
+
cdef class DifferentialAGCodeDecoder_K(Decoder_K):
|
|
2065
|
+
"""
|
|
2066
|
+
This class implements the decoding algorithm K for differential AG codes.
|
|
2067
|
+
|
|
2068
|
+
INPUT:
|
|
2069
|
+
|
|
2070
|
+
- ``pls`` -- list of places of a function field
|
|
2071
|
+
|
|
2072
|
+
- ``G`` -- a divisor of the function field
|
|
2073
|
+
|
|
2074
|
+
- ``Q`` -- a rational place not in ``pls``
|
|
2075
|
+
|
|
2076
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
2077
|
+
|
|
2078
|
+
EXAMPLES::
|
|
2079
|
+
|
|
2080
|
+
sage: F.<a> = GF(4)
|
|
2081
|
+
sage: P.<x,y> = AffineSpace(F, 2);
|
|
2082
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2083
|
+
sage: pls = C.places()
|
|
2084
|
+
sage: p = C([0,0])
|
|
2085
|
+
sage: Q, = p.places()
|
|
2086
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
2087
|
+
sage: G = 5*Q
|
|
2088
|
+
sage: from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K
|
|
2089
|
+
sage: circuit = DifferentialAGCodeDecoder_K(D, G, Q) # long time
|
|
2090
|
+
sage: rv = vector([1, a, 1, a, 1, a, a, a + 1])
|
|
2091
|
+
sage: cw = circuit.encode(circuit.decode(rv)) # long time
|
|
2092
|
+
sage: rv - cw # long time
|
|
2093
|
+
(0, 0, 0, a + 1, 1, 0, 0, 0)
|
|
2094
|
+
sage: circuit.info['designed_distance'] # long time
|
|
2095
|
+
5
|
|
2096
|
+
sage: circuit.info['decoding_radius'] # long time
|
|
2097
|
+
2
|
|
2098
|
+
"""
|
|
2099
|
+
def __init__(self, pls, G, Q, verbose=False):
|
|
2100
|
+
"""
|
|
2101
|
+
Initialize.
|
|
2102
|
+
|
|
2103
|
+
TESTS::
|
|
2104
|
+
|
|
2105
|
+
sage: F.<a> = GF(4)
|
|
2106
|
+
sage: P.<x,y> = AffineSpace(F, 2)
|
|
2107
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2108
|
+
sage: pls = C.places()
|
|
2109
|
+
sage: p = C([0,0])
|
|
2110
|
+
sage: Q, = p.places()
|
|
2111
|
+
sage: D = [pl for pl in pls if pl != Q]
|
|
2112
|
+
sage: G = 5*Q
|
|
2113
|
+
sage: from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K
|
|
2114
|
+
sage: circuit = DifferentialAGCodeDecoder_K(D, G, Q) # long time
|
|
2115
|
+
sage: TestSuite(circuit).run(skip='_test_pickling') # long time
|
|
2116
|
+
"""
|
|
2117
|
+
cdef int i, j, s, s0, sk, si, n, r, d
|
|
2118
|
+
cdef int code_length, genus, gamma, dLO, tau
|
|
2119
|
+
cdef list gaps, dR, yR, dWbar, wWbar, reswWbar, nus, mul_mat
|
|
2120
|
+
cdef list message_index, code_basis
|
|
2121
|
+
cdef FreeModuleElement evxR
|
|
2122
|
+
cdef set temp
|
|
2123
|
+
|
|
2124
|
+
D = sum(pls)
|
|
2125
|
+
F = D.parent().function_field()
|
|
2126
|
+
K = F.constant_base_field()
|
|
2127
|
+
W = PolynomialRing(K, name='x') # working polynomial ring
|
|
2128
|
+
x = W.gen()
|
|
2129
|
+
|
|
2130
|
+
# length of the code
|
|
2131
|
+
code_length = len(pls)
|
|
2132
|
+
|
|
2133
|
+
# compute gamma
|
|
2134
|
+
gamma = 1
|
|
2135
|
+
while True:
|
|
2136
|
+
if Q.divisor(gamma).dimension() > 1:
|
|
2137
|
+
break
|
|
2138
|
+
gamma += 1
|
|
2139
|
+
|
|
2140
|
+
# compute xR
|
|
2141
|
+
for xR in Q.divisor(gamma).basis_function_space():
|
|
2142
|
+
if xR.valuation(Q) == -gamma:
|
|
2143
|
+
break
|
|
2144
|
+
|
|
2145
|
+
# Apéry R
|
|
2146
|
+
dR = [0 for i in range(gamma)]
|
|
2147
|
+
yR = [None for i in range(gamma)]
|
|
2148
|
+
s = 0
|
|
2149
|
+
n = 0
|
|
2150
|
+
while n < gamma:
|
|
2151
|
+
g = 0
|
|
2152
|
+
for b in Q.divisor(s).basis_function_space():
|
|
2153
|
+
if b.valuation(Q) == -s:
|
|
2154
|
+
g = b
|
|
2155
|
+
break
|
|
2156
|
+
r = pos_mod(s, gamma)
|
|
2157
|
+
if g != 0 and not yR[r]:
|
|
2158
|
+
dR[r] = s
|
|
2159
|
+
yR[r] = g
|
|
2160
|
+
n += 1
|
|
2161
|
+
s += 1
|
|
2162
|
+
|
|
2163
|
+
# gaps of L
|
|
2164
|
+
temp = set()
|
|
2165
|
+
for d in dR:
|
|
2166
|
+
temp.update([d - gamma*(i + 1) for i in range(d // gamma)])
|
|
2167
|
+
gaps = list(temp)
|
|
2168
|
+
del temp
|
|
2169
|
+
|
|
2170
|
+
# genus of L
|
|
2171
|
+
genus = len(gaps)
|
|
2172
|
+
|
|
2173
|
+
# Apéry Wbar
|
|
2174
|
+
dWbar = [0 for i in range(gamma)]
|
|
2175
|
+
wWbar = [None for i in range(gamma)]
|
|
2176
|
+
s = -code_length + G.degree() - 2 * genus + 2
|
|
2177
|
+
n = 0
|
|
2178
|
+
while n < gamma:
|
|
2179
|
+
B = (-D + G - Q.divisor(s)).basis_differential_space()
|
|
2180
|
+
g = 0
|
|
2181
|
+
for b in B:
|
|
2182
|
+
if b.valuation(Q) == G.multiplicity(Q) - s:
|
|
2183
|
+
g = b
|
|
2184
|
+
break
|
|
2185
|
+
r = pos_mod(s, gamma)
|
|
2186
|
+
if g != 0 and not wWbar[r]:
|
|
2187
|
+
dWbar[r] = s
|
|
2188
|
+
wWbar[r] = g
|
|
2189
|
+
n += 1
|
|
2190
|
+
s += 1
|
|
2191
|
+
|
|
2192
|
+
if verbose:
|
|
2193
|
+
print("gamma:", gamma)
|
|
2194
|
+
print("x = {}".format(xR))
|
|
2195
|
+
print("Apéry system of R")
|
|
2196
|
+
for i in range(gamma):
|
|
2197
|
+
print(" {}: {}, y{} = {}".format(i, dR[i], i, yR[i]))
|
|
2198
|
+
print("Apéry system of Wbar")
|
|
2199
|
+
for i in range(gamma):
|
|
2200
|
+
print(" {}: {}, w{} = {}".format(i, dWbar[i], i, wWbar[i]))
|
|
2201
|
+
|
|
2202
|
+
# res map for the monomial whose weighted degree is s
|
|
2203
|
+
evxR = vector(K, [xR.evaluate(p) for p in pls])
|
|
2204
|
+
reswWbar = [vector(K, [wWbar[i].residue(p) for p in pls]) for i in range(gamma)]
|
|
2205
|
+
|
|
2206
|
+
self.is_differential = True
|
|
2207
|
+
self.code_length = code_length
|
|
2208
|
+
self.designed_distance = G.degree() - 2 * genus + 2
|
|
2209
|
+
self.gamma = gamma
|
|
2210
|
+
self.dR = dR
|
|
2211
|
+
self.dRbar = dWbar
|
|
2212
|
+
self.W = W
|
|
2213
|
+
self.x = x
|
|
2214
|
+
|
|
2215
|
+
def res_mon(int sk, int si):
|
|
2216
|
+
cdef int i
|
|
2217
|
+
return vector([evxR.get_unsafe(i)**sk * reswWbar[si][i] for i in range(code_length)])
|
|
2218
|
+
|
|
2219
|
+
# minimum of nongaps of Wbar
|
|
2220
|
+
s0 = self._next(-code_length + G.degree() - 2*genus + 1)
|
|
2221
|
+
|
|
2222
|
+
# basis of the code res(Omega(G))
|
|
2223
|
+
message_index = []
|
|
2224
|
+
code_basis = []
|
|
2225
|
+
s = s0
|
|
2226
|
+
self._exponents(s, &sk, &si)
|
|
2227
|
+
v = res_mon(sk, si)
|
|
2228
|
+
V = v.parent()
|
|
2229
|
+
while s <= 0:
|
|
2230
|
+
if not V.are_linearly_dependent(code_basis + [v]):
|
|
2231
|
+
message_index.append(s)
|
|
2232
|
+
code_basis.append(v)
|
|
2233
|
+
s = self._next(s)
|
|
2234
|
+
self._exponents(s, &sk, &si)
|
|
2235
|
+
v = res_mon(sk, si)
|
|
2236
|
+
|
|
2237
|
+
# compute a basis of J and h-functions via FGLM algorithm
|
|
2238
|
+
eta_vecs = [None for i in range(gamma)]
|
|
2239
|
+
hvecs = [None for i in range(code_length)]
|
|
2240
|
+
|
|
2241
|
+
self._get_eta_basis(eta_vecs, hvecs, s0, res_mon)
|
|
2242
|
+
|
|
2243
|
+
if verbose:
|
|
2244
|
+
print("message indices:", message_index)
|
|
2245
|
+
print("eta basis:", eta_vecs)
|
|
2246
|
+
print("Lagrange polynomials")
|
|
2247
|
+
for i in range(code_length):
|
|
2248
|
+
print("h{} = {}".format(i, hvecs[i]))
|
|
2249
|
+
|
|
2250
|
+
# Lee-O'Sullivan bound
|
|
2251
|
+
def nu(int s):
|
|
2252
|
+
cdef int i, sk, si, m
|
|
2253
|
+
m = 0
|
|
2254
|
+
for i in range(gamma):
|
|
2255
|
+
self._exponents(s + dR[i], &sk, &si)
|
|
2256
|
+
m += max(0, self._degree(eta_vecs[si][si]) - sk)
|
|
2257
|
+
return m
|
|
2258
|
+
|
|
2259
|
+
nus = [nu(s) for s in message_index]
|
|
2260
|
+
dLO = <int> min(nus)
|
|
2261
|
+
tau = (dLO - 1) // 2
|
|
2262
|
+
|
|
2263
|
+
if verbose:
|
|
2264
|
+
print("gaps:", gaps)
|
|
2265
|
+
print("genus:", genus)
|
|
2266
|
+
print("nus:", nus)
|
|
2267
|
+
print("dLO:", dLO)
|
|
2268
|
+
print("tau:", tau)
|
|
2269
|
+
|
|
2270
|
+
# the vector form corresponding to f in Wbar
|
|
2271
|
+
def vec_form(f):
|
|
2272
|
+
r = f
|
|
2273
|
+
cdef list l = [W.zero() for i in range(gamma)]
|
|
2274
|
+
while r != 0:
|
|
2275
|
+
s = -r.valuation(Q) + G.valuation(Q)
|
|
2276
|
+
self._exponents(s, &sk, &si)
|
|
2277
|
+
mon = xR**sk * wWbar[si]
|
|
2278
|
+
c = (r / mon).evaluate(Q)
|
|
2279
|
+
l[si] += c * x**sk
|
|
2280
|
+
r -= c*mon
|
|
2281
|
+
return vector(l)
|
|
2282
|
+
|
|
2283
|
+
# the matrix of the leading coefficient of y_i*w_j and the product
|
|
2284
|
+
coeff_mat = <Matrix> matrix.zero(K, gamma, gamma)
|
|
2285
|
+
mul_mat = [[None for j in range(gamma)] for i in range(gamma)]
|
|
2286
|
+
for i in range(gamma):
|
|
2287
|
+
for j in range(gamma):
|
|
2288
|
+
f = yR[i] * wWbar[j]
|
|
2289
|
+
v = vec_form(f)
|
|
2290
|
+
self._exponents((<int> dR[i]) + (<int> dWbar[j]), &sk, &si)
|
|
2291
|
+
coeff_mat[i, j] = v[si][sk]
|
|
2292
|
+
(<list> mul_mat[i])[j] = v
|
|
2293
|
+
|
|
2294
|
+
if verbose:
|
|
2295
|
+
print("multiplication table")
|
|
2296
|
+
for i in range(gamma):
|
|
2297
|
+
for j in range(gamma):
|
|
2298
|
+
print("y{} * w{}:".format(i, j), mul_mat[i][j])
|
|
2299
|
+
print("coefficient array")
|
|
2300
|
+
print(coeff_mat)
|
|
2301
|
+
|
|
2302
|
+
self.code_basis = code_basis
|
|
2303
|
+
self.message_index = message_index
|
|
2304
|
+
self.hvecs = hvecs
|
|
2305
|
+
self.eta_vecs = eta_vecs
|
|
2306
|
+
self.mul_mat = mul_mat
|
|
2307
|
+
self.coeff_mat = coeff_mat
|
|
2308
|
+
self.s0 = s0
|
|
2309
|
+
self.tau = tau
|
|
2310
|
+
|
|
2311
|
+
cdef dict info = {}
|
|
2312
|
+
info['designed_distance'] = dLO
|
|
2313
|
+
info['decoding_radius'] = tau
|
|
2314
|
+
|
|
2315
|
+
self.info = info
|
|
2316
|
+
|
|
2317
|
+
|
|
2318
|
+
cdef class Decoder_K_extension():
|
|
2319
|
+
"""
|
|
2320
|
+
Common base class for decoding algorithm K for AG codes via constant field extension.
|
|
2321
|
+
|
|
2322
|
+
INPUT:
|
|
2323
|
+
|
|
2324
|
+
- ``pls`` -- list of places of a function field
|
|
2325
|
+
|
|
2326
|
+
- ``G`` -- a divisor of the function field
|
|
2327
|
+
|
|
2328
|
+
- ``Q`` -- a non-rational place
|
|
2329
|
+
|
|
2330
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
2331
|
+
|
|
2332
|
+
EXAMPLES::
|
|
2333
|
+
|
|
2334
|
+
sage: A.<x,y> = AffineSpace(GF(4), 2)
|
|
2335
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2336
|
+
sage: pls = C.places()
|
|
2337
|
+
sage: F = C.function_field()
|
|
2338
|
+
sage: G = 1*F.get_place(4)
|
|
2339
|
+
sage: code = codes.EvaluationAGCode(pls, G)
|
|
2340
|
+
sage: dec = code.decoder('K'); dec # long time
|
|
2341
|
+
Unique decoder for [9, 4] evaluation AG code over GF(4)
|
|
2342
|
+
|
|
2343
|
+
::
|
|
2344
|
+
|
|
2345
|
+
sage: P.<x,y> = ProjectiveSpace(GF(4), 1)
|
|
2346
|
+
sage: C = Curve(P)
|
|
2347
|
+
sage: pls = C.places()
|
|
2348
|
+
sage: len(pls)
|
|
2349
|
+
5
|
|
2350
|
+
sage: F = C.function_field()
|
|
2351
|
+
sage: G = F.get_place(2).divisor()
|
|
2352
|
+
sage: code = codes.EvaluationAGCode(pls, G)
|
|
2353
|
+
sage: code.decoder('K')
|
|
2354
|
+
Unique decoder for [5, 3] evaluation AG code over GF(4)
|
|
2355
|
+
"""
|
|
2356
|
+
cdef object _embedK, _K
|
|
2357
|
+
cdef Decoder_K decoder_ext
|
|
2358
|
+
|
|
2359
|
+
cdef readonly dict info
|
|
2360
|
+
|
|
2361
|
+
def __init__(self, pls, G, Q, decoder_cls, verbose=False):
|
|
2362
|
+
"""
|
|
2363
|
+
Initialize.
|
|
2364
|
+
|
|
2365
|
+
TESTS::
|
|
2366
|
+
|
|
2367
|
+
sage: A.<x,y> = AffineSpace(GF(4), 2)
|
|
2368
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2369
|
+
sage: pls = C.places()
|
|
2370
|
+
sage: F = C.function_field()
|
|
2371
|
+
sage: G = 1*F.get_place(4)
|
|
2372
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
2373
|
+
sage: dec = code.decoder('K') # long time
|
|
2374
|
+
sage: TestSuite(dec).run(skip='_test_pickling') # long time
|
|
2375
|
+
"""
|
|
2376
|
+
F = G.parent().function_field()
|
|
2377
|
+
K = F.constant_base_field()
|
|
2378
|
+
F_base = F.base_field()
|
|
2379
|
+
|
|
2380
|
+
K_ext = K.extension(Q.degree())
|
|
2381
|
+
|
|
2382
|
+
if verbose:
|
|
2383
|
+
print('extended constant field:', K_ext)
|
|
2384
|
+
|
|
2385
|
+
F_ext_base = FunctionField(K_ext, F_base.variable_name())
|
|
2386
|
+
|
|
2387
|
+
if F.degree() > 1:
|
|
2388
|
+
# construct constant field extension F_ext of F
|
|
2389
|
+
def_poly = F.polynomial().base_extend(F_ext_base)
|
|
2390
|
+
F_ext = F_ext_base.extension(def_poly, names=def_poly.variable_name())
|
|
2391
|
+
else: # rational function field
|
|
2392
|
+
F_ext = F_ext_base
|
|
2393
|
+
|
|
2394
|
+
O_ext = F_ext.maximal_order()
|
|
2395
|
+
Oinf_ext = F_ext.maximal_order_infinite()
|
|
2396
|
+
|
|
2397
|
+
# embedding of F into F_ext
|
|
2398
|
+
embedK = K_ext.coerce_map_from(K)
|
|
2399
|
+
embedF_base = F_base.hom(F_ext_base.gen(), embedK)
|
|
2400
|
+
|
|
2401
|
+
if F.degree() > 1:
|
|
2402
|
+
embedF = F.hom(F_ext.gen(), embedF_base)
|
|
2403
|
+
else:
|
|
2404
|
+
embedF = embedF_base
|
|
2405
|
+
|
|
2406
|
+
self._embedK = embedK
|
|
2407
|
+
self._K = K
|
|
2408
|
+
|
|
2409
|
+
Div_ext = F_ext.divisor_group()
|
|
2410
|
+
|
|
2411
|
+
def conorm_prime_divisor(pl):
|
|
2412
|
+
"""
|
|
2413
|
+
Conorm map for prime divisors.
|
|
2414
|
+
"""
|
|
2415
|
+
if pl.is_infinite_place():
|
|
2416
|
+
ideal = Oinf_ext.ideal([embedF(g) for g in pl.prime_ideal().gens()])
|
|
2417
|
+
else:
|
|
2418
|
+
ideal = O_ext.ideal([embedF(g) for g in pl.prime_ideal().gens()])
|
|
2419
|
+
return ideal.divisor()
|
|
2420
|
+
|
|
2421
|
+
def conorm(d):
|
|
2422
|
+
"""
|
|
2423
|
+
Conorm map from F to F_ext.
|
|
2424
|
+
"""
|
|
2425
|
+
c = Div_ext.zero()
|
|
2426
|
+
for pl, mul in d.list():
|
|
2427
|
+
c += mul * conorm_prime_divisor(pl)
|
|
2428
|
+
return c
|
|
2429
|
+
|
|
2430
|
+
def lift_place(pl):
|
|
2431
|
+
"""
|
|
2432
|
+
Get a place of F_ext lying above pl.
|
|
2433
|
+
"""
|
|
2434
|
+
return conorm_prime_divisor(pl).support()[0]
|
|
2435
|
+
|
|
2436
|
+
pls_ext = [lift_place(pl) for pl in pls]
|
|
2437
|
+
G_ext = conorm(G)
|
|
2438
|
+
Q_ext = lift_place(Q)
|
|
2439
|
+
|
|
2440
|
+
self.decoder_ext = decoder_cls(pls_ext, G_ext, Q_ext, verbose=verbose)
|
|
2441
|
+
self.info = self.decoder_ext.info
|
|
2442
|
+
|
|
2443
|
+
def _lift(self, v):
|
|
2444
|
+
"""
|
|
2445
|
+
Lift a vector over the base field to a vector over the extension field.
|
|
2446
|
+
|
|
2447
|
+
TESTS::
|
|
2448
|
+
|
|
2449
|
+
sage: A.<x,y> = AffineSpace(GF(4), 2)
|
|
2450
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2451
|
+
sage: pls = C.places()
|
|
2452
|
+
sage: F = C.function_field()
|
|
2453
|
+
sage: G = 1*F.get_place(4)
|
|
2454
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
2455
|
+
sage: decoder = code.decoder('K') # long time
|
|
2456
|
+
sage: lift = decoder._circuit._lift # long time
|
|
2457
|
+
sage: pull_back = decoder._circuit._pull_back # long time
|
|
2458
|
+
sage: v = code.random_element() # long time
|
|
2459
|
+
sage: pull_back(lift(v)) == v # long time
|
|
2460
|
+
True
|
|
2461
|
+
"""
|
|
2462
|
+
embedK = self._embedK
|
|
2463
|
+
return vector(embedK(e) for e in v)
|
|
2464
|
+
|
|
2465
|
+
def _pull_back(self, v):
|
|
2466
|
+
"""
|
|
2467
|
+
Pull back a vector over the extension field to a vector over the base
|
|
2468
|
+
field.
|
|
2469
|
+
|
|
2470
|
+
TESTS::
|
|
2471
|
+
|
|
2472
|
+
sage: A.<x,y> = AffineSpace(GF(4), 2)
|
|
2473
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2474
|
+
sage: pls = C.places()
|
|
2475
|
+
sage: F = C.function_field()
|
|
2476
|
+
sage: G = 1*F.get_place(4)
|
|
2477
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
2478
|
+
sage: decoder = code.decoder('K') # long time
|
|
2479
|
+
sage: code = decoder.code() # long time
|
|
2480
|
+
sage: lift = decoder._circuit._lift # long time
|
|
2481
|
+
sage: pull_back = decoder._circuit._pull_back # long time
|
|
2482
|
+
sage: v = code.random_element() # long time
|
|
2483
|
+
sage: pull_back(lift(v)) == v # long time
|
|
2484
|
+
True
|
|
2485
|
+
"""
|
|
2486
|
+
K = self._K
|
|
2487
|
+
return vector(K(e) for e in v)
|
|
2488
|
+
|
|
2489
|
+
def encode(self, message, **kwargs):
|
|
2490
|
+
"""
|
|
2491
|
+
Encode ``message`` to a codeword.
|
|
2492
|
+
|
|
2493
|
+
TESTS::
|
|
2494
|
+
|
|
2495
|
+
sage: A.<x,y> = AffineSpace(GF(4), 2)
|
|
2496
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2497
|
+
sage: pls = C.places()
|
|
2498
|
+
sage: F = C.function_field()
|
|
2499
|
+
sage: G = 1*F.get_place(4)
|
|
2500
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
2501
|
+
sage: decoder = code.decoder('K') # long time
|
|
2502
|
+
sage: cw = code.random_element() # long time
|
|
2503
|
+
sage: circuit = decoder._circuit # long time
|
|
2504
|
+
sage: circuit.encode(circuit.decode(cw)) == cw # long time
|
|
2505
|
+
True
|
|
2506
|
+
"""
|
|
2507
|
+
return self.decoder_ext.encode(message, **kwargs)
|
|
2508
|
+
|
|
2509
|
+
def decode(self, received_vector, **kwargs):
|
|
2510
|
+
"""
|
|
2511
|
+
Decode the received vector to a message.
|
|
2512
|
+
|
|
2513
|
+
INPUT:
|
|
2514
|
+
|
|
2515
|
+
- ``received_vector`` -- a vector in the ambient space of the code
|
|
2516
|
+
|
|
2517
|
+
TESTS::
|
|
2518
|
+
|
|
2519
|
+
sage: A.<x,y> = AffineSpace(GF(4), 2)
|
|
2520
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2521
|
+
sage: pls = C.places()
|
|
2522
|
+
sage: F = C.function_field()
|
|
2523
|
+
sage: G = 1*F.get_place(4)
|
|
2524
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
2525
|
+
sage: decoder = code.decoder('K') # long time
|
|
2526
|
+
sage: cw = code.random_element() # long time
|
|
2527
|
+
sage: circuit = decoder._circuit # long time
|
|
2528
|
+
sage: circuit.encode(circuit.decode(cw)) == cw # long time
|
|
2529
|
+
True
|
|
2530
|
+
"""
|
|
2531
|
+
return self.decoder_ext.decode(received_vector, **kwargs)
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
@cython.auto_pickle(True)
|
|
2535
|
+
cdef class EvaluationAGCodeDecoder_K_extension(Decoder_K_extension):
|
|
2536
|
+
"""
|
|
2537
|
+
This class implements the decoding algorithm K for evaluation AG codes via
|
|
2538
|
+
constant field extension.
|
|
2539
|
+
|
|
2540
|
+
INPUT:
|
|
2541
|
+
|
|
2542
|
+
- ``pls`` -- list of places of a function field
|
|
2543
|
+
|
|
2544
|
+
- ``G`` -- a divisor of the function field
|
|
2545
|
+
|
|
2546
|
+
- ``Q`` -- a non-rational place
|
|
2547
|
+
|
|
2548
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
2549
|
+
|
|
2550
|
+
EXAMPLES::
|
|
2551
|
+
|
|
2552
|
+
sage: F.<a> = GF(4)
|
|
2553
|
+
sage: A.<x,y> = AffineSpace(F, 2)
|
|
2554
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2555
|
+
sage: pls = C.places()
|
|
2556
|
+
sage: F = C.function_field()
|
|
2557
|
+
sage: G = 1*F.get_place(4)
|
|
2558
|
+
sage: code = codes.EvaluationAGCode(pls, G)
|
|
2559
|
+
sage: Q = F.get_place(3)
|
|
2560
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K_extension
|
|
2561
|
+
sage: circuit = EvaluationAGCodeDecoder_K_extension(pls, G, Q)
|
|
2562
|
+
sage: cw = code.random_element()
|
|
2563
|
+
sage: rv = cw + vector([0,1,1,0,0,0,0,0,0])
|
|
2564
|
+
sage: circuit.encode(circuit.decode(circuit._lift(rv))) == circuit._lift(cw)
|
|
2565
|
+
True
|
|
2566
|
+
"""
|
|
2567
|
+
def __init__(self, pls, G, Q, verbose=False):
|
|
2568
|
+
"""
|
|
2569
|
+
Initialize.
|
|
2570
|
+
|
|
2571
|
+
TESTS::
|
|
2572
|
+
|
|
2573
|
+
sage: F.<a> = GF(4)
|
|
2574
|
+
sage: A.<x,y> = AffineSpace(F, 2)
|
|
2575
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2576
|
+
sage: pls = C.places()
|
|
2577
|
+
sage: F = C.function_field()
|
|
2578
|
+
sage: G = 1*F.get_place(4)
|
|
2579
|
+
sage: code = codes.EvaluationAGCode(pls, G) # long time
|
|
2580
|
+
sage: Q = F.get_place(3) # long time
|
|
2581
|
+
sage: from sage.coding.ag_code_decoders import EvaluationAGCodeDecoder_K_extension # long time
|
|
2582
|
+
sage: circuit = EvaluationAGCodeDecoder_K_extension(pls, G, Q) # long time
|
|
2583
|
+
sage: TestSuite(circuit).run(skip='_test_pickling') # long time
|
|
2584
|
+
"""
|
|
2585
|
+
super().__init__(pls, G, Q, EvaluationAGCodeDecoder_K, verbose=verbose)
|
|
2586
|
+
|
|
2587
|
+
|
|
2588
|
+
@cython.auto_pickle(True)
|
|
2589
|
+
cdef class DifferentialAGCodeDecoder_K_extension(Decoder_K_extension):
|
|
2590
|
+
"""
|
|
2591
|
+
This class implements the decoding algorithm K for differential AG codes via
|
|
2592
|
+
constant field extension.
|
|
2593
|
+
|
|
2594
|
+
INPUT:
|
|
2595
|
+
|
|
2596
|
+
- ``pls`` -- list of places of a function field
|
|
2597
|
+
|
|
2598
|
+
- ``G`` -- a divisor of the function field
|
|
2599
|
+
|
|
2600
|
+
- ``Q`` -- a non-rational place
|
|
2601
|
+
|
|
2602
|
+
- ``verbose`` -- if ``True``, verbose information is printed
|
|
2603
|
+
|
|
2604
|
+
EXAMPLES::
|
|
2605
|
+
|
|
2606
|
+
sage: F.<a> = GF(4)
|
|
2607
|
+
sage: A.<x,y> = AffineSpace(F, 2)
|
|
2608
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2609
|
+
sage: pls = C.places()
|
|
2610
|
+
sage: F = C.function_field()
|
|
2611
|
+
sage: G = 1*F.get_place(4)
|
|
2612
|
+
sage: code = codes.DifferentialAGCode(pls, G)
|
|
2613
|
+
sage: Q = F.get_place(3)
|
|
2614
|
+
sage: from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K_extension
|
|
2615
|
+
sage: circuit = DifferentialAGCodeDecoder_K_extension(pls, G, Q) # long time
|
|
2616
|
+
sage: cw = code.random_element()
|
|
2617
|
+
sage: rv = cw + vector([0,0,a,0,0,0,0,0,0])
|
|
2618
|
+
sage: circuit.encode(circuit.decode(circuit._lift(rv))) == circuit._lift(cw) # long time
|
|
2619
|
+
True
|
|
2620
|
+
"""
|
|
2621
|
+
def __init__(self, pls, G, Q, verbose=False):
|
|
2622
|
+
"""
|
|
2623
|
+
Initialize.
|
|
2624
|
+
|
|
2625
|
+
TESTS::
|
|
2626
|
+
|
|
2627
|
+
sage: F.<a> = GF(4)
|
|
2628
|
+
sage: A.<x,y> = AffineSpace(F, 2)
|
|
2629
|
+
sage: C = Curve(y^2 + y - x^3)
|
|
2630
|
+
sage: pls = C.places()
|
|
2631
|
+
sage: F = C.function_field()
|
|
2632
|
+
sage: G = 1*F.get_place(4)
|
|
2633
|
+
sage: code = codes.DifferentialAGCode(pls, G) # long time
|
|
2634
|
+
sage: Q = F.get_place(3) # long time
|
|
2635
|
+
sage: from sage.coding.ag_code_decoders import DifferentialAGCodeDecoder_K_extension # long time
|
|
2636
|
+
sage: circuit = DifferentialAGCodeDecoder_K_extension(pls, G, Q) # long time
|
|
2637
|
+
sage: TestSuite(circuit).run(skip='_test_pickling') # long time
|
|
2638
|
+
"""
|
|
2639
|
+
super().__init__(pls, G, Q, DifferentialAGCodeDecoder_K, verbose=verbose)
|