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,2208 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ # sage.doctest: needs sage.rings.finite_rings
3
+ r"""
4
+ Ore modules
5
+
6
+ Let `R` be a commutative ring, `\theta : K \to K` by a ring
7
+ endomorphism and `\partial : K \to K` be a `\theta`-derivation,
8
+ that is an additive map satisfying the following axiom
9
+
10
+ .. MATH::
11
+
12
+ \partial(x y) = \theta(x) \partial(y) + \partial(x) y
13
+
14
+ A Ore module over `(R, \theta, \partial)` is a `R`-module `M`
15
+ equipped with a additive `f : M \to M` such that
16
+
17
+ .. MATH::
18
+
19
+ f(a x) = \theta(a) f(x) + \partial(a) x
20
+
21
+ Such a map `f` is called a pseudomorphism.
22
+
23
+ Equivalently, a Ore module is a module over the (noncommutative)
24
+ Ore polynomial ring `\mathcal S = R[X; \theta, \partial]`.
25
+
26
+ .. RUBRIC:: Defining Ore modules
27
+
28
+ SageMath provides support for creating and manipulating Ore
29
+ modules that are finite free over the base ring `R`.
30
+
31
+ To start with, the method
32
+ :meth:`sage.rings.polynomial.ore_polynomial_ring.OrePolynomialRing.quotient_module`
33
+ creates the quotient `\mathcal S/ \mathcal S P`, endowed with its structure
34
+ of `\mathcal S`-module, that is its structure of Ore module::
35
+
36
+ sage: K.<z> = GF(5^3)
37
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
38
+ sage: M = S.quotient_module(X^2 + z)
39
+ sage: M
40
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
41
+
42
+ Classical methods are available and we can work with elements in
43
+ `M` as we do usually for vectors in finite free modules::
44
+
45
+ sage: M.basis()
46
+ [(1, 0), (0, 1)]
47
+
48
+ sage: v = M((z, z^2)); v
49
+ (z, z^2)
50
+ sage: z*v
51
+ (z^2, 2*z + 2)
52
+
53
+ The Ore action (or equivalently the structure of `\mathcal S`-module)
54
+ is also easily accessible::
55
+
56
+ sage: X*v
57
+ (3*z^2 + 2*z, 2*z^2 + 4*z + 4)
58
+
59
+ The method :meth:`sage.modules.ore_module.OreModule.pseudohom`
60
+ returns the map `f` defining the action of `X`::
61
+
62
+ sage: M.pseudohom()
63
+ Free module pseudomorphism (twisted by z |--> z^5) defined by the matrix
64
+ [ 0 1]
65
+ [4*z 0]
66
+ Domain: Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
67
+ Codomain: Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
68
+
69
+ A useful feature is the possibility to give chosen names to the vectors
70
+ of the canonical basis. This is easily done as follows::
71
+
72
+ sage: N.<u,v,w> = S.quotient_module(X^3 + z*X + 1)
73
+ sage: N
74
+ Ore module <u, v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
75
+ sage: N.basis()
76
+ [u, v, w]
77
+
78
+ Alternatively, one can pass in the argument ``names``; this
79
+ could be useful in particular when we want to name the vectors
80
+ basis `e_0, e_1, \ldots`::
81
+
82
+ sage: A = S.quotient_module(X^11 + z, names='e')
83
+ sage: A
84
+ Ore module <e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10> over Finite Field in z of size 5^3 twisted by z |--> z^5
85
+ sage: A.basis()
86
+ [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10]
87
+
88
+ Do not forget to use the method :meth:`inject_variables` to get the
89
+ `e_i` in your namespace::
90
+
91
+ sage: e0
92
+ Traceback (most recent call last):
93
+ ...
94
+ NameError: name 'e0' is not defined
95
+ sage: A.inject_variables()
96
+ Defining e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10
97
+ sage: e0
98
+ e0
99
+
100
+ .. RUBRIC:: Submodules and quotients
101
+
102
+ SageMath provides facilities for creating submodules and quotient
103
+ modules of Ore modules.
104
+ First of all, we define the Ore module `\mathcal S/\mathcal S P^2`
105
+ (for some Ore polynomials `P`), which is obviously not simple::
106
+
107
+ sage: P = X^2 + z*X + 1
108
+ sage: U = S.quotient_module(P^2, names='u')
109
+ sage: U.inject_variables()
110
+ Defining u0, u1, u2, u3
111
+
112
+ We now build the submodule `\mathcal S P / \mathcal S P^2` using
113
+ the method :meth:`sage.modules.ore_module.OreModule.span`::
114
+
115
+ sage: V = U.span(P*u0)
116
+ sage: V
117
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
118
+ sage: V.basis()
119
+ [u0 + (z^2+2*z+2)*u2 + 4*z*u3,
120
+ u1 + (2*z^2+4*z+4)*u2 + u3]
121
+
122
+ We underline that the span is really the `\mathcal S`-span and
123
+ not the `R`-span (as otherwise, it will not be a Ore module).
124
+
125
+ As before, one can use the attributes ``names`` to give explicit
126
+ names to the basis vectors::
127
+
128
+ sage: V = U.span(P*u0, names='v')
129
+ sage: V
130
+ Ore module <v0, v1> over Finite Field in z of size 5^3 twisted by z |--> z^5
131
+ sage: V.inject_variables()
132
+ Defining v0, v1
133
+ sage: v0
134
+ v0
135
+ sage: U(v0)
136
+ u0 + (z^2+2*z+2)*u2 + 4*z*u3
137
+
138
+ A coercion map from `V` to `U` is automatically created.
139
+ Hence, we can safely combine vectors in `V` and vectors in `U` in a
140
+ single expression::
141
+
142
+ sage: v0 - u0
143
+ (z^2+2*z+2)*u2 + 4*z*u3
144
+
145
+ We can create the quotient `U/V` using a similar syntax::
146
+
147
+ sage: W = U.quo(P*u0)
148
+ sage: W
149
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
150
+ sage: W.basis()
151
+ [u2, u3]
152
+
153
+ We see that SageMath reuses by default the names of the representatives
154
+ to denote the vectors in the quotient `U/V`. This behaviour can be
155
+ overridden by providing explicit names using the attributes ``names``.
156
+
157
+ Shortcuts for creating quotients are also available::
158
+
159
+ sage: U / (P*u0)
160
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
161
+ sage: U/V
162
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
163
+
164
+ .. RUBRIC:: Morphisms of Ore modules
165
+
166
+ For a tutorial on morphisms of Ore modules, we refer to
167
+ :mod:`sage.modules.ore_module_morphism`.
168
+
169
+ AUTHOR:
170
+
171
+ - Xavier Caruso (2024-10)
172
+ """
173
+
174
+ # ***************************************************************************
175
+ # Copyright (C) 2024 Xavier Caruso <xavier.caruso@normalesup.org>
176
+ #
177
+ # This program is free software: you can redistribute it and/or modify
178
+ # it under the terms of the GNU General Public License as published by
179
+ # the Free Software Foundation, either version 2 of the License, or
180
+ # (at your option) any later version.
181
+ # https://www.gnu.org/licenses/
182
+ # ***************************************************************************
183
+
184
+ import operator
185
+
186
+ from sage.misc.latex import latex
187
+ from sage.misc.latex import latex_variable_name
188
+ from sage.structure.sequence import Sequence
189
+ from sage.structure.unique_representation import UniqueRepresentation
190
+
191
+ from sage.categories.action import Action
192
+ from sage.categories.fields import Fields
193
+ from sage.categories.ore_modules import OreModules
194
+
195
+ from sage.matrix.matrix0 import Matrix
196
+ from sage.matrix.constructor import matrix
197
+ from sage.matrix.special import identity_matrix
198
+
199
+ from sage.rings.polynomial.ore_polynomial_element import OrePolynomial
200
+ from sage.modules.free_module import FreeModule_ambient
201
+ from sage.modules.free_module_element import FreeModuleElement_generic_dense
202
+ from sage.modules.ore_module_element import OreModuleElement
203
+
204
+ # Action by left multiplication on Ore modules
205
+ ##############################################
206
+
207
+
208
+ class ScalarAction(Action):
209
+ r"""
210
+ Action by scalar multiplication on Ore modules.
211
+ """
212
+ def _act_(self, a, x):
213
+ r"""
214
+ Return the result of the action of `a` on `x`.
215
+
216
+ INPUT:
217
+
218
+ - ``a`` -- a scalar in the base ring
219
+
220
+ - ``x`` -- a vector in a Ore module
221
+
222
+ EXAMPLES::
223
+
224
+ sage: K.<z> = GF(5^3)
225
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
226
+ sage: M.<e0,e1> = S.quotient_module(X^2 + z) # indirect doctest
227
+ sage: z*e0 # indirect doctest
228
+ z*e0
229
+ """
230
+ return x._rmul_(a)
231
+
232
+
233
+ class OreAction(Action):
234
+ r"""
235
+ Action by left multiplication of Ore polynomial rings
236
+ over Ore modules.
237
+ """
238
+ def _act_(self, P, x):
239
+ r"""
240
+ Return the result of the action of `P` on `x`.
241
+
242
+ INPUT:
243
+
244
+ - ``P`` -- a Ore polynomial
245
+
246
+ - ``x`` -- a vector in a Ore module
247
+
248
+ EXAMPLES::
249
+
250
+ sage: K.<z> = GF(5^3)
251
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
252
+ sage: M.<e0,e1> = S.quotient_module(X^2 + z) # indirect doctest
253
+ sage: X*e0 # indirect doctest
254
+ e1
255
+ """
256
+ ans = P[0]*x
257
+ y = x
258
+ for i in range(1, P.degree() + 1):
259
+ y = y.image()
260
+ ans += y._rmul_(P[i])
261
+ return ans
262
+
263
+ # Generic class for Ore modules
264
+ ###############################
265
+
266
+
267
+ def normalize_names(names, rank):
268
+ r"""
269
+ Return a normalized form of ``names``.
270
+
271
+ INPUT:
272
+
273
+ - ``names`` -- a string, a list of strings or ``None``
274
+
275
+ - ``rank`` -- the number of names to normalize
276
+
277
+ EXAMPLES::
278
+
279
+ sage: from sage.modules.ore_module import normalize_names
280
+
281
+ When ``names`` is a string, indices are added::
282
+
283
+ sage: normalize_names('e', 3)
284
+ ('e0', 'e1', 'e2')
285
+
286
+ When ``names`` is a list or a tuple, it remains untouched
287
+ except that it is always casted to a tuple (in order to be
288
+ hashable and serve as a key)::
289
+
290
+ sage: normalize_names(['u', 'v', 'w'], 3)
291
+ ('u', 'v', 'w')
292
+
293
+ Similarly, when ``names`` is ``None``, nothing is returned::
294
+
295
+ sage: normalize_names(None, 3)
296
+
297
+ If the number of names is not equal to ``rank``, an error
298
+ is raised::
299
+
300
+ sage: normalize_names(['u', 'v', 'w'], 2)
301
+ Traceback (most recent call last):
302
+ ...
303
+ ValueError: the number of given names does not match the rank of the Ore module
304
+ """
305
+ if names is None:
306
+ pass
307
+ elif isinstance(names, (list, tuple)):
308
+ if rank != len(names):
309
+ raise ValueError("the number of given names does not match the rank of the Ore module")
310
+ names = tuple([str(name) for name in names])
311
+ elif isinstance(names, str):
312
+ names = tuple([names + str(i) for i in range(rank)])
313
+ else:
314
+ raise ValueError("names must be a string or a list/tuple of strings")
315
+ return names
316
+
317
+
318
+ class OreModule(UniqueRepresentation, FreeModule_ambient):
319
+ r"""
320
+ Generic class for Ore modules.
321
+ """
322
+ Element = OreModuleElement
323
+
324
+ def __classcall_private__(cls, mat, twist, names=None, category=None):
325
+ r"""
326
+ Normalize the input before passing it to the init function
327
+ (useful to ensure the uniqueness assumption).
328
+
329
+ INPUT:
330
+
331
+ - ``mat`` -- the matrix defining the action of the Ore variable
332
+
333
+ - ``twist`` -- the twisting morphism/derivation
334
+
335
+ - ``names`` (default: ``None``) -- a string of a list of strings,
336
+ the names of the vector of the canonical basis; if ``None``,
337
+ elements are represented as vectors in `K^d`
338
+
339
+ - ``category`` (default: ``None``) -- the category of this
340
+ Ore module
341
+
342
+ TESTS::
343
+
344
+ sage: K.<z> = GF(5^3)
345
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
346
+ sage: P = X^2 + z
347
+
348
+ sage: M1 = S.quotient_module(P)
349
+ sage: M2 = S.quotient_module(P, names='e')
350
+ sage: M3.<e0,e1> = S.quotient_module(P)
351
+
352
+ sage: M1 is M2
353
+ False
354
+ sage: M2 is M3
355
+ True
356
+ """
357
+ base = mat.base_ring()
358
+ if category is None:
359
+ category = OreModules(base, twist)
360
+ rank = mat.nrows()
361
+ if mat.ncols() != rank:
362
+ raise ValueError("matrix must be square")
363
+ names = normalize_names(names, rank)
364
+ return cls.__classcall__(cls, mat, category._ore, names, category)
365
+
366
+ def __init__(self, mat, ore, names, category) -> None:
367
+ r"""
368
+ Initialize this Ore module.
369
+
370
+ INPUT:
371
+
372
+ - ``mat`` -- the matrix defining the action of the Ore variable
373
+
374
+ - ``ore`` -- the underlying Ore polynomial ring
375
+
376
+ - ``names`` -- a string of a list of strings,
377
+ the names of the vector of the canonical basis; if ``None``,
378
+ elements are represented as vectors in `K^d`
379
+
380
+ - ``category`` -- the category of this Ore module
381
+
382
+ TESTS::
383
+
384
+ sage: K.<z> = GF(5^3)
385
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
386
+ sage: M = S.quotient_module(X^2 + z) # indirect doctest
387
+ sage: type(M)
388
+ <class 'sage.modules.ore_module.OreModule_with_category'>
389
+
390
+ sage: TestSuite(M).run()
391
+ """
392
+ base = mat.base_ring()
393
+ rank = mat.nrows()
394
+ FreeModule_ambient.__init__(self, base, rank, category=category)
395
+ self.register_action(ScalarAction(base, self, True, operator.mul))
396
+ self._ore = ore
397
+ self._ore_category = category
398
+ self._names = names
399
+ if names is not None:
400
+ self._latex_names = [latex_variable_name(name) for name in names]
401
+ self._submodule_class = OreSubmodule
402
+ self._quotientModule_class = OreQuotientModule
403
+ self._pseudohom = FreeModule_ambient.pseudohom(self, mat, ore, codomain=self)
404
+
405
+ def _repr_(self) -> str:
406
+ r"""
407
+ Return a string representation of this Ore module.
408
+
409
+ TESTS::
410
+
411
+ sage: K.<z> = GF(5^3)
412
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
413
+ sage: M = S.quotient_module(X^2 + z)
414
+ sage: M._repr_()
415
+ 'Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5'
416
+ sage: N = S.quotient_module(X^2 + z, names='e')
417
+ sage: N._repr_()
418
+ 'Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5'
419
+
420
+ ::
421
+
422
+ sage: K.<z> = Frac(GF(17)['z'])
423
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
424
+ sage: M = S.quotient_module(X^2 + z)
425
+ sage: M._repr_()
426
+ 'Ore module of rank 2 over Fraction Field of Univariate Polynomial Ring in z over Finite Field of size 17 twisted by d/dz'
427
+ """
428
+ s = "Ore module "
429
+ if self._names is None:
430
+ s += "of rank %s " % self.rank()
431
+ else:
432
+ s += "<" + ", ".join(self._names) + "> "
433
+ s += "over %s %s" % (self.base_ring(), self._ore._repr_twist())
434
+ return s
435
+
436
+ def _latex_(self) -> str:
437
+ r"""
438
+ Return a LaTeX representation of this Ore module.
439
+
440
+ TESTS::
441
+
442
+ sage: K.<z> = GF(5^3)
443
+ sage: Frob = K.frobenius_endomorphism()
444
+ sage: S.<X> = OrePolynomialRing(K, Frob)
445
+ sage: M = S.quotient_module(X^2 + z)
446
+ sage: latex(M)
447
+ \texttt{Ore module of rank } 2\texttt{ over } \Bold{F}_{5^{3}} \texttt{ twisted by } z \mapsto z^{5}
448
+ sage: N = S.quotient_module(X^2 + z, names='e')
449
+ sage: latex(N)
450
+ \left<e_{0}, e_{1}\right>_{\Bold{F}_{5^{3}} , z \mapsto z^{5} }
451
+
452
+ ::
453
+
454
+ sage: T.<Y> = OrePolynomialRing(K, Frob^3, polcast=False)
455
+ sage: M = T.quotient_module(Y^2 + z^2)
456
+ sage: latex(M)
457
+ \texttt{Ore module of rank } 2\texttt{ over } \Bold{F}_{5^{3}}\texttt{ untwisted}
458
+ """
459
+ if self._names is None:
460
+ s = "\\texttt{Ore module of rank } %s" % self.rank()
461
+ s += "\\texttt{ over } %s" % latex(self.base_ring())
462
+ twist = self._ore._latex_twist()
463
+ if twist == "":
464
+ s += "\\texttt{ untwisted}"
465
+ else:
466
+ s += "\\texttt{ twisted by }" + twist
467
+ else:
468
+ s = "\\left<" + ", ".join(self._latex_names) + "\\right>"
469
+ s += "_{%s" % latex(self.base_ring())
470
+ twist = self._ore._latex_twist()
471
+ if twist != "":
472
+ s += "," + twist
473
+ s += "}"
474
+ return s
475
+
476
+ def _repr_element(self, x) -> str:
477
+ r"""
478
+ Return a string representation of the element `x` in
479
+ this Ore module.
480
+
481
+ EXAMPLES::
482
+
483
+ sage: K.<z> = GF(5^3)
484
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
485
+ sage: M = S.quotient_module(X^2 + z)
486
+ sage: M((z, z^2)) # indirect doctest
487
+ (z, z^2)
488
+ """
489
+ return FreeModuleElement_generic_dense._repr_(x)
490
+
491
+ def _latex_element(self, x) -> str:
492
+ r"""
493
+ Return a LaTeX representation of the element `x` in
494
+ this Ore module.
495
+
496
+ EXAMPLES::
497
+
498
+ sage: K.<z> = GF(5^3)
499
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
500
+ sage: M = S.quotient_module(X^2 + z)
501
+ sage: v = M((z, z^2))
502
+ sage: latex(v) # indirect doctest
503
+ \left(z,\,z^{2}\right)
504
+ """
505
+ return FreeModuleElement_generic_dense._latex_(x)
506
+
507
+ def _coerce_map_from_(self, S):
508
+ r"""
509
+ Return a coercion map from `M` to ``self``, or ``None``.
510
+
511
+ This method always returns ``None``; all coercions between
512
+ Ore modules are currently handled using the method
513
+ :meth:`register_coercion`.
514
+
515
+ TESTS::
516
+
517
+ sage: K.<z> = GF(5^3)
518
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
519
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
520
+ sage: N = M.span((X + z)*v)
521
+
522
+ sage: M._coerce_map_from_(N)
523
+ sage: M.coerce_map_from(N)
524
+ Ore module morphism:
525
+ From: Ore module of rank 1 over Finite Field in z of size 5^3 twisted by z |--> z^5
526
+ To: Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
527
+ """
528
+ pass
529
+
530
+ def is_zero(self) -> bool:
531
+ r"""
532
+ Return ``True`` if this Ore module is reduced to zero.
533
+
534
+ EXAMPLES::
535
+
536
+ sage: K.<z> = GF(5^3)
537
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
538
+ sage: M = S.quotient_module(X^2 + z)
539
+ sage: M
540
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
541
+ sage: M.is_zero()
542
+ False
543
+
544
+ sage: Q = M.quo(M)
545
+ sage: Q.is_zero()
546
+ True
547
+ """
548
+ return self.rank() == 0
549
+
550
+ def rename_basis(self, names, coerce=False):
551
+ r"""
552
+ Return the same Ore module with the given naming
553
+ for the vectors in its distinguished basis.
554
+
555
+ INPUT:
556
+
557
+ - ``names`` -- a string or a list of strings, the
558
+ new names
559
+
560
+ - ``coerce`` (default: ``False``) -- a boolean; if
561
+ ``True``, a coercion map from this Ore module to
562
+ renamed version is set
563
+
564
+ EXAMPLES::
565
+
566
+ sage: K.<z> = GF(5^3)
567
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
568
+ sage: M = S.quotient_module(X^2 + z)
569
+ sage: M
570
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
571
+
572
+ sage: Me = M.rename_basis('e')
573
+ sage: Me
574
+ Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5
575
+
576
+ Now compare how elements are displayed::
577
+
578
+ sage: M.random_element() # random
579
+ (3*z^2 + 4*z + 2, 3*z^2 + z)
580
+ sage: Me.random_element() # random
581
+ (2*z+4)*e0 + (z^2+4*z+4)*e1
582
+
583
+ At this point, there is no coercion map between ``M``
584
+ and ``Me``. Therefore, adding elements in both parents
585
+ results in an error::
586
+
587
+ sage: M.random_element() + Me.random_element()
588
+ Traceback (most recent call last):
589
+ ...
590
+ TypeError: unsupported operand parent(s) for +:
591
+ 'Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5' and
592
+ 'Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5'
593
+
594
+ In order to set this coercion, one should define ``Me``
595
+ by passing the extra argument ``coerce=True``::
596
+
597
+ sage: Me = M.rename_basis('e', coerce=True)
598
+ sage: M.random_element() + Me.random_element() # random
599
+ 2*z^2*e0 + (z^2+z+4)*e1
600
+
601
+ .. WARNING::
602
+
603
+ Use ``coerce=True`` with extreme caution. Indeed,
604
+ setting inappropriate coercion maps may result in a
605
+ circular path in the coercion graph which, in turn,
606
+ could eventually break the coercion system.
607
+
608
+ Note that the bracket construction also works::
609
+
610
+ sage: M.<v,w> = M.rename_basis()
611
+ sage: M
612
+ Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
613
+
614
+ In this case, `v` and `w` are automatically defined::
615
+
616
+ sage: v + w
617
+ v + w
618
+ """
619
+ rank = self.rank()
620
+ names = normalize_names(names, rank)
621
+ cls = self.__class__
622
+ M = cls.__classcall__(cls, self._pseudohom._matrix,
623
+ self._ore, names, self._ore_category)
624
+ if coerce:
625
+ mat = identity_matrix(self.base_ring(), rank)
626
+ id = self.hom(mat, codomain=M)
627
+ M._unset_coercions_used()
628
+ M.register_coercion(id)
629
+ return M
630
+
631
+ def pseudohom(self):
632
+ r"""
633
+ Return the pseudomorphism giving the action of the Ore
634
+ variable on this Ore module.
635
+
636
+ EXAMPLES::
637
+
638
+ sage: K.<z> = GF(5^3)
639
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
640
+ sage: P = X^3 + z*X^2 - z^2*X + (z+2)
641
+ sage: M = S.quotient_module(P)
642
+ sage: M.pseudohom()
643
+ Free module pseudomorphism (twisted by z |--> z^5) defined by the matrix
644
+ [ 0 1 0]
645
+ [ 0 0 1]
646
+ [4*z + 3 z^2 4*z]
647
+ Domain: Ore module of rank 3 over Finite Field in z of size 5^3 twisted by z |--> z^5
648
+ Codomain: Ore module of rank 3 over Finite Field in z of size 5^3 twisted by z |--> z^5
649
+
650
+ .. SEEALSO::
651
+
652
+ :meth:`matrix`
653
+ """
654
+ return self._pseudohom
655
+
656
+ def ore_ring(self, names='x', action=True):
657
+ r"""
658
+ Return the underlying Ore polynomial ring.
659
+
660
+ INPUT:
661
+
662
+ - ``names`` (default: ``x``) -- a string, the name
663
+ of the variable
664
+
665
+ - ``action`` (default: ``True``) -- a boolean; if
666
+ ``True``, an action of the Ore polynomial ring on
667
+ the Ore module is set
668
+
669
+ EXAMPLES::
670
+
671
+ sage: K.<a> = GF(5^3)
672
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
673
+ sage: M.<e1,e2> = S.quotient_module(X^2 - a)
674
+ sage: M.ore_ring()
675
+ Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5
676
+
677
+ We can use a different variable name::
678
+
679
+ sage: M.ore_ring('Y')
680
+ Ore Polynomial Ring in Y over Finite Field in a of size 5^3 twisted by a |--> a^5
681
+
682
+ Alternatively, one can use the following shortcut::
683
+
684
+ sage: T.<Z> = M.ore_ring()
685
+ sage: T
686
+ Ore Polynomial Ring in Z over Finite Field in a of size 5^3 twisted by a |--> a^5
687
+
688
+ In all the above cases, an action of the returned Ore polynomial
689
+ ring on `M` is registered::
690
+
691
+ sage: Z*e1
692
+ e2
693
+ sage: Z*e2
694
+ a*e1
695
+
696
+ Specifying ``action=False`` prevents this to happen::
697
+
698
+ sage: T.<U> = M.ore_ring(action=False)
699
+ sage: U*e1
700
+ Traceback (most recent call last):
701
+ ...
702
+ TypeError: unsupported operand parent(s) for *:
703
+ 'Ore Polynomial Ring in U over Finite Field in a of size 5^3 twisted by a |--> a^5' and
704
+ 'Ore module <e1, e2> over Finite Field in a of size 5^3 twisted by a |--> a^5'
705
+ """
706
+ S = self._ore_category.ore_ring(names)
707
+ if action:
708
+ self._unset_coercions_used()
709
+ self.register_action(OreAction(S, self, True, operator.mul))
710
+ return S
711
+
712
+ def twisting_morphism(self):
713
+ r"""
714
+ Return the twisting morphism corresponding to this Ore module.
715
+
716
+ EXAMPLES::
717
+
718
+ sage: K.<z> = GF(5^3)
719
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
720
+ sage: M = S.quotient_module(X + z)
721
+ sage: M.twisting_morphism()
722
+ Frobenius endomorphism z |--> z^5 on Finite Field in z of size 5^3
723
+
724
+ When the twisting morphism is trivial (that is, the identity),
725
+ nothing is returned::
726
+
727
+ sage: R.<t> = QQ[]
728
+ sage: T.<Y> = OrePolynomialRing(R, R.derivation())
729
+ sage: M = T.quotient_module(Y + t^2)
730
+ sage: M.twisting_morphism()
731
+
732
+ .. SEEALSO::
733
+
734
+ :meth:`twisting_derivation`
735
+ """
736
+ return self._ore.twisting_morphism()
737
+
738
+ def twisting_derivation(self):
739
+ r"""
740
+ Return the twisting derivation corresponding to this Ore module.
741
+
742
+ EXAMPLES::
743
+
744
+ sage: R.<t> = QQ[]
745
+ sage: T.<Y> = OrePolynomialRing(R, R.derivation())
746
+ sage: M = T.quotient_module(Y + t^2)
747
+ sage: M.twisting_derivation()
748
+ d/dt
749
+
750
+ When the twisting derivation in zero, nothing is returned::
751
+
752
+ sage: K.<z> = GF(5^3)
753
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
754
+ sage: M = S.quotient_module(X + z)
755
+ sage: M.twisting_derivation()
756
+
757
+ .. SEEALSO::
758
+
759
+ :meth:`twisting_morphism`
760
+ """
761
+ return self._ore.twisting_derivation()
762
+
763
+ def matrix(self):
764
+ r"""
765
+ Return the matrix giving the action of the Ore variable
766
+ on this Ore module.
767
+
768
+ EXAMPLES::
769
+
770
+ sage: K.<z> = GF(5^3)
771
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
772
+ sage: P = X^3 + z*X^2 - z^2*X + (z+2)
773
+ sage: M = S.quotient_module(P)
774
+ sage: M.matrix()
775
+ [ 0 1 0]
776
+ [ 0 0 1]
777
+ [4*z + 3 z^2 4*z]
778
+
779
+ We recognize the companion matrix attached to the Ore
780
+ polynomial `P`. This is of course not a coincidence given
781
+ that the pseudomorphism corresponds to the left multiplication
782
+
783
+ .. SEEALSO::
784
+
785
+ :meth:`pseudohom`
786
+ """
787
+ return self._pseudohom.matrix()
788
+
789
+ def basis(self) -> list:
790
+ r"""
791
+ Return the canonical basis of this Ore module.
792
+
793
+ EXAMPLES::
794
+
795
+ sage: K.<z> = GF(5^3)
796
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
797
+ sage: M = S.quotient_module(X^3 - z)
798
+ sage: M.basis()
799
+ [(1, 0, 0), (0, 1, 0), (0, 0, 1)]
800
+ """
801
+ rank = self.rank()
802
+ zero = self.base_ring().zero()
803
+ one = self.base_ring().one()
804
+ coeffs = [zero] * rank
805
+ B = []
806
+ for i in range(rank):
807
+ coeffs[i] = one
808
+ B.append(self(coeffs))
809
+ coeffs[i] = zero
810
+ return B
811
+
812
+ def gens(self) -> list:
813
+ r"""
814
+ Return the canonical basis of this Ore module.
815
+
816
+ EXAMPLES::
817
+
818
+ sage: K.<z> = GF(5^3)
819
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
820
+ sage: M = S.quotient_module(X^3 - z)
821
+ sage: M.gens()
822
+ [(1, 0, 0), (0, 1, 0), (0, 0, 1)]
823
+ """
824
+ return self.basis()
825
+
826
+ def gen(self, i):
827
+ r"""
828
+ Return the `i`-th vector of the canonical basis
829
+ of this Ore module.
830
+
831
+ EXAMPLES::
832
+
833
+ sage: K.<z> = GF(5^3)
834
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
835
+ sage: M = S.quotient_module(X^3 - z)
836
+ sage: M.gen(0)
837
+ (1, 0, 0)
838
+ sage: M.gen(1)
839
+ (0, 1, 0)
840
+ sage: M.gen(2)
841
+ (0, 0, 1)
842
+ sage: M.gen(3)
843
+ Traceback (most recent call last):
844
+ ...
845
+ IndexError: generator is not defined
846
+ """
847
+ rank = self.rank()
848
+ if i < 0 or i >= rank:
849
+ raise IndexError("generator is not defined")
850
+ zero = self.base_ring().zero()
851
+ one = self.base_ring().one()
852
+ coeffs = [zero] * rank
853
+ coeffs[i] = one
854
+ return self(coeffs)
855
+
856
+ def _an_element_(self):
857
+ r"""
858
+ Return an element of this Ore module.
859
+
860
+ EXAMPLES:
861
+
862
+ When the Ore module is not zero, the returned element
863
+ is the first vector of the distinguished basis::
864
+
865
+ sage: K.<t> = Frac(QQ['t'])
866
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
867
+ sage: M.<u,v> = S.quotient_module(X^2 - t)
868
+ sage: M.an_element()
869
+ u
870
+
871
+ On the contrary, when the Ore module vanishes, the
872
+ returned element is of course zero::
873
+
874
+ sage: N = M / u
875
+ sage: N
876
+ Ore module of rank 0 over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by d/dt
877
+ sage: N.an_element()
878
+ 0
879
+ """
880
+ if self.rank() > 0:
881
+ return self.gen(0)
882
+ return self.zero()
883
+
884
+ def random_element(self, *args, **kwds):
885
+ r"""
886
+ Return a random element in this Ore module.
887
+
888
+ Extra arguments are passed to the random generator
889
+ of the base ring.
890
+
891
+ EXAMPLES::
892
+
893
+ sage: A.<t> = QQ['t']
894
+ sage: S.<X> = OrePolynomialRing(A, A.derivation())
895
+ sage: M = S.quotient_module(X^3 - t, names='e')
896
+ sage: M.random_element() # random
897
+ (-1/2*t^2 - 3/4*t + 3/2)*e0 + (-3/2*t^2 - 3*t + 4)*e1 + (-6*t + 2)*e2
898
+
899
+ sage: M.random_element(degree=5) # random
900
+ (4*t^5 - 1/2*t^4 + 3/2*t^3 + 6*t^2 - t - 1/10)*e0 + (19/3*t^5 - t^3 - t^2 + 1)*e1 + (t^5 + 4*t^4 + 4*t^2 + 1/3*t - 33)*e2
901
+ """
902
+ K = self.base_ring()
903
+ r = self.rank()
904
+ vs = [K.random_element(*args, **kwds) for _ in range(r)]
905
+ return self(vs)
906
+
907
+ def module(self):
908
+ r"""
909
+ Return the underlying free module of this Ore module.
910
+
911
+ EXAMPLES::
912
+
913
+ sage: A.<t> = QQ['t']
914
+ sage: S.<X> = OrePolynomialRing(A, A.derivation())
915
+ sage: M = S.quotient_module(X^3 - t)
916
+ sage: M
917
+ Ore module of rank 3 over Univariate Polynomial Ring in t over Rational Field twisted by d/dt
918
+
919
+ sage: M.module()
920
+ Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in t over Rational Field
921
+ """
922
+ return self.base_ring() ** self.rank()
923
+
924
+ def _Hom_(self, codomain, category):
925
+ r"""
926
+ Return the space of Ore morphisms from this Ore module
927
+ to ``codomain``.
928
+
929
+ INPUT:
930
+
931
+ - ``codomain`` -- a Ore module
932
+
933
+ - ``category`` -- the category in which the morphisms are
934
+
935
+ TESTS::
936
+
937
+ sage: K.<z> = GF(5^3)
938
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
939
+ sage: M = S.quotient_module(X^2 - z)
940
+ sage: N = S.quotient_module(X^3 - z)
941
+
942
+ sage: Hom(M, N) # indirect doctest
943
+ Set of Morphisms
944
+ from Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
945
+ to Ore module of rank 3 over Finite Field in z of size 5^3 twisted by z |--> z^5
946
+ in Category of enumerated finite dimensional Ore modules with basis over Finite Field in z of size 5^3 twisted by z |--> z^5
947
+
948
+ ::
949
+
950
+ sage: End(M) # indirect doctest
951
+ Set of Morphisms
952
+ from Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
953
+ to Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
954
+ in Category of enumerated finite dimensional Ore modules with basis over Finite Field in z of size 5^3 twisted by z |--> z^5
955
+ """
956
+ from sage.modules.ore_module_homspace import OreModule_homspace
957
+ return OreModule_homspace(self, codomain)
958
+
959
+ def hom(self, im_gens, codomain=None):
960
+ r"""
961
+ Return the morphism from this Ore module to ``codomain``
962
+ defined by ``im_gens``.
963
+
964
+ INPUT:
965
+
966
+ - ``im_gens`` -- a datum defining the morphism to build;
967
+ it could either a list, a tuple, a dictionary or a morphism
968
+ of Ore modules
969
+
970
+ - ``codomain`` (default: ``None``) -- a Ore module, the
971
+ codomain of the morphism; if ``None``, it is inferred from
972
+ ``im_gens``
973
+
974
+ EXAMPLES::
975
+
976
+ sage: K.<t> = Frac(GF(5)['t'])
977
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
978
+ sage: P = X^3 + 2*t*X^2 + (t^2 + 2)*X + t
979
+ sage: Q = t*X^2 - X + 1
980
+
981
+ sage: U = S.quotient_module(P, names='u')
982
+ sage: U.inject_variables()
983
+ Defining u0, u1, u2
984
+ sage: V = S.quotient_module(P*Q, names='v')
985
+ sage: V.inject_variables()
986
+ Defining v0, v1, v2, v3, v4
987
+
988
+ The first method for creating a morphism from `U` to `V` is
989
+ to explicitly write down its matrix in the canonical bases::
990
+
991
+ sage: mat = matrix(3, 5, [1, 4, t, 0, 0,
992
+ ....: 0, 1, 0, t, 0,
993
+ ....: 0, 0, 1, 1, t])
994
+ sage: f = U.hom(mat, codomain=V)
995
+ sage: f
996
+ Ore module morphism:
997
+ From: Ore module <u0, u1, u2> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
998
+ To: Ore module <v0, v1, v2, v3, v4> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
999
+
1000
+ This method is however not really convenient because it
1001
+ requires to compute beforehand all the entries of the
1002
+ defining matrix.
1003
+ Instead, we can pass the list of images of the generators::
1004
+
1005
+ sage: g = U.hom([Q*v0, X*Q*v0, X^2*Q*v0])
1006
+ sage: g
1007
+ Ore module morphism:
1008
+ From: Ore module <u0, u1, u2> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1009
+ To: Ore module <v0, v1, v2, v3, v4> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1010
+ sage: g.matrix()
1011
+ [1 4 t 0 0]
1012
+ [0 1 0 t 0]
1013
+ [0 0 1 1 t]
1014
+
1015
+ One can even give the values of the morphism on a smaller
1016
+ set as soon as the latter generates the domain as Ore module.
1017
+ The syntax uses dictionaries as follows::
1018
+
1019
+ sage: h = U.hom({u0: Q*v0})
1020
+ sage: h
1021
+ Ore module morphism:
1022
+ From: Ore module <u0, u1, u2> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1023
+ To: Ore module <v0, v1, v2, v3, v4> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1024
+ sage: g == h
1025
+ True
1026
+
1027
+ Finally ``im_gens`` can also be itself a Ore morphism, in which
1028
+ case SageMath tries to cast it into a morphism with the requested
1029
+ domains and codomains.
1030
+ As an example below, we restrict `g` to a subspace::
1031
+
1032
+ sage: C.<c0,c1> = U.span((X + t)*u0)
1033
+ sage: gC = C.hom(g)
1034
+ sage: gC
1035
+ Ore module morphism:
1036
+ From: Ore module <c0, c1> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1037
+ To: Ore module <v0, v1, v2, v3, v4> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1038
+
1039
+ sage: g(c0) == gC(c0)
1040
+ True
1041
+ sage: g(c1) == gC(c1)
1042
+ True
1043
+
1044
+ TESTS::
1045
+
1046
+ sage: U.hom(0)
1047
+ Traceback (most recent call last):
1048
+ ...
1049
+ ValueError: im_gens must be a list, a tuple, a dictionary, a matrix or a Ore module morphism
1050
+
1051
+ sage: U.hom([Q*v0])
1052
+ Traceback (most recent call last):
1053
+ ...
1054
+ ValueError: wrong number of generators
1055
+
1056
+ sage: U.hom({u0: Q*v0, u1: Q*v0})
1057
+ Traceback (most recent call last):
1058
+ ...
1059
+ ValueError: does not define a morphism of Ore modules
1060
+
1061
+ sage: U.hom({(X+t)*u0: (X+t)*Q*v0})
1062
+ Traceback (most recent call last):
1063
+ ...
1064
+ ValueError: does not define a morphism of Ore modules
1065
+ """
1066
+ from sage.modules.ore_module_morphism import OreModuleMorphism
1067
+ if codomain is None:
1068
+ if isinstance(im_gens, Matrix):
1069
+ codomain = self
1070
+ elif isinstance(im_gens, OreModuleMorphism):
1071
+ codomain = im_gens.codomain()
1072
+ elif isinstance(im_gens, (list, tuple)):
1073
+ codomain = Sequence(im_gens).universe()
1074
+ elif isinstance(im_gens, dict):
1075
+ codomain = Sequence(im_gens.values()).universe()
1076
+ else:
1077
+ raise ValueError("im_gens must be a list, a tuple, a dictionary, a matrix or a Ore module morphism")
1078
+ H = self.Hom(codomain)
1079
+ return H(im_gens)
1080
+
1081
+ def multiplication_map(self, P):
1082
+ r"""
1083
+ Return the multiplication by `P` acting on this Ore module.
1084
+
1085
+ INPUT:
1086
+
1087
+ - ``P`` -- a scalar in the base ring, or a Ore polynomial
1088
+
1089
+ EXAMPLES::
1090
+
1091
+ sage: K.<a> = GF(7^5)
1092
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1093
+ sage: P = X^3 + a*X^2 + X - a^2
1094
+ sage: M = S.quotient_module(P)
1095
+
1096
+ We define the scalar multiplication by an element in the base ring::
1097
+
1098
+ sage: f = M.multiplication_map(3)
1099
+ sage: f
1100
+ Ore module endomorphism of Ore module of rank 3 over Finite Field in a of size 7^5 twisted by a |--> a^7
1101
+ sage: f.matrix()
1102
+ [3 0 0]
1103
+ [0 3 0]
1104
+ [0 0 3]
1105
+
1106
+ Be careful that an element in the base ring defines a Ore morphism
1107
+ if and only if it is fixed by the twisting morphisms and killed by
1108
+ the derivation (otherwise the multiplication by this element does
1109
+ not commute with the Ore action).
1110
+ In SageMath, attempting to create the multiplication by an element
1111
+ which does not fulfill these requirements leads to an error::
1112
+
1113
+ sage: M.multiplication_map(a)
1114
+ Traceback (most recent call last):
1115
+ ...
1116
+ ValueError: does not define a morphism of Ore modules
1117
+
1118
+ As soon as it defines a Ore morphism, one can also build the left
1119
+ multiplication by an Ore polynomial::
1120
+
1121
+ sage: g = M.multiplication_map(X^5)
1122
+ sage: g
1123
+ Ore module endomorphism of Ore module of rank 3 over Finite Field in a of size 7^5 twisted by a |--> a^7
1124
+ sage: g.matrix()
1125
+ [ 3*a^4 + 3*a^3 + 6*a^2 + 5*a 4*a^4 + 5*a^3 + 2*a^2 + 6 6*a^4 + 6*a^3 + a^2 + 4]
1126
+ [ a^2 + 3 5*a^4 + 5*a^3 + 6*a^2 + 4*a + 1 a^3 + 5*a^2 + 4]
1127
+ [6*a^4 + 6*a^3 + 3*a^2 + 3*a + 1 4*a^4 + 2*a^3 + 3*a + 5 6*a^4 + 6*a^3 + 2*a^2 + 5*a + 2]
1128
+
1129
+ We check that the characteristic polynomial of `g` is the reduced
1130
+ norm of the Ore polynomial `P` we started with (this is a classical
1131
+ property)::
1132
+
1133
+ sage: g.charpoly()
1134
+ x^3 + 4*x^2 + 2*x + 5
1135
+ sage: P.reduced_norm(var='x')
1136
+ x^3 + 4*x^2 + 2*x + 5
1137
+ """
1138
+ if isinstance(P, OrePolynomial):
1139
+ S = P.parent()
1140
+ ore = self._ore
1141
+ if S._morphism != ore._morphism or S._derivation != ore._derivation:
1142
+ raise ValueError("twist does not match")
1143
+ action = OreAction(S, self, True, operator.mul)
1144
+ M = matrix([action._act_(P, x).list() for x in self.basis()])
1145
+ else:
1146
+ P = self.base_ring()(P)
1147
+ r = self.rank()
1148
+ M = matrix(r, r, P)
1149
+ H = self.Hom(self)
1150
+ return H(M)
1151
+
1152
+ def identity_morphism(self):
1153
+ r"""
1154
+ Return the identity morphism of this Ore module.
1155
+
1156
+ EXAMPLES::
1157
+
1158
+ sage: K.<a> = GF(7^5)
1159
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1160
+ sage: M.<u,v> = S.quotient_module(X^2 + a*X + a^2)
1161
+ sage: id = M.identity_morphism()
1162
+ sage: id
1163
+ Ore module endomorphism of Ore module <u, v> over Finite Field in a of size 7^5 twisted by a |--> a^7
1164
+
1165
+ sage: id(u)
1166
+ u
1167
+ sage: id(v)
1168
+ v
1169
+ """
1170
+ H = self.Hom(self)
1171
+ one = self.base_ring().one()
1172
+ return H(one)
1173
+
1174
+ def _span(self, gens):
1175
+ r"""
1176
+ Return a matrix whose lines form a basis over the base field
1177
+ of the submodule of this Ore module generated over the Ore
1178
+ ring by ``gens``.
1179
+
1180
+ INPUT:
1181
+
1182
+ - ``gens`` -- a list of vectors or submodules of this Ore module
1183
+
1184
+ TESTS::
1185
+
1186
+ sage: K.<a> = GF(7^5)
1187
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1188
+ sage: P = X^2 + a
1189
+ sage: Q = X^3 + a^2*X + 1
1190
+ sage: M = S.quotient_module(P*Q, names='e')
1191
+ sage: M.inject_variables()
1192
+ Defining e0, e1, e2, e3, e4
1193
+
1194
+ sage: M._span([Q*e0])
1195
+ [ 1 0 a^4 + 5*a^3 + 6*a^2 + a 1 6*a^2]
1196
+ [ 0 1 2*a^4 + 6*a^2 + 2*a + 3 0 1]
1197
+
1198
+ sage: M._span([Q*e0, e1])
1199
+ [1 0 0 0 0]
1200
+ [0 1 0 0 0]
1201
+ [0 0 1 0 0]
1202
+ [0 0 0 1 0]
1203
+ [0 0 0 0 1]
1204
+
1205
+ sage: N = M.span(Q*e0)
1206
+ sage: M._span([N, e2])
1207
+ [1 0 0 0 0]
1208
+ [0 1 0 0 0]
1209
+ [0 0 1 0 0]
1210
+ [0 0 0 1 0]
1211
+ [0 0 0 0 1]
1212
+ """
1213
+ base = self.base_ring()
1214
+ rank = self.rank()
1215
+ f = self._pseudohom
1216
+ if not isinstance(gens, (list, tuple)):
1217
+ gens = [gens]
1218
+ rows = []
1219
+ for gen in gens:
1220
+ if isinstance(gen, OreModule):
1221
+ incl = self.coerce_map_from(gen)
1222
+ if incl is None:
1223
+ raise ValueError("not canonically a submodule")
1224
+ rows += incl._matrix.rows()
1225
+ elif isinstance(gen, OreModuleElement):
1226
+ rows.append(self(gen).list())
1227
+ if len(rows) < 2*rank:
1228
+ zero = rank * [base.zero()]
1229
+ rows += (2*rank - len(rows)) * [zero]
1230
+ M = matrix(base, rows)
1231
+ M.echelonize()
1232
+ oldr = 0
1233
+ r = M.rank()
1234
+ iter = 1
1235
+ while r > oldr:
1236
+ for i in range(r):
1237
+ v = M.row(i)
1238
+ for _ in range(iter):
1239
+ v = f(v)
1240
+ v = v.list()
1241
+ for j in range(rank):
1242
+ M[i+r, j] = v[j]
1243
+ M.echelonize()
1244
+ oldr = r
1245
+ r = M.rank()
1246
+ iter *= 2
1247
+ return M.matrix_from_rows(range(r))
1248
+
1249
+ def span(self, gens, names=None):
1250
+ r"""
1251
+ Return the submodule of this Ore module generated (over the
1252
+ underlying Ore ring) by ``gens``.
1253
+
1254
+ INPUT:
1255
+
1256
+ - ``gens`` -- a list of vectors or submodules of this Ore module
1257
+
1258
+ - ``names`` (default: ``None``) -- the name of the vectors in a
1259
+ basis of this submodule
1260
+
1261
+ EXAMPLES::
1262
+
1263
+ sage: K.<t> = Frac(GF(5)['t'])
1264
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1265
+ sage: P = X^2 + t*X + 1
1266
+ sage: M = S.quotient_module(P^3, names='e')
1267
+ sage: M.inject_variables()
1268
+ Defining e0, e1, e2, e3, e4, e5
1269
+
1270
+ We create the submodule `M P`::
1271
+
1272
+ sage: MP = M.span([P*e0])
1273
+ sage: MP
1274
+ Ore module of rank 4 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1275
+ sage: MP.basis()
1276
+ [e0 + (t^4+t^2+3)*e4 + t^3*e5,
1277
+ e1 + (4*t^3+2*t)*e4 + (4*t^2+3)*e5,
1278
+ e2 + (2*t^2+2)*e4 + 2*t*e5,
1279
+ e3 + 4*t*e4 + 4*e5]
1280
+
1281
+ When there is only one generator, encapsulating it in a list is
1282
+ not necessary; one can equally write::
1283
+
1284
+ sage: MP = M.span(P*e0)
1285
+
1286
+ If one wants, one can give names to the basis of the submodule using
1287
+ the attribute ``names``::
1288
+
1289
+ sage: MP2 = M.span(P^2*e0, names='u')
1290
+ sage: MP2.inject_variables()
1291
+ Defining u0, u1
1292
+ sage: MP2.basis()
1293
+ [u0, u1]
1294
+
1295
+ sage: M(u0)
1296
+ e0 + (t^2+4)*e2 + 3*t^3*e3 + (t^2+1)*e4 + 3*t*e5
1297
+
1298
+ Note that a coercion map from the submodule to the ambient module
1299
+ is automatically set::
1300
+
1301
+ sage: M.has_coerce_map_from(MP2)
1302
+ True
1303
+
1304
+ Therefore, combining elements of ``M`` and ``MP2`` in the same
1305
+ expression perfectly works::
1306
+
1307
+ sage: t*u0 + e1
1308
+ t*e0 + e1 + (t^3+4*t)*e2 + 3*t^4*e3 + (t^3+t)*e4 + 3*t^2*e5
1309
+
1310
+ Here is an example with multiple generators::
1311
+
1312
+ sage: MM = M.span([MP2, P*e1])
1313
+ sage: MM.basis()
1314
+ [e0, e1, e2, e3, e4, e5]
1315
+
1316
+ In this case, we obtain the whole space.
1317
+
1318
+ Creating submodules of submodules is also allowed::
1319
+
1320
+ sage: N = MP.span(P^2*e0)
1321
+ sage: N
1322
+ Ore module of rank 2 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1323
+ sage: N.basis()
1324
+ [e0 + (t^2+4)*e2 + 3*t^3*e3 + (t^2+1)*e4 + 3*t*e5,
1325
+ e1 + (4*t^2+4)*e3 + 3*t*e4 + 4*e5]
1326
+
1327
+ .. SEEALSO::
1328
+
1329
+ :meth:`quotient`
1330
+ """
1331
+ gens = self._span(gens)
1332
+ return self._submodule_class(self, gens, names=names)
1333
+
1334
+ def quotient(self, sub, names=None, check=True):
1335
+ r"""
1336
+ Return the quotient of this Ore module by the submodule
1337
+ generated (over the underlying Ore ring) by ``gens``.
1338
+
1339
+ INPUT:
1340
+
1341
+ - ``gens`` -- a list of vectors or submodules of this Ore module
1342
+
1343
+ - ``names`` (default: ``None``) -- the name of the vectors in a
1344
+ basis of the quotient
1345
+
1346
+ - ``check`` (default: ``True``) -- a boolean, ignored
1347
+
1348
+ EXAMPLES::
1349
+
1350
+ sage: K.<t> = Frac(GF(5)['t'])
1351
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1352
+ sage: P = X^2 + t*X + 1
1353
+ sage: M = S.quotient_module(P^3, names='e')
1354
+ sage: M.inject_variables()
1355
+ Defining e0, e1, e2, e3, e4, e5
1356
+
1357
+ We create the quotient `M/MP`::
1358
+
1359
+ sage: modP = M.quotient(P*e0)
1360
+ sage: modP
1361
+ Ore module of rank 2 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1362
+
1363
+ As a shortcut, we can write ``quo`` instead of ``quotient`` or even
1364
+ use the ``/`` operator::
1365
+
1366
+ sage: modP = M / (P*e0)
1367
+ sage: modP
1368
+ Ore module of rank 2 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1369
+
1370
+ By default, the vectors in the quotient have the same names as their
1371
+ representatives in `M`::
1372
+
1373
+ sage: modP.basis()
1374
+ [e4, e5]
1375
+
1376
+ One can override this behavior by setting the attributes ``names``::
1377
+
1378
+ sage: modP = M.quo(P*e0, names='u')
1379
+ sage: modP.inject_variables()
1380
+ Defining u0, u1
1381
+ sage: modP.basis()
1382
+ [u0, u1]
1383
+
1384
+ Note that a coercion map from the initial Ore module to its quotient
1385
+ is automatically set. As a consequence, combining elements of ``M``
1386
+ and ``modP`` in the same formula works::
1387
+
1388
+ sage: t*u0 + e1
1389
+ (t^3+4*t)*u0 + (t^2+2)*u1
1390
+
1391
+ One can combine the construction of quotients and submodules without
1392
+ trouble. For instance, here we build the space `M P / M P^2`::
1393
+
1394
+ sage: modP2 = M / (P^2*e0)
1395
+ sage: N = modP2.span(P*e0)
1396
+ sage: N
1397
+ Ore module of rank 2 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1398
+ sage: N.basis()
1399
+ [e2 + (2*t^2+2)*e4 + 2*t*e5,
1400
+ e3 + 4*t*e4 + 4*e5]
1401
+
1402
+ .. SEEALSO::
1403
+
1404
+ :meth:`quo`, :meth:`span`
1405
+ """
1406
+ gens = self._span(sub)
1407
+ return self._quotientModule_class(self, gens, names=names)
1408
+
1409
+ quo = quotient
1410
+
1411
+ def __eq__(self, other) -> bool:
1412
+ r"""
1413
+ Return ``True`` if this Ore module is the same than ``other``.
1414
+
1415
+ TESTS:
1416
+
1417
+ Different names lead to different parents::
1418
+
1419
+ sage: K.<a> = GF(7^5)
1420
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1421
+ sage: M.<u,v> = S.quotient_module(X^2 + a*X + a^2)
1422
+ sage: N.<e0,e1> = S.quotient_module(X^2 + a*X + a^2)
1423
+ sage: M == N
1424
+ False
1425
+
1426
+ However, different syntaxes resulting in the same names lead
1427
+ to the same parent::
1428
+
1429
+ sage: N2 = S.quotient_module(X^2 + a*X + a^2, names='e')
1430
+ sage: N == N2
1431
+ True
1432
+ """
1433
+ return self is other
1434
+
1435
+ def __hash__(self) -> int:
1436
+ r"""
1437
+ Return a hash of this Ore module.
1438
+
1439
+ TESTS::
1440
+
1441
+ sage: K.<z> = GF(5^3)
1442
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1443
+ sage: M = S.quotient_module(X^3 - z)
1444
+ sage: hash(M) # random
1445
+ 128873304640624
1446
+ """
1447
+ return id(self)
1448
+
1449
+
1450
+ # Submodules
1451
+ ############
1452
+
1453
+ class OreSubmodule(OreModule):
1454
+ r"""
1455
+ Class for submodules of Ore modules.
1456
+ """
1457
+ def __classcall_private__(cls, ambient, gens, names):
1458
+ r"""
1459
+ Normalize the input before passing it to the init function
1460
+ (useful to ensure the uniqueness assupmtion).
1461
+
1462
+ INPUT:
1463
+
1464
+ - ``ambient`` -- a Ore module, the ambient module where
1465
+ this submodule sits
1466
+
1467
+ - ``gens`` -- a list of generators (formatted as coordinates
1468
+ vectors) of this submodule
1469
+
1470
+ - ``names`` -- the name of the vectors of the basis of
1471
+ the submodule, or ``None``
1472
+
1473
+ TESTS::
1474
+
1475
+ sage: K.<z> = GF(5^3)
1476
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1477
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1478
+ sage: N1 = M.span((X + z)*v)
1479
+ sage: N2 = M.span((X + z^5)*w)
1480
+ sage: N1 is N2
1481
+ True
1482
+
1483
+ ::
1484
+
1485
+ sage: R.<t> = QQ[]
1486
+ sage: S.<X> = OrePolynomialRing(R, R.derivation())
1487
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1488
+ sage: M.span((X + t)*v)
1489
+ Traceback (most recent call last):
1490
+ ...
1491
+ NotImplementedError: Ore submodules are currently only implemented over fields
1492
+ """
1493
+ base = ambient.base_ring()
1494
+ if base not in Fields():
1495
+ raise NotImplementedError("Ore submodules are currently only implemented over fields")
1496
+ if isinstance(gens, Matrix):
1497
+ basis = gens
1498
+ else:
1499
+ basis = matrix(base, gens)
1500
+ basis = basis.echelon_form()
1501
+ basis.set_immutable()
1502
+ rank = basis.rank()
1503
+ if basis.nrows() != rank:
1504
+ basis = basis.matrix_from_rows(range(rank))
1505
+ names = normalize_names(names, rank)
1506
+ return cls.__classcall__(cls, ambient, basis, names)
1507
+
1508
+ def __init__(self, ambient, basis, names) -> None:
1509
+ r"""
1510
+ Initialize this Ore submodule.
1511
+
1512
+ INPUT:
1513
+
1514
+ - ``ambient`` -- a Ore module, the ambient module where
1515
+ this submodule sits
1516
+
1517
+ - ``basis`` -- the echelon basis of this submodule
1518
+
1519
+ - ``names`` -- the name of the vectors of the basis of
1520
+ the submodule, or ``None``
1521
+
1522
+ TESTS::
1523
+
1524
+ sage: K.<z> = GF(5^3)
1525
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1526
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1527
+ sage: N = M.span((X + z)*v) # indirect doctest
1528
+ sage: type(N)
1529
+ <class 'sage.modules.ore_module.OreSubmodule_with_category'>
1530
+
1531
+ sage: TestSuite(N).run()
1532
+ """
1533
+ from sage.modules.ore_module_morphism import OreModuleRetraction
1534
+ base = ambient.base_ring()
1535
+ self._ambient = ambient
1536
+ self._basis = basis
1537
+ rows = [basis.solve_left(ambient(x).image()) for x in basis.rows()]
1538
+ OreModule.__init__(self, matrix(base, rows),
1539
+ ambient.ore_ring(action=False),
1540
+ names, ambient._ore_category)
1541
+ coerce = self.hom(basis, codomain=ambient)
1542
+ ambient.register_coercion(coerce)
1543
+ self._inject = coerce.__copy__()
1544
+ self.register_conversion(OreModuleRetraction(ambient, self))
1545
+
1546
+ def _repr_element(self, x) -> str:
1547
+ r"""
1548
+ Return a string representation of ``x``.
1549
+
1550
+ By default, elements in a Ore submodule are printed as their
1551
+ images in the ambient module.
1552
+
1553
+ TESTS::
1554
+
1555
+ sage: K.<z> = GF(5^3)
1556
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1557
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1558
+ sage: N = M.span((X + z)*v)
1559
+ sage: N.an_element() # indirect doctest
1560
+ v + (3*z^2+4)*w
1561
+ """
1562
+ return self._ambient(x)._repr_()
1563
+
1564
+ def _latex_element(self, x) -> str:
1565
+ r"""
1566
+ Return a LaTeX representation of ``x``.
1567
+
1568
+ By default, elements in a Ore submodule are rendered as their
1569
+ images in the ambient module.
1570
+
1571
+ TESTS::
1572
+
1573
+ sage: K.<z> = GF(5^3)
1574
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1575
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1576
+ sage: N = M.span((X + z)*v)
1577
+ sage: latex(N.an_element()) # indirect doctest
1578
+ v + \left(3 z^{2} + 4\right) w
1579
+ """
1580
+ return self._ambient(x)._latex_()
1581
+
1582
+ def ambient(self):
1583
+ r"""
1584
+ Return the ambient Ore module in which this submodule lives.
1585
+
1586
+ EXAMPLES::
1587
+
1588
+ sage: K.<z> = GF(5^3)
1589
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1590
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1591
+ sage: N = M.span((X + z)*v)
1592
+ sage: N.ambient()
1593
+ Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1594
+ sage: N.ambient() is M
1595
+ True
1596
+ """
1597
+ return self._ambient
1598
+
1599
+ def rename_basis(self, names, coerce=False):
1600
+ r"""
1601
+ Return the same Ore module with the given naming
1602
+ for the vectors in its distinguished basis.
1603
+
1604
+ INPUT:
1605
+
1606
+ - ``names`` -- a string or a list of strings, the
1607
+ new names
1608
+
1609
+ - ``coerce`` (default: ``False``) -- a boolean; if
1610
+ ``True``, a coercion map from this Ore module to
1611
+ renamed version is set
1612
+
1613
+ EXAMPLES::
1614
+
1615
+ sage: K.<z> = GF(5^3)
1616
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1617
+ sage: M = S.quotient_module(X^2 + z^2)
1618
+ sage: M
1619
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
1620
+
1621
+ sage: Me = M.rename_basis('e')
1622
+ sage: Me
1623
+ Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5
1624
+
1625
+ Now compare how elements are displayed::
1626
+
1627
+ sage: M.random_element() # random
1628
+ (3*z^2 + 4*z + 2, 3*z^2 + z)
1629
+ sage: Me.random_element() # random
1630
+ (2*z + 4)*e0 + (z^2 + 4*z + 4)*e1
1631
+
1632
+ At this point, there is no coercion map between ``M``
1633
+ and ``Me``. Therefore, adding elements in both parents
1634
+ results in an error::
1635
+
1636
+ sage: M.random_element() + Me.random_element()
1637
+ Traceback (most recent call last):
1638
+ ...
1639
+ TypeError: unsupported operand parent(s) for +:
1640
+ 'Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5' and
1641
+ 'Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5'
1642
+
1643
+ In order to set this coercion, one should define ``Me``
1644
+ by passing the extra argument ``coerce=True``::
1645
+
1646
+ sage: Me = M.rename_basis('e', coerce=True)
1647
+ sage: M.random_element() + Me.random_element() # random
1648
+ 2*z^2*e0 + (z^2 + z + 4)*e1
1649
+
1650
+ .. WARNING::
1651
+
1652
+ Use ``coerce=True`` with extreme caution. Indeed,
1653
+ setting inappropriate coercion maps may result in a
1654
+ circular path in the coercion graph which, in turn,
1655
+ could eventually break the coercion system.
1656
+
1657
+ Note that the bracket construction also works::
1658
+
1659
+ sage: M.<v,w> = M.rename_basis()
1660
+ sage: M
1661
+ Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1662
+
1663
+ In this case, `v` and `w` are automatically defined::
1664
+
1665
+ sage: v + w
1666
+ v + w
1667
+
1668
+ TESTS::
1669
+
1670
+ sage: K.<z> = GF(5^3)
1671
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1672
+ sage: P = X + z
1673
+ sage: A.<v,w> = S.quotient_module(P^2)
1674
+ sage: M = A.span(P*v)
1675
+ sage: Me = M.rename_basis('e', coerce=True)
1676
+ sage: M.an_element() + Me.an_element()
1677
+ 2*e0
1678
+ """
1679
+ rank = self.rank()
1680
+ names = normalize_names(names, rank)
1681
+ cls = self.__class__
1682
+ M = cls.__classcall__(cls, self._ambient, self._basis, names)
1683
+ if coerce:
1684
+ mat = identity_matrix(self.base_ring(), rank)
1685
+ id = self.hom(mat, codomain=M)
1686
+ M._unset_coercions_used()
1687
+ M.register_coercion(id)
1688
+ return M
1689
+
1690
+ def injection_morphism(self):
1691
+ r"""
1692
+ Return the inclusion of this submodule in the ambient space.
1693
+
1694
+ EXAMPLES::
1695
+
1696
+ sage: K.<z> = GF(5^3)
1697
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1698
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1699
+ sage: N = M.span((X + z)*v)
1700
+ sage: N.injection_morphism()
1701
+ Ore module morphism:
1702
+ From: Ore module of rank 1 over Finite Field in z of size 5^3 twisted by z |--> z^5
1703
+ To: Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1704
+ """
1705
+ return self._inject
1706
+
1707
+ def morphism_restriction(self, f):
1708
+ r"""
1709
+ Return the restriction of `f` to this submodule.
1710
+
1711
+ EXAMPLES::
1712
+
1713
+ sage: K.<z> = GF(5^3)
1714
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1715
+ sage: M.<v,w> = S.quotient_module((X + z)^2)
1716
+ sage: N = M.span((X + z)*v)
1717
+
1718
+ sage: f = M.multiplication_map(X^3)
1719
+ sage: f
1720
+ Ore module endomorphism of Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1721
+
1722
+ sage: g = N.morphism_restriction(f)
1723
+ sage: g
1724
+ Ore module morphism:
1725
+ From: Ore module of rank 1 over Finite Field in z of size 5^3 twisted by z |--> z^5
1726
+ To: Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1727
+ sage: g.matrix()
1728
+ [ 3 4*z^2 + 2]
1729
+
1730
+ TESTS::
1731
+
1732
+ sage: N.morphism_restriction(g)
1733
+ Traceback (most recent call last):
1734
+ ...
1735
+ ValueError: the domain of the morphism must be the ambient space
1736
+ """
1737
+ if f.domain() is not self._ambient:
1738
+ raise ValueError("the domain of the morphism must be the ambient space")
1739
+ return f * self._inject
1740
+
1741
+ def morphism_corestriction(self, f):
1742
+ r"""
1743
+ If the image of `f` is contained in this submodule,
1744
+ return the corresponding corestriction of `f`.
1745
+
1746
+ EXAMPLES::
1747
+
1748
+ sage: K.<z> = GF(5^3)
1749
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
1750
+ sage: P = X + z
1751
+ sage: M.<v,w> = S.quotient_module(P^2)
1752
+ sage: N = M.span(P*v)
1753
+
1754
+ sage: f = M.hom({v: P*v})
1755
+ sage: f
1756
+ Ore module endomorphism of Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1757
+
1758
+ sage: g = N.morphism_corestriction(f)
1759
+ sage: g
1760
+ Ore module morphism:
1761
+ From: Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
1762
+ To: Ore module of rank 1 over Finite Field in z of size 5^3 twisted by z |--> z^5
1763
+ sage: g.matrix()
1764
+ [ z]
1765
+ [4*z^2]
1766
+
1767
+ When the image of the morphism is not contained in this submodule,
1768
+ an error is raised::
1769
+
1770
+ sage: h = M.multiplication_map(X^3)
1771
+ sage: N.morphism_corestriction(h)
1772
+ Traceback (most recent call last):
1773
+ ...
1774
+ ValueError: the image of the morphism is not contained in this submodule
1775
+
1776
+ TESTS::
1777
+
1778
+ sage: N.morphism_corestriction(g)
1779
+ Traceback (most recent call last):
1780
+ ...
1781
+ ValueError: the codomain of the morphism must be the ambient space
1782
+ """
1783
+ if f.codomain() is not self._ambient:
1784
+ raise ValueError("the codomain of the morphism must be the ambient space")
1785
+ rows = []
1786
+ basis = self._basis
1787
+ try:
1788
+ rows = [basis.solve_left(y) for y in f._matrix.rows()]
1789
+ except ValueError:
1790
+ raise ValueError("the image of the morphism is not contained in this submodule")
1791
+ return f.domain().hom(rows, codomain=self)
1792
+
1793
+ _hom_change_domain = morphism_restriction
1794
+ _hom_change_codomain = morphism_corestriction
1795
+
1796
+
1797
+ # Quotients
1798
+ ###########
1799
+
1800
+ class OreQuotientModule(OreModule):
1801
+ r"""
1802
+ Class for quotients of Ore modules.
1803
+ """
1804
+ def __classcall_private__(cls, cover, gens, names):
1805
+ r"""
1806
+ Normalize the input before passing it to the init function
1807
+ (useful to ensure the uniqueness assumption).
1808
+
1809
+ INPUT:
1810
+
1811
+ - ``cover`` -- a Ore module, the cover module of this
1812
+ quotient
1813
+
1814
+ - ``gens`` -- a list of generators (formatted as coordinates
1815
+ vectors) of the submodule by which we quotient out
1816
+
1817
+ - ``names`` -- the name of the vectors of the basis of
1818
+ the quotient, or ``None``
1819
+
1820
+ TESTS::
1821
+
1822
+ sage: K.<t> = Frac(GF(5)['t'])
1823
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1824
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1825
+ sage: Q1 = M.quo((X + t)*v)
1826
+ sage: Q2 = M.quo(v + (X + t)*w)
1827
+ sage: Q1 is Q2
1828
+ True
1829
+
1830
+ ::
1831
+
1832
+ sage: R.<t> = QQ[]
1833
+ sage: S.<X> = OrePolynomialRing(R, R.derivation())
1834
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1835
+ sage: M.quo((X + t)*v)
1836
+ Traceback (most recent call last):
1837
+ ...
1838
+ NotImplementedError: quotient of Ore modules are currently only implemented over fields
1839
+ """
1840
+ base = cover.base_ring()
1841
+ if base not in Fields():
1842
+ raise NotImplementedError("quotient of Ore modules are currently only implemented over fields")
1843
+ if isinstance(gens, Matrix):
1844
+ basis = gens
1845
+ else:
1846
+ basis = matrix(base, gens)
1847
+ basis = basis.echelon_form()
1848
+ basis.set_immutable()
1849
+ rank = basis.rank()
1850
+ if basis.nrows() != rank:
1851
+ basis = basis.matrix_from_rows(range(rank))
1852
+ names = normalize_names(names, cover.rank() - rank)
1853
+ return cls.__classcall__(cls, cover, basis, names)
1854
+
1855
+ def __init__(self, cover, basis, names) -> None:
1856
+ r"""
1857
+ Initialize this Ore quotient.
1858
+
1859
+ INPUT:
1860
+
1861
+ - ``cover`` -- a Ore module, the cover module of this
1862
+ quotient
1863
+
1864
+ - ``basis`` -- the echelon basis of the submodule
1865
+ defining the quotient
1866
+
1867
+ - ``names`` -- the name of the vectors of the basis of
1868
+ the submodule, or ``None``
1869
+
1870
+ TESTS::
1871
+
1872
+ sage: K.<t> = Frac(GF(5)['t'])
1873
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1874
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1875
+ sage: Q = M.quo((X + t)*v) # indirect doctest
1876
+ sage: type(Q)
1877
+ <class 'sage.modules.ore_module.OreQuotientModule_with_category'>
1878
+
1879
+ sage: TestSuite(N).run()
1880
+ """
1881
+ from sage.modules.ore_module_morphism import OreModuleSection
1882
+ self._cover = cover
1883
+ d = cover.rank()
1884
+ base = cover.base_ring()
1885
+ self._relations = basis
1886
+ pivots = basis.pivots()
1887
+ r = basis.rank()
1888
+ coerce = matrix(base, d, d-r)
1889
+ indices = []
1890
+ i = 0
1891
+ for j in range(d):
1892
+ if i < r and pivots[i] == j:
1893
+ i += 1
1894
+ else:
1895
+ indices.append(j)
1896
+ coerce[j, j-i] = base.one()
1897
+ for i in range(r):
1898
+ for j in range(d-r):
1899
+ coerce[pivots[i], j] = -basis[i, indices[j]]
1900
+ rows = [cover.gen(i).image() * coerce for i in indices]
1901
+ OreModule.__init__(self, matrix(base, rows),
1902
+ cover.ore_ring(action=False),
1903
+ names, cover._ore_category)
1904
+ self._indices = indices
1905
+ self._project = coerce = cover.hom(coerce, codomain=self)
1906
+ self.register_coercion(coerce)
1907
+ cover.register_conversion(OreModuleSection(self, cover))
1908
+
1909
+ def _repr_element(self, x) -> str:
1910
+ r"""
1911
+ Return a string representation of `x`.
1912
+
1913
+ By default, elements in a Ore quotient are printed as
1914
+ their (canonical) representatives.
1915
+
1916
+ TESTS::
1917
+
1918
+ sage: K.<t> = Frac(GF(5)['t'])
1919
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1920
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1921
+ sage: Q = M.quo((X + t)*v)
1922
+ sage: Q.an_element() # indirect doctest
1923
+ w
1924
+ """
1925
+ M = self._cover
1926
+ indices = self._indices
1927
+ base = self.base_ring()
1928
+ coords = M.rank() * [base.zero()]
1929
+ for i in range(self.rank()):
1930
+ coords[indices[i]] = x[i]
1931
+ return M(coords)._repr_()
1932
+
1933
+ def _latex_element(self, x) -> str:
1934
+ r"""
1935
+ Return a LaTeX representation of `x`.
1936
+
1937
+ By default, elements in a Ore quotient are rendered as
1938
+ their (canonical) representatives with a bar.
1939
+
1940
+ TESTS::
1941
+
1942
+ sage: K.<t> = Frac(GF(5)['t'])
1943
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1944
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1945
+ sage: Q = M.quo((X + t)*v)
1946
+ sage: latex(Q.an_element()) # indirect doctest
1947
+ \overline{w}
1948
+ """
1949
+ M = self._cover
1950
+ indices = self._indices
1951
+ base = self.base_ring()
1952
+ coords = M.rank() * [base.zero()]
1953
+ for i in range(self.rank()):
1954
+ coords[indices[i]] = x[i]
1955
+ return "\\overline{%s}" % M(coords)._latex_()
1956
+
1957
+ def cover(self):
1958
+ r"""
1959
+ If this quotient in `M/N`, return `M`.
1960
+
1961
+ EXAMPLES::
1962
+
1963
+ sage: K.<t> = Frac(GF(5)['t'])
1964
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1965
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1966
+ sage: N = M.quo((X + t)*v)
1967
+
1968
+ sage: N.cover()
1969
+ Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1970
+ sage: N.cover() is M
1971
+ True
1972
+
1973
+ .. SEEALSO::
1974
+
1975
+ :meth:`relations`
1976
+ """
1977
+ return self._cover
1978
+
1979
+ def relations(self, names=None):
1980
+ r"""
1981
+ If this quotient in `M/N`, return `N`.
1982
+
1983
+ INPUT:
1984
+
1985
+ - ``names`` -- the names of the vectors of the basis
1986
+ of `N`, or ``None``
1987
+
1988
+ EXAMPLES::
1989
+
1990
+ sage: K.<t> = Frac(GF(5)['t'])
1991
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
1992
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
1993
+ sage: Q = M.quo((X + t)*v)
1994
+
1995
+ sage: N = Q.relations()
1996
+ sage: N
1997
+ Ore module of rank 1 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
1998
+ sage: (X + t)*v in N
1999
+ True
2000
+ sage: Q == M/N
2001
+ True
2002
+
2003
+ It is also possible to define names for the basis elements
2004
+ of `N`::
2005
+
2006
+ sage: N.<u> = Q.relations()
2007
+ sage: N
2008
+ Ore module <u> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2009
+ sage: M(u)
2010
+ v + 1/t*w
2011
+
2012
+ .. SEEALSO::
2013
+
2014
+ :meth:`relations`
2015
+ """
2016
+ return self._submodule_class(self._cover, self._relations, names=names)
2017
+
2018
+ def rename_basis(self, names, coerce=False):
2019
+ r"""
2020
+ Return the same Ore module with the given naming
2021
+ for the vectors in its distinguished basis.
2022
+
2023
+ INPUT:
2024
+
2025
+ - ``names`` -- a string or a list of strings, the
2026
+ new names
2027
+
2028
+ - ``coerce`` (default: ``False``) -- a boolean; if
2029
+ ``True``, a coercion map from this Ore module to
2030
+ the renamed version is set
2031
+
2032
+ EXAMPLES::
2033
+
2034
+ sage: K.<z> = GF(5^3)
2035
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
2036
+ sage: M = S.quotient_module(X^2 + z*X + 1)
2037
+ sage: M
2038
+ Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5
2039
+
2040
+ sage: Me = M.rename_basis('e')
2041
+ sage: Me
2042
+ Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5
2043
+
2044
+ Now compare how elements are displayed::
2045
+
2046
+ sage: M.random_element() # random
2047
+ (3*z^2 + 4*z + 2, 3*z^2 + z)
2048
+ sage: Me.random_element() # random
2049
+ (2*z + 4)*e0 + (z^2 + 4*z + 4)*e1
2050
+
2051
+ At this point, there is no coercion map between ``M``
2052
+ and ``Me``. Therefore, adding elements in both parents
2053
+ results in an error::
2054
+
2055
+ sage: M.random_element() + Me.random_element()
2056
+ Traceback (most recent call last):
2057
+ ...
2058
+ TypeError: unsupported operand parent(s) for +:
2059
+ 'Ore module of rank 2 over Finite Field in z of size 5^3 twisted by z |--> z^5' and
2060
+ 'Ore module <e0, e1> over Finite Field in z of size 5^3 twisted by z |--> z^5'
2061
+
2062
+ In order to set this coercion, one should define ``Me``
2063
+ by passing the extra argument ``coerce=True``::
2064
+
2065
+ sage: Me = M.rename_basis('e', coerce=True)
2066
+ sage: M.random_element() + Me.random_element() # random
2067
+ 2*z^2*e0 + (z^2 + z + 4)*e1
2068
+
2069
+ .. WARNING::
2070
+
2071
+ Use ``coerce=True`` with extreme caution. Indeed,
2072
+ setting inappropriate coercion maps may result in a
2073
+ circular path in the coercion graph which, in turn,
2074
+ could eventually break the coercion system.
2075
+
2076
+ Note that the bracket construction also works::
2077
+
2078
+ sage: M.<v,w> = M.rename_basis()
2079
+ sage: M
2080
+ Ore module <v, w> over Finite Field in z of size 5^3 twisted by z |--> z^5
2081
+
2082
+ In this case, `v` and `w` are automatically defined::
2083
+
2084
+ sage: v + w
2085
+ v + w
2086
+
2087
+ TESTS::
2088
+
2089
+ sage: K.<z> = GF(5^3)
2090
+ sage: S.<X> = OrePolynomialRing(K, K.frobenius_endomorphism())
2091
+ sage: P = X + z
2092
+ sage: A.<v,w> = S.quotient_module(P^2)
2093
+ sage: M = A.quo(P*v)
2094
+ sage: Me = M.rename_basis('e', coerce=True)
2095
+ sage: M.an_element() + Me.an_element()
2096
+ 2*e0
2097
+
2098
+ """
2099
+ rank = self.rank()
2100
+ names = normalize_names(names, rank)
2101
+ cls = self.__class__
2102
+ M = cls.__classcall__(cls, self._cover, self._relations, names)
2103
+ if coerce:
2104
+ mat = identity_matrix(self.base_ring(), rank)
2105
+ id = self.hom(mat, codomain=M)
2106
+ M._unset_coercions_used()
2107
+ M.register_coercion(id)
2108
+ return M
2109
+
2110
+ def projection_morphism(self):
2111
+ r"""
2112
+ Return the projection from the cover module to this quotient.
2113
+
2114
+ EXAMPLES::
2115
+
2116
+ sage: K.<t> = Frac(GF(5)['t'])
2117
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
2118
+ sage: M.<v,w> = S.quotient_module((X + t)^2)
2119
+ sage: Q = M.quo((X + t)*v)
2120
+ sage: Q.projection_morphism()
2121
+ Ore module morphism:
2122
+ From: Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2123
+ To: Ore module of rank 1 over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2124
+ """
2125
+ return self._project
2126
+
2127
+ def morphism_quotient(self, f):
2128
+ r"""
2129
+ If this quotient in `M/N` and `f : M \to X` is a morphism
2130
+ vanishing on `N`, return the induced map `M/N \to X`.
2131
+
2132
+ EXAMPLES::
2133
+
2134
+ sage: K.<t> = Frac(GF(5)['t'])
2135
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
2136
+ sage: P = X + t
2137
+ sage: M.<v,w> = S.quotient_module(P^2)
2138
+ sage: Q.<wbar> = M.quo(P*v)
2139
+
2140
+ sage: f = M.hom({v: P*v})
2141
+ sage: f
2142
+ Ore module endomorphism of Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2143
+ sage: g = Q.morphism_quotient(f)
2144
+ sage: g
2145
+ Ore module morphism:
2146
+ From: Ore module <wbar> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2147
+ To: Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2148
+
2149
+ When the given morphism does not vanish on `N`, an error is raised::
2150
+
2151
+ sage: h = M.multiplication_map(X^5)
2152
+ sage: h
2153
+ Ore module endomorphism of Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2154
+ sage: Q.morphism_quotient(h)
2155
+ Traceback (most recent call last):
2156
+ ...
2157
+ ValueError: the morphism does not factor through this quotient
2158
+
2159
+ TESTS::
2160
+
2161
+ sage: Q.morphism_quotient(g)
2162
+ Traceback (most recent call last):
2163
+ ...
2164
+ ValueError: the domain of the morphism must be the cover ring
2165
+ """
2166
+ if f.domain() is not self._cover:
2167
+ raise ValueError("the domain of the morphism must be the cover ring")
2168
+ Z = self._relations * f._matrix
2169
+ if not Z.is_zero():
2170
+ raise ValueError("the morphism does not factor through this quotient")
2171
+ mat = f._matrix.matrix_from_rows(self._indices)
2172
+ return self.hom(mat, codomain=f.codomain())
2173
+
2174
+ def morphism_modulo(self, f):
2175
+ r"""
2176
+ If this quotient in `M/N` and `f : X \to M` is a morphism,
2177
+ return the induced map `X \to M/N`.
2178
+
2179
+ EXAMPLES::
2180
+
2181
+ sage: K.<t> = Frac(GF(5)['t'])
2182
+ sage: S.<X> = OrePolynomialRing(K, K.derivation())
2183
+ sage: P = X + t
2184
+ sage: M.<v,w> = S.quotient_module(P^2)
2185
+ sage: Q.<wbar> = M.quo(P*v)
2186
+
2187
+ sage: f = M.multiplication_map(X^5)
2188
+ sage: f
2189
+ Ore module endomorphism of Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2190
+ sage: g = Q.morphism_modulo(f)
2191
+ sage: g
2192
+ Ore module morphism:
2193
+ From: Ore module <v, w> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2194
+ To: Ore module <wbar> over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 twisted by d/dt
2195
+
2196
+ TESTS::
2197
+
2198
+ sage: Q.morphism_modulo(g)
2199
+ Traceback (most recent call last):
2200
+ ...
2201
+ ValueError: the codomain of the morphism must be the cover ring
2202
+ """
2203
+ if f.codomain() is not self._cover:
2204
+ raise ValueError("the codomain of the morphism must be the cover ring")
2205
+ return self._project * f
2206
+
2207
+ _hom_change_domain = morphism_quotient
2208
+ _hom_change_codomain = morphism_modulo