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.

Files changed (807) hide show
  1. passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
  2. passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
  3. passagemath_modules-10.6.31rc3.dist-info/WHEEL +5 -0
  4. passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_modules.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_modules.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
  7. passagemath_modules.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  8. passagemath_modules.libs/libgsl-23768756.so.28.0.0 +0 -0
  9. passagemath_modules.libs/libmpc-7897025b.so.3.3.1 +0 -0
  10. passagemath_modules.libs/libmpfr-e34bb864.so.6.2.1 +0 -0
  11. passagemath_modules.libs/libopenblasp-r0-503f0c35.3.29.so +0 -0
  12. sage/algebras/all__sagemath_modules.py +20 -0
  13. sage/algebras/catalog.py +148 -0
  14. sage/algebras/clifford_algebra.py +3107 -0
  15. sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
  16. sage/algebras/clifford_algebra_element.pxd +16 -0
  17. sage/algebras/clifford_algebra_element.pyx +997 -0
  18. sage/algebras/commutative_dga.py +4252 -0
  19. sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-musl.so +0 -0
  20. sage/algebras/exterior_algebra_groebner.pxd +55 -0
  21. sage/algebras/exterior_algebra_groebner.pyx +727 -0
  22. sage/algebras/finite_dimensional_algebras/all.py +2 -0
  23. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
  24. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
  25. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
  26. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
  27. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
  28. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
  29. sage/algebras/finite_gca.py +528 -0
  30. sage/algebras/group_algebra.py +232 -0
  31. sage/algebras/lie_algebras/abelian.py +197 -0
  32. sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
  33. sage/algebras/lie_algebras/all.py +25 -0
  34. sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
  35. sage/algebras/lie_algebras/bch.py +177 -0
  36. sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
  37. sage/algebras/lie_algebras/bgg_resolution.py +232 -0
  38. sage/algebras/lie_algebras/center_uea.py +767 -0
  39. sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
  40. sage/algebras/lie_algebras/examples.py +683 -0
  41. sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
  42. sage/algebras/lie_algebras/heisenberg.py +820 -0
  43. sage/algebras/lie_algebras/lie_algebra.py +1562 -0
  44. sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
  45. sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
  46. sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
  47. sage/algebras/lie_algebras/morphism.py +661 -0
  48. sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
  49. sage/algebras/lie_algebras/onsager.py +1324 -0
  50. sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
  51. sage/algebras/lie_algebras/quotient.py +462 -0
  52. sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
  53. sage/algebras/lie_algebras/representation.py +1040 -0
  54. sage/algebras/lie_algebras/structure_coefficients.py +459 -0
  55. sage/algebras/lie_algebras/subalgebra.py +967 -0
  56. sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
  57. sage/algebras/lie_algebras/verma_module.py +1630 -0
  58. sage/algebras/lie_algebras/virasoro.py +1186 -0
  59. sage/algebras/octonion_algebra.cpython-314-aarch64-linux-musl.so +0 -0
  60. sage/algebras/octonion_algebra.pxd +20 -0
  61. sage/algebras/octonion_algebra.pyx +987 -0
  62. sage/algebras/orlik_solomon.py +907 -0
  63. sage/algebras/orlik_terao.py +779 -0
  64. sage/algebras/steenrod/all.py +7 -0
  65. sage/algebras/steenrod/steenrod_algebra.py +4258 -0
  66. sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
  67. sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
  68. sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
  69. sage/algebras/weyl_algebra.py +1126 -0
  70. sage/all__sagemath_modules.py +62 -0
  71. sage/calculus/all__sagemath_modules.py +19 -0
  72. sage/calculus/expr.py +205 -0
  73. sage/calculus/integration.cpython-314-aarch64-linux-musl.so +0 -0
  74. sage/calculus/integration.pyx +698 -0
  75. sage/calculus/interpolation.cpython-314-aarch64-linux-musl.so +0 -0
  76. sage/calculus/interpolation.pxd +13 -0
  77. sage/calculus/interpolation.pyx +387 -0
  78. sage/calculus/interpolators.cpython-314-aarch64-linux-musl.so +0 -0
  79. sage/calculus/interpolators.pyx +326 -0
  80. sage/calculus/ode.cpython-314-aarch64-linux-musl.so +0 -0
  81. sage/calculus/ode.pxd +5 -0
  82. sage/calculus/ode.pyx +610 -0
  83. sage/calculus/riemann.cpython-314-aarch64-linux-musl.so +0 -0
  84. sage/calculus/riemann.pyx +1521 -0
  85. sage/calculus/test_sympy.py +201 -0
  86. sage/calculus/transforms/all.py +7 -0
  87. sage/calculus/transforms/dft.py +844 -0
  88. sage/calculus/transforms/dwt.cpython-314-aarch64-linux-musl.so +0 -0
  89. sage/calculus/transforms/dwt.pxd +7 -0
  90. sage/calculus/transforms/dwt.pyx +160 -0
  91. sage/calculus/transforms/fft.cpython-314-aarch64-linux-musl.so +0 -0
  92. sage/calculus/transforms/fft.pxd +12 -0
  93. sage/calculus/transforms/fft.pyx +487 -0
  94. sage/calculus/wester.py +662 -0
  95. sage/coding/abstract_code.py +1108 -0
  96. sage/coding/ag_code.py +868 -0
  97. sage/coding/ag_code_decoders.cpython-314-aarch64-linux-musl.so +0 -0
  98. sage/coding/ag_code_decoders.pyx +2639 -0
  99. sage/coding/all.py +15 -0
  100. sage/coding/bch_code.py +494 -0
  101. sage/coding/binary_code.cpython-314-aarch64-linux-musl.so +0 -0
  102. sage/coding/binary_code.pxd +124 -0
  103. sage/coding/binary_code.pyx +4139 -0
  104. sage/coding/bounds_catalog.py +43 -0
  105. sage/coding/channel.py +819 -0
  106. sage/coding/channels_catalog.py +29 -0
  107. sage/coding/code_bounds.py +755 -0
  108. sage/coding/code_constructions.py +804 -0
  109. sage/coding/codes_catalog.py +111 -0
  110. sage/coding/cyclic_code.py +1329 -0
  111. sage/coding/databases.py +316 -0
  112. sage/coding/decoder.py +373 -0
  113. sage/coding/decoders_catalog.py +88 -0
  114. sage/coding/delsarte_bounds.py +709 -0
  115. sage/coding/encoder.py +390 -0
  116. sage/coding/encoders_catalog.py +64 -0
  117. sage/coding/extended_code.py +468 -0
  118. sage/coding/gabidulin_code.py +1058 -0
  119. sage/coding/golay_code.py +404 -0
  120. sage/coding/goppa_code.py +441 -0
  121. sage/coding/grs_code.py +2371 -0
  122. sage/coding/guava.py +107 -0
  123. sage/coding/guruswami_sudan/all.py +1 -0
  124. sage/coding/guruswami_sudan/gs_decoder.py +897 -0
  125. sage/coding/guruswami_sudan/interpolation.py +409 -0
  126. sage/coding/guruswami_sudan/utils.py +176 -0
  127. sage/coding/hamming_code.py +176 -0
  128. sage/coding/information_set_decoder.py +1032 -0
  129. sage/coding/kasami_codes.cpython-314-aarch64-linux-musl.so +0 -0
  130. sage/coding/kasami_codes.pyx +351 -0
  131. sage/coding/linear_code.py +3067 -0
  132. sage/coding/linear_code_no_metric.py +1354 -0
  133. sage/coding/linear_rank_metric.py +961 -0
  134. sage/coding/parity_check_code.py +353 -0
  135. sage/coding/punctured_code.py +719 -0
  136. sage/coding/reed_muller_code.py +999 -0
  137. sage/coding/self_dual_codes.py +942 -0
  138. sage/coding/source_coding/all.py +2 -0
  139. sage/coding/source_coding/huffman.py +553 -0
  140. sage/coding/subfield_subcode.py +423 -0
  141. sage/coding/two_weight_db.py +399 -0
  142. sage/combinat/all__sagemath_modules.py +7 -0
  143. sage/combinat/cartesian_product.py +347 -0
  144. sage/combinat/family.py +11 -0
  145. sage/combinat/free_module.py +1977 -0
  146. sage/combinat/root_system/all.py +147 -0
  147. sage/combinat/root_system/ambient_space.py +527 -0
  148. sage/combinat/root_system/associahedron.py +471 -0
  149. sage/combinat/root_system/braid_move_calculator.py +143 -0
  150. sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-musl.so +0 -0
  151. sage/combinat/root_system/braid_orbit.pyx +144 -0
  152. sage/combinat/root_system/branching_rules.py +2301 -0
  153. sage/combinat/root_system/cartan_matrix.py +1245 -0
  154. sage/combinat/root_system/cartan_type.py +3069 -0
  155. sage/combinat/root_system/coxeter_group.py +162 -0
  156. sage/combinat/root_system/coxeter_matrix.py +1261 -0
  157. sage/combinat/root_system/coxeter_type.py +681 -0
  158. sage/combinat/root_system/dynkin_diagram.py +900 -0
  159. sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
  160. sage/combinat/root_system/fundamental_group.py +795 -0
  161. sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
  162. sage/combinat/root_system/integrable_representations.py +1227 -0
  163. sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
  164. sage/combinat/root_system/pieri_factors.py +1147 -0
  165. sage/combinat/root_system/plot.py +1615 -0
  166. sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
  167. sage/combinat/root_system/root_lattice_realizations.py +4628 -0
  168. sage/combinat/root_system/root_space.py +487 -0
  169. sage/combinat/root_system/root_system.py +882 -0
  170. sage/combinat/root_system/type_A.py +348 -0
  171. sage/combinat/root_system/type_A_affine.py +227 -0
  172. sage/combinat/root_system/type_A_infinity.py +241 -0
  173. sage/combinat/root_system/type_B.py +347 -0
  174. sage/combinat/root_system/type_BC_affine.py +287 -0
  175. sage/combinat/root_system/type_B_affine.py +216 -0
  176. sage/combinat/root_system/type_C.py +317 -0
  177. sage/combinat/root_system/type_C_affine.py +188 -0
  178. sage/combinat/root_system/type_D.py +357 -0
  179. sage/combinat/root_system/type_D_affine.py +208 -0
  180. sage/combinat/root_system/type_E.py +641 -0
  181. sage/combinat/root_system/type_E_affine.py +231 -0
  182. sage/combinat/root_system/type_F.py +387 -0
  183. sage/combinat/root_system/type_F_affine.py +137 -0
  184. sage/combinat/root_system/type_G.py +293 -0
  185. sage/combinat/root_system/type_G_affine.py +132 -0
  186. sage/combinat/root_system/type_H.py +105 -0
  187. sage/combinat/root_system/type_I.py +110 -0
  188. sage/combinat/root_system/type_Q.py +150 -0
  189. sage/combinat/root_system/type_affine.py +509 -0
  190. sage/combinat/root_system/type_dual.py +704 -0
  191. sage/combinat/root_system/type_folded.py +301 -0
  192. sage/combinat/root_system/type_marked.py +748 -0
  193. sage/combinat/root_system/type_reducible.py +601 -0
  194. sage/combinat/root_system/type_relabel.py +730 -0
  195. sage/combinat/root_system/type_super_A.py +837 -0
  196. sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
  197. sage/combinat/root_system/weight_space.py +639 -0
  198. sage/combinat/root_system/weyl_characters.py +2238 -0
  199. sage/crypto/__init__.py +4 -0
  200. sage/crypto/all.py +28 -0
  201. sage/crypto/block_cipher/all.py +7 -0
  202. sage/crypto/block_cipher/des.py +1065 -0
  203. sage/crypto/block_cipher/miniaes.py +2171 -0
  204. sage/crypto/block_cipher/present.py +909 -0
  205. sage/crypto/block_cipher/sdes.py +1527 -0
  206. sage/crypto/boolean_function.cpython-314-aarch64-linux-musl.so +0 -0
  207. sage/crypto/boolean_function.pxd +10 -0
  208. sage/crypto/boolean_function.pyx +1487 -0
  209. sage/crypto/cipher.py +78 -0
  210. sage/crypto/classical.py +3668 -0
  211. sage/crypto/classical_cipher.py +569 -0
  212. sage/crypto/cryptosystem.py +387 -0
  213. sage/crypto/key_exchange/all.py +7 -0
  214. sage/crypto/key_exchange/catalog.py +24 -0
  215. sage/crypto/key_exchange/diffie_hellman.py +323 -0
  216. sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
  217. sage/crypto/lattice.py +312 -0
  218. sage/crypto/lfsr.py +295 -0
  219. sage/crypto/lwe.py +840 -0
  220. sage/crypto/mq/__init__.py +4 -0
  221. sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
  222. sage/crypto/mq/rijndael_gf.py +2345 -0
  223. sage/crypto/mq/sbox.py +7 -0
  224. sage/crypto/mq/sr.py +3344 -0
  225. sage/crypto/public_key/all.py +5 -0
  226. sage/crypto/public_key/blum_goldwasser.py +776 -0
  227. sage/crypto/sbox.cpython-314-aarch64-linux-musl.so +0 -0
  228. sage/crypto/sbox.pyx +2090 -0
  229. sage/crypto/sboxes.py +2090 -0
  230. sage/crypto/stream.py +390 -0
  231. sage/crypto/stream_cipher.py +297 -0
  232. sage/crypto/util.py +519 -0
  233. sage/ext/all__sagemath_modules.py +1 -0
  234. sage/ext/interpreters/__init__.py +1 -0
  235. sage/ext/interpreters/all__sagemath_modules.py +2 -0
  236. sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-musl.so +0 -0
  237. sage/ext/interpreters/wrapper_cc.pxd +30 -0
  238. sage/ext/interpreters/wrapper_cc.pyx +252 -0
  239. sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-musl.so +0 -0
  240. sage/ext/interpreters/wrapper_cdf.pxd +26 -0
  241. sage/ext/interpreters/wrapper_cdf.pyx +245 -0
  242. sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-musl.so +0 -0
  243. sage/ext/interpreters/wrapper_rdf.pxd +23 -0
  244. sage/ext/interpreters/wrapper_rdf.pyx +221 -0
  245. sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-musl.so +0 -0
  246. sage/ext/interpreters/wrapper_rr.pxd +28 -0
  247. sage/ext/interpreters/wrapper_rr.pyx +335 -0
  248. sage/geometry/all__sagemath_modules.py +5 -0
  249. sage/geometry/toric_lattice.py +1745 -0
  250. sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-musl.so +0 -0
  251. sage/geometry/toric_lattice_element.pyx +432 -0
  252. sage/groups/abelian_gps/abelian_group.py +1925 -0
  253. sage/groups/abelian_gps/abelian_group_element.py +164 -0
  254. sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
  255. sage/groups/abelian_gps/dual_abelian_group.py +421 -0
  256. sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
  257. sage/groups/abelian_gps/element_base.py +341 -0
  258. sage/groups/abelian_gps/values.py +488 -0
  259. sage/groups/additive_abelian/additive_abelian_group.py +476 -0
  260. sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
  261. sage/groups/additive_abelian/all.py +4 -0
  262. sage/groups/additive_abelian/qmodnz.py +231 -0
  263. sage/groups/additive_abelian/qmodnz_element.py +349 -0
  264. sage/groups/affine_gps/affine_group.py +535 -0
  265. sage/groups/affine_gps/all.py +1 -0
  266. sage/groups/affine_gps/catalog.py +17 -0
  267. sage/groups/affine_gps/euclidean_group.py +246 -0
  268. sage/groups/affine_gps/group_element.py +562 -0
  269. sage/groups/all__sagemath_modules.py +12 -0
  270. sage/groups/galois_group.py +479 -0
  271. sage/groups/matrix_gps/all.py +4 -0
  272. sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
  273. sage/groups/matrix_gps/catalog.py +26 -0
  274. sage/groups/matrix_gps/coxeter_group.py +927 -0
  275. sage/groups/matrix_gps/finitely_generated.py +487 -0
  276. sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-musl.so +0 -0
  277. sage/groups/matrix_gps/group_element.pxd +11 -0
  278. sage/groups/matrix_gps/group_element.pyx +431 -0
  279. sage/groups/matrix_gps/linear.py +440 -0
  280. sage/groups/matrix_gps/matrix_group.py +617 -0
  281. sage/groups/matrix_gps/named_group.py +296 -0
  282. sage/groups/matrix_gps/orthogonal.py +544 -0
  283. sage/groups/matrix_gps/symplectic.py +251 -0
  284. sage/groups/matrix_gps/unitary.py +436 -0
  285. sage/groups/misc_gps/all__sagemath_modules.py +1 -0
  286. sage/groups/misc_gps/argument_groups.py +1905 -0
  287. sage/groups/misc_gps/imaginary_groups.py +479 -0
  288. sage/groups/perm_gps/all__sagemath_modules.py +1 -0
  289. sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
  290. sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-musl.so +0 -0
  291. sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
  292. sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
  293. sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-musl.so +0 -0
  294. sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
  295. sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
  296. sage/homology/algebraic_topological_model.py +595 -0
  297. sage/homology/all.py +2 -0
  298. sage/homology/all__sagemath_modules.py +8 -0
  299. sage/homology/chain_complex.py +2148 -0
  300. sage/homology/chain_complex_homspace.py +165 -0
  301. sage/homology/chain_complex_morphism.py +629 -0
  302. sage/homology/chain_homotopy.py +604 -0
  303. sage/homology/chains.py +653 -0
  304. sage/homology/free_resolution.py +923 -0
  305. sage/homology/graded_resolution.py +567 -0
  306. sage/homology/hochschild_complex.py +756 -0
  307. sage/homology/homology_group.py +188 -0
  308. sage/homology/homology_morphism.py +422 -0
  309. sage/homology/homology_vector_space_with_basis.py +1454 -0
  310. sage/homology/koszul_complex.py +169 -0
  311. sage/homology/matrix_utils.py +205 -0
  312. sage/libs/all__sagemath_modules.py +1 -0
  313. sage/libs/gsl/__init__.py +1 -0
  314. sage/libs/gsl/airy.pxd +56 -0
  315. sage/libs/gsl/all.pxd +66 -0
  316. sage/libs/gsl/array.cpython-314-aarch64-linux-musl.so +0 -0
  317. sage/libs/gsl/array.pxd +5 -0
  318. sage/libs/gsl/array.pyx +102 -0
  319. sage/libs/gsl/bessel.pxd +208 -0
  320. sage/libs/gsl/blas.pxd +116 -0
  321. sage/libs/gsl/blas_types.pxd +34 -0
  322. sage/libs/gsl/block.pxd +52 -0
  323. sage/libs/gsl/chebyshev.pxd +37 -0
  324. sage/libs/gsl/clausen.pxd +12 -0
  325. sage/libs/gsl/combination.pxd +47 -0
  326. sage/libs/gsl/complex.pxd +151 -0
  327. sage/libs/gsl/coulomb.pxd +30 -0
  328. sage/libs/gsl/coupling.pxd +21 -0
  329. sage/libs/gsl/dawson.pxd +12 -0
  330. sage/libs/gsl/debye.pxd +24 -0
  331. sage/libs/gsl/dilog.pxd +14 -0
  332. sage/libs/gsl/eigen.pxd +46 -0
  333. sage/libs/gsl/elementary.pxd +12 -0
  334. sage/libs/gsl/ellint.pxd +48 -0
  335. sage/libs/gsl/elljac.pxd +8 -0
  336. sage/libs/gsl/erf.pxd +32 -0
  337. sage/libs/gsl/errno.pxd +26 -0
  338. sage/libs/gsl/exp.pxd +44 -0
  339. sage/libs/gsl/expint.pxd +44 -0
  340. sage/libs/gsl/fermi_dirac.pxd +44 -0
  341. sage/libs/gsl/fft.pxd +121 -0
  342. sage/libs/gsl/fit.pxd +50 -0
  343. sage/libs/gsl/gamma.pxd +94 -0
  344. sage/libs/gsl/gegenbauer.pxd +26 -0
  345. sage/libs/gsl/histogram.pxd +176 -0
  346. sage/libs/gsl/hyperg.pxd +52 -0
  347. sage/libs/gsl/integration.pxd +69 -0
  348. sage/libs/gsl/interp.pxd +109 -0
  349. sage/libs/gsl/laguerre.pxd +24 -0
  350. sage/libs/gsl/lambert.pxd +16 -0
  351. sage/libs/gsl/legendre.pxd +90 -0
  352. sage/libs/gsl/linalg.pxd +185 -0
  353. sage/libs/gsl/log.pxd +26 -0
  354. sage/libs/gsl/math.pxd +43 -0
  355. sage/libs/gsl/matrix.pxd +143 -0
  356. sage/libs/gsl/matrix_complex.pxd +130 -0
  357. sage/libs/gsl/min.pxd +67 -0
  358. sage/libs/gsl/monte.pxd +56 -0
  359. sage/libs/gsl/ntuple.pxd +32 -0
  360. sage/libs/gsl/odeiv.pxd +70 -0
  361. sage/libs/gsl/permutation.pxd +78 -0
  362. sage/libs/gsl/poly.pxd +40 -0
  363. sage/libs/gsl/pow_int.pxd +12 -0
  364. sage/libs/gsl/psi.pxd +28 -0
  365. sage/libs/gsl/qrng.pxd +29 -0
  366. sage/libs/gsl/random.pxd +257 -0
  367. sage/libs/gsl/rng.pxd +100 -0
  368. sage/libs/gsl/roots.pxd +72 -0
  369. sage/libs/gsl/sort.pxd +36 -0
  370. sage/libs/gsl/statistics.pxd +59 -0
  371. sage/libs/gsl/sum.pxd +55 -0
  372. sage/libs/gsl/synchrotron.pxd +16 -0
  373. sage/libs/gsl/transport.pxd +24 -0
  374. sage/libs/gsl/trig.pxd +58 -0
  375. sage/libs/gsl/types.pxd +137 -0
  376. sage/libs/gsl/vector.pxd +101 -0
  377. sage/libs/gsl/vector_complex.pxd +83 -0
  378. sage/libs/gsl/wavelet.pxd +49 -0
  379. sage/libs/gsl/zeta.pxd +28 -0
  380. sage/libs/mpc/__init__.pxd +114 -0
  381. sage/libs/mpc/types.pxd +28 -0
  382. sage/libs/mpfr/__init__.pxd +299 -0
  383. sage/libs/mpfr/types.pxd +26 -0
  384. sage/libs/mpmath/__init__.py +1 -0
  385. sage/libs/mpmath/all.py +27 -0
  386. sage/libs/mpmath/all__sagemath_modules.py +1 -0
  387. sage/libs/mpmath/utils.cpython-314-aarch64-linux-musl.so +0 -0
  388. sage/libs/mpmath/utils.pxd +4 -0
  389. sage/libs/mpmath/utils.pyx +319 -0
  390. sage/matrix/action.cpython-314-aarch64-linux-musl.so +0 -0
  391. sage/matrix/action.pxd +26 -0
  392. sage/matrix/action.pyx +596 -0
  393. sage/matrix/all.py +9 -0
  394. sage/matrix/args.cpython-314-aarch64-linux-musl.so +0 -0
  395. sage/matrix/args.pxd +144 -0
  396. sage/matrix/args.pyx +1668 -0
  397. sage/matrix/benchmark.py +1258 -0
  398. sage/matrix/berlekamp_massey.py +95 -0
  399. sage/matrix/compute_J_ideal.py +926 -0
  400. sage/matrix/constructor.cpython-314-aarch64-linux-musl.so +0 -0
  401. sage/matrix/constructor.pyx +750 -0
  402. sage/matrix/docs.py +430 -0
  403. sage/matrix/echelon_matrix.cpython-314-aarch64-linux-musl.so +0 -0
  404. sage/matrix/echelon_matrix.pyx +155 -0
  405. sage/matrix/matrix.pxd +2 -0
  406. sage/matrix/matrix0.cpython-314-aarch64-linux-musl.so +0 -0
  407. sage/matrix/matrix0.pxd +68 -0
  408. sage/matrix/matrix0.pyx +6324 -0
  409. sage/matrix/matrix1.cpython-314-aarch64-linux-musl.so +0 -0
  410. sage/matrix/matrix1.pxd +8 -0
  411. sage/matrix/matrix1.pyx +2851 -0
  412. sage/matrix/matrix2.cpython-314-aarch64-linux-musl.so +0 -0
  413. sage/matrix/matrix2.pxd +25 -0
  414. sage/matrix/matrix2.pyx +20181 -0
  415. sage/matrix/matrix_cdv.cpython-314-aarch64-linux-musl.so +0 -0
  416. sage/matrix/matrix_cdv.pxd +4 -0
  417. sage/matrix/matrix_cdv.pyx +93 -0
  418. sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  419. sage/matrix/matrix_complex_double_dense.pxd +5 -0
  420. sage/matrix/matrix_complex_double_dense.pyx +98 -0
  421. sage/matrix/matrix_dense.cpython-314-aarch64-linux-musl.so +0 -0
  422. sage/matrix/matrix_dense.pxd +5 -0
  423. sage/matrix/matrix_dense.pyx +343 -0
  424. sage/matrix/matrix_domain_dense.pxd +5 -0
  425. sage/matrix/matrix_domain_sparse.pxd +5 -0
  426. sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  427. sage/matrix/matrix_double_dense.pxd +7 -0
  428. sage/matrix/matrix_double_dense.pyx +3906 -0
  429. sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  430. sage/matrix/matrix_double_sparse.pxd +6 -0
  431. sage/matrix/matrix_double_sparse.pyx +248 -0
  432. sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
  433. sage/matrix/matrix_generic_dense.pxd +7 -0
  434. sage/matrix/matrix_generic_dense.pyx +354 -0
  435. sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  436. sage/matrix/matrix_generic_sparse.pxd +7 -0
  437. sage/matrix/matrix_generic_sparse.pyx +461 -0
  438. sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
  439. sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
  440. sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
  441. sage/matrix/matrix_misc.py +313 -0
  442. sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
  443. sage/matrix/matrix_numpy_dense.pxd +14 -0
  444. sage/matrix/matrix_numpy_dense.pyx +450 -0
  445. sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
  446. sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
  447. sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
  448. sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
  449. sage/matrix/matrix_polynomial_dense.pxd +5 -0
  450. sage/matrix/matrix_polynomial_dense.pyx +5341 -0
  451. sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  452. sage/matrix/matrix_real_double_dense.pxd +7 -0
  453. sage/matrix/matrix_real_double_dense.pyx +122 -0
  454. sage/matrix/matrix_space.py +2848 -0
  455. sage/matrix/matrix_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  456. sage/matrix/matrix_sparse.pxd +5 -0
  457. sage/matrix/matrix_sparse.pyx +1222 -0
  458. sage/matrix/matrix_window.cpython-314-aarch64-linux-musl.so +0 -0
  459. sage/matrix/matrix_window.pxd +37 -0
  460. sage/matrix/matrix_window.pyx +242 -0
  461. sage/matrix/misc_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
  462. sage/matrix/misc_mpfr.pyx +80 -0
  463. sage/matrix/operation_table.py +1182 -0
  464. sage/matrix/special.py +3666 -0
  465. sage/matrix/strassen.cpython-314-aarch64-linux-musl.so +0 -0
  466. sage/matrix/strassen.pyx +851 -0
  467. sage/matrix/symplectic_basis.py +541 -0
  468. sage/matrix/template.pxd +6 -0
  469. sage/matrix/tests.py +71 -0
  470. sage/matroids/advanced.py +77 -0
  471. sage/matroids/all.py +13 -0
  472. sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  473. sage/matroids/basis_exchange_matroid.pxd +96 -0
  474. sage/matroids/basis_exchange_matroid.pyx +2344 -0
  475. sage/matroids/basis_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  476. sage/matroids/basis_matroid.pxd +45 -0
  477. sage/matroids/basis_matroid.pyx +1217 -0
  478. sage/matroids/catalog.py +44 -0
  479. sage/matroids/chow_ring.py +473 -0
  480. sage/matroids/chow_ring_ideal.py +849 -0
  481. sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  482. sage/matroids/circuit_closures_matroid.pxd +16 -0
  483. sage/matroids/circuit_closures_matroid.pyx +559 -0
  484. sage/matroids/circuits_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  485. sage/matroids/circuits_matroid.pxd +38 -0
  486. sage/matroids/circuits_matroid.pyx +947 -0
  487. sage/matroids/constructor.py +1086 -0
  488. sage/matroids/database_collections.py +365 -0
  489. sage/matroids/database_matroids.py +5338 -0
  490. sage/matroids/dual_matroid.py +583 -0
  491. sage/matroids/extension.cpython-314-aarch64-linux-musl.so +0 -0
  492. sage/matroids/extension.pxd +34 -0
  493. sage/matroids/extension.pyx +519 -0
  494. sage/matroids/flats_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  495. sage/matroids/flats_matroid.pxd +28 -0
  496. sage/matroids/flats_matroid.pyx +715 -0
  497. sage/matroids/gammoid.py +600 -0
  498. sage/matroids/graphic_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  499. sage/matroids/graphic_matroid.pxd +39 -0
  500. sage/matroids/graphic_matroid.pyx +2024 -0
  501. sage/matroids/lean_matrix.cpython-314-aarch64-linux-musl.so +0 -0
  502. sage/matroids/lean_matrix.pxd +126 -0
  503. sage/matroids/lean_matrix.pyx +3667 -0
  504. sage/matroids/linear_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  505. sage/matroids/linear_matroid.pxd +180 -0
  506. sage/matroids/linear_matroid.pyx +6649 -0
  507. sage/matroids/matroid.cpython-314-aarch64-linux-musl.so +0 -0
  508. sage/matroids/matroid.pxd +243 -0
  509. sage/matroids/matroid.pyx +8759 -0
  510. sage/matroids/matroids_catalog.py +190 -0
  511. sage/matroids/matroids_plot_helpers.py +890 -0
  512. sage/matroids/minor_matroid.py +480 -0
  513. sage/matroids/minorfix.h +9 -0
  514. sage/matroids/named_matroids.py +5 -0
  515. sage/matroids/rank_matroid.py +268 -0
  516. sage/matroids/set_system.cpython-314-aarch64-linux-musl.so +0 -0
  517. sage/matroids/set_system.pxd +38 -0
  518. sage/matroids/set_system.pyx +800 -0
  519. sage/matroids/transversal_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  520. sage/matroids/transversal_matroid.pxd +14 -0
  521. sage/matroids/transversal_matroid.pyx +893 -0
  522. sage/matroids/union_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  523. sage/matroids/union_matroid.pxd +20 -0
  524. sage/matroids/union_matroid.pyx +331 -0
  525. sage/matroids/unpickling.cpython-314-aarch64-linux-musl.so +0 -0
  526. sage/matroids/unpickling.pyx +843 -0
  527. sage/matroids/utilities.py +809 -0
  528. sage/misc/all__sagemath_modules.py +20 -0
  529. sage/misc/c3.cpython-314-aarch64-linux-musl.so +0 -0
  530. sage/misc/c3.pyx +238 -0
  531. sage/misc/compat.py +87 -0
  532. sage/misc/element_with_label.py +173 -0
  533. sage/misc/func_persist.py +79 -0
  534. sage/misc/pickle_old.cpython-314-aarch64-linux-musl.so +0 -0
  535. sage/misc/pickle_old.pyx +19 -0
  536. sage/misc/proof.py +7 -0
  537. sage/misc/replace_dot_all.py +472 -0
  538. sage/misc/sagedoc_conf.py +168 -0
  539. sage/misc/sphinxify.py +167 -0
  540. sage/misc/test_class_pickling.py +85 -0
  541. sage/modules/all.py +42 -0
  542. sage/modules/complex_double_vector.py +25 -0
  543. sage/modules/diamond_cutting.py +380 -0
  544. sage/modules/fg_pid/all.py +1 -0
  545. sage/modules/fg_pid/fgp_element.py +456 -0
  546. sage/modules/fg_pid/fgp_module.py +2091 -0
  547. sage/modules/fg_pid/fgp_morphism.py +550 -0
  548. sage/modules/filtered_vector_space.py +1271 -0
  549. sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-musl.so +0 -0
  550. sage/modules/finite_submodule_iter.pxd +27 -0
  551. sage/modules/finite_submodule_iter.pyx +452 -0
  552. sage/modules/fp_graded/all.py +1 -0
  553. sage/modules/fp_graded/element.py +346 -0
  554. sage/modules/fp_graded/free_element.py +298 -0
  555. sage/modules/fp_graded/free_homspace.py +53 -0
  556. sage/modules/fp_graded/free_module.py +1060 -0
  557. sage/modules/fp_graded/free_morphism.py +217 -0
  558. sage/modules/fp_graded/homspace.py +563 -0
  559. sage/modules/fp_graded/module.py +1340 -0
  560. sage/modules/fp_graded/morphism.py +1990 -0
  561. sage/modules/fp_graded/steenrod/all.py +1 -0
  562. sage/modules/fp_graded/steenrod/homspace.py +65 -0
  563. sage/modules/fp_graded/steenrod/module.py +477 -0
  564. sage/modules/fp_graded/steenrod/morphism.py +404 -0
  565. sage/modules/fp_graded/steenrod/profile.py +241 -0
  566. sage/modules/free_module.py +8447 -0
  567. sage/modules/free_module_element.cpython-314-aarch64-linux-musl.so +0 -0
  568. sage/modules/free_module_element.pxd +22 -0
  569. sage/modules/free_module_element.pyx +5445 -0
  570. sage/modules/free_module_homspace.py +369 -0
  571. sage/modules/free_module_integer.py +896 -0
  572. sage/modules/free_module_morphism.py +823 -0
  573. sage/modules/free_module_pseudohomspace.py +352 -0
  574. sage/modules/free_module_pseudomorphism.py +578 -0
  575. sage/modules/free_quadratic_module.py +1706 -0
  576. sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
  577. sage/modules/matrix_morphism.py +1745 -0
  578. sage/modules/misc.py +103 -0
  579. sage/modules/module_functors.py +192 -0
  580. sage/modules/multi_filtered_vector_space.py +719 -0
  581. sage/modules/ore_module.py +2208 -0
  582. sage/modules/ore_module_element.py +178 -0
  583. sage/modules/ore_module_homspace.py +147 -0
  584. sage/modules/ore_module_morphism.py +968 -0
  585. sage/modules/quotient_module.py +699 -0
  586. sage/modules/real_double_vector.py +22 -0
  587. sage/modules/submodule.py +255 -0
  588. sage/modules/tensor_operations.py +567 -0
  589. sage/modules/torsion_quadratic_module.py +1352 -0
  590. sage/modules/tutorial_free_modules.py +248 -0
  591. sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  592. sage/modules/vector_complex_double_dense.pxd +6 -0
  593. sage/modules/vector_complex_double_dense.pyx +117 -0
  594. sage/modules/vector_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  595. sage/modules/vector_double_dense.pxd +6 -0
  596. sage/modules/vector_double_dense.pyx +604 -0
  597. sage/modules/vector_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
  598. sage/modules/vector_integer_dense.pxd +15 -0
  599. sage/modules/vector_integer_dense.pyx +361 -0
  600. sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  601. sage/modules/vector_integer_sparse.pxd +29 -0
  602. sage/modules/vector_integer_sparse.pyx +406 -0
  603. sage/modules/vector_modn_dense.cpython-314-aarch64-linux-musl.so +0 -0
  604. sage/modules/vector_modn_dense.pxd +12 -0
  605. sage/modules/vector_modn_dense.pyx +394 -0
  606. sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  607. sage/modules/vector_modn_sparse.pxd +21 -0
  608. sage/modules/vector_modn_sparse.pyx +298 -0
  609. sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
  610. sage/modules/vector_numpy_dense.pxd +15 -0
  611. sage/modules/vector_numpy_dense.pyx +304 -0
  612. sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
  613. sage/modules/vector_numpy_integer_dense.pxd +7 -0
  614. sage/modules/vector_numpy_integer_dense.pyx +54 -0
  615. sage/modules/vector_rational_dense.cpython-314-aarch64-linux-musl.so +0 -0
  616. sage/modules/vector_rational_dense.pxd +15 -0
  617. sage/modules/vector_rational_dense.pyx +387 -0
  618. sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  619. sage/modules/vector_rational_sparse.pxd +30 -0
  620. sage/modules/vector_rational_sparse.pyx +413 -0
  621. sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  622. sage/modules/vector_real_double_dense.pxd +6 -0
  623. sage/modules/vector_real_double_dense.pyx +126 -0
  624. sage/modules/vector_space_homspace.py +430 -0
  625. sage/modules/vector_space_morphism.py +989 -0
  626. sage/modules/with_basis/all.py +15 -0
  627. sage/modules/with_basis/cell_module.py +494 -0
  628. sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-musl.so +0 -0
  629. sage/modules/with_basis/indexed_element.pxd +13 -0
  630. sage/modules/with_basis/indexed_element.pyx +1058 -0
  631. sage/modules/with_basis/invariant.py +1075 -0
  632. sage/modules/with_basis/morphism.py +1636 -0
  633. sage/modules/with_basis/representation.py +2939 -0
  634. sage/modules/with_basis/subquotient.py +685 -0
  635. sage/numerical/all__sagemath_modules.py +6 -0
  636. sage/numerical/gauss_legendre.cpython-314-aarch64-linux-musl.so +0 -0
  637. sage/numerical/gauss_legendre.pyx +381 -0
  638. sage/numerical/optimize.py +910 -0
  639. sage/probability/all.py +10 -0
  640. sage/probability/probability_distribution.cpython-314-aarch64-linux-musl.so +0 -0
  641. sage/probability/probability_distribution.pyx +1242 -0
  642. sage/probability/random_variable.py +411 -0
  643. sage/quadratic_forms/all.py +4 -0
  644. sage/quadratic_forms/all__sagemath_modules.py +15 -0
  645. sage/quadratic_forms/binary_qf.py +2042 -0
  646. sage/quadratic_forms/bqf_class_group.py +748 -0
  647. sage/quadratic_forms/constructions.py +93 -0
  648. sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-musl.so +0 -0
  649. sage/quadratic_forms/count_local_2.pyx +365 -0
  650. sage/quadratic_forms/extras.py +195 -0
  651. sage/quadratic_forms/quadratic_form.py +1753 -0
  652. sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
  653. sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
  654. sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-musl.so +0 -0
  655. sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
  656. sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
  657. sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
  658. sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
  659. sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
  660. sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
  661. sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
  662. sage/quadratic_forms/quadratic_form__theta.py +352 -0
  663. sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
  664. sage/quadratic_forms/random_quadraticform.py +209 -0
  665. sage/quadratic_forms/ternary.cpython-314-aarch64-linux-musl.so +0 -0
  666. sage/quadratic_forms/ternary.pyx +1154 -0
  667. sage/quadratic_forms/ternary_qf.py +2027 -0
  668. sage/rings/all__sagemath_modules.py +28 -0
  669. sage/rings/asymptotic/all__sagemath_modules.py +1 -0
  670. sage/rings/asymptotic/misc.py +1252 -0
  671. sage/rings/cc.py +4 -0
  672. sage/rings/cfinite_sequence.py +1306 -0
  673. sage/rings/complex_conversion.cpython-314-aarch64-linux-musl.so +0 -0
  674. sage/rings/complex_conversion.pxd +8 -0
  675. sage/rings/complex_conversion.pyx +23 -0
  676. sage/rings/complex_double.cpython-314-aarch64-linux-musl.so +0 -0
  677. sage/rings/complex_double.pxd +21 -0
  678. sage/rings/complex_double.pyx +2654 -0
  679. sage/rings/complex_mpc.cpython-314-aarch64-linux-musl.so +0 -0
  680. sage/rings/complex_mpc.pxd +21 -0
  681. sage/rings/complex_mpc.pyx +2576 -0
  682. sage/rings/complex_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
  683. sage/rings/complex_mpfr.pxd +18 -0
  684. sage/rings/complex_mpfr.pyx +3602 -0
  685. sage/rings/derivation.py +2334 -0
  686. sage/rings/finite_rings/all__sagemath_modules.py +1 -0
  687. sage/rings/finite_rings/maps_finite_field.py +191 -0
  688. sage/rings/function_field/all__sagemath_modules.py +8 -0
  689. sage/rings/function_field/derivations.py +102 -0
  690. sage/rings/function_field/derivations_rational.py +132 -0
  691. sage/rings/function_field/differential.py +853 -0
  692. sage/rings/function_field/divisor.py +1107 -0
  693. sage/rings/function_field/drinfeld_modules/action.py +199 -0
  694. sage/rings/function_field/drinfeld_modules/all.py +1 -0
  695. sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
  696. sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
  697. sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
  698. sage/rings/function_field/drinfeld_modules/homset.py +420 -0
  699. sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
  700. sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-musl.so +0 -0
  701. sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
  702. sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-musl.so +0 -0
  703. sage/rings/function_field/khuri_makdisi.pyx +935 -0
  704. sage/rings/invariants/all.py +4 -0
  705. sage/rings/invariants/invariant_theory.py +4597 -0
  706. sage/rings/invariants/reconstruction.py +395 -0
  707. sage/rings/polynomial/all__sagemath_modules.py +17 -0
  708. sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
  709. sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-musl.so +0 -0
  710. sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
  711. sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
  712. sage/rings/polynomial/ore_function_element.py +952 -0
  713. sage/rings/polynomial/ore_function_field.py +1028 -0
  714. sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
  715. sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
  716. sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
  717. sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
  718. sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-musl.so +0 -0
  719. sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
  720. sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
  721. sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
  722. sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
  723. sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
  724. sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-musl.so +0 -0
  725. sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
  726. sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
  727. sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-musl.so +0 -0
  728. sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
  729. sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
  730. sage/rings/polynomial/skew_polynomial_ring.py +908 -0
  731. sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-musl.so +0 -0
  732. sage/rings/real_double_element_gsl.pxd +8 -0
  733. sage/rings/real_double_element_gsl.pyx +794 -0
  734. sage/rings/real_field.py +58 -0
  735. sage/rings/real_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
  736. sage/rings/real_mpfr.pxd +29 -0
  737. sage/rings/real_mpfr.pyx +6122 -0
  738. sage/rings/ring_extension.cpython-314-aarch64-linux-musl.so +0 -0
  739. sage/rings/ring_extension.pxd +42 -0
  740. sage/rings/ring_extension.pyx +2779 -0
  741. sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-musl.so +0 -0
  742. sage/rings/ring_extension_conversion.pxd +16 -0
  743. sage/rings/ring_extension_conversion.pyx +462 -0
  744. sage/rings/ring_extension_element.cpython-314-aarch64-linux-musl.so +0 -0
  745. sage/rings/ring_extension_element.pxd +21 -0
  746. sage/rings/ring_extension_element.pyx +1635 -0
  747. sage/rings/ring_extension_homset.py +64 -0
  748. sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-musl.so +0 -0
  749. sage/rings/ring_extension_morphism.pxd +35 -0
  750. sage/rings/ring_extension_morphism.pyx +920 -0
  751. sage/schemes/all__sagemath_modules.py +1 -0
  752. sage/schemes/projective/all__sagemath_modules.py +1 -0
  753. sage/schemes/projective/coherent_sheaf.py +300 -0
  754. sage/schemes/projective/cohomology.py +510 -0
  755. sage/stats/all.py +15 -0
  756. sage/stats/basic_stats.py +489 -0
  757. sage/stats/distributions/all.py +7 -0
  758. sage/stats/distributions/catalog.py +34 -0
  759. sage/stats/distributions/dgs.h +50 -0
  760. sage/stats/distributions/dgs.pxd +111 -0
  761. sage/stats/distributions/dgs_bern.h +400 -0
  762. sage/stats/distributions/dgs_gauss.h +614 -0
  763. sage/stats/distributions/dgs_misc.h +104 -0
  764. sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-musl.so +0 -0
  765. sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
  766. sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
  767. sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
  768. sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
  769. sage/stats/hmm/all.py +15 -0
  770. sage/stats/hmm/chmm.cpython-314-aarch64-linux-musl.so +0 -0
  771. sage/stats/hmm/chmm.pyx +1595 -0
  772. sage/stats/hmm/distributions.cpython-314-aarch64-linux-musl.so +0 -0
  773. sage/stats/hmm/distributions.pxd +29 -0
  774. sage/stats/hmm/distributions.pyx +531 -0
  775. sage/stats/hmm/hmm.cpython-314-aarch64-linux-musl.so +0 -0
  776. sage/stats/hmm/hmm.pxd +17 -0
  777. sage/stats/hmm/hmm.pyx +1388 -0
  778. sage/stats/hmm/util.cpython-314-aarch64-linux-musl.so +0 -0
  779. sage/stats/hmm/util.pxd +7 -0
  780. sage/stats/hmm/util.pyx +165 -0
  781. sage/stats/intlist.cpython-314-aarch64-linux-musl.so +0 -0
  782. sage/stats/intlist.pxd +14 -0
  783. sage/stats/intlist.pyx +588 -0
  784. sage/stats/r.py +49 -0
  785. sage/stats/time_series.cpython-314-aarch64-linux-musl.so +0 -0
  786. sage/stats/time_series.pxd +6 -0
  787. sage/stats/time_series.pyx +2546 -0
  788. sage/tensor/all.py +2 -0
  789. sage/tensor/modules/all.py +8 -0
  790. sage/tensor/modules/alternating_contr_tensor.py +761 -0
  791. sage/tensor/modules/comp.py +5598 -0
  792. sage/tensor/modules/ext_pow_free_module.py +824 -0
  793. sage/tensor/modules/finite_rank_free_module.py +3589 -0
  794. sage/tensor/modules/format_utilities.py +333 -0
  795. sage/tensor/modules/free_module_alt_form.py +858 -0
  796. sage/tensor/modules/free_module_automorphism.py +1207 -0
  797. sage/tensor/modules/free_module_basis.py +1074 -0
  798. sage/tensor/modules/free_module_element.py +284 -0
  799. sage/tensor/modules/free_module_homset.py +652 -0
  800. sage/tensor/modules/free_module_linear_group.py +564 -0
  801. sage/tensor/modules/free_module_morphism.py +1581 -0
  802. sage/tensor/modules/free_module_tensor.py +3289 -0
  803. sage/tensor/modules/reflexive_module.py +386 -0
  804. sage/tensor/modules/tensor_free_module.py +780 -0
  805. sage/tensor/modules/tensor_free_submodule.py +538 -0
  806. sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
  807. sage/tensor/modules/tensor_with_indices.py +1043 -0
@@ -0,0 +1,2371 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ # sage.doctest: needs sage.modules sage.rings.finite_rings
3
+ r"""
4
+ Reed-Solomon codes and Generalized Reed-Solomon codes
5
+
6
+ Given `n` different evaluation points `\alpha_1, \dots, \alpha_n` from some
7
+ finite field `F`, the corresponding Reed-Solomon code (RS code) of dimension
8
+ `k` is the set:
9
+
10
+ .. MATH::
11
+
12
+ \{ (f(\alpha_1), \ldots, f(\alpha_n)) \mid f \in F[x], \deg f < k \}
13
+
14
+ An RS code is often called "classical" if `\alpha_i = \alpha^{i-1}` and `\alpha`
15
+ is a primitive `n`-th root of unity.
16
+
17
+ More generally, given also `n` "column multipliers" `\beta_1, \dots, \beta_n`,
18
+ the corresponding Generalized Reed-Solomon code (GRS code) of dimension `k` is
19
+ the set:
20
+
21
+ .. MATH::
22
+
23
+ \{ (\beta_1 f(\alpha_1), \ldots, \beta_n f(\alpha_n))
24
+ \mid f \in F[x], \deg f < k \}
25
+
26
+ Here is a list of all content related to GRS codes:
27
+
28
+ - :class:`GeneralizedReedSolomonCode`, the class for GRS codes
29
+ - :func:`ReedSolomonCode`, function for constructing classical Reed-Solomon codes.
30
+ - :class:`GRSEvaluationVectorEncoder`, an encoder with a vectorial message
31
+ space
32
+ - :class:`GRSEvaluationPolynomialEncoder`, an encoder with a polynomial
33
+ message space
34
+ - :class:`GRSBerlekampWelchDecoder`, a decoder which corrects errors using
35
+ Berlekamp-Welch algorithm
36
+ - :class:`GRSGaoDecoder`, a decoder which corrects errors using Gao algorithm
37
+ - :class:`GRSErrorErasureDecoder`, a decoder which corrects both errors
38
+ and erasures
39
+ - :class:`GRSKeyEquationSyndromeDecoder`, a decoder which corrects errors
40
+ using the key equation on syndrome polynomials
41
+ """
42
+
43
+ # ****************************************************************************
44
+ # Copyright (C) 2015 David Lucas <david.lucas@inria.fr>
45
+ #
46
+ # This program is free software: you can redistribute it and/or modify
47
+ # it under the terms of the GNU General Public License as published by
48
+ # the Free Software Foundation, either version 2 of the License, or
49
+ # (at your option) any later version.
50
+ # https://www.gnu.org/licenses/
51
+ # ****************************************************************************
52
+ from copy import copy
53
+
54
+ from sage.categories.cartesian_product import cartesian_product
55
+
56
+ from sage.matrix.constructor import matrix
57
+
58
+ from sage.rings.finite_rings.finite_field_constructor import GF
59
+ from sage.rings.integer import Integer
60
+ from sage.rings.integer_ring import ZZ
61
+
62
+ from sage.modules.free_module_element import vector
63
+ from sage.modules.free_module import VectorSpace
64
+
65
+ from sage.misc.cachefunc import cached_method
66
+ from sage.misc.functional import symbolic_sum
67
+ from sage.misc.misc_c import prod
68
+
69
+ from .linear_code import AbstractLinearCode
70
+ from .encoder import Encoder
71
+ from .decoder import Decoder, DecodingError
72
+
73
+
74
+ class GeneralizedReedSolomonCode(AbstractLinearCode):
75
+ r"""
76
+ Representation of a (Generalized) Reed-Solomon code.
77
+
78
+ INPUT:
79
+
80
+ - ``evaluation_points`` -- list of distinct elements of some
81
+ finite field `F`
82
+
83
+ - ``dimension`` -- the dimension of the resulting code
84
+
85
+ - ``column_multipliers`` -- (default: ``None``) list of nonzero
86
+ elements of `F`; all column multipliers are set to 1 if default
87
+ value is kept
88
+
89
+ EXAMPLES:
90
+
91
+ Often, one constructs a Reed-Solomon code by taking all nonzero elements of
92
+ the field as evaluation points, and specifying no column multipliers (see
93
+ also :func:`ReedSolomonCode` for constructing classical Reed-Solomon codes
94
+ directly)::
95
+
96
+ sage: F = GF(7)
97
+ sage: evalpts = [F(i) for i in range(1,7)]
98
+ sage: C = codes.GeneralizedReedSolomonCode(evalpts, 3)
99
+ sage: C
100
+ [6, 3, 4] Reed-Solomon Code over GF(7)
101
+
102
+ More generally, the following is a Reed-Solomon code where the evaluation
103
+ points are a subset of the field and includes zero::
104
+
105
+ sage: F = GF(59)
106
+ sage: n, k = 40, 12
107
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
108
+ sage: C
109
+ [40, 12, 29] Reed-Solomon Code over GF(59)
110
+
111
+ It is also possible to specify the column multipliers::
112
+
113
+ sage: F = GF(59)
114
+ sage: n, k = 40, 12
115
+ sage: colmults = F.list()[1:n+1]
116
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)
117
+ sage: C
118
+ [40, 12, 29] Generalized Reed-Solomon Code over GF(59)
119
+
120
+ SageMath implements efficient decoding algorithms for GRS codes::
121
+
122
+ sage: F = GF(11)
123
+ sage: n, k = 10, 5
124
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
125
+ sage: r = vector(F, (8, 2, 6, 10, 6, 10, 7, 6, 7, 2))
126
+ sage: C.decode_to_message(r)
127
+ (3, 6, 6, 3, 1)
128
+
129
+ TESTS:
130
+
131
+ Test that the bug in :issue:`30045` is fixed::
132
+
133
+ sage: F = GF(5)
134
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:5], 2)
135
+ sage: D = codes.decoders.GRSErrorErasureDecoder(C)
136
+ sage: y = (vector(F, [3, 0, 3, 0, 3]), vector(GF(2),[0, 1, 0, 1, 0]))
137
+ sage: D.decode_to_code(y)
138
+ (3, 3, 3, 3, 3)
139
+ sage: D.decode_to_message(y)
140
+ (3, 0)
141
+ """
142
+ _registered_encoders = {}
143
+ _registered_decoders = {}
144
+
145
+ def __init__(self, evaluation_points, dimension, column_multipliers=None):
146
+ r"""
147
+ TESTS:
148
+
149
+ If the evaluation points are not from a finite field, it raises an error::
150
+
151
+ sage: C = codes.GeneralizedReedSolomonCode([1,2,3], 1)
152
+ Traceback (most recent call last):
153
+ ...
154
+ ValueError: Evaluation points must be in a finite field (and Integer Ring is not one)
155
+
156
+ If the evaluation points are not from the same finite field, it raises an error::
157
+
158
+ sage: F2, F3 = GF(2) , GF(3)
159
+ sage: C = codes.GeneralizedReedSolomonCode([F2.zero(),F2.one(),F3(2)], 1)
160
+ Traceback (most recent call last):
161
+ ...
162
+ ValueError: Failed converting all evaluation points to the same field (unable to find a common ring for all elements)
163
+
164
+ If the column multipliers cannot be converted into the finite are not from a finite field, or cannot be not in the same
165
+ finite field as the evaluation points, it raises an error::
166
+
167
+ sage: F = GF(59)
168
+ sage: F2 = GF(61)
169
+ sage: n, k = 40, 12
170
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, [.3]*n )
171
+ Traceback (most recent call last):
172
+ ...
173
+ ValueError: Failed converting all evaluation points and column multipliers to the same field (unable to find a common ring for all elements)
174
+
175
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, F2.list()[1:n+1])
176
+ Traceback (most recent call last):
177
+ ...
178
+ ValueError: Failed converting all evaluation points and column multipliers to the same field (unable to find a common ring for all elements)
179
+
180
+ The number of column multipliers is checked as well::
181
+
182
+ sage: F = GF(59)
183
+ sage: n, k = 40, 12
184
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, F.list()[1:n])
185
+ Traceback (most recent call last):
186
+ ...
187
+ ValueError: There must be the same number of evaluation points as column multipliers
188
+
189
+ It is not allowed to have 0 as a column multiplier::
190
+
191
+ sage: F = GF(59)
192
+ sage: n, k = 40, 12
193
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k, F.list()[:n])
194
+ Traceback (most recent call last):
195
+ ...
196
+ ValueError: All column multipliers must be nonzero
197
+
198
+ And all the evaluation points must be different. Note that they should
199
+ be different after converting into the same field::
200
+
201
+ sage: F = GF(5)
202
+ sage: C = codes.GeneralizedReedSolomonCode([ F(0), 1, 2, 3, 5 ], 3)
203
+ Traceback (most recent call last):
204
+ ...
205
+ ValueError: All evaluation points must be different
206
+
207
+ The dimension is not allowed to exceed the length::
208
+
209
+ sage: F = GF(59)
210
+ sage: n, k = 40, 100
211
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
212
+ Traceback (most recent call last):
213
+ ...
214
+ ValueError: The dimension must be a positive integer at most the length of the code.
215
+ """
216
+ if column_multipliers:
217
+ if len(evaluation_points) != len(column_multipliers):
218
+ raise ValueError("There must be the same number of evaluation points as column multipliers")
219
+ try:
220
+ common_points = vector(list(evaluation_points) + list(column_multipliers))
221
+ F = common_points.base_ring()
222
+ self._evaluation_points = common_points[:len(evaluation_points)]
223
+ self._column_multipliers = common_points[len(evaluation_points):]
224
+ except (TypeError, ValueError) as e:
225
+ raise ValueError("Failed converting all evaluation points and column multipliers to the same field (%s)" % e)
226
+ else:
227
+ try:
228
+ self._evaluation_points = vector(evaluation_points)
229
+ F = self._evaluation_points.base_ring()
230
+ self._column_multipliers = vector(F, [F.one()] * len(self._evaluation_points))
231
+ except (TypeError, ValueError) as e:
232
+ raise ValueError("Failed converting all evaluation points to the same field (%s)" % e)
233
+
234
+ if not F.is_finite() or not F.is_field():
235
+ raise ValueError("Evaluation points must be in a finite field (and %s is not one)" % F)
236
+ super().__init__(F,
237
+ len(self._evaluation_points), "EvaluationVector", "Gao")
238
+
239
+ if dimension not in ZZ or dimension > self._length or dimension < 1:
240
+ raise ValueError("The dimension must be a positive integer at most the length of the code.")
241
+ self._dimension = dimension
242
+
243
+ if F.zero() in self._column_multipliers:
244
+ raise ValueError("All column multipliers must be nonzero")
245
+ if len(self._evaluation_points) != len(set(self._evaluation_points)):
246
+ raise ValueError("All evaluation points must be different")
247
+
248
+ def __eq__(self, other):
249
+ r"""
250
+ Test equality between Generalized Reed-Solomon codes.
251
+
252
+ EXAMPLES::
253
+
254
+ sage: F = GF(59)
255
+ sage: n, k = 40, 12
256
+ sage: C1 = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
257
+ sage: C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
258
+ sage: C1 == C2
259
+ True
260
+ """
261
+ return isinstance(other, GeneralizedReedSolomonCode) \
262
+ and self.base_field() == other.base_field() \
263
+ and self.length() == other.length() \
264
+ and self.dimension() == other.dimension() \
265
+ and self.evaluation_points() == other.evaluation_points() \
266
+ and self.column_multipliers() == other.column_multipliers()
267
+
268
+ def __hash__(self):
269
+ """
270
+ Return the hash of ``self``.
271
+
272
+ EXAMPLES::
273
+
274
+ sage: F = GF(59)
275
+ sage: n, k = 40, 12
276
+ sage: C1 = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
277
+ sage: C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
278
+ sage: hash(C1) == hash(C2)
279
+ True
280
+ """
281
+ return hash((self.base_field(), self.length(), self.dimension(),
282
+ tuple(self.evaluation_points()),
283
+ tuple(self.column_multipliers())))
284
+
285
+ def _repr_(self):
286
+ r"""
287
+ Return a string representation of ``self``.
288
+
289
+ EXAMPLES::
290
+
291
+ sage: F = GF(59)
292
+ sage: n, k = 40, 12
293
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
294
+ sage: C
295
+ [40, 12, 29] Reed-Solomon Code over GF(59)
296
+ sage: colmults = F.list()[1:n+1]
297
+ sage: C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)
298
+ sage: C2
299
+ [40, 12, 29] Generalized Reed-Solomon Code over GF(59)
300
+ """
301
+ return "[%s, %s, %s] %sReed-Solomon Code over GF(%s)"\
302
+ % (self.length(), self.dimension(), self.minimum_distance(),
303
+ "Generalized " if self.is_generalized() else "",
304
+ self.base_field().cardinality())
305
+
306
+ def _latex_(self):
307
+ r"""
308
+ Return a latex representation of ``self``.
309
+
310
+ EXAMPLES::
311
+
312
+ sage: F = GF(59)
313
+ sage: n, k = 40, 12
314
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
315
+ sage: latex(C)
316
+ [40, 12, 29] \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
317
+ sage: colmults = F.list()[1:n+1]
318
+ sage: C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)
319
+ sage: latex(C2)
320
+ [40, 12, 29] \textnormal{ Generalized Reed-Solomon Code over } \Bold{F}_{59}
321
+ """
322
+ return "[%s, %s, %s] \\textnormal{ %sReed-Solomon Code over } %s"\
323
+ % (self.length(), self.dimension(), self.minimum_distance(),
324
+ "Generalized " if self.is_generalized() else "",
325
+ self.base_field()._latex_())
326
+
327
+ def minimum_distance(self):
328
+ r"""
329
+ Return the minimum distance between any two words in ``self``.
330
+
331
+ Since a GRS code is always Maximum-Distance-Separable (MDS),
332
+ this returns ``C.length() - C.dimension() + 1``.
333
+
334
+ EXAMPLES::
335
+
336
+ sage: F = GF(59)
337
+ sage: n, k = 40, 12
338
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
339
+ sage: C.minimum_distance()
340
+ 29
341
+ """
342
+ return self.length() - self.dimension() + 1
343
+
344
+ def evaluation_points(self):
345
+ r"""
346
+ Return the vector of field elements used for the polynomial evaluations.
347
+
348
+ EXAMPLES::
349
+
350
+ sage: F = GF(11)
351
+ sage: n, k = 10, 5
352
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
353
+ sage: C.evaluation_points()
354
+ (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
355
+ """
356
+ return self._evaluation_points
357
+
358
+ def column_multipliers(self):
359
+ r"""
360
+ Return the vector of column multipliers of ``self``.
361
+
362
+ EXAMPLES::
363
+
364
+ sage: F = GF(11)
365
+ sage: n, k = 10, 5
366
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
367
+ sage: C.column_multipliers()
368
+ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
369
+ """
370
+ return self._column_multipliers
371
+
372
+ def is_generalized(self):
373
+ r"""
374
+ Return whether ``self`` is a Generalized Reed-Solomon code or
375
+ a regular Reed-Solomon code.
376
+
377
+ ``self`` is a Generalized Reed-Solomon code if its column multipliers
378
+ are not all 1.
379
+
380
+ EXAMPLES::
381
+
382
+ sage: F = GF(11)
383
+ sage: n, k = 10, 5
384
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
385
+ sage: C.column_multipliers()
386
+ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
387
+ sage: C.is_generalized()
388
+ False
389
+ sage: colmults = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1]
390
+ sage: C2 = codes.GeneralizedReedSolomonCode(F.list()[:n], k, colmults)
391
+ sage: C2.is_generalized()
392
+ True
393
+ """
394
+ return not all(beta.is_one() for beta in self.column_multipliers())
395
+
396
+ @cached_method
397
+ def multipliers_product(self):
398
+ r"""
399
+ Return the component-wise product of the column multipliers of ``self``
400
+ with the column multipliers of the dual GRS code.
401
+
402
+ This is a simple Cramer's rule-like expression on the evaluation points
403
+ of ``self``. Recall that the column multipliers of the dual GRS code are
404
+ also the column multipliers of the parity check matrix of ``self``.
405
+
406
+ EXAMPLES::
407
+
408
+ sage: F = GF(11)
409
+ sage: n, k = 10, 5
410
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
411
+ sage: C.multipliers_product()
412
+ [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
413
+ """
414
+ a = self.evaluation_points()
415
+ one = self.base_ring().one()
416
+ return [one / prod(ai - ah for h, ah in enumerate(a) if h != i)
417
+ for i, ai in enumerate(a)]
418
+
419
+ @cached_method
420
+ def parity_column_multipliers(self):
421
+ r"""
422
+ Return the list of column multipliers of the parity check matrix of
423
+ ``self``. They are also column multipliers of the generator matrix for
424
+ the dual GRS code of ``self``.
425
+
426
+ EXAMPLES::
427
+
428
+ sage: F = GF(11)
429
+ sage: n, k = 10, 5
430
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
431
+ sage: C.parity_column_multipliers()
432
+ [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
433
+ """
434
+ n = self.length()
435
+ col_mults = self.column_multipliers()
436
+ etas = self.multipliers_product()
437
+ return [etas[i] / col_mults[i] for i in range(n)]
438
+
439
+ @cached_method
440
+ def parity_check_matrix(self):
441
+ r"""
442
+ Return the parity check matrix of ``self``.
443
+
444
+ EXAMPLES::
445
+
446
+ sage: F = GF(11)
447
+ sage: n, k = 10, 5
448
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
449
+ sage: C.parity_check_matrix()
450
+ [10 9 8 7 6 5 4 3 2 1]
451
+ [ 0 9 5 10 2 3 2 10 5 9]
452
+ [ 0 9 10 8 8 4 1 4 7 4]
453
+ [ 0 9 9 2 10 9 6 6 1 3]
454
+ [ 0 9 7 6 7 1 3 9 8 5]
455
+ """
456
+ return self.dual_code().generator_matrix()
457
+
458
+ @cached_method
459
+ def dual_code(self):
460
+ r"""
461
+ Return the dual code of ``self``, which is also a GRS code.
462
+
463
+ EXAMPLES::
464
+
465
+ sage: F = GF(59)
466
+ sage: colmults = [ F._random_nonzero_element() for i in range(40) ]
467
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:40], 12, colmults)
468
+ sage: Cd = C.dual_code(); Cd
469
+ [40, 28, 13] Generalized Reed-Solomon Code over GF(59)
470
+
471
+ The dual code of the dual code is the original code::
472
+
473
+ sage: C == Cd.dual_code()
474
+ True
475
+ """
476
+ col_mults = self.parity_column_multipliers()
477
+ return GeneralizedReedSolomonCode(self.evaluation_points(),
478
+ self.length() - self.dimension(),
479
+ col_mults)
480
+
481
+ def covering_radius(self):
482
+ r"""
483
+ Return the covering radius of ``self``.
484
+
485
+ The covering radius of a linear code `C` is the smallest
486
+ number `r` s.t. any element of the ambient space of `C` is
487
+ at most at distance `r` to `C`.
488
+
489
+ As GRS codes are Maximum Distance Separable codes (MDS), their covering
490
+ radius is always `d-1`, where `d` is the minimum distance. This is
491
+ opposed to random linear codes where the covering radius is
492
+ computationally hard to determine.
493
+
494
+ EXAMPLES::
495
+
496
+ sage: F = GF(2^8, 'a')
497
+ sage: n, k = 256, 100
498
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
499
+ sage: C.covering_radius()
500
+ 156
501
+ """
502
+ return self.length() - self.dimension()
503
+
504
+ @cached_method
505
+ def weight_distribution(self):
506
+ r"""
507
+ Return the list whose `i`-th entry is the number of words of weight `i`
508
+ in ``self``.
509
+
510
+ Computing the weight distribution for a GRS code is very fast. Note that
511
+ for random linear codes, it is computationally hard.
512
+
513
+ EXAMPLES::
514
+
515
+ sage: F = GF(11)
516
+ sage: n, k = 10, 5
517
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
518
+ sage: C.weight_distribution() # needs sage.symbolic
519
+ [1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200]
520
+
521
+ TESTS:
522
+
523
+ Test that this method agrees with the generic algorithm::
524
+
525
+ sage: F = GF(7)
526
+ sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3)
527
+ sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time, needs sage.symbolic
528
+ True
529
+ sage: F = GF(8)
530
+ sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3)
531
+ sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time, needs sage.symbolic
532
+ True
533
+ """
534
+ from sage.symbolic.ring import SR
535
+ from sage.functions.other import binomial
536
+
537
+ d = self.minimum_distance()
538
+ n = self.length()
539
+ q = self.base_ring().order()
540
+ s = SR.var('s')
541
+ wd = [1] + [0] * (d - 1)
542
+ for i in range(d, n + 1):
543
+ tmp = binomial(n, i) * (q - 1)
544
+ wd.append(tmp * symbolic_sum(binomial(i-1, s) * (-1)**s * q**(i - d - s), s, 0, i-d))
545
+ return wd
546
+
547
+ def _punctured_form(self, points):
548
+ r"""
549
+ Return a representation of ``self`` as a
550
+ :class:`GeneralizedReedSolomonCode` punctured in ``points``.
551
+
552
+ INPUT:
553
+
554
+ - ``points`` -- set of positions where to puncture ``self``
555
+
556
+ EXAMPLES::
557
+
558
+ sage: C_grs = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12)
559
+ sage: C_grs._punctured_form({4, 3})
560
+ [38, 12, 27] Reed-Solomon Code over GF(59)
561
+ """
562
+ if not isinstance(points, (Integer, int, set)):
563
+ raise TypeError("points must be either a Sage Integer, a Python int, or a set")
564
+ alphas = list(self.evaluation_points())
565
+ col_mults = list(self.column_multipliers())
566
+ n = self.length()
567
+ punctured_alphas = []
568
+ punctured_col_mults = []
569
+ punctured_alphas = [alphas[i] for i in range(n) if i not in points]
570
+ punctured_col_mults = [col_mults[i] for i in range(n) if i not in points]
571
+ G = self.generator_matrix()
572
+ G = G.delete_columns(list(points))
573
+ dimension = G.rank()
574
+ return GeneralizedReedSolomonCode(punctured_alphas, dimension, punctured_col_mults)
575
+
576
+
577
+ def ReedSolomonCode(base_field, length, dimension, primitive_root=None):
578
+ r"""
579
+ Construct a classical Reed-Solomon code.
580
+
581
+ A classical `[n,k]` Reed-Solomon code over `\GF{q}` with `1 \le k \le n` and
582
+ `n | (q-1)` is a Reed-Solomon code whose evaluation points are the
583
+ consecutive powers of a primitive `n`-th root of unity `\alpha`, i.e.
584
+ `\alpha_i = \alpha^{i-1}`, where `\alpha_1, \ldots, \alpha_n` are the
585
+ evaluation points. A classical Reed-Solomon codes has all column multipliers
586
+ equal `1`.
587
+
588
+ Classical Reed-Solomon codes are cyclic, unlike most Generalized
589
+ Reed-Solomon codes.
590
+
591
+ Use :class:`GeneralizedReedSolomonCode` if you instead wish to construct
592
+ non-classical Reed-Solomon and Generalized Reed-Solomon codes.
593
+
594
+ INPUT:
595
+
596
+ - ``base_field`` -- the finite field for which to build the classical
597
+ Reed-Solomon code
598
+
599
+ - ``length`` -- the length of the classical Reed-Solomon code. Must divide
600
+ `q-1` where `q` is the cardinality of ``base_field``
601
+
602
+ - ``dimension`` -- the dimension of the resulting code
603
+
604
+ - ``primitive_root`` -- (default: ``None``) a primitive `n`-th root of unity
605
+ to use for constructing the classical Reed-Solomon code; if not supplied,
606
+ one will be computed and can be recovered as ``C.evaluation_points()[1]``
607
+ where `C` is the code returned by this method
608
+
609
+ EXAMPLES::
610
+
611
+ sage: C = codes.ReedSolomonCode(GF(7), 6, 3); C
612
+ [6, 3, 4] Reed-Solomon Code over GF(7)
613
+
614
+ This code is cyclic as can be seen by coercing it into a cyclic code::
615
+
616
+ sage: Ccyc = codes.CyclicCode(code=C); Ccyc
617
+ [6, 3] Cyclic Code over GF(7)
618
+
619
+ sage: Ccyc.generator_polynomial()
620
+ x^3 + 3*x^2 + x + 6
621
+
622
+ Another example over an extension field::
623
+
624
+ sage: C = codes.ReedSolomonCode(GF(64,'a'), 9, 4); C
625
+ [9, 4, 6] Reed-Solomon Code over GF(64)
626
+
627
+ The primitive `n`-th root of unity can be recovered as the 2nd evaluation point of the code::
628
+
629
+ sage: alpha = C.evaluation_points()[1]; alpha
630
+ a^5 + a^4 + a^2 + a
631
+
632
+ We can also supply a different primitive `n`-th root of unity::
633
+
634
+ sage: beta = alpha^2; beta
635
+ a^4 + a
636
+ sage: beta.multiplicative_order()
637
+ 9
638
+ sage: D = codes.ReedSolomonCode(GF(64), 9, 4, primitive_root=beta); D
639
+ [9, 4, 6] Reed-Solomon Code over GF(64)
640
+ sage: C == D
641
+ False
642
+ """
643
+ if not length.divides(base_field.cardinality()-1):
644
+ raise ValueError("A classical Reed-Solomon code has a length which divides the field cardinality minus 1")
645
+ if primitive_root is None:
646
+ g = base_field.multiplicative_generator()
647
+ primitive_root = g**((base_field.cardinality()-1)/length)
648
+ else:
649
+ if primitive_root.multiplicative_order() != length:
650
+ raise ValueError("Supplied primitive_root is not a primitive n'th root of unity")
651
+ return GeneralizedReedSolomonCode([primitive_root**i for i in range(length)], dimension)
652
+
653
+ # ###################### encoders ###############################
654
+
655
+
656
+ class GRSEvaluationVectorEncoder(Encoder):
657
+ r"""
658
+ Encoder for (Generalized) Reed-Solomon codes that encodes vectors
659
+ into codewords.
660
+
661
+ Let `C` be a GRS code of length `n` and dimension `k` over some
662
+ finite field `F`. We denote by `\alpha_i` its evaluations points
663
+ and by `\beta_i` its column multipliers, where `1 \leq i \leq n`.
664
+ Let `m = (m_1, \dots, m_k)`, a vector over `F`, be the message.
665
+ We build a polynomial using the coordinates of `m` as coefficients:
666
+
667
+ .. MATH::
668
+
669
+ p = \Sigma_{i=1}^{m} m_i x^i.
670
+
671
+ The encoding of `m` will be the following codeword:
672
+
673
+ .. MATH::
674
+
675
+ (\beta_1 p(\alpha_1), \dots, \beta_n p(\alpha_n)).
676
+
677
+ INPUT:
678
+
679
+ - ``code`` -- the associated code of this encoder
680
+
681
+ EXAMPLES::
682
+
683
+ sage: F = GF(59)
684
+ sage: n, k = 40, 12
685
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
686
+ sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)
687
+ sage: E
688
+ Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
689
+
690
+ Actually, we can construct the encoder from ``C`` directly::
691
+
692
+ sage: E = C.encoder("EvaluationVector")
693
+ sage: E
694
+ Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
695
+ """
696
+
697
+ def __init__(self, code):
698
+ r"""
699
+ EXAMPLES::
700
+
701
+ sage: F = GF(59)
702
+ sage: n, k = 40, 12
703
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
704
+ sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)
705
+ sage: E
706
+ Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
707
+ """
708
+ super().__init__(code)
709
+
710
+ def __eq__(self, other):
711
+ r"""
712
+ Test equality between GRSEvaluationVectorEncoder objects.
713
+
714
+ EXAMPLES::
715
+
716
+ sage: F = GF(59)
717
+ sage: n, k = 40, 12
718
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
719
+ sage: D1 = codes.encoders.GRSEvaluationVectorEncoder(C)
720
+ sage: D2 = codes.encoders.GRSEvaluationVectorEncoder(C)
721
+ sage: D1.__eq__(D2)
722
+ True
723
+ sage: D1 is D2
724
+ False
725
+ """
726
+ return isinstance(other, GRSEvaluationVectorEncoder) \
727
+ and self.code() == other.code()
728
+
729
+ def _repr_(self):
730
+ r"""
731
+ Return a string representation of ``self``.
732
+
733
+ EXAMPLES::
734
+
735
+ sage: F = GF(59)
736
+ sage: n, k = 40, 12
737
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
738
+ sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)
739
+ sage: E
740
+ Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
741
+ """
742
+ return "Evaluation vector-style encoder for %s" % self.code()
743
+
744
+ def _latex_(self):
745
+ r"""
746
+ Return a latex representation of ``self``.
747
+
748
+ EXAMPLES::
749
+
750
+ sage: F = GF(59)
751
+ sage: n, k = 40, 12
752
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
753
+ sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)
754
+ sage: latex(E)
755
+ \textnormal{Evaluation vector-style encoder for }[40, 12, 29]
756
+ \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
757
+ """
758
+ return "\\textnormal{Evaluation vector-style encoder for }%s" % self.code()._latex_()
759
+
760
+ @cached_method
761
+ def generator_matrix(self):
762
+ r"""
763
+ Return a generator matrix of ``self``.
764
+
765
+ Considering a GRS code of length `n`, dimension `k`, with
766
+ evaluation points `(\alpha_1, \dots, \alpha_n)` and column multipliers
767
+ `(\beta_1, \dots, \beta_n)`, its generator matrix `G` is built using
768
+ the following formula:
769
+
770
+ .. MATH::
771
+
772
+ G = [g_{i,j}], g_{i,j} = \beta_j \alpha_{j}^{i}.
773
+
774
+ This matrix is a Vandermonde matrix.
775
+
776
+ EXAMPLES::
777
+
778
+ sage: F = GF(11)
779
+ sage: n, k = 10, 5
780
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
781
+ sage: E = codes.encoders.GRSEvaluationVectorEncoder(C)
782
+ sage: E.generator_matrix()
783
+ [1 1 1 1 1 1 1 1 1 1]
784
+ [0 1 2 3 4 5 6 7 8 9]
785
+ [0 1 4 9 5 3 3 5 9 4]
786
+ [0 1 8 5 9 4 7 2 6 3]
787
+ [0 1 5 4 3 9 9 3 4 5]
788
+ """
789
+ C = self.code()
790
+ alphas = C.evaluation_points()
791
+ col_mults = C.column_multipliers()
792
+ g = matrix(C.base_field(), C.dimension(), C.length(), lambda i, j: col_mults[j] * alphas[j]**i)
793
+ g.set_immutable()
794
+ return g
795
+
796
+
797
+ class GRSEvaluationPolynomialEncoder(Encoder):
798
+ r"""
799
+ Encoder for (Generalized) Reed-Solomon codes which uses evaluation of
800
+ polynomials to obtain codewords.
801
+
802
+ Let `C` be a GRS code of length `n` and dimension `k` over some
803
+ finite field `F`. We denote by `\alpha_i` its evaluations points
804
+ and by `\beta_i` its column multipliers, where `1 \leq i \leq n`.
805
+ Let `p` be a polynomial of degree at most `k-1` in `F[x]` be the message.
806
+
807
+ The encoding of `m` will be the following codeword:
808
+
809
+ .. MATH::
810
+
811
+ (\beta_1 p(\alpha_1), \dots, \beta_n p(\alpha_n)).
812
+
813
+ INPUT:
814
+
815
+ - ``code`` -- the associated code of this encoder
816
+
817
+ - ``polynomial_ring`` -- (default: ``None``) a polynomial ring to specify
818
+ the message space of ``self``, if needed; it is set to `F[x]` (where `F`
819
+ is the base field of ``code``) if default value is kept
820
+
821
+ EXAMPLES::
822
+
823
+ sage: F = GF(59)
824
+ sage: n, k = 40, 12
825
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
826
+ sage: E = codes.encoders.GRSEvaluationPolynomialEncoder(C)
827
+ sage: E
828
+ Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
829
+ sage: E.message_space()
830
+ Univariate Polynomial Ring in x over Finite Field of size 59
831
+
832
+ Actually, we can construct the encoder from ``C`` directly::
833
+
834
+ sage: E = C.encoder("EvaluationPolynomial")
835
+ sage: E
836
+ Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
837
+
838
+ We can also specify another polynomial ring::
839
+
840
+ sage: R = PolynomialRing(F, 'y')
841
+ sage: E = C.encoder("EvaluationPolynomial", polynomial_ring=R)
842
+ sage: E.message_space()
843
+ Univariate Polynomial Ring in y over Finite Field of size 59
844
+ """
845
+
846
+ def __init__(self, code, polynomial_ring=None):
847
+ r"""
848
+ TESTS:
849
+
850
+ If ``polynomial_ring`` is not a polynomial ring, an exception
851
+ is raised::
852
+
853
+ sage: F = GF(59)
854
+ sage: n, k = 40, 12
855
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
856
+ sage: E = codes.encoders.GRSEvaluationPolynomialEncoder(C, polynomial_ring = F)
857
+ Traceback (most recent call last):
858
+ ...
859
+ ValueError: polynomial_ring has to be a univariate polynomial ring
860
+
861
+ Same if ``polynomial_ring`` is a multivariate polynomial ring::
862
+
863
+ sage: Fxy.<x,y> = F[]
864
+ sage: E = codes.encoders.GRSEvaluationPolynomialEncoder(C, polynomial_ring = Fxy)
865
+ Traceback (most recent call last):
866
+ ...
867
+ ValueError: polynomial_ring has to be a univariate polynomial ring
868
+
869
+ ``polynomial_ring``'s base field and ``code``'s base field have to be the same::
870
+
871
+ sage: Gx.<x> = GF(7)[]
872
+ sage: E = codes.encoders.GRSEvaluationPolynomialEncoder(C, polynomial_ring = Gx)
873
+ Traceback (most recent call last):
874
+ ...
875
+ ValueError: polynomial_ring's base field has to be the same as code's
876
+ """
877
+ from sage.rings.polynomial.polynomial_ring import PolynomialRing_commutative
878
+ super().__init__(code)
879
+ if polynomial_ring is None:
880
+ self._polynomial_ring = code.base_field()['x']
881
+ else:
882
+ if not isinstance(polynomial_ring, PolynomialRing_commutative):
883
+ raise ValueError("polynomial_ring has to be a univariate polynomial ring")
884
+ elif not len(polynomial_ring.variable_names()) == 1:
885
+ raise ValueError("polynomial_ring has to be a univariate polynomial ring")
886
+ if not polynomial_ring.base_ring() == code.base_field():
887
+ raise ValueError("polynomial_ring's base field has to be the same as code's")
888
+ self._polynomial_ring = polynomial_ring
889
+
890
+ def __eq__(self, other):
891
+ r"""
892
+ Test equality between GRSEvaluationPolynomialEncoder objects.
893
+
894
+ EXAMPLES::
895
+
896
+ sage: F = GF(59)
897
+ sage: n, k = 40, 12
898
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
899
+ sage: D1 = codes.encoders.GRSEvaluationPolynomialEncoder(C)
900
+ sage: D2 = codes.encoders.GRSEvaluationPolynomialEncoder(C)
901
+ sage: D1 is D2
902
+ False
903
+ sage: D1.__eq__(D2)
904
+ True
905
+ sage: R = PolynomialRing(F, 'y')
906
+ sage: D3 = codes.encoders.GRSEvaluationPolynomialEncoder(C, polynomial_ring=R)
907
+ sage: D1.__eq__(D3)
908
+ False
909
+ """
910
+ return (isinstance(other, GRSEvaluationPolynomialEncoder)
911
+ and self.code() == other.code()
912
+ and self.polynomial_ring() == other.polynomial_ring())
913
+
914
+ def _repr_(self):
915
+ r"""
916
+ Return a string representation of ``self``.
917
+
918
+ EXAMPLES::
919
+
920
+ sage: F = GF(59)
921
+ sage: n, k = 40, 12
922
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
923
+ sage: E = C.encoder("EvaluationPolynomial")
924
+ sage: E
925
+ Evaluation polynomial-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59)
926
+ """
927
+ return "Evaluation polynomial-style encoder for %s" % self.code()
928
+
929
+ def _latex_(self):
930
+ r"""
931
+ Return a latex representation of ``self``.
932
+
933
+ EXAMPLES::
934
+
935
+ sage: F = GF(59)
936
+ sage: n, k = 40, 12
937
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
938
+ sage: E = C.encoder("EvaluationPolynomial")
939
+ sage: latex(E)
940
+ \textnormal{Evaluation polynomial-style encoder for }[40, 12, 29]
941
+ \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
942
+ """
943
+ return "\\textnormal{Evaluation polynomial-style encoder for }%s" % self.code()._latex_()
944
+
945
+ def encode(self, p):
946
+ r"""
947
+ Transform the polynomial ``p`` into a codeword of :meth:`code`.
948
+
949
+ One can use the following shortcut to encode a word with
950
+ an encoder ``E``::
951
+
952
+ E(word)
953
+
954
+ INPUT:
955
+
956
+ - ``p`` -- a polynomial from the message space of ``self`` of degree
957
+ less than ``self.code().dimension()``
958
+
959
+ OUTPUT: a codeword in associated code of ``self``
960
+
961
+ EXAMPLES::
962
+
963
+ sage: F = GF(11)
964
+ sage: Fx.<x> = F[]
965
+ sage: n, k = 10 , 5
966
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
967
+ sage: E = C.encoder("EvaluationPolynomial")
968
+ sage: p = x^2 + 3*x + 10
969
+ sage: c = E.encode(p); c
970
+ (10, 3, 9, 6, 5, 6, 9, 3, 10, 8)
971
+ sage: c in C
972
+ True
973
+
974
+ If a polynomial of too high degree is given, an error is raised::
975
+
976
+ sage: p = x^10
977
+ sage: E.encode(p)
978
+ Traceback (most recent call last):
979
+ ...
980
+ ValueError: The polynomial to encode must have degree at most 4
981
+
982
+ If ``p`` is not an element of the proper polynomial ring, an error is raised::
983
+
984
+ sage: Qy.<y> = QQ[]
985
+ sage: p = y^2 + 1
986
+ sage: E.encode(p)
987
+ Traceback (most recent call last):
988
+ ...
989
+ ValueError: The value to encode must be in
990
+ Univariate Polynomial Ring in x over Finite Field of size 11
991
+
992
+ TESTS:
993
+
994
+ The bug described in :issue:`20744` is now fixed::
995
+
996
+ sage: F = GF(11)
997
+ sage: Fm.<my_variable> = F[]
998
+ sage: n, k = 10 , 5
999
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1000
+ sage: E = C.encoder("EvaluationPolynomial", polynomial_ring = Fm)
1001
+ sage: p = my_variable^2 + 3*my_variable + 10
1002
+ sage: c = E.encode(p)
1003
+ sage: c in C
1004
+ True
1005
+ """
1006
+ M = self.message_space()
1007
+ if p not in M:
1008
+ raise ValueError("The value to encode must be in %s" % M)
1009
+ C = self.code()
1010
+ if p.degree() >= C.dimension():
1011
+ raise ValueError("The polynomial to encode must have degree at most %s" % (C.dimension() - 1))
1012
+ alphas = C.evaluation_points()
1013
+ col_mults = C.column_multipliers()
1014
+ c = vector(C.base_ring(), [col_mults[i]*p(alphas[i]) for i in range(C.length())])
1015
+ return c
1016
+
1017
+ def unencode_nocheck(self, c):
1018
+ r"""
1019
+ Return the message corresponding to the codeword ``c``.
1020
+
1021
+ Use this method with caution: it does not check if ``c``
1022
+ belongs to the code, and if this is not the case, the output is
1023
+ unspecified. Instead, use :meth:`unencode`.
1024
+
1025
+ INPUT:
1026
+
1027
+ - ``c`` -- a codeword of :meth:`code`
1028
+
1029
+ OUTPUT:
1030
+
1031
+ - a polynomial of degree less than ``self.code().dimension()``
1032
+
1033
+ EXAMPLES::
1034
+
1035
+ sage: F = GF(11)
1036
+ sage: n, k = 10 , 5
1037
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1038
+ sage: E = C.encoder("EvaluationPolynomial")
1039
+ sage: c = vector(F, (10, 3, 9, 6, 5, 6, 9, 3, 10, 8))
1040
+ sage: c in C
1041
+ True
1042
+ sage: p = E.unencode_nocheck(c); p
1043
+ x^2 + 3*x + 10
1044
+ sage: E.encode(p) == c
1045
+ True
1046
+
1047
+ Note that no error is thrown if ``c`` is not a codeword, and that the
1048
+ result is undefined::
1049
+
1050
+ sage: c = vector(F, (11, 3, 9, 6, 5, 6, 9, 3, 10, 8))
1051
+ sage: c in C
1052
+ False
1053
+ sage: p = E.unencode_nocheck(c); p
1054
+ 6*x^4 + 6*x^3 + 2*x^2
1055
+ sage: E.encode(p) == c
1056
+ False
1057
+ """
1058
+ C = self.code()
1059
+ alphas = C.evaluation_points()
1060
+ col_mults = C.column_multipliers()
1061
+
1062
+ c = [c[i]/col_mults[i] for i in range(C.length())]
1063
+ points = [(alphas[i], c[i]) for i in range(C.dimension())]
1064
+
1065
+ Pc = self.polynomial_ring().lagrange_polynomial(points)
1066
+ return Pc
1067
+
1068
+ def message_space(self):
1069
+ r"""
1070
+ Return the message space of ``self``.
1071
+
1072
+ EXAMPLES::
1073
+
1074
+ sage: F = GF(11)
1075
+ sage: n, k = 10 , 5
1076
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1077
+ sage: E = C.encoder("EvaluationPolynomial")
1078
+ sage: E.message_space()
1079
+ Univariate Polynomial Ring in x over Finite Field of size 11
1080
+ """
1081
+ return self._polynomial_ring
1082
+
1083
+ polynomial_ring = message_space
1084
+
1085
+
1086
+ # ###################### decoders ###############################
1087
+
1088
+
1089
+ class GRSBerlekampWelchDecoder(Decoder):
1090
+ r"""
1091
+ Decoder for (Generalized) Reed-Solomon codes which uses Berlekamp-Welch
1092
+ decoding algorithm to correct errors in codewords.
1093
+
1094
+ This algorithm recovers the error locator polynomial by solving a
1095
+ linear system. See [HJ2004]_ pp. 51-52 for details.
1096
+
1097
+ INPUT:
1098
+
1099
+ - ``code`` -- a code associated to this decoder
1100
+
1101
+ EXAMPLES::
1102
+
1103
+ sage: F = GF(59)
1104
+ sage: n, k = 40, 12
1105
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1106
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1107
+ sage: D
1108
+ Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1109
+
1110
+ Actually, we can construct the decoder from ``C`` directly::
1111
+
1112
+ sage: D = C.decoder("BerlekampWelch")
1113
+ sage: D
1114
+ Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1115
+ """
1116
+
1117
+ def __init__(self, code):
1118
+ r"""
1119
+ TESTS:
1120
+
1121
+ If ``code`` is not a GRS code, an error is raised::
1122
+
1123
+ sage: C = codes.random_linear_code(GF(11), 10, 4)
1124
+ sage: codes.decoders.GRSBerlekampWelchDecoder(C)
1125
+ Traceback (most recent call last):
1126
+ ...
1127
+ ValueError: code has to be a generalized Reed-Solomon code
1128
+ """
1129
+ if not isinstance(code, GeneralizedReedSolomonCode):
1130
+ raise ValueError("code has to be a generalized Reed-Solomon code")
1131
+ super().__init__(code, code.ambient_space(),
1132
+ "EvaluationPolynomial")
1133
+
1134
+ def __eq__(self, other):
1135
+ r"""
1136
+ Test equality between GRSBerlekampWelchDecoder objects.
1137
+
1138
+ EXAMPLES::
1139
+
1140
+ sage: F = GF(59)
1141
+ sage: n, k = 40, 12
1142
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1143
+ sage: D1 = codes.decoders.GRSBerlekampWelchDecoder(C)
1144
+ sage: D2 = codes.decoders.GRSBerlekampWelchDecoder(C)
1145
+ sage: D1.__eq__(D2)
1146
+ True
1147
+ sage: D1 is D2
1148
+ False
1149
+ """
1150
+ return (isinstance(other, GRSBerlekampWelchDecoder)
1151
+ and self.code() == other.code()
1152
+ and self.input_space() == other.input_space())
1153
+
1154
+ def _repr_(self):
1155
+ r"""
1156
+ Return a string representation of ``self``.
1157
+
1158
+ EXAMPLES::
1159
+
1160
+ sage: F = GF(59)
1161
+ sage: n, k = 40, 12
1162
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1163
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1164
+ sage: D
1165
+ Berlekamp-Welch decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1166
+ """
1167
+ return "Berlekamp-Welch decoder for %s" % self.code()
1168
+
1169
+ def _latex_(self):
1170
+ r"""
1171
+ Return a latex representation of ``self``.
1172
+
1173
+ EXAMPLES::
1174
+
1175
+ sage: F = GF(59)
1176
+ sage: n, k = 40, 12
1177
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1178
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1179
+ sage: latex(D)
1180
+ \textnormal{Berlekamp Welch decoder for }[40, 12, 29]
1181
+ \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
1182
+ """
1183
+ return "\\textnormal{Berlekamp Welch decoder for }%s"\
1184
+ % self.code()._latex_()
1185
+
1186
+ def _decode_to_code_and_message(self, r):
1187
+ r"""
1188
+ Decode ``r`` to an element in message space of ``self`` and its
1189
+ representation in the ambient space of the code associated to ``self``.
1190
+
1191
+ INPUT:
1192
+
1193
+ - ``r`` -- a codeword of ``self``
1194
+
1195
+ OUTPUT:
1196
+
1197
+ - a pair ``(c, f)``, where
1198
+
1199
+ * ``c`` is the representation of ``r`` decoded in the ambient
1200
+ space of the associated code of ``self``
1201
+ * ``f`` its representation in the message space of ``self``
1202
+
1203
+ EXAMPLES::
1204
+
1205
+ sage: F = GF(59)
1206
+ sage: n, k = 40, 12
1207
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1208
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1209
+ sage: c = C.random_element()
1210
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius())
1211
+ sage: y = Chan(c)
1212
+ sage: c_dec, f_dec = D._decode_to_code_and_message(y)
1213
+ sage: f_dec == D.connected_encoder().unencode(c)
1214
+ True
1215
+ sage: c_dec == c
1216
+ True
1217
+ """
1218
+ C = self.code()
1219
+ if r not in C.ambient_space():
1220
+ raise ValueError("The word to decode has to be in the ambient space of the code")
1221
+ n, k = C.length(), C.dimension()
1222
+ if n == k:
1223
+ return r, self.connected_encoder().unencode_nocheck(r)
1224
+ if r in C:
1225
+ return r, self.connected_encoder().unencode_nocheck(r)
1226
+ col_mults = C.column_multipliers()
1227
+
1228
+ r_list = copy(r)
1229
+ r_list = [r[i] / col_mults[i] for i in range(C.length())]
1230
+
1231
+ t = (C.minimum_distance() - 1) // 2
1232
+ l0 = n - 1 - t
1233
+ l1 = n - t - k
1234
+ pts = C.evaluation_points()
1235
+ S = matrix(C.base_field(), n, l0 + l1 + 2,
1236
+ lambda i, j: (pts[i]**j if j < (l0 + 1)
1237
+ else r_list[i] * pts[i]**(j - (l0 + 1))))
1238
+ S = S.right_kernel()
1239
+ S = S.basis_matrix().row(0)
1240
+ R = C.base_field()['x']
1241
+
1242
+ Q0 = R(S.list_from_positions(range(l0 + 1)))
1243
+ Q1 = R(S.list_from_positions(range(l0 + 1, l0 + l1 + 2)))
1244
+
1245
+ f, rem = (-Q0).quo_rem(Q1)
1246
+ if not rem.is_zero():
1247
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1248
+ if f not in R:
1249
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1250
+ c = self.connected_encoder().encode(f)
1251
+ if (c - r).hamming_weight() > self.decoding_radius():
1252
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1253
+ return c, f
1254
+
1255
+ def decode_to_message(self, r):
1256
+ r"""
1257
+ Decode ``r`` to an element in message space of ``self``.
1258
+
1259
+ .. NOTE::
1260
+
1261
+ If the code associated to ``self`` has the same length as its
1262
+ dimension, ``r`` will be unencoded as is. In that case,
1263
+ if ``r`` is not a codeword, the output is unspecified.
1264
+
1265
+ INPUT:
1266
+
1267
+ - ``r`` -- a codeword of ``self``
1268
+
1269
+ OUTPUT: a vector of ``self`` message space
1270
+
1271
+ EXAMPLES::
1272
+
1273
+ sage: F = GF(59)
1274
+ sage: n, k = 40, 12
1275
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1276
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1277
+ sage: c = C.random_element()
1278
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(),
1279
+ ....: D.decoding_radius())
1280
+ sage: y = Chan(c)
1281
+ sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)
1282
+ True
1283
+
1284
+ TESTS:
1285
+
1286
+ If one tries to decode a word which is too far from any codeword, an exception is raised::
1287
+
1288
+ sage: e = vector(F,[0, 0, 54, 23, 1, 0, 0, 0, 53, 21, 0, 0, 0, 34, 6, 11, 0, 0, 16, 0, 0, 0, 9, 0, 10, 27, 35, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 44, 0]); e.hamming_weight()
1289
+ 15
1290
+ sage: D.decode_to_message(c + e)
1291
+ Traceback (most recent call last):
1292
+ ...
1293
+ DecodingError: Decoding failed because the number of errors exceeded the decoding radius
1294
+
1295
+ If one tries to decode something which is not in the ambient space of the code,
1296
+ an exception is raised::
1297
+
1298
+ sage: D.decode_to_message(42)
1299
+ Traceback (most recent call last):
1300
+ ...
1301
+ ValueError: The word to decode has to be in the ambient space of the code
1302
+
1303
+ The bug detailed in :issue:`20340` has been fixed::
1304
+
1305
+ sage: C = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12)
1306
+ sage: c = C.random_element()
1307
+ sage: D = C.decoder("BerlekampWelch")
1308
+ sage: E = D.connected_encoder()
1309
+ sage: m = E.message_space().random_element()
1310
+ sage: c = E.encode(m)
1311
+ sage: D.decode_to_message(c) == m
1312
+ True
1313
+ """
1314
+ return self._decode_to_code_and_message(r)[1]
1315
+
1316
+ def decode_to_code(self, r):
1317
+ r"""
1318
+ Correct the errors in ``r`` and returns a codeword.
1319
+
1320
+ .. NOTE::
1321
+
1322
+ If the code associated to ``self`` has the same length as its
1323
+ dimension, ``r`` will be returned as is.
1324
+
1325
+ INPUT:
1326
+
1327
+ - ``r`` -- a vector of the ambient space of ``self.code()``
1328
+
1329
+ OUTPUT:
1330
+
1331
+ - a vector of ``self.code()``
1332
+
1333
+ EXAMPLES::
1334
+
1335
+ sage: F = GF(59)
1336
+ sage: n, k = 40, 12
1337
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1338
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1339
+ sage: c = C.random_element()
1340
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(),
1341
+ ....: D.decoding_radius())
1342
+ sage: y = Chan(c)
1343
+ sage: c == D.decode_to_code(y)
1344
+ True
1345
+
1346
+ TESTS:
1347
+
1348
+ If one tries to decode a word which is too far from any codeword, an exception is raised::
1349
+
1350
+ sage: e = vector(F,[0, 0, 54, 23, 1, 0, 0, 0, 53, 21, 0, 0, 0, 34, 6, 11, 0, 0, 16, 0, 0, 0, 9, 0, 10, 27, 35, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 44, 0]); e.hamming_weight()
1351
+ 15
1352
+ sage: D.decode_to_code(c + e)
1353
+ Traceback (most recent call last):
1354
+ ...
1355
+ DecodingError: Decoding failed because the number of errors exceeded the decoding radius
1356
+
1357
+ If one tries to decode something which is not in the ambient space of the code,
1358
+ an exception is raised::
1359
+
1360
+ sage: D.decode_to_code(42)
1361
+ Traceback (most recent call last):
1362
+ ...
1363
+ ValueError: The word to decode has to be in the ambient space of the code
1364
+
1365
+ The bug detailed in :issue:`20340` has been fixed::
1366
+
1367
+ sage: C = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12)
1368
+ sage: c = C.random_element()
1369
+ sage: D = C.decoder("BerlekampWelch")
1370
+ sage: D.decode_to_code(c) == c
1371
+ True
1372
+ """
1373
+ return self._decode_to_code_and_message(r)[0]
1374
+
1375
+ def decoding_radius(self):
1376
+ r"""
1377
+ Return maximal number of errors that ``self`` can decode.
1378
+
1379
+ OUTPUT: the number of errors as an integer
1380
+
1381
+ EXAMPLES::
1382
+
1383
+ sage: F = GF(59)
1384
+ sage: n, k = 40, 12
1385
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1386
+ sage: D = codes.decoders.GRSBerlekampWelchDecoder(C)
1387
+ sage: D.decoding_radius()
1388
+ 14
1389
+ """
1390
+ return (self.code().minimum_distance()-1)//2
1391
+
1392
+
1393
+ class GRSGaoDecoder(Decoder):
1394
+ r"""
1395
+ Decoder for (Generalized) Reed-Solomon codes which uses Gao
1396
+ decoding algorithm to correct errors in codewords.
1397
+
1398
+ Gao decoding algorithm uses early terminated extended Euclidean algorithm
1399
+ to find the error locator polynomial. See [Ga02]_ for details.
1400
+
1401
+ INPUT:
1402
+
1403
+ - ``code`` -- the associated code of this decoder
1404
+
1405
+ EXAMPLES::
1406
+
1407
+ sage: F = GF(59)
1408
+ sage: n, k = 40, 12
1409
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1410
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1411
+ sage: D
1412
+ Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1413
+
1414
+ Actually, we can construct the decoder from ``C`` directly::
1415
+
1416
+ sage: D = C.decoder("Gao")
1417
+ sage: D
1418
+ Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1419
+ """
1420
+
1421
+ def __init__(self, code):
1422
+ r"""
1423
+ TESTS:
1424
+
1425
+ If ``code`` is not a GRS code, an error is raised::
1426
+
1427
+ sage: C = codes.random_linear_code(GF(11), 10, 4)
1428
+ sage: codes.decoders.GRSGaoDecoder(C)
1429
+ Traceback (most recent call last):
1430
+ ...
1431
+ ValueError: code has to be a generalized Reed-Solomon code
1432
+ """
1433
+ if not isinstance(code, GeneralizedReedSolomonCode):
1434
+ raise ValueError("code has to be a generalized Reed-Solomon code")
1435
+ super().__init__(code, code.ambient_space(),
1436
+ "EvaluationPolynomial")
1437
+
1438
+ def __eq__(self, other):
1439
+ r"""
1440
+ Test equality of GRSGaoDecoder objects.
1441
+
1442
+ EXAMPLES::
1443
+
1444
+ sage: F = GF(59)
1445
+ sage: n, k = 40, 12
1446
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1447
+ sage: D1 = codes.decoders.GRSGaoDecoder(C)
1448
+ sage: D2 = codes.decoders.GRSGaoDecoder(C)
1449
+ sage: D1 == D2
1450
+ True
1451
+ sage: D1 is D2
1452
+ False
1453
+ """
1454
+ return (isinstance(other, GRSGaoDecoder)
1455
+ and self.code() == other.code()
1456
+ and self.input_space() == other.input_space())
1457
+
1458
+ def __hash__(self):
1459
+ """
1460
+ Return the hash of ``self``.
1461
+
1462
+ EXAMPLES::
1463
+
1464
+ sage: F = GF(59)
1465
+ sage: n, k = 40, 12
1466
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1467
+ sage: D1 = codes.decoders.GRSGaoDecoder(C)
1468
+ sage: D2 = codes.decoders.GRSGaoDecoder(C)
1469
+ sage: hash(D1) == hash(D2)
1470
+ True
1471
+ """
1472
+ return hash((self.code(), self.input_space()))
1473
+
1474
+ def _repr_(self):
1475
+ r"""
1476
+ Return a string representation of ``self``.
1477
+
1478
+ EXAMPLES::
1479
+
1480
+ sage: F = GF(59)
1481
+ sage: n, k = 40, 12
1482
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1483
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1484
+ sage: D
1485
+ Gao decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1486
+ """
1487
+ return "Gao decoder for %s" % self.code()
1488
+
1489
+ def _latex_(self):
1490
+ r"""
1491
+ Return a latex representation of ``self``.
1492
+
1493
+ EXAMPLES::
1494
+
1495
+ sage: F = GF(59)
1496
+ sage: n, k = 40, 12
1497
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1498
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1499
+ sage: latex(D)
1500
+ \textnormal{Gao decoder for }[40, 12, 29]
1501
+ \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
1502
+ """
1503
+ return "\\textnormal{Gao decoder for }%s" % self.code()._latex_()
1504
+
1505
+ @cached_method
1506
+ def _polynomial_vanishing_at_alphas(self, PolRing):
1507
+ r"""
1508
+ Return the unique minimal-degree polynomial vanishing at all
1509
+ the evaluation points.
1510
+
1511
+ INPUT:
1512
+
1513
+ - ``PolRing`` -- polynomial ring of the output
1514
+
1515
+ OUTPUT: a polynomial over ``PolRing``
1516
+
1517
+ EXAMPLES::
1518
+
1519
+ sage: F = GF(11)
1520
+ sage: n, k = 10, 5
1521
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1522
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1523
+ sage: P = PolynomialRing(F,'x')
1524
+ sage: D._polynomial_vanishing_at_alphas(P)
1525
+ x^10 + 10*x^9 + x^8 + 10*x^7 + x^6 + 10*x^5 + x^4 + 10*x^3 + x^2 + 10*x
1526
+ """
1527
+ G = PolRing.one()
1528
+ x = PolRing.gen()
1529
+ for i in range(self.code().length()):
1530
+ G = G*(x-self.code().evaluation_points()[i])
1531
+ return G
1532
+
1533
+ def _partial_xgcd(self, a, b, PolRing):
1534
+ r"""
1535
+ Perform a Euclidean algorithm on ``a`` and ``b`` until a remainder
1536
+ has degree less than `\frac{n+k}{2}`, `n` being the dimension of the
1537
+ code, `k` its dimension, and returns `(r, s)` such that in the step
1538
+ just before termination, `r = a s + b t`.
1539
+
1540
+ INPUT:
1541
+
1542
+ - ``a``, ``b`` -- polynomials over ``PolRing``
1543
+
1544
+ - ``PolRing`` -- polynomial ring of the output
1545
+
1546
+ OUTPUT: tuple of polynomials
1547
+
1548
+ EXAMPLES::
1549
+
1550
+ sage: F = GF(11)
1551
+ sage: n, k = 10, 5
1552
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1553
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1554
+ sage: P = PolynomialRing(F,'x')
1555
+ sage: x = P.parameter()
1556
+ sage: a = 5*x^2 + 9*x + 8
1557
+ sage: b = 10*x^2 + 3*x + 5
1558
+ sage: D._partial_xgcd(a, b, P)
1559
+ (10*x^2 + 3*x + 5, 1)
1560
+ """
1561
+ stop = (self.code().dimension() + self.code().length()) // 2
1562
+ s = PolRing.one()
1563
+ prev_s = PolRing.zero()
1564
+
1565
+ r = b
1566
+ prev_r = a
1567
+ while r.degree() >= stop:
1568
+ q = prev_r.quo_rem(r)[0]
1569
+ (prev_r, r) = (r, prev_r - q * r)
1570
+ (prev_s, s) = (s, prev_s - q * s)
1571
+
1572
+ return (r, s)
1573
+
1574
+ def _decode_to_code_and_message(self, r):
1575
+ r"""
1576
+ Decode ``r`` to an element in message space of ``self`` and its
1577
+ representation in the ambient space of the code associated to ``self``.
1578
+
1579
+ INPUT:
1580
+
1581
+ - ``r`` -- a codeword of ``self``
1582
+
1583
+ OUTPUT:
1584
+
1585
+ - ``(c, h)`` -- ``c`` is the representation of ``r`` decoded in the ambient
1586
+ space of the associated code of ``self``, ``h`` its representation in
1587
+ the message space of ``self``.
1588
+
1589
+ EXAMPLES::
1590
+
1591
+ sage: F = GF(59)
1592
+ sage: n, k = 40, 12
1593
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1594
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1595
+ sage: c = C.random_element()
1596
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius())
1597
+ sage: y = Chan(c)
1598
+ sage: c_dec, h_dec = D._decode_to_code_and_message(y)
1599
+ sage: h_dec == D.connected_encoder().unencode(c)
1600
+ True
1601
+ sage: c_dec == c
1602
+ True
1603
+ """
1604
+ C = self.code()
1605
+ if r not in C.ambient_space():
1606
+ raise ValueError("The word to decode has to be in the ambient space of the code")
1607
+ alphas = C.evaluation_points()
1608
+ col_mults = C.column_multipliers()
1609
+ PolRing = C.base_field()['x']
1610
+ G = self._polynomial_vanishing_at_alphas(PolRing)
1611
+ n = C.length()
1612
+
1613
+ if n == C.dimension() or r in C:
1614
+ return r, self.connected_encoder().unencode_nocheck(r)
1615
+
1616
+ points = [(alphas[i], r[i]/col_mults[i]) for i in range(n)]
1617
+ R = PolRing.lagrange_polynomial(points)
1618
+
1619
+ Q1, Q0 = self._partial_xgcd(G, R, PolRing)
1620
+
1621
+ h, rem = Q1.quo_rem(Q0)
1622
+ if not rem.is_zero():
1623
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1624
+ if h not in PolRing:
1625
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1626
+ c = self.connected_encoder().encode(h)
1627
+ if (c - r).hamming_weight() > self.decoding_radius():
1628
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
1629
+ return c, h
1630
+
1631
+ def decode_to_message(self, r):
1632
+ r"""
1633
+ Decode ``r`` to an element in message space of ``self``.
1634
+
1635
+ .. NOTE::
1636
+
1637
+ If the code associated to ``self`` has the same length as its
1638
+ dimension, ``r`` will be unencoded as is. In that case,
1639
+ if ``r`` is not a codeword, the output is unspecified.
1640
+
1641
+ INPUT:
1642
+
1643
+ - ``r`` -- a codeword of ``self``
1644
+
1645
+ OUTPUT: a vector of ``self`` message space
1646
+
1647
+ EXAMPLES::
1648
+
1649
+ sage: F = GF(59)
1650
+ sage: n, k = 40, 12
1651
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1652
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1653
+ sage: c = C.random_element()
1654
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(),
1655
+ ....: D.decoding_radius())
1656
+ sage: y = Chan(c)
1657
+ sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)
1658
+ True
1659
+
1660
+ TESTS:
1661
+
1662
+ If one tries to decode a word which is too far from any codeword, an exception is raised::
1663
+
1664
+ sage: e = vector(F,[0, 0, 54, 23, 1, 0, 0, 0, 53, 21, 0, 0, 0, 34, 6, 11, 0, 0, 16, 0, 0, 0, 9, 0, 10, 27, 35, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 44, 0]); e.hamming_weight()
1665
+ 15
1666
+ sage: D.decode_to_message(c + e)
1667
+ Traceback (most recent call last):
1668
+ ...
1669
+ DecodingError: Decoding failed because the number of errors exceeded the decoding radius
1670
+
1671
+ If one tries to decode something which is not in the ambient space of the code,
1672
+ an exception is raised::
1673
+
1674
+ sage: D.decode_to_message(42)
1675
+ Traceback (most recent call last):
1676
+ ...
1677
+ ValueError: The word to decode has to be in the ambient space of the code
1678
+
1679
+ The bug detailed in :issue:`20340` has been fixed::
1680
+
1681
+ sage: C = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12)
1682
+ sage: c = C.random_element()
1683
+ sage: D = C.decoder("Gao")
1684
+ sage: E = D.connected_encoder()
1685
+ sage: m = E.message_space().random_element()
1686
+ sage: c = E.encode(m)
1687
+ sage: D.decode_to_message(c) == m
1688
+ True
1689
+ """
1690
+ return self._decode_to_code_and_message(r)[1]
1691
+
1692
+ def decode_to_code(self, r):
1693
+ r"""
1694
+ Correct the errors in ``r`` and returns a codeword.
1695
+
1696
+ .. NOTE::
1697
+
1698
+ If the code associated to ``self`` has the same length as its
1699
+ dimension, ``r`` will be returned as is.
1700
+
1701
+ INPUT:
1702
+
1703
+ - ``r`` -- a vector of the ambient space of ``self.code()``
1704
+
1705
+ OUTPUT:
1706
+
1707
+ - a vector of ``self.code()``
1708
+
1709
+ EXAMPLES::
1710
+
1711
+ sage: F = GF(59)
1712
+ sage: n, k = 40, 12
1713
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1714
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1715
+ sage: c = C.random_element()
1716
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(),
1717
+ ....: D.decoding_radius())
1718
+ sage: y = Chan(c)
1719
+ sage: c == D.decode_to_code(y)
1720
+ True
1721
+
1722
+ TESTS:
1723
+
1724
+
1725
+ If one tries to decode a word which is too far from any codeword, an exception is raised::
1726
+
1727
+ sage: e = vector(F,[0, 0, 54, 23, 1, 0, 0, 0, 53, 21, 0, 0, 0, 34, 6, 11, 0, 0, 16, 0, 0, 0, 9, 0, 10, 27, 35, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 44, 0]); e.hamming_weight()
1728
+ 15
1729
+ sage: D.decode_to_code(c + e)
1730
+ Traceback (most recent call last):
1731
+ ...
1732
+ DecodingError: Decoding failed because the number of errors exceeded the decoding radius
1733
+
1734
+ If one tries to decode something which is not in the ambient space of the code,
1735
+ an exception is raised::
1736
+
1737
+ sage: D.decode_to_code(42)
1738
+ Traceback (most recent call last):
1739
+ ...
1740
+ ValueError: The word to decode has to be in the ambient space of the code
1741
+
1742
+ The bug detailed in :issue:`20340` has been fixed::
1743
+
1744
+ sage: C = codes.GeneralizedReedSolomonCode(GF(59).list()[:40], 12)
1745
+ sage: c = C.random_element()
1746
+ sage: D = C.decoder("Gao")
1747
+ sage: c = C.random_element()
1748
+ sage: D.decode_to_code(c) == c
1749
+ True
1750
+ """
1751
+ return self._decode_to_code_and_message(r)[0]
1752
+
1753
+ def decoding_radius(self):
1754
+ r"""
1755
+ Return maximal number of errors that ``self`` can decode.
1756
+
1757
+ OUTPUT: the number of errors as an integer
1758
+
1759
+ EXAMPLES::
1760
+
1761
+ sage: F = GF(59)
1762
+ sage: n, k = 40, 12
1763
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1764
+ sage: D = codes.decoders.GRSGaoDecoder(C)
1765
+ sage: D.decoding_radius()
1766
+ 14
1767
+ """
1768
+ return (self.code().minimum_distance() - 1) // 2
1769
+
1770
+
1771
+ class GRSErrorErasureDecoder(Decoder):
1772
+ r"""
1773
+ Decoder for (Generalized) Reed-Solomon codes which is able to correct both
1774
+ errors and erasures in codewords.
1775
+
1776
+ Let `C` be a GRS code of length `n` and dimension `k`.
1777
+ Considering `y` a codeword with at most `t` errors
1778
+ (`t` being the `\left\lfloor \frac{d-1}{2} \right\rfloor`
1779
+ decoding radius), and `e` the erasure vector,
1780
+ this decoder works as follows:
1781
+
1782
+ - Puncture the erased coordinates which are identified in `e`.
1783
+ - Create a new GRS code of length `n - w(e)`, where `w` is
1784
+ the Hamming weight function, and dimension `k`.
1785
+ - Use Gao decoder over this new code one the punctured word built on
1786
+ the first step.
1787
+ - Recover the original message from the decoded word computed on the
1788
+ previous step.
1789
+ - Encode this message using an encoder over `C`.
1790
+
1791
+ INPUT:
1792
+
1793
+ - ``code`` -- the associated code of this decoder
1794
+
1795
+ EXAMPLES::
1796
+
1797
+ sage: F = GF(59)
1798
+ sage: n, k = 40, 12
1799
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1800
+ sage: D = codes.decoders.GRSErrorErasureDecoder(C)
1801
+ sage: D
1802
+ Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1803
+
1804
+ Actually, we can construct the decoder from ``C`` directly::
1805
+
1806
+ sage: D = C.decoder("ErrorErasure")
1807
+ sage: D
1808
+ Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1809
+ """
1810
+
1811
+ def __init__(self, code):
1812
+ r"""
1813
+ TESTS:
1814
+
1815
+ If ``code`` is not a GRS code, an error is raised::
1816
+
1817
+ sage: C = codes.random_linear_code(GF(11), 10, 4)
1818
+ sage: codes.decoders.GRSErrorErasureDecoder(C)
1819
+ Traceback (most recent call last):
1820
+ ...
1821
+ ValueError: code has to be a generalized Reed-Solomon code
1822
+ """
1823
+ if not isinstance(code, GeneralizedReedSolomonCode):
1824
+ raise ValueError("code has to be a generalized Reed-Solomon code")
1825
+ input_space = cartesian_product([code.ambient_space(),
1826
+ VectorSpace(GF(2), code.ambient_space().dimension())])
1827
+ super().__init__(code, input_space, "EvaluationVector")
1828
+
1829
+ def __eq__(self, other):
1830
+ r"""
1831
+ Test equality of GRSErrorErasureDecoder objects.
1832
+
1833
+ EXAMPLES::
1834
+
1835
+ sage: F = GF(59)
1836
+ sage: n, k = 40, 12
1837
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1838
+ sage: D1 = codes.decoders.GRSErrorErasureDecoder(C)
1839
+ sage: D2 = codes.decoders.GRSErrorErasureDecoder(C)
1840
+ sage: D1.__eq__(D2)
1841
+ True
1842
+ sage: D1 is D2
1843
+ False
1844
+ """
1845
+ return isinstance(other, GRSErrorErasureDecoder) \
1846
+ and self.code() == other.code()
1847
+
1848
+ def _repr_(self) -> str:
1849
+ r"""
1850
+ Return a string representation of ``self``.
1851
+
1852
+ EXAMPLES::
1853
+
1854
+ sage: F = GF(59)
1855
+ sage: n, k = 40, 12
1856
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1857
+ sage: D = codes.decoders.GRSErrorErasureDecoder(C)
1858
+ sage: D
1859
+ Error-Erasure decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
1860
+ """
1861
+ return "Error-Erasure decoder for %s" % self.code()
1862
+
1863
+ def _latex_(self):
1864
+ r"""
1865
+ Return a latex representation of ``self``.
1866
+
1867
+ EXAMPLES::
1868
+
1869
+ sage: F = GF(59)
1870
+ sage: n, k = 40, 12
1871
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1872
+ sage: D = codes.decoders.GRSErrorErasureDecoder(C)
1873
+ sage: latex(D)
1874
+ \textnormal{Error-Erasure decoder for }[40, 12, 29]
1875
+ \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
1876
+ """
1877
+ return "\\textnormal{Error-Erasure decoder for }%s"\
1878
+ % self.code()._latex_()
1879
+
1880
+ def decode_to_message(self, word_and_erasure_vector):
1881
+ r"""
1882
+ Decode ``word_and_erasure_vector`` to an element in message space
1883
+ of ``self``
1884
+
1885
+ INPUT:
1886
+
1887
+ - ``word_and_erasure_vector`` -- tuple whose:
1888
+
1889
+ * first element is an element of the ambient space of the code
1890
+ * second element is a vector over `\GF{2}` whose length is the
1891
+ same as the code's, containing erasure positions
1892
+
1893
+ .. NOTE::
1894
+
1895
+ If the code associated to ``self`` has the same length as its
1896
+ dimension, ``r`` will be unencoded as is.
1897
+ If the number of erasures is exactly `n - k`, where `n` is the
1898
+ length of the code associated to ``self`` and `k` its dimension,
1899
+ ``r`` will be returned as is.
1900
+ In either case, if ``r`` is not a codeword,
1901
+ the output is unspecified.
1902
+
1903
+ OUTPUT: a vector of ``self`` message space
1904
+
1905
+ EXAMPLES::
1906
+
1907
+ sage: F = GF(59)
1908
+ sage: n, k = 40, 12
1909
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1910
+ sage: D = codes.decoders.GRSErrorErasureDecoder(C)
1911
+ sage: c = C.random_element()
1912
+ sage: n_era = randint(0, C.minimum_distance() - 2)
1913
+ sage: Chan = channels.ErrorErasureChannel(C.ambient_space(),
1914
+ ....: D.decoding_radius(n_era), n_era)
1915
+ sage: y = Chan(c)
1916
+ sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)
1917
+ True
1918
+ sage: n_era = C.minimum_distance() - 1
1919
+ sage: Chan = channels.ErrorErasureChannel(C.ambient_space(),
1920
+ ....: D.decoding_radius(n_era), n_era)
1921
+ sage: y = Chan(c)
1922
+ sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)
1923
+ True
1924
+
1925
+ TESTS:
1926
+
1927
+ If one tries to decode a word with too many erasures, it returns
1928
+ an exception::
1929
+
1930
+ sage: Chan = channels.ErrorErasureChannel(C.ambient_space(), 0, C.minimum_distance() + 1)
1931
+ sage: y = Chan(c)
1932
+ sage: D.decode_to_message(y)
1933
+ Traceback (most recent call last):
1934
+ ...
1935
+ DecodingError: Too many erasures in the received word
1936
+
1937
+ If one tries to decode something which is not in the ambient space of the code,
1938
+ an exception is raised::
1939
+
1940
+ sage: D.decode_to_message((42, random_vector(GF(2), C.length())))
1941
+ Traceback (most recent call last):
1942
+ ...
1943
+ ValueError: The word to decode has to be in the ambient space of the code
1944
+
1945
+ If one tries to pass an erasure_vector which is not a vector over GF(2) of the same length as code's,
1946
+ an exception is raised::
1947
+
1948
+ sage: D.decode_to_message((C.random_element(), 42))
1949
+ Traceback (most recent call last):
1950
+ ...
1951
+ ValueError: The erasure vector has to be a vector over GF(2) of the same length as the code
1952
+ """
1953
+ C = self.code()
1954
+ word, erasure_vector = word_and_erasure_vector
1955
+ n, k = C.length(), C.dimension()
1956
+ if word not in C.ambient_space():
1957
+ raise ValueError("The word to decode has to be in the ambient space of the code")
1958
+ if erasure_vector not in VectorSpace(GF(2), n):
1959
+ raise ValueError("The erasure vector has to be a vector over GF(2) of the same length as the code")
1960
+ if erasure_vector.hamming_weight() >= self.code().minimum_distance():
1961
+ raise DecodingError("Too many erasures in the received word")
1962
+
1963
+ punctured_word = vector(self.code().base_ring(),
1964
+ [word[i] for i in range(len(word))
1965
+ if not erasure_vector[i]])
1966
+ C1_length = len(punctured_word)
1967
+ C1_evaluation_points = [self.code().evaluation_points()[i] for i in
1968
+ range(n) if erasure_vector[i] != 1]
1969
+ C1_column_multipliers = [self.code().column_multipliers()[i] for i in
1970
+ range(n) if erasure_vector[i] != 1]
1971
+ C1 = GeneralizedReedSolomonCode(C1_evaluation_points, k,
1972
+ C1_column_multipliers)
1973
+ if C1_length == k:
1974
+ return C1.unencode(punctured_word, nocheck=True)
1975
+ return C1.decode_to_message(punctured_word)
1976
+
1977
+ def decoding_radius(self, number_erasures):
1978
+ r"""
1979
+ Return maximal number of errors that ``self`` can decode according
1980
+ to how many erasures it receives.
1981
+
1982
+ INPUT:
1983
+
1984
+ - ``number_erasures`` -- the number of erasures when we try to decode
1985
+
1986
+ OUTPUT: the number of errors as an integer
1987
+
1988
+ EXAMPLES::
1989
+
1990
+ sage: F = GF(59)
1991
+ sage: n, k = 40, 12
1992
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
1993
+ sage: D = codes.decoders.GRSErrorErasureDecoder(C)
1994
+ sage: D.decoding_radius(5)
1995
+ 11
1996
+
1997
+ If we receive too many erasures, it returns an exception as codeword will
1998
+ be impossible to decode::
1999
+
2000
+ sage: D.decoding_radius(30)
2001
+ Traceback (most recent call last):
2002
+ ...
2003
+ ValueError: The number of erasures exceed decoding capability
2004
+ """
2005
+ diff = self.code().minimum_distance() - 1 - number_erasures
2006
+ if diff < 0:
2007
+ raise ValueError("The number of erasures exceed decoding capability")
2008
+ else:
2009
+ return diff // 2
2010
+
2011
+
2012
+ class GRSKeyEquationSyndromeDecoder(Decoder):
2013
+ r"""
2014
+ Decoder for (Generalized) Reed-Solomon codes which uses a
2015
+ Key equation decoding based on the syndrome polynomial to
2016
+ correct errors in codewords.
2017
+
2018
+ This algorithm uses early terminated extended euclidean algorithm
2019
+ to solve the key equations, as described in [Rot2006]_, pp. 183-195.
2020
+
2021
+ INPUT:
2022
+
2023
+ - ``code`` -- the associated code of this decoder
2024
+
2025
+ EXAMPLES::
2026
+
2027
+ sage: F = GF(59)
2028
+ sage: n, k = 40, 12
2029
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2030
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2031
+ sage: D
2032
+ Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
2033
+
2034
+ Actually, we can construct the decoder from ``C`` directly::
2035
+
2036
+ sage: D = C.decoder("KeyEquationSyndrome")
2037
+ sage: D
2038
+ Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
2039
+ """
2040
+
2041
+ def __init__(self, code):
2042
+ r"""
2043
+ TESTS::
2044
+
2045
+ sage: F = GF(59)
2046
+ sage: n, k = 40, 12
2047
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k)
2048
+ sage: codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2049
+ Traceback (most recent call last):
2050
+ ...
2051
+ ValueError: Impossible to use this decoder over a GRS code which contains 0 amongst its evaluation points
2052
+
2053
+ If ``code`` is not a GRS code, an error is raised::
2054
+
2055
+ sage: C = codes.random_linear_code(GF(11), 10, 4)
2056
+ sage: codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2057
+ Traceback (most recent call last):
2058
+ ...
2059
+ ValueError: code has to be a generalized Reed-Solomon code
2060
+ """
2061
+ if not isinstance(code, GeneralizedReedSolomonCode):
2062
+ raise ValueError("code has to be a generalized Reed-Solomon code")
2063
+ if code.base_field().zero() in code.evaluation_points():
2064
+ raise ValueError("Impossible to use this decoder over a GRS code which contains 0 amongst its evaluation points")
2065
+ super().__init__(code, code.ambient_space(),
2066
+ "EvaluationVector")
2067
+
2068
+ def __eq__(self, other):
2069
+ r"""
2070
+ Test equality of GRSKeyEquationSyndromeDecoder objects.
2071
+
2072
+ EXAMPLES::
2073
+
2074
+ sage: F = GF(59)
2075
+ sage: n, k = 40, 12
2076
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2077
+ sage: D1 = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2078
+ sage: D2 = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2079
+ sage: D1.__eq__(D2)
2080
+ True
2081
+ sage: D1 is D2
2082
+ False
2083
+ """
2084
+ return isinstance(other, GRSKeyEquationSyndromeDecoder) \
2085
+ and self.code() == other.code()\
2086
+ and self.input_space() == other.input_space()
2087
+
2088
+ def _repr_(self):
2089
+ r"""
2090
+ Return a string representation of ``self``.
2091
+
2092
+ EXAMPLES::
2093
+
2094
+ sage: F = GF(59)
2095
+ sage: n, k = 40, 12
2096
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2097
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2098
+ sage: D
2099
+ Key equation decoder for [40, 12, 29] Reed-Solomon Code over GF(59)
2100
+ """
2101
+ return "Key equation decoder for %s" % self.code()
2102
+
2103
+ def _latex_(self):
2104
+ r"""
2105
+ Return a latex representation of ``self``.
2106
+
2107
+ EXAMPLES::
2108
+
2109
+ sage: F = GF(59)
2110
+ sage: n, k = 40, 12
2111
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2112
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2113
+ sage: latex(D)
2114
+ \textnormal{Key equation decoder for }[40, 12, 29]
2115
+ \textnormal{ Reed-Solomon Code over } \Bold{F}_{59}
2116
+ """
2117
+ return "\\textnormal{Key equation decoder for }%s" % self.code()._latex_()
2118
+
2119
+ def _partial_xgcd(self, a, b, PolRing):
2120
+ r"""
2121
+ Perform a Euclidean algorithm on ``a`` and ``b`` until a remainder
2122
+ has degree less than `\frac{n+k}{2}`, `n` being the dimension of the
2123
+ code, `k` its dimension, and returns `(r, t)` such that in the step
2124
+ just before termination, `r = a s + b t`.
2125
+
2126
+ INPUT:
2127
+
2128
+ - ``a``, ``b`` -- polynomials over ``PolRing``
2129
+
2130
+ - ``PolRing`` -- polynomial ring of the output
2131
+
2132
+ OUTPUT: tuple of polynomials
2133
+
2134
+ EXAMPLES::
2135
+
2136
+ sage: F = GF(11)
2137
+ sage: n, k = 10, 5
2138
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2139
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2140
+ sage: P = PolynomialRing(F,'x')
2141
+ sage: x = P.parameter()
2142
+ sage: a = 5*x^2 + 9*x + 8
2143
+ sage: b = 10*x^2 + 3*x + 5
2144
+ sage: D._partial_xgcd(a, b, P)
2145
+ (5, 8*x + 10)
2146
+ """
2147
+ prev_t = PolRing.zero()
2148
+ t = PolRing.one()
2149
+
2150
+ prev_r = a
2151
+ r = b
2152
+
2153
+ while r.degree() >= t.degree():
2154
+ q = prev_r.quo_rem(r)[0]
2155
+ prev_r, r = r, prev_r - q * r
2156
+ prev_t, t = t, prev_t - q * t
2157
+
2158
+ return (r, t)
2159
+
2160
+ def _syndrome(self, r):
2161
+ r"""
2162
+ Return the coefficients of the syndrome polynomial of ``r``.
2163
+
2164
+ INPUT:
2165
+
2166
+ - ``r`` -- a vector of the ambient space of ``self.code()``
2167
+
2168
+ OUTPUT: list
2169
+
2170
+ EXAMPLES::
2171
+
2172
+
2173
+ sage: F = GF(11)
2174
+ sage: n, k = 10, 5
2175
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2176
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2177
+ sage: r = vector(F, (8, 2, 6, 10, 6, 10, 7, 6, 7, 2))
2178
+ sage: D._syndrome(r)
2179
+ [1, 10, 1, 10, 1]
2180
+ """
2181
+ C = self.code()
2182
+ F = C.base_ring()
2183
+ S = []
2184
+ col_mults = C.parity_column_multipliers()
2185
+ alphas = C.evaluation_points()
2186
+
2187
+ for l in range(C.minimum_distance() - 1):
2188
+ Sl = F.zero()
2189
+ for j in range(C.length()):
2190
+ Sl += r[j] * col_mults[j] * (alphas[j] ** l)
2191
+ S.append(Sl)
2192
+
2193
+ return S
2194
+
2195
+ def _forney_formula(self, error_evaluator, error_locator):
2196
+ r"""
2197
+ Return the error vector computed through Forney's formula.
2198
+
2199
+ INPUT:
2200
+
2201
+ - ``error_evaluator``, ``error_locator`` -- two polynomials
2202
+
2203
+ OUTPUT: a vector
2204
+
2205
+ EXAMPLES::
2206
+
2207
+ sage: F = GF(11)
2208
+ sage: n, k = 10, 5
2209
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2210
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2211
+ sage: R.<x> = F[]
2212
+ sage: evaluator, locator = R(10), R([10, 10])
2213
+ sage: D._forney_formula(evaluator, locator)
2214
+ (0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
2215
+ """
2216
+ C = self.code()
2217
+ alphas = C.evaluation_points()
2218
+ col_mults = C.parity_column_multipliers()
2219
+ ELPp = error_locator.derivative()
2220
+ F = C.base_ring()
2221
+ zero, one = F.zero(), F.one()
2222
+ e = []
2223
+
2224
+ for i in range(C.length()):
2225
+ alpha_inv = one/alphas[i]
2226
+ if error_locator(alpha_inv) == zero:
2227
+ e.append(-alphas[i]/col_mults[i] * error_evaluator(alpha_inv)/ELPp(alpha_inv))
2228
+ else:
2229
+ e.append(zero)
2230
+
2231
+ return vector(F, e)
2232
+
2233
+ def decode_to_code(self, r):
2234
+ r"""
2235
+ Correct the errors in ``r`` and returns a codeword.
2236
+
2237
+ .. NOTE::
2238
+
2239
+ If the code associated to ``self`` has the same length as its
2240
+ dimension, ``r`` will be returned as is.
2241
+
2242
+ INPUT:
2243
+
2244
+ - ``r`` -- a vector of the ambient space of ``self.code()``
2245
+
2246
+ OUTPUT:
2247
+
2248
+ - a vector of ``self.code()``
2249
+
2250
+ EXAMPLES::
2251
+
2252
+ sage: F = GF(59)
2253
+ sage: n, k = 40, 12
2254
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2255
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2256
+ sage: c = C.random_element()
2257
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(),
2258
+ ....: D.decoding_radius())
2259
+ sage: y = Chan(c)
2260
+ sage: c == D.decode_to_code(y)
2261
+ True
2262
+
2263
+ TESTS:
2264
+
2265
+ If one tries to decode a word with too many errors, it returns
2266
+ an exception::
2267
+
2268
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()+1)
2269
+ sage: while True:
2270
+ ....: try:
2271
+ ....: y = Chan(c)
2272
+ ....: D.decode_to_message(y)
2273
+ ....: except ZeroDivisionError:
2274
+ ....: pass
2275
+ Traceback (most recent call last):
2276
+ ...
2277
+ DecodingError: Decoding failed because the number of errors exceeded the decoding radius
2278
+
2279
+ If one tries to decode something which is not in the ambient space of the code,
2280
+ an exception is raised::
2281
+
2282
+ sage: D.decode_to_code(42)
2283
+ Traceback (most recent call last):
2284
+ ...
2285
+ ValueError: The word to decode has to be in the ambient space of the code
2286
+ """
2287
+ C = self.code()
2288
+ if r not in C.ambient_space():
2289
+ raise ValueError("The word to decode has to be in the ambient space of the code")
2290
+ PolRing = C.base_field()['x']
2291
+ x = PolRing.gen()
2292
+
2293
+ if C.length() == C.dimension() or r in C:
2294
+ return r
2295
+
2296
+ S = PolRing(self._syndrome(r))
2297
+ a = x ** (C.minimum_distance() - 1)
2298
+
2299
+ (EEP, ELP) = self._partial_xgcd(a, S, PolRing)
2300
+
2301
+ e = self._forney_formula(EEP, ELP)
2302
+ dec = r - e
2303
+ if dec not in C:
2304
+ raise DecodingError("Decoding failed because the number of errors exceeded the decoding radius")
2305
+ return dec
2306
+
2307
+ def decode_to_message(self, r):
2308
+ r"""
2309
+ Decode ``r`` to an element in message space of ``self``.
2310
+
2311
+ .. NOTE::
2312
+
2313
+ If the code associated to ``self`` has the same length as its
2314
+ dimension, ``r`` will be unencoded as is. In that case,
2315
+ if ``r`` is not a codeword, the output is unspecified.
2316
+
2317
+ INPUT:
2318
+
2319
+ - ``r`` -- a codeword of ``self``
2320
+
2321
+ OUTPUT: a vector of ``self`` message space
2322
+
2323
+ EXAMPLES::
2324
+
2325
+ sage: F = GF(59)
2326
+ sage: n, k = 40, 12
2327
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2328
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2329
+ sage: c = C.random_element()
2330
+ sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(),
2331
+ ....: D.decoding_radius())
2332
+ sage: y = Chan(c)
2333
+ sage: D.connected_encoder().unencode(c) == D.decode_to_message(y)
2334
+ True
2335
+ """
2336
+ C = self.code()
2337
+ if C.length() == C.dimension():
2338
+ return self.connected_encoder().unencode_nocheck(r)
2339
+ return super().decode_to_message(r)
2340
+
2341
+ def decoding_radius(self):
2342
+ r"""
2343
+ Return maximal number of errors that ``self`` can decode.
2344
+
2345
+ OUTPUT: the number of errors as an integer
2346
+
2347
+ EXAMPLES::
2348
+
2349
+ sage: F = GF(59)
2350
+ sage: n, k = 40, 12
2351
+ sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k)
2352
+ sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C)
2353
+ sage: D.decoding_radius()
2354
+ 14
2355
+ """
2356
+ return (self.code().minimum_distance() - 1) // 2
2357
+
2358
+
2359
+ # ###################### registration ###############################
2360
+
2361
+ GeneralizedReedSolomonCode._registered_encoders["EvaluationVector"] = GRSEvaluationVectorEncoder
2362
+ GeneralizedReedSolomonCode._registered_encoders["EvaluationPolynomial"] = GRSEvaluationPolynomialEncoder
2363
+
2364
+ GeneralizedReedSolomonCode._registered_decoders["BerlekampWelch"] = GRSBerlekampWelchDecoder
2365
+ GRSBerlekampWelchDecoder._decoder_type = {"hard-decision", "always-succeed"}
2366
+ GeneralizedReedSolomonCode._registered_decoders["Gao"] = GRSGaoDecoder
2367
+ GRSGaoDecoder._decoder_type = {"hard-decision", "always-succeed"}
2368
+ GeneralizedReedSolomonCode._registered_decoders["ErrorErasure"] = GRSErrorErasureDecoder
2369
+ GRSErrorErasureDecoder._decoder_type = {"error-erasure", "always-succeed"}
2370
+ GeneralizedReedSolomonCode._registered_decoders["KeyEquationSyndrome"] = GRSKeyEquationSyndromeDecoder
2371
+ GRSKeyEquationSyndromeDecoder._decoder_type = {"hard-decision", "always-succeed"}