passagemath-modules 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_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 (806) hide show
  1. passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
  2. passagemath_modules-10.6.31rc3.dist-info/RECORD +806 -0
  3. passagemath_modules-10.6.31rc3.dist-info/WHEEL +6 -0
  4. passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_modules.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  6. passagemath_modules.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
  7. passagemath_modules.libs/libgsl-e3525837.so.28.0.0 +0 -0
  8. passagemath_modules.libs/libmpc-c5c421e1.so.3.3.1 +0 -0
  9. passagemath_modules.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
  10. passagemath_modules.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  11. sage/algebras/all__sagemath_modules.py +20 -0
  12. sage/algebras/catalog.py +148 -0
  13. sage/algebras/clifford_algebra.py +3107 -0
  14. sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  15. sage/algebras/clifford_algebra_element.pxd +16 -0
  16. sage/algebras/clifford_algebra_element.pyx +997 -0
  17. sage/algebras/commutative_dga.py +4252 -0
  18. sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-gnu.so +0 -0
  19. sage/algebras/exterior_algebra_groebner.pxd +55 -0
  20. sage/algebras/exterior_algebra_groebner.pyx +727 -0
  21. sage/algebras/finite_dimensional_algebras/all.py +2 -0
  22. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
  23. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  24. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
  25. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
  26. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
  27. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
  28. sage/algebras/finite_gca.py +528 -0
  29. sage/algebras/group_algebra.py +232 -0
  30. sage/algebras/lie_algebras/abelian.py +197 -0
  31. sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
  32. sage/algebras/lie_algebras/all.py +25 -0
  33. sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
  34. sage/algebras/lie_algebras/bch.py +177 -0
  35. sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
  36. sage/algebras/lie_algebras/bgg_resolution.py +232 -0
  37. sage/algebras/lie_algebras/center_uea.py +767 -0
  38. sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
  39. sage/algebras/lie_algebras/examples.py +683 -0
  40. sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
  41. sage/algebras/lie_algebras/heisenberg.py +820 -0
  42. sage/algebras/lie_algebras/lie_algebra.py +1562 -0
  43. sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  44. sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
  45. sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
  46. sage/algebras/lie_algebras/morphism.py +661 -0
  47. sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
  48. sage/algebras/lie_algebras/onsager.py +1324 -0
  49. sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
  50. sage/algebras/lie_algebras/quotient.py +462 -0
  51. sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
  52. sage/algebras/lie_algebras/representation.py +1040 -0
  53. sage/algebras/lie_algebras/structure_coefficients.py +459 -0
  54. sage/algebras/lie_algebras/subalgebra.py +967 -0
  55. sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
  56. sage/algebras/lie_algebras/verma_module.py +1630 -0
  57. sage/algebras/lie_algebras/virasoro.py +1186 -0
  58. sage/algebras/octonion_algebra.cpython-314-aarch64-linux-gnu.so +0 -0
  59. sage/algebras/octonion_algebra.pxd +20 -0
  60. sage/algebras/octonion_algebra.pyx +987 -0
  61. sage/algebras/orlik_solomon.py +907 -0
  62. sage/algebras/orlik_terao.py +779 -0
  63. sage/algebras/steenrod/all.py +7 -0
  64. sage/algebras/steenrod/steenrod_algebra.py +4258 -0
  65. sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
  66. sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
  67. sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
  68. sage/algebras/weyl_algebra.py +1126 -0
  69. sage/all__sagemath_modules.py +62 -0
  70. sage/calculus/all__sagemath_modules.py +19 -0
  71. sage/calculus/expr.py +205 -0
  72. sage/calculus/integration.cpython-314-aarch64-linux-gnu.so +0 -0
  73. sage/calculus/integration.pyx +698 -0
  74. sage/calculus/interpolation.cpython-314-aarch64-linux-gnu.so +0 -0
  75. sage/calculus/interpolation.pxd +13 -0
  76. sage/calculus/interpolation.pyx +387 -0
  77. sage/calculus/interpolators.cpython-314-aarch64-linux-gnu.so +0 -0
  78. sage/calculus/interpolators.pyx +326 -0
  79. sage/calculus/ode.cpython-314-aarch64-linux-gnu.so +0 -0
  80. sage/calculus/ode.pxd +5 -0
  81. sage/calculus/ode.pyx +610 -0
  82. sage/calculus/riemann.cpython-314-aarch64-linux-gnu.so +0 -0
  83. sage/calculus/riemann.pyx +1521 -0
  84. sage/calculus/test_sympy.py +201 -0
  85. sage/calculus/transforms/all.py +7 -0
  86. sage/calculus/transforms/dft.py +844 -0
  87. sage/calculus/transforms/dwt.cpython-314-aarch64-linux-gnu.so +0 -0
  88. sage/calculus/transforms/dwt.pxd +7 -0
  89. sage/calculus/transforms/dwt.pyx +160 -0
  90. sage/calculus/transforms/fft.cpython-314-aarch64-linux-gnu.so +0 -0
  91. sage/calculus/transforms/fft.pxd +12 -0
  92. sage/calculus/transforms/fft.pyx +487 -0
  93. sage/calculus/wester.py +662 -0
  94. sage/coding/abstract_code.py +1108 -0
  95. sage/coding/ag_code.py +868 -0
  96. sage/coding/ag_code_decoders.cpython-314-aarch64-linux-gnu.so +0 -0
  97. sage/coding/ag_code_decoders.pyx +2639 -0
  98. sage/coding/all.py +15 -0
  99. sage/coding/bch_code.py +494 -0
  100. sage/coding/binary_code.cpython-314-aarch64-linux-gnu.so +0 -0
  101. sage/coding/binary_code.pxd +124 -0
  102. sage/coding/binary_code.pyx +4139 -0
  103. sage/coding/bounds_catalog.py +43 -0
  104. sage/coding/channel.py +819 -0
  105. sage/coding/channels_catalog.py +29 -0
  106. sage/coding/code_bounds.py +755 -0
  107. sage/coding/code_constructions.py +804 -0
  108. sage/coding/codes_catalog.py +111 -0
  109. sage/coding/cyclic_code.py +1329 -0
  110. sage/coding/databases.py +316 -0
  111. sage/coding/decoder.py +373 -0
  112. sage/coding/decoders_catalog.py +88 -0
  113. sage/coding/delsarte_bounds.py +709 -0
  114. sage/coding/encoder.py +390 -0
  115. sage/coding/encoders_catalog.py +64 -0
  116. sage/coding/extended_code.py +468 -0
  117. sage/coding/gabidulin_code.py +1058 -0
  118. sage/coding/golay_code.py +404 -0
  119. sage/coding/goppa_code.py +441 -0
  120. sage/coding/grs_code.py +2371 -0
  121. sage/coding/guava.py +107 -0
  122. sage/coding/guruswami_sudan/all.py +1 -0
  123. sage/coding/guruswami_sudan/gs_decoder.py +897 -0
  124. sage/coding/guruswami_sudan/interpolation.py +409 -0
  125. sage/coding/guruswami_sudan/utils.py +176 -0
  126. sage/coding/hamming_code.py +176 -0
  127. sage/coding/information_set_decoder.py +1032 -0
  128. sage/coding/kasami_codes.cpython-314-aarch64-linux-gnu.so +0 -0
  129. sage/coding/kasami_codes.pyx +351 -0
  130. sage/coding/linear_code.py +3067 -0
  131. sage/coding/linear_code_no_metric.py +1354 -0
  132. sage/coding/linear_rank_metric.py +961 -0
  133. sage/coding/parity_check_code.py +353 -0
  134. sage/coding/punctured_code.py +719 -0
  135. sage/coding/reed_muller_code.py +999 -0
  136. sage/coding/self_dual_codes.py +942 -0
  137. sage/coding/source_coding/all.py +2 -0
  138. sage/coding/source_coding/huffman.py +553 -0
  139. sage/coding/subfield_subcode.py +423 -0
  140. sage/coding/two_weight_db.py +399 -0
  141. sage/combinat/all__sagemath_modules.py +7 -0
  142. sage/combinat/cartesian_product.py +347 -0
  143. sage/combinat/family.py +11 -0
  144. sage/combinat/free_module.py +1977 -0
  145. sage/combinat/root_system/all.py +147 -0
  146. sage/combinat/root_system/ambient_space.py +527 -0
  147. sage/combinat/root_system/associahedron.py +471 -0
  148. sage/combinat/root_system/braid_move_calculator.py +143 -0
  149. sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-gnu.so +0 -0
  150. sage/combinat/root_system/braid_orbit.pyx +144 -0
  151. sage/combinat/root_system/branching_rules.py +2301 -0
  152. sage/combinat/root_system/cartan_matrix.py +1245 -0
  153. sage/combinat/root_system/cartan_type.py +3069 -0
  154. sage/combinat/root_system/coxeter_group.py +162 -0
  155. sage/combinat/root_system/coxeter_matrix.py +1261 -0
  156. sage/combinat/root_system/coxeter_type.py +681 -0
  157. sage/combinat/root_system/dynkin_diagram.py +900 -0
  158. sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
  159. sage/combinat/root_system/fundamental_group.py +795 -0
  160. sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
  161. sage/combinat/root_system/integrable_representations.py +1227 -0
  162. sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
  163. sage/combinat/root_system/pieri_factors.py +1147 -0
  164. sage/combinat/root_system/plot.py +1615 -0
  165. sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
  166. sage/combinat/root_system/root_lattice_realizations.py +4628 -0
  167. sage/combinat/root_system/root_space.py +487 -0
  168. sage/combinat/root_system/root_system.py +882 -0
  169. sage/combinat/root_system/type_A.py +348 -0
  170. sage/combinat/root_system/type_A_affine.py +227 -0
  171. sage/combinat/root_system/type_A_infinity.py +241 -0
  172. sage/combinat/root_system/type_B.py +347 -0
  173. sage/combinat/root_system/type_BC_affine.py +287 -0
  174. sage/combinat/root_system/type_B_affine.py +216 -0
  175. sage/combinat/root_system/type_C.py +317 -0
  176. sage/combinat/root_system/type_C_affine.py +188 -0
  177. sage/combinat/root_system/type_D.py +357 -0
  178. sage/combinat/root_system/type_D_affine.py +208 -0
  179. sage/combinat/root_system/type_E.py +641 -0
  180. sage/combinat/root_system/type_E_affine.py +231 -0
  181. sage/combinat/root_system/type_F.py +387 -0
  182. sage/combinat/root_system/type_F_affine.py +137 -0
  183. sage/combinat/root_system/type_G.py +293 -0
  184. sage/combinat/root_system/type_G_affine.py +132 -0
  185. sage/combinat/root_system/type_H.py +105 -0
  186. sage/combinat/root_system/type_I.py +110 -0
  187. sage/combinat/root_system/type_Q.py +150 -0
  188. sage/combinat/root_system/type_affine.py +509 -0
  189. sage/combinat/root_system/type_dual.py +704 -0
  190. sage/combinat/root_system/type_folded.py +301 -0
  191. sage/combinat/root_system/type_marked.py +748 -0
  192. sage/combinat/root_system/type_reducible.py +601 -0
  193. sage/combinat/root_system/type_relabel.py +730 -0
  194. sage/combinat/root_system/type_super_A.py +837 -0
  195. sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
  196. sage/combinat/root_system/weight_space.py +639 -0
  197. sage/combinat/root_system/weyl_characters.py +2238 -0
  198. sage/crypto/__init__.py +4 -0
  199. sage/crypto/all.py +28 -0
  200. sage/crypto/block_cipher/all.py +7 -0
  201. sage/crypto/block_cipher/des.py +1065 -0
  202. sage/crypto/block_cipher/miniaes.py +2171 -0
  203. sage/crypto/block_cipher/present.py +909 -0
  204. sage/crypto/block_cipher/sdes.py +1527 -0
  205. sage/crypto/boolean_function.cpython-314-aarch64-linux-gnu.so +0 -0
  206. sage/crypto/boolean_function.pxd +10 -0
  207. sage/crypto/boolean_function.pyx +1487 -0
  208. sage/crypto/cipher.py +78 -0
  209. sage/crypto/classical.py +3668 -0
  210. sage/crypto/classical_cipher.py +569 -0
  211. sage/crypto/cryptosystem.py +387 -0
  212. sage/crypto/key_exchange/all.py +7 -0
  213. sage/crypto/key_exchange/catalog.py +24 -0
  214. sage/crypto/key_exchange/diffie_hellman.py +323 -0
  215. sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
  216. sage/crypto/lattice.py +312 -0
  217. sage/crypto/lfsr.py +295 -0
  218. sage/crypto/lwe.py +840 -0
  219. sage/crypto/mq/__init__.py +4 -0
  220. sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
  221. sage/crypto/mq/rijndael_gf.py +2345 -0
  222. sage/crypto/mq/sbox.py +7 -0
  223. sage/crypto/mq/sr.py +3344 -0
  224. sage/crypto/public_key/all.py +5 -0
  225. sage/crypto/public_key/blum_goldwasser.py +776 -0
  226. sage/crypto/sbox.cpython-314-aarch64-linux-gnu.so +0 -0
  227. sage/crypto/sbox.pyx +2090 -0
  228. sage/crypto/sboxes.py +2090 -0
  229. sage/crypto/stream.py +390 -0
  230. sage/crypto/stream_cipher.py +297 -0
  231. sage/crypto/util.py +519 -0
  232. sage/ext/all__sagemath_modules.py +1 -0
  233. sage/ext/interpreters/__init__.py +1 -0
  234. sage/ext/interpreters/all__sagemath_modules.py +2 -0
  235. sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-gnu.so +0 -0
  236. sage/ext/interpreters/wrapper_cc.pxd +30 -0
  237. sage/ext/interpreters/wrapper_cc.pyx +252 -0
  238. sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-gnu.so +0 -0
  239. sage/ext/interpreters/wrapper_cdf.pxd +26 -0
  240. sage/ext/interpreters/wrapper_cdf.pyx +245 -0
  241. sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-gnu.so +0 -0
  242. sage/ext/interpreters/wrapper_rdf.pxd +23 -0
  243. sage/ext/interpreters/wrapper_rdf.pyx +221 -0
  244. sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-gnu.so +0 -0
  245. sage/ext/interpreters/wrapper_rr.pxd +28 -0
  246. sage/ext/interpreters/wrapper_rr.pyx +335 -0
  247. sage/geometry/all__sagemath_modules.py +5 -0
  248. sage/geometry/toric_lattice.py +1745 -0
  249. sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-gnu.so +0 -0
  250. sage/geometry/toric_lattice_element.pyx +432 -0
  251. sage/groups/abelian_gps/abelian_group.py +1925 -0
  252. sage/groups/abelian_gps/abelian_group_element.py +164 -0
  253. sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
  254. sage/groups/abelian_gps/dual_abelian_group.py +421 -0
  255. sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
  256. sage/groups/abelian_gps/element_base.py +341 -0
  257. sage/groups/abelian_gps/values.py +488 -0
  258. sage/groups/additive_abelian/additive_abelian_group.py +476 -0
  259. sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
  260. sage/groups/additive_abelian/all.py +4 -0
  261. sage/groups/additive_abelian/qmodnz.py +231 -0
  262. sage/groups/additive_abelian/qmodnz_element.py +349 -0
  263. sage/groups/affine_gps/affine_group.py +535 -0
  264. sage/groups/affine_gps/all.py +1 -0
  265. sage/groups/affine_gps/catalog.py +17 -0
  266. sage/groups/affine_gps/euclidean_group.py +246 -0
  267. sage/groups/affine_gps/group_element.py +562 -0
  268. sage/groups/all__sagemath_modules.py +12 -0
  269. sage/groups/galois_group.py +479 -0
  270. sage/groups/matrix_gps/all.py +4 -0
  271. sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
  272. sage/groups/matrix_gps/catalog.py +26 -0
  273. sage/groups/matrix_gps/coxeter_group.py +927 -0
  274. sage/groups/matrix_gps/finitely_generated.py +487 -0
  275. sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-gnu.so +0 -0
  276. sage/groups/matrix_gps/group_element.pxd +11 -0
  277. sage/groups/matrix_gps/group_element.pyx +431 -0
  278. sage/groups/matrix_gps/linear.py +440 -0
  279. sage/groups/matrix_gps/matrix_group.py +617 -0
  280. sage/groups/matrix_gps/named_group.py +296 -0
  281. sage/groups/matrix_gps/orthogonal.py +544 -0
  282. sage/groups/matrix_gps/symplectic.py +251 -0
  283. sage/groups/matrix_gps/unitary.py +436 -0
  284. sage/groups/misc_gps/all__sagemath_modules.py +1 -0
  285. sage/groups/misc_gps/argument_groups.py +1905 -0
  286. sage/groups/misc_gps/imaginary_groups.py +479 -0
  287. sage/groups/perm_gps/all__sagemath_modules.py +1 -0
  288. sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
  289. sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-gnu.so +0 -0
  290. sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
  291. sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
  292. sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-gnu.so +0 -0
  293. sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
  294. sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
  295. sage/homology/algebraic_topological_model.py +595 -0
  296. sage/homology/all.py +2 -0
  297. sage/homology/all__sagemath_modules.py +8 -0
  298. sage/homology/chain_complex.py +2148 -0
  299. sage/homology/chain_complex_homspace.py +165 -0
  300. sage/homology/chain_complex_morphism.py +629 -0
  301. sage/homology/chain_homotopy.py +604 -0
  302. sage/homology/chains.py +653 -0
  303. sage/homology/free_resolution.py +923 -0
  304. sage/homology/graded_resolution.py +567 -0
  305. sage/homology/hochschild_complex.py +756 -0
  306. sage/homology/homology_group.py +188 -0
  307. sage/homology/homology_morphism.py +422 -0
  308. sage/homology/homology_vector_space_with_basis.py +1454 -0
  309. sage/homology/koszul_complex.py +169 -0
  310. sage/homology/matrix_utils.py +205 -0
  311. sage/libs/all__sagemath_modules.py +1 -0
  312. sage/libs/gsl/__init__.py +1 -0
  313. sage/libs/gsl/airy.pxd +56 -0
  314. sage/libs/gsl/all.pxd +66 -0
  315. sage/libs/gsl/array.cpython-314-aarch64-linux-gnu.so +0 -0
  316. sage/libs/gsl/array.pxd +5 -0
  317. sage/libs/gsl/array.pyx +102 -0
  318. sage/libs/gsl/bessel.pxd +208 -0
  319. sage/libs/gsl/blas.pxd +116 -0
  320. sage/libs/gsl/blas_types.pxd +34 -0
  321. sage/libs/gsl/block.pxd +52 -0
  322. sage/libs/gsl/chebyshev.pxd +37 -0
  323. sage/libs/gsl/clausen.pxd +12 -0
  324. sage/libs/gsl/combination.pxd +47 -0
  325. sage/libs/gsl/complex.pxd +151 -0
  326. sage/libs/gsl/coulomb.pxd +30 -0
  327. sage/libs/gsl/coupling.pxd +21 -0
  328. sage/libs/gsl/dawson.pxd +12 -0
  329. sage/libs/gsl/debye.pxd +24 -0
  330. sage/libs/gsl/dilog.pxd +14 -0
  331. sage/libs/gsl/eigen.pxd +46 -0
  332. sage/libs/gsl/elementary.pxd +12 -0
  333. sage/libs/gsl/ellint.pxd +48 -0
  334. sage/libs/gsl/elljac.pxd +8 -0
  335. sage/libs/gsl/erf.pxd +32 -0
  336. sage/libs/gsl/errno.pxd +26 -0
  337. sage/libs/gsl/exp.pxd +44 -0
  338. sage/libs/gsl/expint.pxd +44 -0
  339. sage/libs/gsl/fermi_dirac.pxd +44 -0
  340. sage/libs/gsl/fft.pxd +121 -0
  341. sage/libs/gsl/fit.pxd +50 -0
  342. sage/libs/gsl/gamma.pxd +94 -0
  343. sage/libs/gsl/gegenbauer.pxd +26 -0
  344. sage/libs/gsl/histogram.pxd +176 -0
  345. sage/libs/gsl/hyperg.pxd +52 -0
  346. sage/libs/gsl/integration.pxd +69 -0
  347. sage/libs/gsl/interp.pxd +109 -0
  348. sage/libs/gsl/laguerre.pxd +24 -0
  349. sage/libs/gsl/lambert.pxd +16 -0
  350. sage/libs/gsl/legendre.pxd +90 -0
  351. sage/libs/gsl/linalg.pxd +185 -0
  352. sage/libs/gsl/log.pxd +26 -0
  353. sage/libs/gsl/math.pxd +43 -0
  354. sage/libs/gsl/matrix.pxd +143 -0
  355. sage/libs/gsl/matrix_complex.pxd +130 -0
  356. sage/libs/gsl/min.pxd +67 -0
  357. sage/libs/gsl/monte.pxd +56 -0
  358. sage/libs/gsl/ntuple.pxd +32 -0
  359. sage/libs/gsl/odeiv.pxd +70 -0
  360. sage/libs/gsl/permutation.pxd +78 -0
  361. sage/libs/gsl/poly.pxd +40 -0
  362. sage/libs/gsl/pow_int.pxd +12 -0
  363. sage/libs/gsl/psi.pxd +28 -0
  364. sage/libs/gsl/qrng.pxd +29 -0
  365. sage/libs/gsl/random.pxd +257 -0
  366. sage/libs/gsl/rng.pxd +100 -0
  367. sage/libs/gsl/roots.pxd +72 -0
  368. sage/libs/gsl/sort.pxd +36 -0
  369. sage/libs/gsl/statistics.pxd +59 -0
  370. sage/libs/gsl/sum.pxd +55 -0
  371. sage/libs/gsl/synchrotron.pxd +16 -0
  372. sage/libs/gsl/transport.pxd +24 -0
  373. sage/libs/gsl/trig.pxd +58 -0
  374. sage/libs/gsl/types.pxd +137 -0
  375. sage/libs/gsl/vector.pxd +101 -0
  376. sage/libs/gsl/vector_complex.pxd +83 -0
  377. sage/libs/gsl/wavelet.pxd +49 -0
  378. sage/libs/gsl/zeta.pxd +28 -0
  379. sage/libs/mpc/__init__.pxd +114 -0
  380. sage/libs/mpc/types.pxd +28 -0
  381. sage/libs/mpfr/__init__.pxd +299 -0
  382. sage/libs/mpfr/types.pxd +26 -0
  383. sage/libs/mpmath/__init__.py +1 -0
  384. sage/libs/mpmath/all.py +27 -0
  385. sage/libs/mpmath/all__sagemath_modules.py +1 -0
  386. sage/libs/mpmath/utils.cpython-314-aarch64-linux-gnu.so +0 -0
  387. sage/libs/mpmath/utils.pxd +4 -0
  388. sage/libs/mpmath/utils.pyx +319 -0
  389. sage/matrix/action.cpython-314-aarch64-linux-gnu.so +0 -0
  390. sage/matrix/action.pxd +26 -0
  391. sage/matrix/action.pyx +596 -0
  392. sage/matrix/all.py +9 -0
  393. sage/matrix/args.cpython-314-aarch64-linux-gnu.so +0 -0
  394. sage/matrix/args.pxd +144 -0
  395. sage/matrix/args.pyx +1668 -0
  396. sage/matrix/benchmark.py +1258 -0
  397. sage/matrix/berlekamp_massey.py +95 -0
  398. sage/matrix/compute_J_ideal.py +926 -0
  399. sage/matrix/constructor.cpython-314-aarch64-linux-gnu.so +0 -0
  400. sage/matrix/constructor.pyx +750 -0
  401. sage/matrix/docs.py +430 -0
  402. sage/matrix/echelon_matrix.cpython-314-aarch64-linux-gnu.so +0 -0
  403. sage/matrix/echelon_matrix.pyx +155 -0
  404. sage/matrix/matrix.pxd +2 -0
  405. sage/matrix/matrix0.cpython-314-aarch64-linux-gnu.so +0 -0
  406. sage/matrix/matrix0.pxd +68 -0
  407. sage/matrix/matrix0.pyx +6324 -0
  408. sage/matrix/matrix1.cpython-314-aarch64-linux-gnu.so +0 -0
  409. sage/matrix/matrix1.pxd +8 -0
  410. sage/matrix/matrix1.pyx +2851 -0
  411. sage/matrix/matrix2.cpython-314-aarch64-linux-gnu.so +0 -0
  412. sage/matrix/matrix2.pxd +25 -0
  413. sage/matrix/matrix2.pyx +20181 -0
  414. sage/matrix/matrix_cdv.cpython-314-aarch64-linux-gnu.so +0 -0
  415. sage/matrix/matrix_cdv.pxd +4 -0
  416. sage/matrix/matrix_cdv.pyx +93 -0
  417. sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  418. sage/matrix/matrix_complex_double_dense.pxd +5 -0
  419. sage/matrix/matrix_complex_double_dense.pyx +98 -0
  420. sage/matrix/matrix_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  421. sage/matrix/matrix_dense.pxd +5 -0
  422. sage/matrix/matrix_dense.pyx +343 -0
  423. sage/matrix/matrix_domain_dense.pxd +5 -0
  424. sage/matrix/matrix_domain_sparse.pxd +5 -0
  425. sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  426. sage/matrix/matrix_double_dense.pxd +7 -0
  427. sage/matrix/matrix_double_dense.pyx +3906 -0
  428. sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  429. sage/matrix/matrix_double_sparse.pxd +6 -0
  430. sage/matrix/matrix_double_sparse.pyx +248 -0
  431. sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  432. sage/matrix/matrix_generic_dense.pxd +7 -0
  433. sage/matrix/matrix_generic_dense.pyx +354 -0
  434. sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  435. sage/matrix/matrix_generic_sparse.pxd +7 -0
  436. sage/matrix/matrix_generic_sparse.pyx +461 -0
  437. sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  438. sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
  439. sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
  440. sage/matrix/matrix_misc.py +313 -0
  441. sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  442. sage/matrix/matrix_numpy_dense.pxd +14 -0
  443. sage/matrix/matrix_numpy_dense.pyx +450 -0
  444. sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  445. sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
  446. sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
  447. sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  448. sage/matrix/matrix_polynomial_dense.pxd +5 -0
  449. sage/matrix/matrix_polynomial_dense.pyx +5341 -0
  450. sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  451. sage/matrix/matrix_real_double_dense.pxd +7 -0
  452. sage/matrix/matrix_real_double_dense.pyx +122 -0
  453. sage/matrix/matrix_space.py +2848 -0
  454. sage/matrix/matrix_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  455. sage/matrix/matrix_sparse.pxd +5 -0
  456. sage/matrix/matrix_sparse.pyx +1222 -0
  457. sage/matrix/matrix_window.cpython-314-aarch64-linux-gnu.so +0 -0
  458. sage/matrix/matrix_window.pxd +37 -0
  459. sage/matrix/matrix_window.pyx +242 -0
  460. sage/matrix/misc_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  461. sage/matrix/misc_mpfr.pyx +80 -0
  462. sage/matrix/operation_table.py +1182 -0
  463. sage/matrix/special.py +3666 -0
  464. sage/matrix/strassen.cpython-314-aarch64-linux-gnu.so +0 -0
  465. sage/matrix/strassen.pyx +851 -0
  466. sage/matrix/symplectic_basis.py +541 -0
  467. sage/matrix/template.pxd +6 -0
  468. sage/matrix/tests.py +71 -0
  469. sage/matroids/advanced.py +77 -0
  470. sage/matroids/all.py +13 -0
  471. sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  472. sage/matroids/basis_exchange_matroid.pxd +96 -0
  473. sage/matroids/basis_exchange_matroid.pyx +2344 -0
  474. sage/matroids/basis_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  475. sage/matroids/basis_matroid.pxd +45 -0
  476. sage/matroids/basis_matroid.pyx +1217 -0
  477. sage/matroids/catalog.py +44 -0
  478. sage/matroids/chow_ring.py +473 -0
  479. sage/matroids/chow_ring_ideal.py +849 -0
  480. sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  481. sage/matroids/circuit_closures_matroid.pxd +16 -0
  482. sage/matroids/circuit_closures_matroid.pyx +559 -0
  483. sage/matroids/circuits_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  484. sage/matroids/circuits_matroid.pxd +38 -0
  485. sage/matroids/circuits_matroid.pyx +947 -0
  486. sage/matroids/constructor.py +1086 -0
  487. sage/matroids/database_collections.py +365 -0
  488. sage/matroids/database_matroids.py +5338 -0
  489. sage/matroids/dual_matroid.py +583 -0
  490. sage/matroids/extension.cpython-314-aarch64-linux-gnu.so +0 -0
  491. sage/matroids/extension.pxd +34 -0
  492. sage/matroids/extension.pyx +519 -0
  493. sage/matroids/flats_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  494. sage/matroids/flats_matroid.pxd +28 -0
  495. sage/matroids/flats_matroid.pyx +715 -0
  496. sage/matroids/gammoid.py +600 -0
  497. sage/matroids/graphic_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  498. sage/matroids/graphic_matroid.pxd +39 -0
  499. sage/matroids/graphic_matroid.pyx +2024 -0
  500. sage/matroids/lean_matrix.cpython-314-aarch64-linux-gnu.so +0 -0
  501. sage/matroids/lean_matrix.pxd +126 -0
  502. sage/matroids/lean_matrix.pyx +3667 -0
  503. sage/matroids/linear_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  504. sage/matroids/linear_matroid.pxd +180 -0
  505. sage/matroids/linear_matroid.pyx +6649 -0
  506. sage/matroids/matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  507. sage/matroids/matroid.pxd +243 -0
  508. sage/matroids/matroid.pyx +8759 -0
  509. sage/matroids/matroids_catalog.py +190 -0
  510. sage/matroids/matroids_plot_helpers.py +890 -0
  511. sage/matroids/minor_matroid.py +480 -0
  512. sage/matroids/minorfix.h +9 -0
  513. sage/matroids/named_matroids.py +5 -0
  514. sage/matroids/rank_matroid.py +268 -0
  515. sage/matroids/set_system.cpython-314-aarch64-linux-gnu.so +0 -0
  516. sage/matroids/set_system.pxd +38 -0
  517. sage/matroids/set_system.pyx +800 -0
  518. sage/matroids/transversal_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  519. sage/matroids/transversal_matroid.pxd +14 -0
  520. sage/matroids/transversal_matroid.pyx +893 -0
  521. sage/matroids/union_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  522. sage/matroids/union_matroid.pxd +20 -0
  523. sage/matroids/union_matroid.pyx +331 -0
  524. sage/matroids/unpickling.cpython-314-aarch64-linux-gnu.so +0 -0
  525. sage/matroids/unpickling.pyx +843 -0
  526. sage/matroids/utilities.py +809 -0
  527. sage/misc/all__sagemath_modules.py +20 -0
  528. sage/misc/c3.cpython-314-aarch64-linux-gnu.so +0 -0
  529. sage/misc/c3.pyx +238 -0
  530. sage/misc/compat.py +87 -0
  531. sage/misc/element_with_label.py +173 -0
  532. sage/misc/func_persist.py +79 -0
  533. sage/misc/pickle_old.cpython-314-aarch64-linux-gnu.so +0 -0
  534. sage/misc/pickle_old.pyx +19 -0
  535. sage/misc/proof.py +7 -0
  536. sage/misc/replace_dot_all.py +472 -0
  537. sage/misc/sagedoc_conf.py +168 -0
  538. sage/misc/sphinxify.py +167 -0
  539. sage/misc/test_class_pickling.py +85 -0
  540. sage/modules/all.py +42 -0
  541. sage/modules/complex_double_vector.py +25 -0
  542. sage/modules/diamond_cutting.py +380 -0
  543. sage/modules/fg_pid/all.py +1 -0
  544. sage/modules/fg_pid/fgp_element.py +456 -0
  545. sage/modules/fg_pid/fgp_module.py +2091 -0
  546. sage/modules/fg_pid/fgp_morphism.py +550 -0
  547. sage/modules/filtered_vector_space.py +1271 -0
  548. sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-gnu.so +0 -0
  549. sage/modules/finite_submodule_iter.pxd +27 -0
  550. sage/modules/finite_submodule_iter.pyx +452 -0
  551. sage/modules/fp_graded/all.py +1 -0
  552. sage/modules/fp_graded/element.py +346 -0
  553. sage/modules/fp_graded/free_element.py +298 -0
  554. sage/modules/fp_graded/free_homspace.py +53 -0
  555. sage/modules/fp_graded/free_module.py +1060 -0
  556. sage/modules/fp_graded/free_morphism.py +217 -0
  557. sage/modules/fp_graded/homspace.py +563 -0
  558. sage/modules/fp_graded/module.py +1340 -0
  559. sage/modules/fp_graded/morphism.py +1990 -0
  560. sage/modules/fp_graded/steenrod/all.py +1 -0
  561. sage/modules/fp_graded/steenrod/homspace.py +65 -0
  562. sage/modules/fp_graded/steenrod/module.py +477 -0
  563. sage/modules/fp_graded/steenrod/morphism.py +404 -0
  564. sage/modules/fp_graded/steenrod/profile.py +241 -0
  565. sage/modules/free_module.py +8447 -0
  566. sage/modules/free_module_element.cpython-314-aarch64-linux-gnu.so +0 -0
  567. sage/modules/free_module_element.pxd +22 -0
  568. sage/modules/free_module_element.pyx +5445 -0
  569. sage/modules/free_module_homspace.py +369 -0
  570. sage/modules/free_module_integer.py +896 -0
  571. sage/modules/free_module_morphism.py +823 -0
  572. sage/modules/free_module_pseudohomspace.py +352 -0
  573. sage/modules/free_module_pseudomorphism.py +578 -0
  574. sage/modules/free_quadratic_module.py +1706 -0
  575. sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
  576. sage/modules/matrix_morphism.py +1745 -0
  577. sage/modules/misc.py +103 -0
  578. sage/modules/module_functors.py +192 -0
  579. sage/modules/multi_filtered_vector_space.py +719 -0
  580. sage/modules/ore_module.py +2208 -0
  581. sage/modules/ore_module_element.py +178 -0
  582. sage/modules/ore_module_homspace.py +147 -0
  583. sage/modules/ore_module_morphism.py +968 -0
  584. sage/modules/quotient_module.py +699 -0
  585. sage/modules/real_double_vector.py +22 -0
  586. sage/modules/submodule.py +255 -0
  587. sage/modules/tensor_operations.py +567 -0
  588. sage/modules/torsion_quadratic_module.py +1352 -0
  589. sage/modules/tutorial_free_modules.py +248 -0
  590. sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  591. sage/modules/vector_complex_double_dense.pxd +6 -0
  592. sage/modules/vector_complex_double_dense.pyx +117 -0
  593. sage/modules/vector_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  594. sage/modules/vector_double_dense.pxd +6 -0
  595. sage/modules/vector_double_dense.pyx +604 -0
  596. sage/modules/vector_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  597. sage/modules/vector_integer_dense.pxd +15 -0
  598. sage/modules/vector_integer_dense.pyx +361 -0
  599. sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  600. sage/modules/vector_integer_sparse.pxd +29 -0
  601. sage/modules/vector_integer_sparse.pyx +406 -0
  602. sage/modules/vector_modn_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  603. sage/modules/vector_modn_dense.pxd +12 -0
  604. sage/modules/vector_modn_dense.pyx +394 -0
  605. sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  606. sage/modules/vector_modn_sparse.pxd +21 -0
  607. sage/modules/vector_modn_sparse.pyx +298 -0
  608. sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  609. sage/modules/vector_numpy_dense.pxd +15 -0
  610. sage/modules/vector_numpy_dense.pyx +304 -0
  611. sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  612. sage/modules/vector_numpy_integer_dense.pxd +7 -0
  613. sage/modules/vector_numpy_integer_dense.pyx +54 -0
  614. sage/modules/vector_rational_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  615. sage/modules/vector_rational_dense.pxd +15 -0
  616. sage/modules/vector_rational_dense.pyx +387 -0
  617. sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  618. sage/modules/vector_rational_sparse.pxd +30 -0
  619. sage/modules/vector_rational_sparse.pyx +413 -0
  620. sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  621. sage/modules/vector_real_double_dense.pxd +6 -0
  622. sage/modules/vector_real_double_dense.pyx +126 -0
  623. sage/modules/vector_space_homspace.py +430 -0
  624. sage/modules/vector_space_morphism.py +989 -0
  625. sage/modules/with_basis/all.py +15 -0
  626. sage/modules/with_basis/cell_module.py +494 -0
  627. sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-gnu.so +0 -0
  628. sage/modules/with_basis/indexed_element.pxd +13 -0
  629. sage/modules/with_basis/indexed_element.pyx +1058 -0
  630. sage/modules/with_basis/invariant.py +1075 -0
  631. sage/modules/with_basis/morphism.py +1636 -0
  632. sage/modules/with_basis/representation.py +2939 -0
  633. sage/modules/with_basis/subquotient.py +685 -0
  634. sage/numerical/all__sagemath_modules.py +6 -0
  635. sage/numerical/gauss_legendre.cpython-314-aarch64-linux-gnu.so +0 -0
  636. sage/numerical/gauss_legendre.pyx +381 -0
  637. sage/numerical/optimize.py +910 -0
  638. sage/probability/all.py +10 -0
  639. sage/probability/probability_distribution.cpython-314-aarch64-linux-gnu.so +0 -0
  640. sage/probability/probability_distribution.pyx +1242 -0
  641. sage/probability/random_variable.py +411 -0
  642. sage/quadratic_forms/all.py +4 -0
  643. sage/quadratic_forms/all__sagemath_modules.py +15 -0
  644. sage/quadratic_forms/binary_qf.py +2042 -0
  645. sage/quadratic_forms/bqf_class_group.py +748 -0
  646. sage/quadratic_forms/constructions.py +93 -0
  647. sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-gnu.so +0 -0
  648. sage/quadratic_forms/count_local_2.pyx +365 -0
  649. sage/quadratic_forms/extras.py +195 -0
  650. sage/quadratic_forms/quadratic_form.py +1753 -0
  651. sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
  652. sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
  653. sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-gnu.so +0 -0
  654. sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
  655. sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
  656. sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
  657. sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
  658. sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
  659. sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
  660. sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
  661. sage/quadratic_forms/quadratic_form__theta.py +352 -0
  662. sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
  663. sage/quadratic_forms/random_quadraticform.py +209 -0
  664. sage/quadratic_forms/ternary.cpython-314-aarch64-linux-gnu.so +0 -0
  665. sage/quadratic_forms/ternary.pyx +1154 -0
  666. sage/quadratic_forms/ternary_qf.py +2027 -0
  667. sage/rings/all__sagemath_modules.py +28 -0
  668. sage/rings/asymptotic/all__sagemath_modules.py +1 -0
  669. sage/rings/asymptotic/misc.py +1252 -0
  670. sage/rings/cc.py +4 -0
  671. sage/rings/cfinite_sequence.py +1306 -0
  672. sage/rings/complex_conversion.cpython-314-aarch64-linux-gnu.so +0 -0
  673. sage/rings/complex_conversion.pxd +8 -0
  674. sage/rings/complex_conversion.pyx +23 -0
  675. sage/rings/complex_double.cpython-314-aarch64-linux-gnu.so +0 -0
  676. sage/rings/complex_double.pxd +21 -0
  677. sage/rings/complex_double.pyx +2654 -0
  678. sage/rings/complex_mpc.cpython-314-aarch64-linux-gnu.so +0 -0
  679. sage/rings/complex_mpc.pxd +21 -0
  680. sage/rings/complex_mpc.pyx +2576 -0
  681. sage/rings/complex_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  682. sage/rings/complex_mpfr.pxd +18 -0
  683. sage/rings/complex_mpfr.pyx +3602 -0
  684. sage/rings/derivation.py +2334 -0
  685. sage/rings/finite_rings/all__sagemath_modules.py +1 -0
  686. sage/rings/finite_rings/maps_finite_field.py +191 -0
  687. sage/rings/function_field/all__sagemath_modules.py +8 -0
  688. sage/rings/function_field/derivations.py +102 -0
  689. sage/rings/function_field/derivations_rational.py +132 -0
  690. sage/rings/function_field/differential.py +853 -0
  691. sage/rings/function_field/divisor.py +1107 -0
  692. sage/rings/function_field/drinfeld_modules/action.py +199 -0
  693. sage/rings/function_field/drinfeld_modules/all.py +1 -0
  694. sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
  695. sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
  696. sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
  697. sage/rings/function_field/drinfeld_modules/homset.py +420 -0
  698. sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
  699. sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-gnu.so +0 -0
  700. sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
  701. sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-gnu.so +0 -0
  702. sage/rings/function_field/khuri_makdisi.pyx +935 -0
  703. sage/rings/invariants/all.py +4 -0
  704. sage/rings/invariants/invariant_theory.py +4597 -0
  705. sage/rings/invariants/reconstruction.py +395 -0
  706. sage/rings/polynomial/all__sagemath_modules.py +17 -0
  707. sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
  708. sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-gnu.so +0 -0
  709. sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
  710. sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
  711. sage/rings/polynomial/ore_function_element.py +952 -0
  712. sage/rings/polynomial/ore_function_field.py +1028 -0
  713. sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-gnu.so +0 -0
  714. sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
  715. sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
  716. sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
  717. sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  718. sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
  719. sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
  720. sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-gnu.so +0 -0
  721. sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
  722. sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
  723. sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-gnu.so +0 -0
  724. sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
  725. sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
  726. sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-gnu.so +0 -0
  727. sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
  728. sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
  729. sage/rings/polynomial/skew_polynomial_ring.py +908 -0
  730. sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-gnu.so +0 -0
  731. sage/rings/real_double_element_gsl.pxd +8 -0
  732. sage/rings/real_double_element_gsl.pyx +794 -0
  733. sage/rings/real_field.py +58 -0
  734. sage/rings/real_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  735. sage/rings/real_mpfr.pxd +29 -0
  736. sage/rings/real_mpfr.pyx +6122 -0
  737. sage/rings/ring_extension.cpython-314-aarch64-linux-gnu.so +0 -0
  738. sage/rings/ring_extension.pxd +42 -0
  739. sage/rings/ring_extension.pyx +2779 -0
  740. sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-gnu.so +0 -0
  741. sage/rings/ring_extension_conversion.pxd +16 -0
  742. sage/rings/ring_extension_conversion.pyx +462 -0
  743. sage/rings/ring_extension_element.cpython-314-aarch64-linux-gnu.so +0 -0
  744. sage/rings/ring_extension_element.pxd +21 -0
  745. sage/rings/ring_extension_element.pyx +1635 -0
  746. sage/rings/ring_extension_homset.py +64 -0
  747. sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-gnu.so +0 -0
  748. sage/rings/ring_extension_morphism.pxd +35 -0
  749. sage/rings/ring_extension_morphism.pyx +920 -0
  750. sage/schemes/all__sagemath_modules.py +1 -0
  751. sage/schemes/projective/all__sagemath_modules.py +1 -0
  752. sage/schemes/projective/coherent_sheaf.py +300 -0
  753. sage/schemes/projective/cohomology.py +510 -0
  754. sage/stats/all.py +15 -0
  755. sage/stats/basic_stats.py +489 -0
  756. sage/stats/distributions/all.py +7 -0
  757. sage/stats/distributions/catalog.py +34 -0
  758. sage/stats/distributions/dgs.h +50 -0
  759. sage/stats/distributions/dgs.pxd +111 -0
  760. sage/stats/distributions/dgs_bern.h +400 -0
  761. sage/stats/distributions/dgs_gauss.h +614 -0
  762. sage/stats/distributions/dgs_misc.h +104 -0
  763. sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-gnu.so +0 -0
  764. sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
  765. sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
  766. sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
  767. sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
  768. sage/stats/hmm/all.py +15 -0
  769. sage/stats/hmm/chmm.cpython-314-aarch64-linux-gnu.so +0 -0
  770. sage/stats/hmm/chmm.pyx +1595 -0
  771. sage/stats/hmm/distributions.cpython-314-aarch64-linux-gnu.so +0 -0
  772. sage/stats/hmm/distributions.pxd +29 -0
  773. sage/stats/hmm/distributions.pyx +531 -0
  774. sage/stats/hmm/hmm.cpython-314-aarch64-linux-gnu.so +0 -0
  775. sage/stats/hmm/hmm.pxd +17 -0
  776. sage/stats/hmm/hmm.pyx +1388 -0
  777. sage/stats/hmm/util.cpython-314-aarch64-linux-gnu.so +0 -0
  778. sage/stats/hmm/util.pxd +7 -0
  779. sage/stats/hmm/util.pyx +165 -0
  780. sage/stats/intlist.cpython-314-aarch64-linux-gnu.so +0 -0
  781. sage/stats/intlist.pxd +14 -0
  782. sage/stats/intlist.pyx +588 -0
  783. sage/stats/r.py +49 -0
  784. sage/stats/time_series.cpython-314-aarch64-linux-gnu.so +0 -0
  785. sage/stats/time_series.pxd +6 -0
  786. sage/stats/time_series.pyx +2546 -0
  787. sage/tensor/all.py +2 -0
  788. sage/tensor/modules/all.py +8 -0
  789. sage/tensor/modules/alternating_contr_tensor.py +761 -0
  790. sage/tensor/modules/comp.py +5598 -0
  791. sage/tensor/modules/ext_pow_free_module.py +824 -0
  792. sage/tensor/modules/finite_rank_free_module.py +3589 -0
  793. sage/tensor/modules/format_utilities.py +333 -0
  794. sage/tensor/modules/free_module_alt_form.py +858 -0
  795. sage/tensor/modules/free_module_automorphism.py +1207 -0
  796. sage/tensor/modules/free_module_basis.py +1074 -0
  797. sage/tensor/modules/free_module_element.py +284 -0
  798. sage/tensor/modules/free_module_homset.py +652 -0
  799. sage/tensor/modules/free_module_linear_group.py +564 -0
  800. sage/tensor/modules/free_module_morphism.py +1581 -0
  801. sage/tensor/modules/free_module_tensor.py +3289 -0
  802. sage/tensor/modules/reflexive_module.py +386 -0
  803. sage/tensor/modules/tensor_free_module.py +780 -0
  804. sage/tensor/modules/tensor_free_submodule.py +538 -0
  805. sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
  806. sage/tensor/modules/tensor_with_indices.py +1043 -0
@@ -0,0 +1,1636 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ r"""
3
+ Morphisms of modules with a basis
4
+
5
+ This module contains a hierarchy of classes for morphisms of modules
6
+ with a basis (category :class:`Modules.WithBasis`):
7
+
8
+ - :class:`ModuleMorphism`
9
+ - :class:`ModuleMorphismByLinearity`
10
+ - :class:`ModuleMorphismFromMatrix`
11
+ - :class:`ModuleMorphismFromFunction`
12
+ - :class:`TriangularModuleMorphism`
13
+ - :class:`TriangularModuleMorphismByLinearity`
14
+ - :class:`TriangularModuleMorphismFromFunction`
15
+
16
+ These are internal classes; it is recommended *not* to use them
17
+ directly, and instead to construct morphisms through the
18
+ :meth:`ModulesWithBasis.ParentMethods.module_morphism` method of the
19
+ domain, or through the homset. See the former for an overview
20
+ of the possible arguments.
21
+
22
+ EXAMPLES:
23
+
24
+ We construct a morphism through the method
25
+ :meth:`ModulesWithBasis.ParentMethods.module_morphism`, by specifying
26
+ the image of each element of the distinguished basis::
27
+
28
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis()
29
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); y = Y.basis()
30
+ sage: on_basis = lambda i: Y.monomial(i) + 2*Y.monomial(i+1)
31
+
32
+ sage: phi1 = X.module_morphism(on_basis, codomain=Y)
33
+ sage: phi1(x[1])
34
+ B[1] + 2*B[2]
35
+
36
+ sage: phi1
37
+ Generic morphism:
38
+ From: Free module generated by {1, 2, 3} over Rational Field
39
+ To: Free module generated by {1, 2, 3, 4} over Rational Field
40
+ sage: phi1.parent()
41
+ Set of Morphisms from Free module generated by {1, 2, 3} over Rational Field to Free module generated by {1, 2, 3, 4} over Rational Field in Category of finite dimensional vector spaces with basis over Rational Field
42
+ sage: phi1.__class__
43
+ <class 'sage.modules.with_basis.morphism.ModuleMorphismByLinearity_with_category'>
44
+
45
+ Constructing the same morphism from the homset::
46
+
47
+ sage: H = Hom(X,Y)
48
+ sage: phi2 = H(on_basis=on_basis)
49
+ sage: phi1 == phi2
50
+ True
51
+
52
+ Constructing the same morphism directly using the class; no backward
53
+ compatibility is guaranteed in this case::
54
+
55
+ sage: from sage.modules.with_basis.morphism import ModuleMorphismByLinearity
56
+ sage: phi3 = ModuleMorphismByLinearity(X, on_basis, codomain=Y)
57
+ sage: phi3 == phi1
58
+ True
59
+
60
+ .. WARNING::
61
+
62
+ The hierarchy of classes implemented in this module is one of the
63
+ first non-trivial hierarchies of classes for morphisms. It is
64
+ hitting a couple scaling issues:
65
+
66
+ - There are many independent properties from which module
67
+ morphisms can get code (being defined by linearity, from a
68
+ matrix, or a function; being triangular, being diagonal,
69
+ ...). How to mitigate the class hierarchy growth?
70
+
71
+ This will become even more stringent as more properties are
72
+ added (e.g. being defined from generators for an algebra
73
+ morphism, ...)
74
+
75
+ Categories, whose primary purpose is to provide infrastructure
76
+ for handling such large hierarchy of classes, can't help at this
77
+ point: there is no category whose morphisms are triangular
78
+ morphisms, and it's not clear such a category would be sensible.
79
+
80
+ - How to properly handle ``__init__`` method calls and
81
+ multiple inheritance?
82
+
83
+ - Who should be in charge of setting the default category: the
84
+ classes themselves, or
85
+ :meth:`ModulesWithBasis.ParentMethods.module_morphism`?
86
+
87
+ Because of this, the hierarchy of classes, and the specific APIs,
88
+ is likely to be refactored as better infrastructure and best
89
+ practices emerge.
90
+
91
+ AUTHORS:
92
+
93
+ - Nicolas M. Thiery (2008-2015)
94
+
95
+ - Jason Bandlow and Florent Hivert (2010): Triangular Morphisms
96
+
97
+ - Christian Stump (2010): :issue:`9648` module_morphism's to a wider class
98
+ of codomains
99
+
100
+ Before :issue:`8678`, this hierarchy of classes used to be in
101
+ sage.categories.modules_with_basis; see :issue:`8678` for the complete log.
102
+ """
103
+
104
+ # ****************************************************************************
105
+ # Copyright (C) 2015 Nicolas M. Thiery <nthiery at users.sf.net>
106
+ #
107
+ # This program is free software: you can redistribute it and/or modify
108
+ # it under the terms of the GNU General Public License as published by
109
+ # the Free Software Foundation, either version 2 of the License, or
110
+ # (at your option) any later version.
111
+ # https://www.gnu.org/licenses/
112
+ # ****************************************************************************
113
+
114
+ from sage.categories.fields import Fields
115
+ from sage.categories.modules import Modules
116
+ from sage.misc.call import attrcall
117
+ # The identity function would deserve a more canonical location
118
+ from sage.misc.c3_controlled import identity
119
+ from sage.categories.commutative_additive_semigroups import CommutativeAdditiveSemigroups
120
+ from sage.categories.homset import Hom
121
+ from sage.categories.modules_with_basis import ModulesWithBasis
122
+ from sage.categories.morphism import SetMorphism, Morphism
123
+ from sage.categories.sets_cat import Sets
124
+ from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
125
+ from sage.structure.richcmp import op_EQ, op_NE
126
+ from sage.structure.element import Matrix
127
+ from sage.structure.sage_object import SageObject
128
+
129
+
130
+ class ModuleMorphism(Morphism):
131
+ """
132
+ The top abstract base class for module with basis morphisms.
133
+
134
+ INPUT:
135
+
136
+ - ``domain`` -- a parent in ``ModulesWithBasis(...)``
137
+ - ``codomain`` -- a parent in ``Modules(...)``
138
+ - ``category`` -- a category or ``None`` (default: ``None``)
139
+ - ``affine`` -- whether we define an affine module morphism
140
+ (default: ``False``)
141
+
142
+ Construct a module morphism from ``domain`` to ``codomain`` in the
143
+ category ``category``. By default, the category is the first of
144
+ ``Modules(R).WithBasis().FiniteDimensional()``,
145
+ ``Modules(R).WithBasis()``, ``Modules(R)``,
146
+ ``CommutativeAdditiveMonoids()`` that contains both the domain and
147
+ the codomain. If initializing an affine morphism, then `Sets()` is
148
+ used instead.
149
+
150
+ .. SEEALSO::
151
+
152
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism` for
153
+ usage information and examples;
154
+ - :mod:`sage.modules.with_basis.morphism` for a technical
155
+ overview of the classes for module morphisms;
156
+ - :class:`ModuleMorphismFromFunction` and
157
+ :class:`TriangularModuleMorphism`.
158
+
159
+ The role of this class is minimal: it provides an :meth:`__init__`
160
+ method which:
161
+
162
+ - handles the choice of the default category
163
+ - handles the proper inheritance from categories by updating the
164
+ class of ``self`` upon construction.
165
+ """
166
+ def __init__(self, domain, codomain=None, category=None, affine=False):
167
+ """
168
+ Initialization of module morphisms.
169
+
170
+ TESTS::
171
+
172
+ sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2])
173
+ sage: Y = CombinatorialFreeModule(ZZ, [1, 2])
174
+ sage: from sage.modules.with_basis.morphism import ModuleMorphismByLinearity
175
+ sage: phi = ModuleMorphismByLinearity(X, on_basis=Y.monomial * abs)
176
+ sage: TestSuite(phi).run()
177
+ """
178
+ if category is None:
179
+ if domain not in ModulesWithBasis:
180
+ raise ValueError("domain(=%s) should be a module with basis" % codomain)
181
+ base_ring = domain.base_ring()
182
+
183
+ if not hasattr(codomain, 'base_ring'):
184
+ raise ValueError("codomain(=%s) needs to have a base_ring attribute" % codomain)
185
+ # codomain should be a module over base_ring
186
+ # The natural test would be ``codomains in Modules(base_ring)``
187
+ # But this is not properly implemented yet::
188
+ #
189
+ # sage: CC in Modules(QQ)
190
+ # False
191
+ # sage: QQ in Modules(QQ)
192
+ # False
193
+ # sage: CC[x] in Modules(QQ)
194
+ # False
195
+
196
+ # The test below is a bit more restrictive
197
+ if (not codomain.base_ring().has_coerce_map_from(base_ring)) \
198
+ and (not codomain.has_coerce_map_from(base_ring)):
199
+ raise ValueError("codomain(=%s) should be a module over the base ring of the domain(=%s)" % (codomain, domain))
200
+
201
+ if affine:
202
+ # We don't yet have a category whose morphisms are affine morphisms
203
+ category = Sets()
204
+ else:
205
+ C = Modules(base_ring)
206
+ for D in [C.WithBasis().FiniteDimensional(),
207
+ C.WithBasis(),
208
+ C,
209
+ # QQ is not in Modules(QQ)!
210
+ CommutativeAdditiveSemigroups()]:
211
+ if codomain in D and domain in D:
212
+ category = D
213
+ break
214
+ if category is None:
215
+ raise ValueError("codomain=(%s) should at least be a commutative additive semigroup")
216
+
217
+ H = Hom(domain, codomain, category=category)
218
+ Morphism.__init__(self, H)
219
+
220
+ # If needed, this creates the element class from the concrete
221
+ # class (ModuleMorphismByLinearity, DiagonalModuleMorphism,
222
+ # ...) and the abstract classes from the categories.
223
+ #
224
+ # The category infrastructure handles this automatically for
225
+ # parents with a single element class. But for now we still
226
+ # need to do it by hand here, since H may have many different
227
+ # element classes
228
+ if not issubclass(self.__class__, H._abstract_element_class):
229
+ self.__class__ = H.__make_element_class__(self.__class__)
230
+
231
+
232
+ class ModuleMorphismFromFunction(ModuleMorphism, SetMorphism):
233
+ """
234
+ A class for module morphisms implemented by a plain function.
235
+
236
+ INPUT:
237
+
238
+ - ``domain``, ``codomain``, ``category`` -- as for :class:`ModuleMorphism`
239
+
240
+ - ``function`` -- any function or callable from domain to codomain
241
+
242
+ .. SEEALSO::
243
+
244
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism` for
245
+ usage information and examples;
246
+ - :mod:`sage.modules.with_basis.morphism` for a technical
247
+ overview of the classes for module morphisms;
248
+ - :class:`ModuleMorphismFromFunction` and
249
+ :class:`TriangularModuleMorphism`.
250
+ """
251
+
252
+ def __init__(self, domain, function, codomain=None, category=None):
253
+ """
254
+ TESTS::
255
+
256
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X'); x = X.basis()
257
+ sage: from sage.modules.with_basis.morphism import ModuleMorphismFromFunction
258
+ sage: def f(x): return 3*x
259
+ sage: import __main__; __main__.f = f # Fake f being defined in a python module
260
+ sage: phi = ModuleMorphismFromFunction(X, f, codomain=X)
261
+ sage: phi(x[1])
262
+ 3*B[1]
263
+ sage: TestSuite(phi).run()
264
+ """
265
+ # Caveat: This calls Morphism.__init__ twice ...
266
+ ModuleMorphism.__init__(self, domain, codomain, category=category)
267
+ SetMorphism.__init__(self, self.parent(), function)
268
+
269
+
270
+ class ModuleMorphismByLinearity(ModuleMorphism):
271
+ """
272
+ A class for module morphisms obtained by extending a function by linearity.
273
+
274
+ INPUT:
275
+
276
+ - ``domain``, ``codomain``, ``category`` -- as for :class:`ModuleMorphism`
277
+ - ``on_basis`` -- a function which accepts indices of the basis of
278
+ ``domain`` as ``position``-th argument
279
+ - ``codomain`` -- a parent in ``Modules(...)``
280
+ (default: ``on_basis.codomain()``)
281
+ - ``position`` -- nonnegative integer (default: 0)
282
+ - ``zero`` -- the zero of the codomain (defaults: ``codomain.zero()``)
283
+
284
+ .. SEEALSO::
285
+
286
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism` for
287
+ usage information and examples;
288
+ - :mod:`sage.modules.with_basis.morphism` for a technical
289
+ overview of the classes for module morphisms;
290
+ - :class:`ModuleMorphismFromFunction` and
291
+ :class:`TriangularModuleMorphism`.
292
+
293
+ .. NOTE::
294
+
295
+ ``on_basis`` may alternatively be provided in derived classes
296
+ by passing ``None`` as argument, and implementing or setting
297
+ the attribute ``_on_basis``
298
+ """
299
+ def __init__(self, domain, on_basis=None, codomain=None, category=None,
300
+ position=0, zero=None):
301
+ """
302
+ TESTS::
303
+
304
+ sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2])
305
+ sage: Y = CombinatorialFreeModule(ZZ, [1, 2])
306
+ sage: from sage.modules.with_basis.morphism import ModuleMorphismByLinearity
307
+ sage: phi = ModuleMorphismByLinearity(X, on_basis=Y.monomial * abs)
308
+
309
+ sage: TestSuite(phi).run()
310
+ """
311
+ # Might want to assert that domain is a module with basis
312
+ base_ring = domain.base_ring()
313
+
314
+ if codomain is None and hasattr(on_basis, 'codomain'):
315
+ codomain = on_basis.codomain()
316
+ if zero is None:
317
+ zero = codomain.zero()
318
+ self._zero = zero
319
+ self._position = position
320
+ if on_basis is not None:
321
+ self._on_basis = on_basis
322
+
323
+ self._is_module_with_basis_over_same_base_ring = \
324
+ codomain in ModulesWithBasis(base_ring) and zero == codomain.zero()
325
+
326
+ ModuleMorphism.__init__(self, domain, codomain,
327
+ category=category,
328
+ affine=(zero != codomain.zero()))
329
+
330
+ def _richcmp_(self, other, op):
331
+ r"""
332
+ Return whether this morphism and ``other`` satisfy ``op``.
333
+
334
+ TESTS::
335
+
336
+ sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2])
337
+ sage: Y = CombinatorialFreeModule(ZZ, [1, 2])
338
+ sage: f = X.module_morphism(on_basis=Y.monomial * abs)
339
+ sage: g = X.module_morphism(on_basis=Y.monomial * abs)
340
+ sage: h1 = X.module_morphism(on_basis=X.monomial * abs)
341
+ sage: h2 = X.module_morphism(on_basis=X.monomial * factorial)
342
+ sage: h3 = X.module_morphism(on_basis=Y.monomial * abs, category=Modules(ZZ))
343
+ sage: f == g, f == h1, f == h2, f == h3, f == 1, 1 == f
344
+ (True, False, False, False, False, False)
345
+ """
346
+ if op == op_EQ:
347
+ return (self.__class__ is other.__class__
348
+ and self._zero == other._zero
349
+ and self._on_basis == other._on_basis
350
+ and self._position == other._position
351
+ and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring)
352
+ if op == op_NE:
353
+ return not (self == other)
354
+ return NotImplemented
355
+
356
+ def on_basis(self):
357
+ """
358
+ Return the action of this morphism on basis elements, as per
359
+ :meth:`ModulesWithBasis.Homsets.ElementMethods.on_basis`.
360
+
361
+ OUTPUT:
362
+
363
+ - a function from the indices of the basis of the domain to the
364
+ codomain
365
+
366
+ EXAMPLES::
367
+
368
+ sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2])
369
+ sage: Y = CombinatorialFreeModule(ZZ, [1, 2])
370
+ sage: phi_on_basis = Y.monomial * abs
371
+ sage: phi = sage.modules.with_basis.morphism.ModuleMorphismByLinearity(X, on_basis = phi_on_basis, codomain=Y)
372
+ sage: x = X.basis()
373
+ sage: phi.on_basis()(-2)
374
+ B[2]
375
+ sage: phi.on_basis() == phi_on_basis
376
+ True
377
+ """
378
+ return self._on_basis
379
+
380
+ def __call__(self, *args):
381
+ r"""
382
+ Apply this morphism to ``*args``.
383
+
384
+ EXAMPLES::
385
+
386
+ sage: X = CombinatorialFreeModule(ZZ, [-2, -1, 1, 2])
387
+ sage: Y = CombinatorialFreeModule(ZZ, [1, 2])
388
+ sage: def phi_on_basis(i): return Y.monomial(abs(i))
389
+ sage: phi = sage.modules.with_basis.morphism.ModuleMorphismByLinearity(X, on_basis = Y.monomial * abs, codomain=Y)
390
+ sage: x = X.basis()
391
+ sage: phi(x[1]), phi(x[-2]), phi(x[1] + 3 * x[-2])
392
+ (B[1], B[2], B[1] + 3*B[2])
393
+
394
+ .. TODO::
395
+
396
+ Add more tests for multi-parameter module morphisms.
397
+ """
398
+ before = args[0:self._position]
399
+ after = args[self._position + 1:len(args)]
400
+ x = args[self._position]
401
+ assert x.parent() is self.domain()
402
+
403
+ mc = x.monomial_coefficients(copy=False)
404
+ if self._is_module_with_basis_over_same_base_ring:
405
+ return self.codomain().linear_combination(
406
+ (self._on_basis(*(before + (index,) + after)), coeff)
407
+ for (index, coeff) in mc.items())
408
+ else:
409
+ return sum((coeff * self._on_basis(*(before + (index,) + after))
410
+ for (index, coeff) in mc.items()), self._zero)
411
+
412
+ # As per the specs of Map, we should in fact implement _call_.
413
+ # However we currently need to abuse Map.__call__ (which strict
414
+ # type checking) for multi-parameter module morphisms
415
+ # To be cleaned up
416
+ _call_ = __call__
417
+
418
+
419
+ class TriangularModuleMorphism(ModuleMorphism):
420
+ r"""
421
+ An abstract class for triangular module morphisms.
422
+
423
+ Let `X` and `Y` be modules over the same base ring, with
424
+ distinguished bases `F` indexed by `I` and `G` indexed by `J`,
425
+ respectively.
426
+
427
+ A module morphism `\phi` from `X` to `Y` is *triangular* if its
428
+ representing matrix in the distinguished bases of `X` and `Y` is
429
+ upper triangular (echelon form).
430
+
431
+ More precisely, `\phi` is *upper triangular* w.r.t. a total order
432
+ `<` on `J` if, for any `j\in J`, there exists at most one index
433
+ `i\in I` such that the leading support of `\phi(F_i)` is `j` (see
434
+ :meth:`leading_support()`). We denote by `r(j)` this index,
435
+ setting `r(j)` to ``None`` if it does not exist.
436
+
437
+ *Lower triangular* morphisms are defined similarly, taking the
438
+ trailing support instead (see :meth:`trailing_support()`).
439
+
440
+ A triangular morphism is *unitriangular* if all its pivots
441
+ (i.e. coefficient of `j` in each `\phi(F[r(j)])`) are `1`.
442
+
443
+ INPUT:
444
+
445
+ - ``domain`` -- a module with basis `X`
446
+ - ``codomain`` -- a module with basis `Y` (default: `X`)
447
+ - ``category`` -- a category, as for :class:`ModuleMorphism`
448
+
449
+ - ``triangular`` -- ``'upper'`` or ``'lower'`` (default: ``'upper'``)
450
+ - ``unitriangular`` -- boolean (default: ``False``)
451
+ As a shorthand, one may use ``unitriangular='lower'``
452
+ for ``triangular='lower', unitriangular=True``.
453
+
454
+ - ``key`` -- a comparison key on `J`
455
+ (default: the usual comparison of elements of `J`)
456
+
457
+ - ``inverse_on_support`` -- a function `J \to I\cup \{None\}`
458
+ implementing `r` (default: the identity function).
459
+ If set to "compute", the values of `r(j)` are precomputed by
460
+ running through the index set `I` of the basis of the
461
+ domain. This of course requires the domain to be finite
462
+ dimensional.
463
+
464
+ - ``invertible`` -- boolean or ``None`` (default: ``None``); can
465
+ be set to specify that `\phi` is known to be (or not to be)
466
+ invertible. If the domain and codomain share the same indexing
467
+ set, this is by default automatically set to ``True`` if
468
+ ``inverse_on_support`` is the identity, or in the finite
469
+ dimensional case.
470
+
471
+ .. SEEALSO::
472
+
473
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism` for
474
+ usage information and examples;
475
+ - :mod:`sage.modules.with_basis.morphism` for a technical
476
+ overview of the classes for module morphisms;
477
+ - :class:`ModuleMorphismFromFunction` and
478
+ :class:`TriangularModuleMorphism`.
479
+
480
+ OUTPUT: a morphism from `X` to `Y`
481
+
482
+ .. WARNING::
483
+
484
+ This class is meant to be used as a complement for a concrete
485
+ morphism class. In particular, the :meth:`__init__` method
486
+ focuses on setting up the data structure describing the
487
+ triangularity of the morphism. It purposely does *not* call
488
+ :meth:`ModuleMorphism.__init__` which should be called
489
+ (directly or indirectly) beforehand.
490
+
491
+ EXAMPLES:
492
+
493
+ We construct and invert an upper unitriangular module morphism between
494
+ two free `\QQ`-modules::
495
+
496
+ sage: I = range(1,200)
497
+ sage: X = CombinatorialFreeModule(QQ, I); X.rename('X'); x = X.basis()
498
+ sage: Y = CombinatorialFreeModule(QQ, I); Y.rename('Y'); y = Y.basis()
499
+ sage: ut = Y.sum_of_monomials * divisors # This * is map composition.
500
+ sage: phi = X.module_morphism(ut, unitriangular='upper', codomain=Y)
501
+ sage: phi(x[2])
502
+ B[1] + B[2]
503
+ sage: phi(x[6])
504
+ B[1] + B[2] + B[3] + B[6]
505
+ sage: phi(x[30])
506
+ B[1] + B[2] + B[3] + B[5] + B[6] + B[10] + B[15] + B[30]
507
+ sage: phi.preimage(y[2])
508
+ -B[1] + B[2]
509
+ sage: phi.preimage(y[6])
510
+ B[1] - B[2] - B[3] + B[6]
511
+ sage: phi.preimage(y[30])
512
+ -B[1] + B[2] + B[3] + B[5] - B[6] - B[10] - B[15] + B[30]
513
+ sage: (phi^-1)(y[30])
514
+ -B[1] + B[2] + B[3] + B[5] - B[6] - B[10] - B[15] + B[30]
515
+
516
+ A lower triangular (but not unitriangular) morphism::
517
+
518
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
519
+ sage: def lt(i): return sum(j*x[j] for j in range(i, 4))
520
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=X)
521
+ sage: phi(x[2])
522
+ 2*B[2] + 3*B[3]
523
+ sage: phi.preimage(x[2])
524
+ 1/2*B[2] - 1/2*B[3]
525
+ sage: phi(phi.preimage(x[2]))
526
+ B[2]
527
+
528
+ Using the ``key`` keyword, we can use triangularity even if
529
+ the map becomes triangular only after a permutation of the basis::
530
+
531
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
532
+ sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0))
533
+ sage: perm = [0, 2, 1, 3]
534
+ sage: phi = X.module_morphism(ut, triangular='upper', codomain=X,
535
+ ....: key=lambda a: perm[a])
536
+ sage: [phi(x[i]) for i in range(1, 4)]
537
+ [B[1] + B[2], B[2], B[2] + B[3]]
538
+ sage: [phi.preimage(x[i]) for i in range(1, 4)]
539
+ [B[1] - B[2], B[2], -B[2] + B[3]]
540
+
541
+ The same works in the lower-triangular case::
542
+
543
+ sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i])
544
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=X,
545
+ ....: key=lambda a: perm[a])
546
+ sage: [phi(x[i]) for i in range(1, 4)]
547
+ [B[1], B[1] + B[2] + B[3], B[3]]
548
+ sage: [phi.preimage(x[i]) for i in range(1, 4)]
549
+ [B[1], -B[1] + B[2] - B[3], B[3]]
550
+
551
+ An injective but not surjective morphism cannot be inverted,
552
+ but the ``inverse_on_support`` keyword allows Sage to find a
553
+ partial inverse::
554
+
555
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis()
556
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis()
557
+ sage: ult = lambda i: sum( y[j] for j in range(i+1,6) )
558
+ sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y,
559
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
560
+ sage: phi(x[2])
561
+ B[3] + B[4] + B[5]
562
+ sage: phi.preimage(y[3])
563
+ B[2] - B[3]
564
+
565
+ The ``inverse_on_support`` keyword can also be used if the
566
+ bases of the domain and the codomain are identical but one of
567
+ them has to be permuted in order to render the morphism
568
+ triangular. For example::
569
+
570
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
571
+ sage: def ut(i):
572
+ ....: return (x[3] if i == 1 else x[1] if i == 2
573
+ ....: else x[1] + x[2])
574
+ sage: def perm(i):
575
+ ....: return (2 if i == 1 else 3 if i == 2 else 1)
576
+ sage: phi = X.module_morphism(ut, triangular='upper', codomain=X,
577
+ ....: inverse_on_support=perm)
578
+ sage: [phi(x[i]) for i in range(1, 4)]
579
+ [B[3], B[1], B[1] + B[2]]
580
+ sage: [phi.preimage(x[i]) for i in range(1, 4)]
581
+ [B[2], -B[2] + B[3], B[1]]
582
+
583
+ The same works if the permutation induces lower triangularity::
584
+
585
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
586
+ sage: def lt(i):
587
+ ....: return (x[3] if i == 1 else x[2] if i == 2
588
+ ....: else x[1] + x[2])
589
+ sage: def perm(i):
590
+ ....: return 4 - i
591
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=X,
592
+ ....: inverse_on_support=perm)
593
+ sage: [phi(x[i]) for i in range(1, 4)]
594
+ [B[3], B[2], B[1] + B[2]]
595
+ sage: [phi.preimage(x[i]) for i in range(1, 4)]
596
+ [-B[2] + B[3], B[2], B[1]]
597
+
598
+ In the finite dimensional case, one can ask Sage to recover
599
+ ``inverse_on_support`` by a precomputation::
600
+
601
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
602
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3, 4]); y = Y.basis()
603
+ sage: ut = lambda i: sum( y[j] for j in range(1,i+2) )
604
+ sage: phi = X.module_morphism(ut, triangular='upper', codomain=Y,
605
+ ....: inverse_on_support='compute')
606
+ sage: tx = "{} {} {}"
607
+ sage: for j in Y.basis().keys():
608
+ ....: i = phi._inverse_on_support(j)
609
+ ....: print(tx.format(j, i, phi(x[i]) if i is not None else None))
610
+ 1 None None
611
+ 2 1 B[1] + B[2]
612
+ 3 2 B[1] + B[2] + B[3]
613
+ 4 3 B[1] + B[2] + B[3] + B[4]
614
+
615
+ The ``inverse_on_basis`` and ``key`` keywords can be combined::
616
+
617
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
618
+ sage: x = X.basis()
619
+ sage: def ut(i):
620
+ ....: return (2*x[2] + 3*x[3] if i == 1
621
+ ....: else x[1] + x[2] + x[3] if i == 2
622
+ ....: else 4*x[2])
623
+ sage: def perm(i):
624
+ ....: return (2 if i == 1 else 3 if i == 2 else 1)
625
+ sage: perverse_key = lambda a: (a - 2) % 3
626
+ sage: phi = X.module_morphism(ut, triangular='upper', codomain=X,
627
+ ....: inverse_on_support=perm, key=perverse_key)
628
+ sage: [phi(x[i]) for i in range(1, 4)]
629
+ [2*B[2] + 3*B[3], B[1] + B[2] + B[3], 4*B[2]]
630
+ sage: [phi.preimage(x[i]) for i in range(1, 4)]
631
+ [-1/3*B[1] + B[2] - 1/12*B[3], 1/4*B[3], 1/3*B[1] - 1/6*B[3]]
632
+ """
633
+ def __init__(self, triangular='upper', unitriangular=False,
634
+ key=None, inverse=None, inverse_on_support=identity, invertible=None):
635
+ """
636
+ TESTS::
637
+
638
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
639
+ sage: def lt(i): return sum(j*x[j] for j in range(i, 4))
640
+ sage: import __main__; __main__.lt = lt # Fake lt being defined in a python module
641
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=X)
642
+ sage: phi.__class__
643
+ <class 'sage.modules.with_basis.morphism.TriangularModuleMorphismByLinearity_with_category'>
644
+ sage: phi._invertible
645
+ True
646
+ sage: TestSuite(phi).run()
647
+
648
+ With the option ``compute``::
649
+
650
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=X,
651
+ ....: inverse_on_support='compute')
652
+ sage: TestSuite(phi).run(skip=["_test_pickling"])
653
+
654
+ Pickling works in Python3 (:issue:`17957`)::
655
+
656
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=X,
657
+ ....: inverse_on_support='compute')
658
+ sage: loads(dumps(phi))
659
+ Generic endomorphism of X
660
+ sage: phi._inverse_on_support
661
+ <built-in method get of dict object at ...>
662
+ sage: ldp = loads(dumps(phi._inverse_on_support))
663
+ sage: [ldp(i) == phi._inverse_on_support(i) for i in range(1, 4)]
664
+ [True, True, True]
665
+ """
666
+ if key is not None:
667
+ self._key_kwds = {"key": key}
668
+ else:
669
+ self._key_kwds = {}
670
+
671
+ if triangular == "upper":
672
+ self._dominant_item = attrcall("leading_item", **self._key_kwds)
673
+ else:
674
+ self._dominant_item = attrcall("trailing_item", **self._key_kwds)
675
+ # We store those two just be able to pass them down to the inverse function
676
+ self._triangular = triangular
677
+
678
+ domain = self.domain()
679
+ codomain = self.codomain()
680
+ on_basis = self.on_basis()
681
+ self._unitriangular = unitriangular
682
+ self._inverse = inverse
683
+
684
+ if inverse_on_support == "compute":
685
+ inverse_on_support = {self._dominant_item(on_basis(i))[0]: i
686
+ for i in self.domain().basis().keys()
687
+ }.get
688
+
689
+ self._inverse_on_support = inverse_on_support
690
+
691
+ if invertible is None and (domain.basis().keys() == codomain.basis().keys()) and \
692
+ (self._inverse_on_support == identity or domain in Modules.FiniteDimensional):
693
+ invertible = True
694
+ self._invertible = invertible
695
+
696
+ def _richcmp_(self, other, op):
697
+ r"""
698
+ Return whether this morphism and ``other`` satisfy ``op``.
699
+
700
+ TESTS::
701
+
702
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
703
+ sage: def ut(i): return (x[1] + x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0))
704
+ sage: perm = [0, 2, 1, 3]
705
+ sage: our_key = lambda a: perm[a]
706
+ sage: phi = X.module_morphism(ut, triangular='upper', codomain=X, key=our_key)
707
+ sage: def ut2(i): return (x[1] + 7*x[2] if i == 1 else x[2] + (x[3] if i == 3 else 0))
708
+ sage: phi2 = X.module_morphism(ut2, triangular='upper', codomain=X, key=our_key)
709
+ sage: def lt(i): return (x[1] + x[2] + x[3] if i == 2 else x[i])
710
+ sage: psi = X.module_morphism(lt, triangular='lower', codomain=X, key=our_key)
711
+ sage: phi == phi
712
+ True
713
+ sage: phi == phi2
714
+ False
715
+ sage: phi == psi
716
+ False
717
+ """
718
+ if op == op_EQ:
719
+ return (self.__class__ is other.__class__
720
+ and self._triangular == other._triangular
721
+ and self._unitriangular == other._unitriangular
722
+ and self._inverse_on_support == other._inverse_on_support
723
+ and self._invertible == other._invertible
724
+ and self._dominant_item == other._dominant_item)
725
+ if op == op_NE:
726
+ return not (self == other)
727
+ return NotImplemented
728
+
729
+ def _test_triangular(self, **options):
730
+ """
731
+ Test that ``self`` is actually triangular.
732
+
733
+ See also: :class:`sage.misc.sage_unittest.TestSuite`.
734
+
735
+ EXAMPLES::
736
+
737
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
738
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis()
739
+ sage: lt = lambda i: sum( y[j] for j in range(i,4) )
740
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y)
741
+ sage: phi._test_triangular()
742
+
743
+ sage: lt = lambda i: sum( y[j] for j in range(i+1,4) )
744
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y)
745
+ sage: phi._test_triangular()
746
+ Traceback (most recent call last):
747
+ ...
748
+ AssertionError: morphism is not triangular on 1
749
+
750
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis()
751
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis()
752
+ sage: ult = lambda i: sum( y[j] for j in range(i+1,6) )
753
+ sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y,
754
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
755
+ sage: phi._test_triangular()
756
+
757
+ sage: ult = lambda i: sum( 2*y[j] for j in range(i+1,6) )
758
+ sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y,
759
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
760
+ sage: phi._test_triangular()
761
+ Traceback (most recent call last):
762
+ ...
763
+ AssertionError: morphism is not unitriangular on 1
764
+ """
765
+ from sage.misc.lazy_format import LazyFormat
766
+ tester = self._tester(**options)
767
+ on_basis = self.on_basis()
768
+ for x in self.domain().basis().keys().some_elements():
769
+ # is there any better set to use ?
770
+ bs, co = self._dominant_item(on_basis(x))
771
+ if self._unitriangular:
772
+ tester.assertEqual(co, self.domain().base_ring().one(),
773
+ LazyFormat("morphism is not unitriangular on %s") % x)
774
+ xback = self._inverse_on_support(bs)
775
+ tester.assertEqual(x, xback,
776
+ LazyFormat("morphism is not triangular on %s") % x)
777
+
778
+ def __invert__(self):
779
+ """
780
+ Return the triangular morphism which is the inverse of ``self``.
781
+
782
+ Raises an error if ``self`` is not invertible.
783
+
784
+ TESTS::
785
+
786
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
787
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis()
788
+ sage: uut = lambda i: sum( y[j] for j in range(1,i+1)) # uni-upper
789
+ sage: ult = lambda i: sum( y[j] for j in range(i,4) ) # uni-lower
790
+ sage: ut = lambda i: sum(j*y[j] for j in range(1,i+1)) # upper
791
+ sage: lt = lambda i: sum(j*y[j] for j in range(i,4 )) # lower
792
+ sage: f_uut = X.module_morphism(uut, codomain=Y,
793
+ ....: unitriangular='upper')
794
+ sage: f_ult = X.module_morphism(ult, codomain=Y,
795
+ ....: unitriangular='lower')
796
+ sage: f_ut = X.module_morphism(ut, codomain=Y, triangular='upper')
797
+ sage: f_lt = X.module_morphism(lt, codomain=Y, triangular='lower')
798
+ sage: (~f_uut)(y[2])
799
+ -B[1] + B[2]
800
+ sage: (~f_ult)(y[2])
801
+ B[2] - B[3]
802
+ sage: (~f_ut)(y[2])
803
+ -1/2*B[1] + 1/2*B[2]
804
+ sage: (~f_lt)(y[2])
805
+ 1/2*B[2] - 1/2*B[3]
806
+ """
807
+ if self._invertible is True:
808
+ return self.section()
809
+ elif self._invertible is False:
810
+ raise ValueError("Non invertible morphism")
811
+ else:
812
+ raise ValueError("Morphism not known to be invertible; see the invertible option of module_morphism")
813
+
814
+ def section(self):
815
+ """
816
+ Return the section (partial inverse) of ``self``.
817
+
818
+ This returns a partial triangular morphism which is a section of
819
+ ``self``. The section morphism raises a :exc:`ValueError` if
820
+ asked to apply on an element which is not in the image of ``self``.
821
+
822
+ EXAMPLES::
823
+
824
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis()
825
+ sage: X.rename('X')
826
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis()
827
+ sage: ult = lambda i: sum( y[j] for j in range(i+1,6) ) # uni-lower
828
+ sage: phi = X.module_morphism(ult, triangular='lower', codomain=Y,
829
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
830
+ sage: ~phi
831
+ Traceback (most recent call last):
832
+ ...
833
+ ValueError: Morphism not known to be invertible;
834
+ see the invertible option of module_morphism
835
+ sage: phiinv = phi.section()
836
+ sage: list(map(phiinv*phi, X.basis().list())) == X.basis().list()
837
+ True
838
+ sage: phiinv(Y.basis()[1])
839
+ Traceback (most recent call last):
840
+ ...
841
+ ValueError: B[1] is not in the image
842
+ """
843
+ if self._inverse is not None:
844
+ return self._inverse
845
+ if self._inverse_on_support == identity:
846
+ retract_dom = None
847
+ else:
848
+ on_basis = self.on_basis()
849
+
850
+ def retract_dom(i):
851
+ self._dominant_item(on_basis(i))[0]
852
+
853
+ if self._invertible:
854
+ return self.__class__(
855
+ domain=self.codomain(),
856
+ on_basis=self._invert_on_basis,
857
+ codomain=self.domain(), category=self.category_for(),
858
+ unitriangular=self._unitriangular, triangular=self._triangular,
859
+ inverse=self, inverse_on_support=retract_dom,
860
+ invertible=self._invertible, **self._key_kwds)
861
+ else:
862
+ return SetMorphism(Hom(self.codomain(), self.domain(),
863
+ SetsWithPartialMaps()),
864
+ self.preimage)
865
+
866
+ # This should be removed and optimized as soon as triangular
867
+ # morphisms not defined by linearity are available
868
+ # (the inverse should not be computed on the basis).
869
+ def _invert_on_basis(self, i):
870
+ r"""
871
+ Return the image, by the inverse of ``self``, of the basis element
872
+ indexed by ``i``.
873
+
874
+ TESTS::
875
+
876
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
877
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis()
878
+ sage: ult = lambda i: sum( y[j] for j in range(i,4) ) # uni-lower
879
+ sage: phi = X.module_morphism(ult, triangular='lower', codomain=Y)
880
+ sage: phi._invert_on_basis(2)
881
+ B[2] - B[3]
882
+ """
883
+ return self.preimage(self.codomain().monomial(i))
884
+
885
+ def preimage(self, f):
886
+ r"""
887
+ Return the preimage of `f` under ``self``.
888
+
889
+ EXAMPLES::
890
+
891
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
892
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis()
893
+ sage: ult = lambda i: sum( y[j] for j in range(i,4) ) # uni-lower
894
+ sage: phi = X.module_morphism(ult, triangular='lower', codomain=Y)
895
+ sage: phi.preimage(y[1] + y[2])
896
+ B[1] - B[3]
897
+
898
+ The morphism need not be surjective. In the following example,
899
+ the codomain is of larger dimension than the domain::
900
+
901
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
902
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3, 4]); y = Y.basis()
903
+ sage: lt = lambda i: sum( y[j] for j in range(i,5) )
904
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y)
905
+ sage: phi.preimage(y[1] + y[2])
906
+ B[1] - B[3]
907
+
908
+ Here are examples using ``inverse_on_support`` to handle a
909
+ morphism that shifts the leading indices by `1`::
910
+
911
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); x = X.basis()
912
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3, 4, 5]); y = Y.basis()
913
+ sage: lt = lambda i: sum( y[j] for j in range(i+1,6) ) # lower
914
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y,
915
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
916
+ sage: phi(x[1])
917
+ B[2] + B[3] + B[4] + B[5]
918
+ sage: phi(x[3])
919
+ B[4] + B[5]
920
+ sage: phi.preimage(y[2] + y[3])
921
+ B[1] - B[3]
922
+ sage: phi(phi.preimage(y[2] + y[3])) == y[2] + y[3]
923
+ True
924
+ sage: el = x[1] + 3*x[2] + 2*x[3]
925
+ sage: phi.preimage(phi(el)) == el
926
+ True
927
+
928
+ sage: phi.preimage(y[1])
929
+ Traceback (most recent call last):
930
+ ...
931
+ ValueError: B[1] is not in the image
932
+ sage: phi.preimage(y[4])
933
+ Traceback (most recent call last):
934
+ ...
935
+ ValueError: B[4] is not in the image
936
+
937
+ Over a base ring like `\ZZ`, the morphism need not be
938
+ surjective even when the dimensions match::
939
+
940
+ sage: X = CombinatorialFreeModule(ZZ, [1, 2, 3]); x = X.basis()
941
+ sage: Y = CombinatorialFreeModule(ZZ, [1, 2, 3]); y = Y.basis()
942
+ sage: lt = lambda i: sum( 2* y[j] for j in range(i,4) ) # lower
943
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y)
944
+ sage: phi.preimage(2*y[1] + 2*y[2])
945
+ B[1] - B[3]
946
+
947
+ The error message in case of failure could be more specific though::
948
+
949
+ sage: phi.preimage(y[1] + y[2])
950
+ Traceback (most recent call last):
951
+ ...
952
+ TypeError: no conversion of this rational to integer
953
+ """
954
+ F = self.domain()
955
+ G = self.codomain()
956
+ on_basis = self.on_basis()
957
+ if f not in G:
958
+ raise ValueError("f(={}) must be in the codomain of the morphism to have a preimage under the latter".format(f))
959
+
960
+ remainder = f
961
+
962
+ out = F.zero()
963
+ while not remainder.is_zero():
964
+ (j, c) = self._dominant_item(remainder)
965
+
966
+ j_preimage = self._inverse_on_support(j)
967
+ if j_preimage is None:
968
+ raise ValueError("{} is not in the image".format(f))
969
+ s = on_basis(j_preimage)
970
+ if not j == self._dominant_item(s)[0]:
971
+ raise ValueError("The morphism (={}) is not triangular at {}, and therefore a preimage cannot be computed".format(f, s))
972
+
973
+ if not self._unitriangular:
974
+ # What's the appropriate way to request an exact
975
+ # division within the base ring and get an error if
976
+ # this is not possible?
977
+ c = c.parent()(c / s[j])
978
+
979
+ # Before this was ``remainder -= s._lmul_(c)`` for speed, but
980
+ # not every module implements scalar multiplication this way.
981
+ remainder -= s * c
982
+ out += F.term(j_preimage, c)
983
+
984
+ return out
985
+
986
+ def coreduced(self, y):
987
+ r"""
988
+ Return `y` reduced w.r.t. the image of ``self``.
989
+
990
+ INPUT:
991
+
992
+ - ``self`` -- a triangular morphism over a field, or a
993
+ unitriangular morphism over a ring
994
+ - ``y`` -- an element of the codomain of ``self``
995
+
996
+ Suppose that ``self`` is a morphism from `X` to `Y`. Then, for
997
+ any `y \in Y`, the call ``self.coreduced(y)`` returns a
998
+ normal form for `y` in the quotient `Y / I` where `I` is the
999
+ image of ``self``.
1000
+
1001
+ EXAMPLES::
1002
+
1003
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis()
1004
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis()
1005
+ sage: ult = lambda i: sum( y[j] for j in range(i+1,6) )
1006
+ sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y,
1007
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1008
+ sage: [phi(v) for v in X.basis()]
1009
+ [B[2] + B[3] + B[4] + B[5],
1010
+ B[3] + B[4] + B[5],
1011
+ B[4] + B[5]]
1012
+ sage: [phi.coreduced(y[1]-2*y[4])]
1013
+ [B[1] + 2*B[5]]
1014
+ sage: [phi.coreduced(v) for v in y]
1015
+ [B[1], 0, 0, -B[5], B[5]]
1016
+
1017
+ Now with a non unitriangular morphism::
1018
+
1019
+ sage: lt = lambda i: sum( j*y[j] for j in range(i+1,6) )
1020
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y,
1021
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1022
+ sage: [phi(v) for v in X.basis()]
1023
+ [2*B[2] + 3*B[3] + 4*B[4] + 5*B[5],
1024
+ 3*B[3] + 4*B[4] + 5*B[5],
1025
+ 4*B[4] + 5*B[5]]
1026
+ sage: [phi.coreduced(y[1]-2*y[4])]
1027
+ [B[1] + 5/2*B[5]]
1028
+ sage: [phi.coreduced(v) for v in y]
1029
+ [B[1], 0, 0, -5/4*B[5], B[5]]
1030
+
1031
+ For general rings, this method is only implemented for
1032
+ unitriangular morphisms::
1033
+
1034
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); x = X.basis()
1035
+ sage: Y = CombinatorialFreeModule(ZZ, [1,2,3,4,5]); y = Y.basis()
1036
+ sage: phi = X.module_morphism(ult, unitriangular='lower', codomain=Y,
1037
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1038
+ sage: [phi.coreduced(y[1]-2*y[4])]
1039
+ [B[1] + 2*B[5]]
1040
+ sage: [phi.coreduced(v) for v in y]
1041
+ [B[1], 0, 0, -B[5], B[5]]
1042
+
1043
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y,
1044
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1045
+ sage: [phi.coreduced(v) for v in y]
1046
+ Traceback (most recent call last):
1047
+ ...
1048
+ NotImplementedError: coreduce for a triangular but not unitriangular morphism over a ring
1049
+
1050
+ .. NOTE:: Before :issue:`8678` this method used to be called co_reduced.
1051
+ """
1052
+ G = self.codomain()
1053
+ if G.base_ring() not in Fields() and not self._unitriangular:
1054
+ raise NotImplementedError("coreduce for a triangular but not unitriangular morphism over a ring")
1055
+ on_basis = self.on_basis()
1056
+ assert y in G
1057
+
1058
+ result = G.zero()
1059
+ remainder = y
1060
+
1061
+ while not remainder.is_zero():
1062
+ (j, c) = self._dominant_item(remainder)
1063
+ j_preimage = self._inverse_on_support(j)
1064
+ if j_preimage is None:
1065
+ dom_term = G.term(j, c)
1066
+ remainder -= dom_term
1067
+ result += dom_term
1068
+ else:
1069
+ s = on_basis(j_preimage)
1070
+ assert j == self._dominant_item(s)[0]
1071
+ if not self._unitriangular:
1072
+ c = c / s[j] # the base ring is a field
1073
+ # Before this was ``remainder -= s._lmul_(c)`` for speed, but
1074
+ # not every module implements scalar multiplication this way.
1075
+ remainder -= s * c
1076
+ return result
1077
+
1078
+ def cokernel_basis_indices(self):
1079
+ r"""
1080
+ Return the indices of the natural monomial basis of the cokernel of ``self``.
1081
+
1082
+ INPUT:
1083
+
1084
+ - ``self`` -- a triangular morphism over a field or a
1085
+ unitriangular morphism over a ring, with a finite
1086
+ dimensional codomain.
1087
+
1088
+ OUTPUT:
1089
+
1090
+ A list `E` of indices of the basis `(B_e)_e` of the codomain
1091
+ of ``self`` so that `(B_e)_{e\in E}` forms a basis of a
1092
+ supplementary of the image set of ``self``.
1093
+
1094
+ Thinking of this triangular morphism as a row echelon matrix,
1095
+ this returns the complementary of the characteristic
1096
+ columns. Namely `E` is the set of indices which do not appear
1097
+ as leading support of some element of the image set of
1098
+ ``self``.
1099
+
1100
+ EXAMPLES::
1101
+
1102
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); x = X.basis()
1103
+ sage: Y = CombinatorialFreeModule(ZZ, [1,2,3,4,5]); y = Y.basis()
1104
+ sage: uut = lambda i: sum( y[j] for j in range(i+1,6) ) # uni-upper
1105
+ sage: phi = X.module_morphism(uut, unitriangular='upper', codomain=Y,
1106
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1107
+ sage: phi.cokernel_basis_indices()
1108
+ [1, 5]
1109
+
1110
+ sage: phi = X.module_morphism(uut, triangular='upper', codomain=Y,
1111
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1112
+ sage: phi.cokernel_basis_indices()
1113
+ Traceback (most recent call last):
1114
+ ...
1115
+ NotImplementedError: cokernel_basis_indices for a triangular but not unitriangular morphism over a ring
1116
+
1117
+ sage: Y = CombinatorialFreeModule(ZZ, NN); y = Y.basis()
1118
+ sage: phi = X.module_morphism(uut, unitriangular='upper', codomain=Y,
1119
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1120
+ sage: phi.cokernel_basis_indices()
1121
+ Traceback (most recent call last):
1122
+ ...
1123
+ NotImplementedError: cokernel_basis_indices implemented only for morphisms with a finite dimensional codomain
1124
+ """
1125
+ R = self.domain().base_ring()
1126
+ if R not in Fields() and not self._unitriangular:
1127
+ raise NotImplementedError("cokernel_basis_indices for a triangular but not unitriangular morphism over a ring")
1128
+ if self.codomain() not in Modules(R).FiniteDimensional():
1129
+ raise NotImplementedError("cokernel_basis_indices implemented only for morphisms with a finite dimensional codomain")
1130
+ return [i for i in self.codomain().basis().keys() if self._inverse_on_support(i) is None]
1131
+
1132
+ def cokernel_projection(self, category=None):
1133
+ """
1134
+ Return a projection on the co-kernel of ``self``.
1135
+
1136
+ INPUT:
1137
+
1138
+ - ``category`` -- the category of the result
1139
+
1140
+ EXAMPLES::
1141
+
1142
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); x = X.basis()
1143
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4,5]); y = Y.basis()
1144
+ sage: lt = lambda i: sum( y[j] for j in range(i+1,6) ) # lower
1145
+ sage: phi = X.module_morphism(lt, triangular='lower', codomain=Y,
1146
+ ....: inverse_on_support=lambda i: i-1 if i in [2,3,4] else None)
1147
+ sage: phipro = phi.cokernel_projection()
1148
+ sage: phipro(y[1] + y[2])
1149
+ B[1]
1150
+ sage: all(phipro(phi(x)).is_zero() for x in X.basis())
1151
+ True
1152
+ sage: phipro(y[1])
1153
+ B[1]
1154
+ sage: phipro(y[4])
1155
+ -B[5]
1156
+ sage: phipro(y[5])
1157
+ B[5]
1158
+ """
1159
+ codomain = self.codomain()
1160
+ category = ModulesWithBasis(codomain.base_ring()).or_subcategory(category)
1161
+ return codomain.module_morphism(function=self.coreduced,
1162
+ codomain=codomain, category=category)
1163
+
1164
+
1165
+ class TriangularModuleMorphismByLinearity(ModuleMorphismByLinearity, TriangularModuleMorphism):
1166
+ r"""
1167
+ A concrete class for triangular module morphisms obtained by extending a function by linearity.
1168
+
1169
+ .. SEEALSO::
1170
+
1171
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism` for
1172
+ usage information and examples;
1173
+ - :mod:`sage.modules.with_basis.morphism` for a technical
1174
+ overview of the classes for module morphisms;
1175
+ - :class:`ModuleMorphismByLinearity` and
1176
+ :class:`TriangularModuleMorphism`.
1177
+ """
1178
+ def __init__(self, domain, on_basis, codomain=None, category=None, **keywords):
1179
+ r"""
1180
+ TESTS::
1181
+
1182
+ sage: X = CombinatorialFreeModule(QQ, ZZ)
1183
+ sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismByLinearity
1184
+ sage: def on_basis(i): return X.sum_of_monomials(range(i-2, i+1))
1185
+ sage: import __main__; __main__.on_basis = on_basis # Fake on_basis being defined in a python module
1186
+ sage: phi = TriangularModuleMorphismByLinearity(
1187
+ ....: X, on_basis=on_basis, codomain=X)
1188
+ sage: TestSuite(phi).run(skip=["_test_nonzero_equal"])
1189
+ """
1190
+ ModuleMorphismByLinearity.__init__(self, on_basis=on_basis,
1191
+ domain=domain, codomain=codomain, category=category)
1192
+ TriangularModuleMorphism.__init__(self, **keywords)
1193
+
1194
+ def _richcmp_(self, other, op):
1195
+ r"""
1196
+ Return whether this morphism and ``other`` satisfy ``op``.
1197
+
1198
+ TESTS::
1199
+
1200
+ sage: X = CombinatorialFreeModule(QQ, ZZ)
1201
+ sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismByLinearity
1202
+ sage: def on_basis(i): return X.sum_of_monomials(range(i-2, i+1))
1203
+ sage: phi = TriangularModuleMorphismByLinearity(
1204
+ ....: X, on_basis=on_basis, codomain=X)
1205
+ sage: phi == phi
1206
+ True
1207
+ """
1208
+ if op == op_EQ:
1209
+ return (ModuleMorphismByLinearity._richcmp_(self, other, op)
1210
+ and TriangularModuleMorphism._richcmp_(self, other, op))
1211
+ if op == op_NE:
1212
+ return not (self == other)
1213
+ return NotImplemented
1214
+
1215
+
1216
+ class TriangularModuleMorphismFromFunction(ModuleMorphismFromFunction, TriangularModuleMorphism):
1217
+ r"""
1218
+ A concrete class for triangular module morphisms implemented by a function.
1219
+
1220
+ .. SEEALSO::
1221
+
1222
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism` for
1223
+ usage information and examples;
1224
+ - :mod:`sage.modules.with_basis.morphism` for a technical
1225
+ overview of the classes for module morphisms;
1226
+ - :class:`ModuleMorphismFromFunction` and
1227
+ :class:`TriangularModuleMorphism`.
1228
+ """
1229
+ def __init__(self, domain, function, codomain=None, category=None, **keywords):
1230
+ r"""
1231
+ TESTS::
1232
+
1233
+ sage: X = CombinatorialFreeModule(QQ, [0,1,2,3,4])
1234
+ sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismFromFunction
1235
+ sage: def f(x): return x + X.term(0, sum(x.coefficients()))
1236
+ sage: import __main__; __main__.f = f # Fake f being defined in a python module
1237
+ sage: phi = TriangularModuleMorphismFromFunction(
1238
+ ....: X, function=f, codomain=X)
1239
+ sage: TestSuite(phi).run()
1240
+ """
1241
+ ModuleMorphismFromFunction.__init__(self, function=function,
1242
+ domain=domain, codomain=codomain,
1243
+ category=category)
1244
+ TriangularModuleMorphism.__init__(self, **keywords)
1245
+
1246
+
1247
+ class ModuleMorphismFromMatrix(ModuleMorphismByLinearity):
1248
+ r"""
1249
+ A class for module morphisms built from a matrix in the
1250
+ distinguished bases of the domain and codomain.
1251
+
1252
+ .. SEEALSO::
1253
+
1254
+ - :meth:`ModulesWithBasis.ParentMethods.module_morphism`
1255
+ - :meth:`ModulesWithBasis.FiniteDimensional.MorphismMethods.matrix`
1256
+
1257
+ INPUT:
1258
+
1259
+ - ``domain``, ``codomain`` -- two finite dimensional modules over
1260
+ the same base ring `R` with basis `F` and `G`, respectively
1261
+
1262
+ - ``matrix`` -- a matrix with base ring `R` and dimensions
1263
+ matching that of `F` and `G`, respectively
1264
+
1265
+ - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``)
1266
+
1267
+ If ``side`` is "left", this morphism is considered as
1268
+ acting on the left; i.e. each column of the matrix
1269
+ represents the image of an element of the basis of the
1270
+ domain.
1271
+
1272
+ - ``category`` -- a category or ``None`` (default: ``None``)
1273
+
1274
+ EXAMPLES::
1275
+
1276
+ sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename('X'); x = X.basis()
1277
+ sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y'); y = Y.basis()
1278
+ sage: m = matrix([[1,2],[3,5]])
1279
+ sage: phi = X.module_morphism(matrix=m, codomain=Y)
1280
+ sage: phi.parent()
1281
+ Set of Morphisms from X to Y in Category of finite dimensional modules with basis over Integer Ring
1282
+ sage: phi.__class__
1283
+ <class 'sage.modules.with_basis.morphism.ModuleMorphismFromMatrix_with_category'>
1284
+ sage: phi(x[1])
1285
+ B[3] + 3*B[4]
1286
+ sage: phi(x[2])
1287
+ 2*B[3] + 5*B[4]
1288
+
1289
+ sage: m = matrix([[1,2],[3,5]])
1290
+ sage: phi = X.module_morphism(matrix=m, codomain=Y, side='right',
1291
+ ....: category=Modules(ZZ).WithBasis())
1292
+ sage: phi.parent()
1293
+ Set of Morphisms from X to Y
1294
+ in Category of modules with basis over Integer Ring
1295
+ sage: phi(x[1])
1296
+ B[3] + 2*B[4]
1297
+ sage: phi(x[2])
1298
+ 3*B[3] + 5*B[4]
1299
+
1300
+ .. TODO::
1301
+
1302
+ Possibly implement rank, addition, multiplication, matrix,
1303
+ etc, from the stored matrix.
1304
+ """
1305
+ def __init__(self, domain, matrix, codomain=None, category=None, side='left'):
1306
+ r"""
1307
+ Initialize ``self``.
1308
+
1309
+ TESTS::
1310
+
1311
+ sage: from sage.modules.with_basis.morphism import ModuleMorphismFromMatrix
1312
+ sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename('X'); x = X.basis()
1313
+ sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y'); y = Y.basis()
1314
+ sage: m = matrix([[1,2],[3,5]])
1315
+ sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side='right')
1316
+ sage: phi.__class__
1317
+ <class 'sage.modules.with_basis.morphism.ModuleMorphismFromMatrix_with_category'>
1318
+ sage: phi.matrix(side='right') == m
1319
+ True
1320
+ sage: TestSuite(phi).run(skip=["_test_pickling"])
1321
+
1322
+ Pickling works (:issue:`17957`) in Python 3::
1323
+
1324
+ sage: phi._on_basis
1325
+ <built-in method __getitem__ of dict object at ...>
1326
+ sage: loads(dumps(phi)) == phi
1327
+ True
1328
+
1329
+ The matrix is stored in the morphism, as if it was for an
1330
+ action on the right::
1331
+
1332
+ sage: phi._matrix
1333
+ [1 2]
1334
+ [3 5]
1335
+
1336
+ sage: phi = ModuleMorphismFromMatrix(matrix=m, side='left',
1337
+ ....: domain=X, codomain=Y)
1338
+ sage: phi._matrix
1339
+ [1 3]
1340
+ [2 5]
1341
+ """
1342
+ C = ModulesWithBasis(domain.base_ring()).FiniteDimensional()
1343
+ if domain not in C:
1344
+ raise ValueError("The domain %s should be finite dimensional" % domain)
1345
+ if codomain is None:
1346
+ raise ValueError("The codomain %s should be specified")
1347
+ if codomain not in C:
1348
+ raise ValueError("The codomain %s should be finite dimensional" % codomain)
1349
+ if not isinstance(matrix, Matrix):
1350
+ raise ValueError("matrix (=%s) should be a matrix" % matrix)
1351
+ import sage.combinat.ranker
1352
+ indices = tuple(domain.basis().keys())
1353
+ rank_domain = sage.combinat.ranker.rank_from_list(indices)
1354
+ if side == "left":
1355
+ matrix = matrix.transpose()
1356
+ if matrix.nrows() != len(indices):
1357
+ raise ValueError("The dimension of the matrix (%s) does not match with the dimension of the domain (%s)"
1358
+ % (matrix.nrows(), len(indices)))
1359
+ if matrix.ncols() != codomain.dimension():
1360
+ raise ValueError("The dimension of the matrix (%s) does not match with the dimension of the codomain (%s)"
1361
+ % (matrix.ncols(), codomain.dimension()))
1362
+ self._matrix = matrix
1363
+ d = {xt: codomain.from_vector(matrix.row(rank_domain(xt)))
1364
+ for xt in domain.basis().keys()}
1365
+
1366
+ ModuleMorphismByLinearity.__init__(self, on_basis=d.__getitem__,
1367
+ domain=domain, codomain=codomain,
1368
+ category=category)
1369
+
1370
+ def _richcmp_(self, other, op):
1371
+ r"""
1372
+ Return whether this morphism and ``other`` satisfy ``op``.
1373
+
1374
+ TESTS::
1375
+
1376
+ sage: from sage.modules.with_basis.morphism import ModuleMorphismFromMatrix
1377
+ sage: X = CombinatorialFreeModule(ZZ, [1,2]); X.rename('X'); x = X.basis()
1378
+ sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y'); y = Y.basis()
1379
+ sage: m = matrix([[1,2],[3,5]])
1380
+ sage: phi = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side='right')
1381
+ sage: phi2 = ModuleMorphismFromMatrix(matrix=m, domain=X, codomain=Y, side='right')
1382
+ sage: phi == phi2
1383
+ True
1384
+ sage: phi is phi2
1385
+ False
1386
+ sage: m2 = matrix([[1,2],[4,5]])
1387
+ sage: phi2 = ModuleMorphismFromMatrix(matrix=m2, domain=X, codomain=Y, side='right')
1388
+ sage: phi == phi2
1389
+ False
1390
+ """
1391
+ if op == op_EQ:
1392
+ # We skip the on_basis check since the matrix defines the morphism
1393
+ return (self.__class__ is other.__class__
1394
+ and self._zero == other._zero
1395
+ and self._position == other._position
1396
+ and self._is_module_with_basis_over_same_base_ring == other._is_module_with_basis_over_same_base_ring
1397
+ and self._matrix == other._matrix)
1398
+ if op == op_NE:
1399
+ return not (self == other)
1400
+ return NotImplemented
1401
+
1402
+
1403
+ class DiagonalModuleMorphism(ModuleMorphismByLinearity):
1404
+ r"""
1405
+ A class for diagonal module morphisms.
1406
+
1407
+ See :meth:`ModulesWithBasis.ParentMethods.module_morphism`.
1408
+
1409
+ INPUT:
1410
+
1411
+ - ``domain``, ``codomain`` -- two modules with basis `F` and `G`,
1412
+ respectively
1413
+ - ``diagonal`` -- a function `d`
1414
+
1415
+ Assumptions:
1416
+
1417
+ - ``domain`` and ``codomain`` have the same base ring `R`,
1418
+ - their respective bases `F` and `G` have the same index set `I`,
1419
+ - `d` is a function `I \to R`.
1420
+
1421
+ Return the diagonal module morphism from ``domain`` to ``codomain``
1422
+ sending `F(i) \mapsto d(i) G(i)` for all `i \in I`.
1423
+
1424
+ By default, ``codomain`` is currently assumed to be ``domain``.
1425
+ (Todo: make a consistent choice with ``*ModuleMorphism``.)
1426
+
1427
+ .. TODO::
1428
+
1429
+ - Implement an optimized ``_call_()`` function.
1430
+ - Generalize to a mapcoeffs.
1431
+ - Generalize to a mapterms.
1432
+
1433
+ EXAMPLES::
1434
+
1435
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
1436
+ sage: phi = X.module_morphism(diagonal=factorial, codomain=X)
1437
+ sage: x = X.basis()
1438
+ sage: phi(x[1]), phi(x[2]), phi(x[3])
1439
+ (B[1], 2*B[2], 6*B[3])
1440
+ """
1441
+ def __init__(self, domain, diagonal, codomain=None, category=None):
1442
+ r"""
1443
+ Initialize ``self``.
1444
+
1445
+ TESTS::
1446
+
1447
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
1448
+ sage: phi = X.module_morphism(diagonal=factorial, codomain=X)
1449
+ sage: phi.__class__
1450
+ <class 'sage.modules.with_basis.morphism.DiagonalModuleMorphism_with_category'>
1451
+ sage: TestSuite(phi).run()
1452
+ """
1453
+ if codomain is None:
1454
+ raise ValueError("The codomain should be specified")
1455
+ if not (domain.basis().keys() == codomain.basis().keys() and
1456
+ domain.base_ring() == codomain.base_ring()):
1457
+ raise ValueError("The domain and codomain should have the same base ring "
1458
+ "and the same basis indexing")
1459
+ from collections.abc import Callable
1460
+ if not isinstance(diagonal, Callable):
1461
+ raise ValueError("diagonal (=%s) should be a function" % diagonal)
1462
+ if category is None:
1463
+ category = ModulesWithBasis(domain.base_ring())
1464
+ ModuleMorphismByLinearity.__init__(
1465
+ self, domain=domain, codomain=codomain, category=category)
1466
+ self._diagonal = diagonal
1467
+
1468
+ def _richcmp_(self, other, op):
1469
+ r"""
1470
+ Return whether this morphism and ``other`` satisfy ``op``.
1471
+
1472
+ TESTS::
1473
+
1474
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
1475
+ sage: phi = X.module_morphism(diagonal=factorial, codomain=X)
1476
+ sage: psi = X.module_morphism(diagonal=factorial, codomain=X)
1477
+ sage: phi == psi
1478
+ True
1479
+ sage: phi is psi
1480
+ False
1481
+ """
1482
+ if op == op_EQ:
1483
+ return (self.__class__ is other.__class__
1484
+ and self._diagonal == other._diagonal)
1485
+ if op == op_NE:
1486
+ return not (self == other)
1487
+ return NotImplemented
1488
+
1489
+ def _on_basis(self, i):
1490
+ """
1491
+ Return the image by ``self`` of the basis element indexed by ``i``.
1492
+
1493
+ TESTS::
1494
+
1495
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
1496
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); Y.rename('Y'); y = Y.basis()
1497
+ sage: phi = X.module_morphism(diagonal=factorial, codomain=X)
1498
+ sage: phi._on_basis(3)
1499
+ 6*B[3]
1500
+ """
1501
+ return self.codomain().term(i, self._diagonal(i))
1502
+
1503
+ def __invert__(self):
1504
+ r"""
1505
+ Return the inverse diagonal morphism.
1506
+
1507
+ EXAMPLES::
1508
+
1509
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X'); x = X.basis()
1510
+ sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); Y.rename('Y'); y = Y.basis()
1511
+ sage: phi = X.module_morphism(diagonal=factorial, codomain=X)
1512
+ sage: phi_inv = ~phi
1513
+ sage: phi_inv
1514
+ Generic endomorphism of Y
1515
+ sage: phi_inv(y[3])
1516
+ 1/6*B[3]
1517
+
1518
+ Caveat: this inverse morphism is only well defined if
1519
+ `d(\lambda)` is always invertible in the base ring. This
1520
+ condition is *not* tested for, so using an ill defined inverse
1521
+ morphism will trigger arithmetic errors.
1522
+ """
1523
+ return self.codomain().module_morphism(
1524
+ diagonal=pointwise_inverse_function(self._diagonal),
1525
+ codomain=self.domain(), category=self.category_for())
1526
+
1527
+
1528
+ def pointwise_inverse_function(f):
1529
+ r"""
1530
+ Return the function `x \mapsto 1 / f(x)`.
1531
+
1532
+ INPUT:
1533
+
1534
+ - ``f`` -- a function
1535
+
1536
+ EXAMPLES::
1537
+
1538
+ sage: from sage.modules.with_basis.morphism import pointwise_inverse_function
1539
+ sage: def f(x): return x
1540
+ sage: g = pointwise_inverse_function(f)
1541
+ sage: g(1), g(2), g(3)
1542
+ (1, 1/2, 1/3)
1543
+
1544
+ :func:`pointwise_inverse_function` is an involution::
1545
+
1546
+ sage: f is pointwise_inverse_function(g)
1547
+ True
1548
+
1549
+ .. TODO::
1550
+
1551
+ This has nothing to do here!!! Should there be a library for
1552
+ pointwise operations on functions somewhere in Sage?
1553
+ """
1554
+ if hasattr(f, "pointwise_inverse"):
1555
+ return f.pointwise_inverse()
1556
+ return PointwiseInverseFunction(f)
1557
+
1558
+
1559
+ class PointwiseInverseFunction(SageObject):
1560
+ r"""
1561
+ A class for pointwise inverse functions.
1562
+
1563
+ The pointwise inverse function of a function `f` is the function
1564
+ sending every `x` to `1 / f(x)`.
1565
+
1566
+ EXAMPLES::
1567
+
1568
+ sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction
1569
+ sage: f = PointwiseInverseFunction(factorial)
1570
+ sage: f(0), f(1), f(2), f(3)
1571
+ (1, 1, 1/2, 1/6)
1572
+ """
1573
+ def __init__(self, f):
1574
+ """
1575
+ TESTS::
1576
+
1577
+ sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction
1578
+ sage: f = PointwiseInverseFunction(factorial)
1579
+ sage: f(0), f(1), f(2), f(3)
1580
+ (1, 1, 1/2, 1/6)
1581
+ sage: TestSuite(f).run()
1582
+ """
1583
+ self._pointwise_inverse = f
1584
+
1585
+ def __eq__(self, other):
1586
+ r"""
1587
+ Return whether this function is equal to ``other``.
1588
+
1589
+ TESTS::
1590
+
1591
+ sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction
1592
+ sage: f = PointwiseInverseFunction(factorial)
1593
+ sage: g = PointwiseInverseFunction(factorial)
1594
+ sage: f is g
1595
+ False
1596
+ sage: f == g
1597
+ True
1598
+ """
1599
+ return (self.__class__ is other.__class__
1600
+ and self._pointwise_inverse == other._pointwise_inverse)
1601
+
1602
+ def __ne__(self, other):
1603
+ r"""
1604
+ Return whether this function is not equal to ``other``.
1605
+
1606
+ TESTS::
1607
+
1608
+ sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction
1609
+ sage: f = PointwiseInverseFunction(factorial)
1610
+ sage: g = PointwiseInverseFunction(factorial)
1611
+ sage: f != g
1612
+ False
1613
+ """
1614
+ return not (self == other)
1615
+
1616
+ def __call__(self, *args):
1617
+ """
1618
+ TESTS::
1619
+
1620
+ sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction
1621
+ sage: g = PointwiseInverseFunction(operator.mul)
1622
+ sage: g(5,7)
1623
+ 1/35
1624
+ """
1625
+ return ~(self._pointwise_inverse(*args))
1626
+
1627
+ def pointwise_inverse(self):
1628
+ """
1629
+ TESTS::
1630
+
1631
+ sage: from sage.modules.with_basis.morphism import PointwiseInverseFunction
1632
+ sage: g = PointwiseInverseFunction(operator.mul)
1633
+ sage: g.pointwise_inverse() is operator.mul
1634
+ True
1635
+ """
1636
+ return self._pointwise_inverse