passagemath-modules 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-modules might be problematic. Click here for more details.

Files changed (807) hide show
  1. passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
  2. passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
  3. passagemath_modules-10.6.31rc3.dist-info/WHEEL +5 -0
  4. passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_modules.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_modules.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
  7. passagemath_modules.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  8. passagemath_modules.libs/libgsl-23768756.so.28.0.0 +0 -0
  9. passagemath_modules.libs/libmpc-7897025b.so.3.3.1 +0 -0
  10. passagemath_modules.libs/libmpfr-e34bb864.so.6.2.1 +0 -0
  11. passagemath_modules.libs/libopenblasp-r0-503f0c35.3.29.so +0 -0
  12. sage/algebras/all__sagemath_modules.py +20 -0
  13. sage/algebras/catalog.py +148 -0
  14. sage/algebras/clifford_algebra.py +3107 -0
  15. sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
  16. sage/algebras/clifford_algebra_element.pxd +16 -0
  17. sage/algebras/clifford_algebra_element.pyx +997 -0
  18. sage/algebras/commutative_dga.py +4252 -0
  19. sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-musl.so +0 -0
  20. sage/algebras/exterior_algebra_groebner.pxd +55 -0
  21. sage/algebras/exterior_algebra_groebner.pyx +727 -0
  22. sage/algebras/finite_dimensional_algebras/all.py +2 -0
  23. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
  24. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
  25. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
  26. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
  27. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
  28. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
  29. sage/algebras/finite_gca.py +528 -0
  30. sage/algebras/group_algebra.py +232 -0
  31. sage/algebras/lie_algebras/abelian.py +197 -0
  32. sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
  33. sage/algebras/lie_algebras/all.py +25 -0
  34. sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
  35. sage/algebras/lie_algebras/bch.py +177 -0
  36. sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
  37. sage/algebras/lie_algebras/bgg_resolution.py +232 -0
  38. sage/algebras/lie_algebras/center_uea.py +767 -0
  39. sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
  40. sage/algebras/lie_algebras/examples.py +683 -0
  41. sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
  42. sage/algebras/lie_algebras/heisenberg.py +820 -0
  43. sage/algebras/lie_algebras/lie_algebra.py +1562 -0
  44. sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-musl.so +0 -0
  45. sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
  46. sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
  47. sage/algebras/lie_algebras/morphism.py +661 -0
  48. sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
  49. sage/algebras/lie_algebras/onsager.py +1324 -0
  50. sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
  51. sage/algebras/lie_algebras/quotient.py +462 -0
  52. sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
  53. sage/algebras/lie_algebras/representation.py +1040 -0
  54. sage/algebras/lie_algebras/structure_coefficients.py +459 -0
  55. sage/algebras/lie_algebras/subalgebra.py +967 -0
  56. sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
  57. sage/algebras/lie_algebras/verma_module.py +1630 -0
  58. sage/algebras/lie_algebras/virasoro.py +1186 -0
  59. sage/algebras/octonion_algebra.cpython-314-aarch64-linux-musl.so +0 -0
  60. sage/algebras/octonion_algebra.pxd +20 -0
  61. sage/algebras/octonion_algebra.pyx +987 -0
  62. sage/algebras/orlik_solomon.py +907 -0
  63. sage/algebras/orlik_terao.py +779 -0
  64. sage/algebras/steenrod/all.py +7 -0
  65. sage/algebras/steenrod/steenrod_algebra.py +4258 -0
  66. sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
  67. sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
  68. sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
  69. sage/algebras/weyl_algebra.py +1126 -0
  70. sage/all__sagemath_modules.py +62 -0
  71. sage/calculus/all__sagemath_modules.py +19 -0
  72. sage/calculus/expr.py +205 -0
  73. sage/calculus/integration.cpython-314-aarch64-linux-musl.so +0 -0
  74. sage/calculus/integration.pyx +698 -0
  75. sage/calculus/interpolation.cpython-314-aarch64-linux-musl.so +0 -0
  76. sage/calculus/interpolation.pxd +13 -0
  77. sage/calculus/interpolation.pyx +387 -0
  78. sage/calculus/interpolators.cpython-314-aarch64-linux-musl.so +0 -0
  79. sage/calculus/interpolators.pyx +326 -0
  80. sage/calculus/ode.cpython-314-aarch64-linux-musl.so +0 -0
  81. sage/calculus/ode.pxd +5 -0
  82. sage/calculus/ode.pyx +610 -0
  83. sage/calculus/riemann.cpython-314-aarch64-linux-musl.so +0 -0
  84. sage/calculus/riemann.pyx +1521 -0
  85. sage/calculus/test_sympy.py +201 -0
  86. sage/calculus/transforms/all.py +7 -0
  87. sage/calculus/transforms/dft.py +844 -0
  88. sage/calculus/transforms/dwt.cpython-314-aarch64-linux-musl.so +0 -0
  89. sage/calculus/transforms/dwt.pxd +7 -0
  90. sage/calculus/transforms/dwt.pyx +160 -0
  91. sage/calculus/transforms/fft.cpython-314-aarch64-linux-musl.so +0 -0
  92. sage/calculus/transforms/fft.pxd +12 -0
  93. sage/calculus/transforms/fft.pyx +487 -0
  94. sage/calculus/wester.py +662 -0
  95. sage/coding/abstract_code.py +1108 -0
  96. sage/coding/ag_code.py +868 -0
  97. sage/coding/ag_code_decoders.cpython-314-aarch64-linux-musl.so +0 -0
  98. sage/coding/ag_code_decoders.pyx +2639 -0
  99. sage/coding/all.py +15 -0
  100. sage/coding/bch_code.py +494 -0
  101. sage/coding/binary_code.cpython-314-aarch64-linux-musl.so +0 -0
  102. sage/coding/binary_code.pxd +124 -0
  103. sage/coding/binary_code.pyx +4139 -0
  104. sage/coding/bounds_catalog.py +43 -0
  105. sage/coding/channel.py +819 -0
  106. sage/coding/channels_catalog.py +29 -0
  107. sage/coding/code_bounds.py +755 -0
  108. sage/coding/code_constructions.py +804 -0
  109. sage/coding/codes_catalog.py +111 -0
  110. sage/coding/cyclic_code.py +1329 -0
  111. sage/coding/databases.py +316 -0
  112. sage/coding/decoder.py +373 -0
  113. sage/coding/decoders_catalog.py +88 -0
  114. sage/coding/delsarte_bounds.py +709 -0
  115. sage/coding/encoder.py +390 -0
  116. sage/coding/encoders_catalog.py +64 -0
  117. sage/coding/extended_code.py +468 -0
  118. sage/coding/gabidulin_code.py +1058 -0
  119. sage/coding/golay_code.py +404 -0
  120. sage/coding/goppa_code.py +441 -0
  121. sage/coding/grs_code.py +2371 -0
  122. sage/coding/guava.py +107 -0
  123. sage/coding/guruswami_sudan/all.py +1 -0
  124. sage/coding/guruswami_sudan/gs_decoder.py +897 -0
  125. sage/coding/guruswami_sudan/interpolation.py +409 -0
  126. sage/coding/guruswami_sudan/utils.py +176 -0
  127. sage/coding/hamming_code.py +176 -0
  128. sage/coding/information_set_decoder.py +1032 -0
  129. sage/coding/kasami_codes.cpython-314-aarch64-linux-musl.so +0 -0
  130. sage/coding/kasami_codes.pyx +351 -0
  131. sage/coding/linear_code.py +3067 -0
  132. sage/coding/linear_code_no_metric.py +1354 -0
  133. sage/coding/linear_rank_metric.py +961 -0
  134. sage/coding/parity_check_code.py +353 -0
  135. sage/coding/punctured_code.py +719 -0
  136. sage/coding/reed_muller_code.py +999 -0
  137. sage/coding/self_dual_codes.py +942 -0
  138. sage/coding/source_coding/all.py +2 -0
  139. sage/coding/source_coding/huffman.py +553 -0
  140. sage/coding/subfield_subcode.py +423 -0
  141. sage/coding/two_weight_db.py +399 -0
  142. sage/combinat/all__sagemath_modules.py +7 -0
  143. sage/combinat/cartesian_product.py +347 -0
  144. sage/combinat/family.py +11 -0
  145. sage/combinat/free_module.py +1977 -0
  146. sage/combinat/root_system/all.py +147 -0
  147. sage/combinat/root_system/ambient_space.py +527 -0
  148. sage/combinat/root_system/associahedron.py +471 -0
  149. sage/combinat/root_system/braid_move_calculator.py +143 -0
  150. sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-musl.so +0 -0
  151. sage/combinat/root_system/braid_orbit.pyx +144 -0
  152. sage/combinat/root_system/branching_rules.py +2301 -0
  153. sage/combinat/root_system/cartan_matrix.py +1245 -0
  154. sage/combinat/root_system/cartan_type.py +3069 -0
  155. sage/combinat/root_system/coxeter_group.py +162 -0
  156. sage/combinat/root_system/coxeter_matrix.py +1261 -0
  157. sage/combinat/root_system/coxeter_type.py +681 -0
  158. sage/combinat/root_system/dynkin_diagram.py +900 -0
  159. sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
  160. sage/combinat/root_system/fundamental_group.py +795 -0
  161. sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
  162. sage/combinat/root_system/integrable_representations.py +1227 -0
  163. sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
  164. sage/combinat/root_system/pieri_factors.py +1147 -0
  165. sage/combinat/root_system/plot.py +1615 -0
  166. sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
  167. sage/combinat/root_system/root_lattice_realizations.py +4628 -0
  168. sage/combinat/root_system/root_space.py +487 -0
  169. sage/combinat/root_system/root_system.py +882 -0
  170. sage/combinat/root_system/type_A.py +348 -0
  171. sage/combinat/root_system/type_A_affine.py +227 -0
  172. sage/combinat/root_system/type_A_infinity.py +241 -0
  173. sage/combinat/root_system/type_B.py +347 -0
  174. sage/combinat/root_system/type_BC_affine.py +287 -0
  175. sage/combinat/root_system/type_B_affine.py +216 -0
  176. sage/combinat/root_system/type_C.py +317 -0
  177. sage/combinat/root_system/type_C_affine.py +188 -0
  178. sage/combinat/root_system/type_D.py +357 -0
  179. sage/combinat/root_system/type_D_affine.py +208 -0
  180. sage/combinat/root_system/type_E.py +641 -0
  181. sage/combinat/root_system/type_E_affine.py +231 -0
  182. sage/combinat/root_system/type_F.py +387 -0
  183. sage/combinat/root_system/type_F_affine.py +137 -0
  184. sage/combinat/root_system/type_G.py +293 -0
  185. sage/combinat/root_system/type_G_affine.py +132 -0
  186. sage/combinat/root_system/type_H.py +105 -0
  187. sage/combinat/root_system/type_I.py +110 -0
  188. sage/combinat/root_system/type_Q.py +150 -0
  189. sage/combinat/root_system/type_affine.py +509 -0
  190. sage/combinat/root_system/type_dual.py +704 -0
  191. sage/combinat/root_system/type_folded.py +301 -0
  192. sage/combinat/root_system/type_marked.py +748 -0
  193. sage/combinat/root_system/type_reducible.py +601 -0
  194. sage/combinat/root_system/type_relabel.py +730 -0
  195. sage/combinat/root_system/type_super_A.py +837 -0
  196. sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
  197. sage/combinat/root_system/weight_space.py +639 -0
  198. sage/combinat/root_system/weyl_characters.py +2238 -0
  199. sage/crypto/__init__.py +4 -0
  200. sage/crypto/all.py +28 -0
  201. sage/crypto/block_cipher/all.py +7 -0
  202. sage/crypto/block_cipher/des.py +1065 -0
  203. sage/crypto/block_cipher/miniaes.py +2171 -0
  204. sage/crypto/block_cipher/present.py +909 -0
  205. sage/crypto/block_cipher/sdes.py +1527 -0
  206. sage/crypto/boolean_function.cpython-314-aarch64-linux-musl.so +0 -0
  207. sage/crypto/boolean_function.pxd +10 -0
  208. sage/crypto/boolean_function.pyx +1487 -0
  209. sage/crypto/cipher.py +78 -0
  210. sage/crypto/classical.py +3668 -0
  211. sage/crypto/classical_cipher.py +569 -0
  212. sage/crypto/cryptosystem.py +387 -0
  213. sage/crypto/key_exchange/all.py +7 -0
  214. sage/crypto/key_exchange/catalog.py +24 -0
  215. sage/crypto/key_exchange/diffie_hellman.py +323 -0
  216. sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
  217. sage/crypto/lattice.py +312 -0
  218. sage/crypto/lfsr.py +295 -0
  219. sage/crypto/lwe.py +840 -0
  220. sage/crypto/mq/__init__.py +4 -0
  221. sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
  222. sage/crypto/mq/rijndael_gf.py +2345 -0
  223. sage/crypto/mq/sbox.py +7 -0
  224. sage/crypto/mq/sr.py +3344 -0
  225. sage/crypto/public_key/all.py +5 -0
  226. sage/crypto/public_key/blum_goldwasser.py +776 -0
  227. sage/crypto/sbox.cpython-314-aarch64-linux-musl.so +0 -0
  228. sage/crypto/sbox.pyx +2090 -0
  229. sage/crypto/sboxes.py +2090 -0
  230. sage/crypto/stream.py +390 -0
  231. sage/crypto/stream_cipher.py +297 -0
  232. sage/crypto/util.py +519 -0
  233. sage/ext/all__sagemath_modules.py +1 -0
  234. sage/ext/interpreters/__init__.py +1 -0
  235. sage/ext/interpreters/all__sagemath_modules.py +2 -0
  236. sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-musl.so +0 -0
  237. sage/ext/interpreters/wrapper_cc.pxd +30 -0
  238. sage/ext/interpreters/wrapper_cc.pyx +252 -0
  239. sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-musl.so +0 -0
  240. sage/ext/interpreters/wrapper_cdf.pxd +26 -0
  241. sage/ext/interpreters/wrapper_cdf.pyx +245 -0
  242. sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-musl.so +0 -0
  243. sage/ext/interpreters/wrapper_rdf.pxd +23 -0
  244. sage/ext/interpreters/wrapper_rdf.pyx +221 -0
  245. sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-musl.so +0 -0
  246. sage/ext/interpreters/wrapper_rr.pxd +28 -0
  247. sage/ext/interpreters/wrapper_rr.pyx +335 -0
  248. sage/geometry/all__sagemath_modules.py +5 -0
  249. sage/geometry/toric_lattice.py +1745 -0
  250. sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-musl.so +0 -0
  251. sage/geometry/toric_lattice_element.pyx +432 -0
  252. sage/groups/abelian_gps/abelian_group.py +1925 -0
  253. sage/groups/abelian_gps/abelian_group_element.py +164 -0
  254. sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
  255. sage/groups/abelian_gps/dual_abelian_group.py +421 -0
  256. sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
  257. sage/groups/abelian_gps/element_base.py +341 -0
  258. sage/groups/abelian_gps/values.py +488 -0
  259. sage/groups/additive_abelian/additive_abelian_group.py +476 -0
  260. sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
  261. sage/groups/additive_abelian/all.py +4 -0
  262. sage/groups/additive_abelian/qmodnz.py +231 -0
  263. sage/groups/additive_abelian/qmodnz_element.py +349 -0
  264. sage/groups/affine_gps/affine_group.py +535 -0
  265. sage/groups/affine_gps/all.py +1 -0
  266. sage/groups/affine_gps/catalog.py +17 -0
  267. sage/groups/affine_gps/euclidean_group.py +246 -0
  268. sage/groups/affine_gps/group_element.py +562 -0
  269. sage/groups/all__sagemath_modules.py +12 -0
  270. sage/groups/galois_group.py +479 -0
  271. sage/groups/matrix_gps/all.py +4 -0
  272. sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
  273. sage/groups/matrix_gps/catalog.py +26 -0
  274. sage/groups/matrix_gps/coxeter_group.py +927 -0
  275. sage/groups/matrix_gps/finitely_generated.py +487 -0
  276. sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-musl.so +0 -0
  277. sage/groups/matrix_gps/group_element.pxd +11 -0
  278. sage/groups/matrix_gps/group_element.pyx +431 -0
  279. sage/groups/matrix_gps/linear.py +440 -0
  280. sage/groups/matrix_gps/matrix_group.py +617 -0
  281. sage/groups/matrix_gps/named_group.py +296 -0
  282. sage/groups/matrix_gps/orthogonal.py +544 -0
  283. sage/groups/matrix_gps/symplectic.py +251 -0
  284. sage/groups/matrix_gps/unitary.py +436 -0
  285. sage/groups/misc_gps/all__sagemath_modules.py +1 -0
  286. sage/groups/misc_gps/argument_groups.py +1905 -0
  287. sage/groups/misc_gps/imaginary_groups.py +479 -0
  288. sage/groups/perm_gps/all__sagemath_modules.py +1 -0
  289. sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
  290. sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-musl.so +0 -0
  291. sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
  292. sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
  293. sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-musl.so +0 -0
  294. sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
  295. sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
  296. sage/homology/algebraic_topological_model.py +595 -0
  297. sage/homology/all.py +2 -0
  298. sage/homology/all__sagemath_modules.py +8 -0
  299. sage/homology/chain_complex.py +2148 -0
  300. sage/homology/chain_complex_homspace.py +165 -0
  301. sage/homology/chain_complex_morphism.py +629 -0
  302. sage/homology/chain_homotopy.py +604 -0
  303. sage/homology/chains.py +653 -0
  304. sage/homology/free_resolution.py +923 -0
  305. sage/homology/graded_resolution.py +567 -0
  306. sage/homology/hochschild_complex.py +756 -0
  307. sage/homology/homology_group.py +188 -0
  308. sage/homology/homology_morphism.py +422 -0
  309. sage/homology/homology_vector_space_with_basis.py +1454 -0
  310. sage/homology/koszul_complex.py +169 -0
  311. sage/homology/matrix_utils.py +205 -0
  312. sage/libs/all__sagemath_modules.py +1 -0
  313. sage/libs/gsl/__init__.py +1 -0
  314. sage/libs/gsl/airy.pxd +56 -0
  315. sage/libs/gsl/all.pxd +66 -0
  316. sage/libs/gsl/array.cpython-314-aarch64-linux-musl.so +0 -0
  317. sage/libs/gsl/array.pxd +5 -0
  318. sage/libs/gsl/array.pyx +102 -0
  319. sage/libs/gsl/bessel.pxd +208 -0
  320. sage/libs/gsl/blas.pxd +116 -0
  321. sage/libs/gsl/blas_types.pxd +34 -0
  322. sage/libs/gsl/block.pxd +52 -0
  323. sage/libs/gsl/chebyshev.pxd +37 -0
  324. sage/libs/gsl/clausen.pxd +12 -0
  325. sage/libs/gsl/combination.pxd +47 -0
  326. sage/libs/gsl/complex.pxd +151 -0
  327. sage/libs/gsl/coulomb.pxd +30 -0
  328. sage/libs/gsl/coupling.pxd +21 -0
  329. sage/libs/gsl/dawson.pxd +12 -0
  330. sage/libs/gsl/debye.pxd +24 -0
  331. sage/libs/gsl/dilog.pxd +14 -0
  332. sage/libs/gsl/eigen.pxd +46 -0
  333. sage/libs/gsl/elementary.pxd +12 -0
  334. sage/libs/gsl/ellint.pxd +48 -0
  335. sage/libs/gsl/elljac.pxd +8 -0
  336. sage/libs/gsl/erf.pxd +32 -0
  337. sage/libs/gsl/errno.pxd +26 -0
  338. sage/libs/gsl/exp.pxd +44 -0
  339. sage/libs/gsl/expint.pxd +44 -0
  340. sage/libs/gsl/fermi_dirac.pxd +44 -0
  341. sage/libs/gsl/fft.pxd +121 -0
  342. sage/libs/gsl/fit.pxd +50 -0
  343. sage/libs/gsl/gamma.pxd +94 -0
  344. sage/libs/gsl/gegenbauer.pxd +26 -0
  345. sage/libs/gsl/histogram.pxd +176 -0
  346. sage/libs/gsl/hyperg.pxd +52 -0
  347. sage/libs/gsl/integration.pxd +69 -0
  348. sage/libs/gsl/interp.pxd +109 -0
  349. sage/libs/gsl/laguerre.pxd +24 -0
  350. sage/libs/gsl/lambert.pxd +16 -0
  351. sage/libs/gsl/legendre.pxd +90 -0
  352. sage/libs/gsl/linalg.pxd +185 -0
  353. sage/libs/gsl/log.pxd +26 -0
  354. sage/libs/gsl/math.pxd +43 -0
  355. sage/libs/gsl/matrix.pxd +143 -0
  356. sage/libs/gsl/matrix_complex.pxd +130 -0
  357. sage/libs/gsl/min.pxd +67 -0
  358. sage/libs/gsl/monte.pxd +56 -0
  359. sage/libs/gsl/ntuple.pxd +32 -0
  360. sage/libs/gsl/odeiv.pxd +70 -0
  361. sage/libs/gsl/permutation.pxd +78 -0
  362. sage/libs/gsl/poly.pxd +40 -0
  363. sage/libs/gsl/pow_int.pxd +12 -0
  364. sage/libs/gsl/psi.pxd +28 -0
  365. sage/libs/gsl/qrng.pxd +29 -0
  366. sage/libs/gsl/random.pxd +257 -0
  367. sage/libs/gsl/rng.pxd +100 -0
  368. sage/libs/gsl/roots.pxd +72 -0
  369. sage/libs/gsl/sort.pxd +36 -0
  370. sage/libs/gsl/statistics.pxd +59 -0
  371. sage/libs/gsl/sum.pxd +55 -0
  372. sage/libs/gsl/synchrotron.pxd +16 -0
  373. sage/libs/gsl/transport.pxd +24 -0
  374. sage/libs/gsl/trig.pxd +58 -0
  375. sage/libs/gsl/types.pxd +137 -0
  376. sage/libs/gsl/vector.pxd +101 -0
  377. sage/libs/gsl/vector_complex.pxd +83 -0
  378. sage/libs/gsl/wavelet.pxd +49 -0
  379. sage/libs/gsl/zeta.pxd +28 -0
  380. sage/libs/mpc/__init__.pxd +114 -0
  381. sage/libs/mpc/types.pxd +28 -0
  382. sage/libs/mpfr/__init__.pxd +299 -0
  383. sage/libs/mpfr/types.pxd +26 -0
  384. sage/libs/mpmath/__init__.py +1 -0
  385. sage/libs/mpmath/all.py +27 -0
  386. sage/libs/mpmath/all__sagemath_modules.py +1 -0
  387. sage/libs/mpmath/utils.cpython-314-aarch64-linux-musl.so +0 -0
  388. sage/libs/mpmath/utils.pxd +4 -0
  389. sage/libs/mpmath/utils.pyx +319 -0
  390. sage/matrix/action.cpython-314-aarch64-linux-musl.so +0 -0
  391. sage/matrix/action.pxd +26 -0
  392. sage/matrix/action.pyx +596 -0
  393. sage/matrix/all.py +9 -0
  394. sage/matrix/args.cpython-314-aarch64-linux-musl.so +0 -0
  395. sage/matrix/args.pxd +144 -0
  396. sage/matrix/args.pyx +1668 -0
  397. sage/matrix/benchmark.py +1258 -0
  398. sage/matrix/berlekamp_massey.py +95 -0
  399. sage/matrix/compute_J_ideal.py +926 -0
  400. sage/matrix/constructor.cpython-314-aarch64-linux-musl.so +0 -0
  401. sage/matrix/constructor.pyx +750 -0
  402. sage/matrix/docs.py +430 -0
  403. sage/matrix/echelon_matrix.cpython-314-aarch64-linux-musl.so +0 -0
  404. sage/matrix/echelon_matrix.pyx +155 -0
  405. sage/matrix/matrix.pxd +2 -0
  406. sage/matrix/matrix0.cpython-314-aarch64-linux-musl.so +0 -0
  407. sage/matrix/matrix0.pxd +68 -0
  408. sage/matrix/matrix0.pyx +6324 -0
  409. sage/matrix/matrix1.cpython-314-aarch64-linux-musl.so +0 -0
  410. sage/matrix/matrix1.pxd +8 -0
  411. sage/matrix/matrix1.pyx +2851 -0
  412. sage/matrix/matrix2.cpython-314-aarch64-linux-musl.so +0 -0
  413. sage/matrix/matrix2.pxd +25 -0
  414. sage/matrix/matrix2.pyx +20181 -0
  415. sage/matrix/matrix_cdv.cpython-314-aarch64-linux-musl.so +0 -0
  416. sage/matrix/matrix_cdv.pxd +4 -0
  417. sage/matrix/matrix_cdv.pyx +93 -0
  418. sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  419. sage/matrix/matrix_complex_double_dense.pxd +5 -0
  420. sage/matrix/matrix_complex_double_dense.pyx +98 -0
  421. sage/matrix/matrix_dense.cpython-314-aarch64-linux-musl.so +0 -0
  422. sage/matrix/matrix_dense.pxd +5 -0
  423. sage/matrix/matrix_dense.pyx +343 -0
  424. sage/matrix/matrix_domain_dense.pxd +5 -0
  425. sage/matrix/matrix_domain_sparse.pxd +5 -0
  426. sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  427. sage/matrix/matrix_double_dense.pxd +7 -0
  428. sage/matrix/matrix_double_dense.pyx +3906 -0
  429. sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  430. sage/matrix/matrix_double_sparse.pxd +6 -0
  431. sage/matrix/matrix_double_sparse.pyx +248 -0
  432. sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-musl.so +0 -0
  433. sage/matrix/matrix_generic_dense.pxd +7 -0
  434. sage/matrix/matrix_generic_dense.pyx +354 -0
  435. sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  436. sage/matrix/matrix_generic_sparse.pxd +7 -0
  437. sage/matrix/matrix_generic_sparse.pyx +461 -0
  438. sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
  439. sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
  440. sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
  441. sage/matrix/matrix_misc.py +313 -0
  442. sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
  443. sage/matrix/matrix_numpy_dense.pxd +14 -0
  444. sage/matrix/matrix_numpy_dense.pyx +450 -0
  445. sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
  446. sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
  447. sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
  448. sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-musl.so +0 -0
  449. sage/matrix/matrix_polynomial_dense.pxd +5 -0
  450. sage/matrix/matrix_polynomial_dense.pyx +5341 -0
  451. sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  452. sage/matrix/matrix_real_double_dense.pxd +7 -0
  453. sage/matrix/matrix_real_double_dense.pyx +122 -0
  454. sage/matrix/matrix_space.py +2848 -0
  455. sage/matrix/matrix_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  456. sage/matrix/matrix_sparse.pxd +5 -0
  457. sage/matrix/matrix_sparse.pyx +1222 -0
  458. sage/matrix/matrix_window.cpython-314-aarch64-linux-musl.so +0 -0
  459. sage/matrix/matrix_window.pxd +37 -0
  460. sage/matrix/matrix_window.pyx +242 -0
  461. sage/matrix/misc_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
  462. sage/matrix/misc_mpfr.pyx +80 -0
  463. sage/matrix/operation_table.py +1182 -0
  464. sage/matrix/special.py +3666 -0
  465. sage/matrix/strassen.cpython-314-aarch64-linux-musl.so +0 -0
  466. sage/matrix/strassen.pyx +851 -0
  467. sage/matrix/symplectic_basis.py +541 -0
  468. sage/matrix/template.pxd +6 -0
  469. sage/matrix/tests.py +71 -0
  470. sage/matroids/advanced.py +77 -0
  471. sage/matroids/all.py +13 -0
  472. sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  473. sage/matroids/basis_exchange_matroid.pxd +96 -0
  474. sage/matroids/basis_exchange_matroid.pyx +2344 -0
  475. sage/matroids/basis_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  476. sage/matroids/basis_matroid.pxd +45 -0
  477. sage/matroids/basis_matroid.pyx +1217 -0
  478. sage/matroids/catalog.py +44 -0
  479. sage/matroids/chow_ring.py +473 -0
  480. sage/matroids/chow_ring_ideal.py +849 -0
  481. sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  482. sage/matroids/circuit_closures_matroid.pxd +16 -0
  483. sage/matroids/circuit_closures_matroid.pyx +559 -0
  484. sage/matroids/circuits_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  485. sage/matroids/circuits_matroid.pxd +38 -0
  486. sage/matroids/circuits_matroid.pyx +947 -0
  487. sage/matroids/constructor.py +1086 -0
  488. sage/matroids/database_collections.py +365 -0
  489. sage/matroids/database_matroids.py +5338 -0
  490. sage/matroids/dual_matroid.py +583 -0
  491. sage/matroids/extension.cpython-314-aarch64-linux-musl.so +0 -0
  492. sage/matroids/extension.pxd +34 -0
  493. sage/matroids/extension.pyx +519 -0
  494. sage/matroids/flats_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  495. sage/matroids/flats_matroid.pxd +28 -0
  496. sage/matroids/flats_matroid.pyx +715 -0
  497. sage/matroids/gammoid.py +600 -0
  498. sage/matroids/graphic_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  499. sage/matroids/graphic_matroid.pxd +39 -0
  500. sage/matroids/graphic_matroid.pyx +2024 -0
  501. sage/matroids/lean_matrix.cpython-314-aarch64-linux-musl.so +0 -0
  502. sage/matroids/lean_matrix.pxd +126 -0
  503. sage/matroids/lean_matrix.pyx +3667 -0
  504. sage/matroids/linear_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  505. sage/matroids/linear_matroid.pxd +180 -0
  506. sage/matroids/linear_matroid.pyx +6649 -0
  507. sage/matroids/matroid.cpython-314-aarch64-linux-musl.so +0 -0
  508. sage/matroids/matroid.pxd +243 -0
  509. sage/matroids/matroid.pyx +8759 -0
  510. sage/matroids/matroids_catalog.py +190 -0
  511. sage/matroids/matroids_plot_helpers.py +890 -0
  512. sage/matroids/minor_matroid.py +480 -0
  513. sage/matroids/minorfix.h +9 -0
  514. sage/matroids/named_matroids.py +5 -0
  515. sage/matroids/rank_matroid.py +268 -0
  516. sage/matroids/set_system.cpython-314-aarch64-linux-musl.so +0 -0
  517. sage/matroids/set_system.pxd +38 -0
  518. sage/matroids/set_system.pyx +800 -0
  519. sage/matroids/transversal_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  520. sage/matroids/transversal_matroid.pxd +14 -0
  521. sage/matroids/transversal_matroid.pyx +893 -0
  522. sage/matroids/union_matroid.cpython-314-aarch64-linux-musl.so +0 -0
  523. sage/matroids/union_matroid.pxd +20 -0
  524. sage/matroids/union_matroid.pyx +331 -0
  525. sage/matroids/unpickling.cpython-314-aarch64-linux-musl.so +0 -0
  526. sage/matroids/unpickling.pyx +843 -0
  527. sage/matroids/utilities.py +809 -0
  528. sage/misc/all__sagemath_modules.py +20 -0
  529. sage/misc/c3.cpython-314-aarch64-linux-musl.so +0 -0
  530. sage/misc/c3.pyx +238 -0
  531. sage/misc/compat.py +87 -0
  532. sage/misc/element_with_label.py +173 -0
  533. sage/misc/func_persist.py +79 -0
  534. sage/misc/pickle_old.cpython-314-aarch64-linux-musl.so +0 -0
  535. sage/misc/pickle_old.pyx +19 -0
  536. sage/misc/proof.py +7 -0
  537. sage/misc/replace_dot_all.py +472 -0
  538. sage/misc/sagedoc_conf.py +168 -0
  539. sage/misc/sphinxify.py +167 -0
  540. sage/misc/test_class_pickling.py +85 -0
  541. sage/modules/all.py +42 -0
  542. sage/modules/complex_double_vector.py +25 -0
  543. sage/modules/diamond_cutting.py +380 -0
  544. sage/modules/fg_pid/all.py +1 -0
  545. sage/modules/fg_pid/fgp_element.py +456 -0
  546. sage/modules/fg_pid/fgp_module.py +2091 -0
  547. sage/modules/fg_pid/fgp_morphism.py +550 -0
  548. sage/modules/filtered_vector_space.py +1271 -0
  549. sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-musl.so +0 -0
  550. sage/modules/finite_submodule_iter.pxd +27 -0
  551. sage/modules/finite_submodule_iter.pyx +452 -0
  552. sage/modules/fp_graded/all.py +1 -0
  553. sage/modules/fp_graded/element.py +346 -0
  554. sage/modules/fp_graded/free_element.py +298 -0
  555. sage/modules/fp_graded/free_homspace.py +53 -0
  556. sage/modules/fp_graded/free_module.py +1060 -0
  557. sage/modules/fp_graded/free_morphism.py +217 -0
  558. sage/modules/fp_graded/homspace.py +563 -0
  559. sage/modules/fp_graded/module.py +1340 -0
  560. sage/modules/fp_graded/morphism.py +1990 -0
  561. sage/modules/fp_graded/steenrod/all.py +1 -0
  562. sage/modules/fp_graded/steenrod/homspace.py +65 -0
  563. sage/modules/fp_graded/steenrod/module.py +477 -0
  564. sage/modules/fp_graded/steenrod/morphism.py +404 -0
  565. sage/modules/fp_graded/steenrod/profile.py +241 -0
  566. sage/modules/free_module.py +8447 -0
  567. sage/modules/free_module_element.cpython-314-aarch64-linux-musl.so +0 -0
  568. sage/modules/free_module_element.pxd +22 -0
  569. sage/modules/free_module_element.pyx +5445 -0
  570. sage/modules/free_module_homspace.py +369 -0
  571. sage/modules/free_module_integer.py +896 -0
  572. sage/modules/free_module_morphism.py +823 -0
  573. sage/modules/free_module_pseudohomspace.py +352 -0
  574. sage/modules/free_module_pseudomorphism.py +578 -0
  575. sage/modules/free_quadratic_module.py +1706 -0
  576. sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
  577. sage/modules/matrix_morphism.py +1745 -0
  578. sage/modules/misc.py +103 -0
  579. sage/modules/module_functors.py +192 -0
  580. sage/modules/multi_filtered_vector_space.py +719 -0
  581. sage/modules/ore_module.py +2208 -0
  582. sage/modules/ore_module_element.py +178 -0
  583. sage/modules/ore_module_homspace.py +147 -0
  584. sage/modules/ore_module_morphism.py +968 -0
  585. sage/modules/quotient_module.py +699 -0
  586. sage/modules/real_double_vector.py +22 -0
  587. sage/modules/submodule.py +255 -0
  588. sage/modules/tensor_operations.py +567 -0
  589. sage/modules/torsion_quadratic_module.py +1352 -0
  590. sage/modules/tutorial_free_modules.py +248 -0
  591. sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  592. sage/modules/vector_complex_double_dense.pxd +6 -0
  593. sage/modules/vector_complex_double_dense.pyx +117 -0
  594. sage/modules/vector_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  595. sage/modules/vector_double_dense.pxd +6 -0
  596. sage/modules/vector_double_dense.pyx +604 -0
  597. sage/modules/vector_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
  598. sage/modules/vector_integer_dense.pxd +15 -0
  599. sage/modules/vector_integer_dense.pyx +361 -0
  600. sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  601. sage/modules/vector_integer_sparse.pxd +29 -0
  602. sage/modules/vector_integer_sparse.pyx +406 -0
  603. sage/modules/vector_modn_dense.cpython-314-aarch64-linux-musl.so +0 -0
  604. sage/modules/vector_modn_dense.pxd +12 -0
  605. sage/modules/vector_modn_dense.pyx +394 -0
  606. sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  607. sage/modules/vector_modn_sparse.pxd +21 -0
  608. sage/modules/vector_modn_sparse.pyx +298 -0
  609. sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-musl.so +0 -0
  610. sage/modules/vector_numpy_dense.pxd +15 -0
  611. sage/modules/vector_numpy_dense.pyx +304 -0
  612. sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-musl.so +0 -0
  613. sage/modules/vector_numpy_integer_dense.pxd +7 -0
  614. sage/modules/vector_numpy_integer_dense.pyx +54 -0
  615. sage/modules/vector_rational_dense.cpython-314-aarch64-linux-musl.so +0 -0
  616. sage/modules/vector_rational_dense.pxd +15 -0
  617. sage/modules/vector_rational_dense.pyx +387 -0
  618. sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-musl.so +0 -0
  619. sage/modules/vector_rational_sparse.pxd +30 -0
  620. sage/modules/vector_rational_sparse.pyx +413 -0
  621. sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-musl.so +0 -0
  622. sage/modules/vector_real_double_dense.pxd +6 -0
  623. sage/modules/vector_real_double_dense.pyx +126 -0
  624. sage/modules/vector_space_homspace.py +430 -0
  625. sage/modules/vector_space_morphism.py +989 -0
  626. sage/modules/with_basis/all.py +15 -0
  627. sage/modules/with_basis/cell_module.py +494 -0
  628. sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-musl.so +0 -0
  629. sage/modules/with_basis/indexed_element.pxd +13 -0
  630. sage/modules/with_basis/indexed_element.pyx +1058 -0
  631. sage/modules/with_basis/invariant.py +1075 -0
  632. sage/modules/with_basis/morphism.py +1636 -0
  633. sage/modules/with_basis/representation.py +2939 -0
  634. sage/modules/with_basis/subquotient.py +685 -0
  635. sage/numerical/all__sagemath_modules.py +6 -0
  636. sage/numerical/gauss_legendre.cpython-314-aarch64-linux-musl.so +0 -0
  637. sage/numerical/gauss_legendre.pyx +381 -0
  638. sage/numerical/optimize.py +910 -0
  639. sage/probability/all.py +10 -0
  640. sage/probability/probability_distribution.cpython-314-aarch64-linux-musl.so +0 -0
  641. sage/probability/probability_distribution.pyx +1242 -0
  642. sage/probability/random_variable.py +411 -0
  643. sage/quadratic_forms/all.py +4 -0
  644. sage/quadratic_forms/all__sagemath_modules.py +15 -0
  645. sage/quadratic_forms/binary_qf.py +2042 -0
  646. sage/quadratic_forms/bqf_class_group.py +748 -0
  647. sage/quadratic_forms/constructions.py +93 -0
  648. sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-musl.so +0 -0
  649. sage/quadratic_forms/count_local_2.pyx +365 -0
  650. sage/quadratic_forms/extras.py +195 -0
  651. sage/quadratic_forms/quadratic_form.py +1753 -0
  652. sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
  653. sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
  654. sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-musl.so +0 -0
  655. sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
  656. sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
  657. sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
  658. sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
  659. sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
  660. sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
  661. sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
  662. sage/quadratic_forms/quadratic_form__theta.py +352 -0
  663. sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
  664. sage/quadratic_forms/random_quadraticform.py +209 -0
  665. sage/quadratic_forms/ternary.cpython-314-aarch64-linux-musl.so +0 -0
  666. sage/quadratic_forms/ternary.pyx +1154 -0
  667. sage/quadratic_forms/ternary_qf.py +2027 -0
  668. sage/rings/all__sagemath_modules.py +28 -0
  669. sage/rings/asymptotic/all__sagemath_modules.py +1 -0
  670. sage/rings/asymptotic/misc.py +1252 -0
  671. sage/rings/cc.py +4 -0
  672. sage/rings/cfinite_sequence.py +1306 -0
  673. sage/rings/complex_conversion.cpython-314-aarch64-linux-musl.so +0 -0
  674. sage/rings/complex_conversion.pxd +8 -0
  675. sage/rings/complex_conversion.pyx +23 -0
  676. sage/rings/complex_double.cpython-314-aarch64-linux-musl.so +0 -0
  677. sage/rings/complex_double.pxd +21 -0
  678. sage/rings/complex_double.pyx +2654 -0
  679. sage/rings/complex_mpc.cpython-314-aarch64-linux-musl.so +0 -0
  680. sage/rings/complex_mpc.pxd +21 -0
  681. sage/rings/complex_mpc.pyx +2576 -0
  682. sage/rings/complex_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
  683. sage/rings/complex_mpfr.pxd +18 -0
  684. sage/rings/complex_mpfr.pyx +3602 -0
  685. sage/rings/derivation.py +2334 -0
  686. sage/rings/finite_rings/all__sagemath_modules.py +1 -0
  687. sage/rings/finite_rings/maps_finite_field.py +191 -0
  688. sage/rings/function_field/all__sagemath_modules.py +8 -0
  689. sage/rings/function_field/derivations.py +102 -0
  690. sage/rings/function_field/derivations_rational.py +132 -0
  691. sage/rings/function_field/differential.py +853 -0
  692. sage/rings/function_field/divisor.py +1107 -0
  693. sage/rings/function_field/drinfeld_modules/action.py +199 -0
  694. sage/rings/function_field/drinfeld_modules/all.py +1 -0
  695. sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
  696. sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
  697. sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
  698. sage/rings/function_field/drinfeld_modules/homset.py +420 -0
  699. sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
  700. sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-musl.so +0 -0
  701. sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
  702. sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-musl.so +0 -0
  703. sage/rings/function_field/khuri_makdisi.pyx +935 -0
  704. sage/rings/invariants/all.py +4 -0
  705. sage/rings/invariants/invariant_theory.py +4597 -0
  706. sage/rings/invariants/reconstruction.py +395 -0
  707. sage/rings/polynomial/all__sagemath_modules.py +17 -0
  708. sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
  709. sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-musl.so +0 -0
  710. sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
  711. sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
  712. sage/rings/polynomial/ore_function_element.py +952 -0
  713. sage/rings/polynomial/ore_function_field.py +1028 -0
  714. sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
  715. sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
  716. sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
  717. sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
  718. sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-musl.so +0 -0
  719. sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
  720. sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
  721. sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-musl.so +0 -0
  722. sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
  723. sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
  724. sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-musl.so +0 -0
  725. sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
  726. sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
  727. sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-musl.so +0 -0
  728. sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
  729. sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
  730. sage/rings/polynomial/skew_polynomial_ring.py +908 -0
  731. sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-musl.so +0 -0
  732. sage/rings/real_double_element_gsl.pxd +8 -0
  733. sage/rings/real_double_element_gsl.pyx +794 -0
  734. sage/rings/real_field.py +58 -0
  735. sage/rings/real_mpfr.cpython-314-aarch64-linux-musl.so +0 -0
  736. sage/rings/real_mpfr.pxd +29 -0
  737. sage/rings/real_mpfr.pyx +6122 -0
  738. sage/rings/ring_extension.cpython-314-aarch64-linux-musl.so +0 -0
  739. sage/rings/ring_extension.pxd +42 -0
  740. sage/rings/ring_extension.pyx +2779 -0
  741. sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-musl.so +0 -0
  742. sage/rings/ring_extension_conversion.pxd +16 -0
  743. sage/rings/ring_extension_conversion.pyx +462 -0
  744. sage/rings/ring_extension_element.cpython-314-aarch64-linux-musl.so +0 -0
  745. sage/rings/ring_extension_element.pxd +21 -0
  746. sage/rings/ring_extension_element.pyx +1635 -0
  747. sage/rings/ring_extension_homset.py +64 -0
  748. sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-musl.so +0 -0
  749. sage/rings/ring_extension_morphism.pxd +35 -0
  750. sage/rings/ring_extension_morphism.pyx +920 -0
  751. sage/schemes/all__sagemath_modules.py +1 -0
  752. sage/schemes/projective/all__sagemath_modules.py +1 -0
  753. sage/schemes/projective/coherent_sheaf.py +300 -0
  754. sage/schemes/projective/cohomology.py +510 -0
  755. sage/stats/all.py +15 -0
  756. sage/stats/basic_stats.py +489 -0
  757. sage/stats/distributions/all.py +7 -0
  758. sage/stats/distributions/catalog.py +34 -0
  759. sage/stats/distributions/dgs.h +50 -0
  760. sage/stats/distributions/dgs.pxd +111 -0
  761. sage/stats/distributions/dgs_bern.h +400 -0
  762. sage/stats/distributions/dgs_gauss.h +614 -0
  763. sage/stats/distributions/dgs_misc.h +104 -0
  764. sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-musl.so +0 -0
  765. sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
  766. sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
  767. sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
  768. sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
  769. sage/stats/hmm/all.py +15 -0
  770. sage/stats/hmm/chmm.cpython-314-aarch64-linux-musl.so +0 -0
  771. sage/stats/hmm/chmm.pyx +1595 -0
  772. sage/stats/hmm/distributions.cpython-314-aarch64-linux-musl.so +0 -0
  773. sage/stats/hmm/distributions.pxd +29 -0
  774. sage/stats/hmm/distributions.pyx +531 -0
  775. sage/stats/hmm/hmm.cpython-314-aarch64-linux-musl.so +0 -0
  776. sage/stats/hmm/hmm.pxd +17 -0
  777. sage/stats/hmm/hmm.pyx +1388 -0
  778. sage/stats/hmm/util.cpython-314-aarch64-linux-musl.so +0 -0
  779. sage/stats/hmm/util.pxd +7 -0
  780. sage/stats/hmm/util.pyx +165 -0
  781. sage/stats/intlist.cpython-314-aarch64-linux-musl.so +0 -0
  782. sage/stats/intlist.pxd +14 -0
  783. sage/stats/intlist.pyx +588 -0
  784. sage/stats/r.py +49 -0
  785. sage/stats/time_series.cpython-314-aarch64-linux-musl.so +0 -0
  786. sage/stats/time_series.pxd +6 -0
  787. sage/stats/time_series.pyx +2546 -0
  788. sage/tensor/all.py +2 -0
  789. sage/tensor/modules/all.py +8 -0
  790. sage/tensor/modules/alternating_contr_tensor.py +761 -0
  791. sage/tensor/modules/comp.py +5598 -0
  792. sage/tensor/modules/ext_pow_free_module.py +824 -0
  793. sage/tensor/modules/finite_rank_free_module.py +3589 -0
  794. sage/tensor/modules/format_utilities.py +333 -0
  795. sage/tensor/modules/free_module_alt_form.py +858 -0
  796. sage/tensor/modules/free_module_automorphism.py +1207 -0
  797. sage/tensor/modules/free_module_basis.py +1074 -0
  798. sage/tensor/modules/free_module_element.py +284 -0
  799. sage/tensor/modules/free_module_homset.py +652 -0
  800. sage/tensor/modules/free_module_linear_group.py +564 -0
  801. sage/tensor/modules/free_module_morphism.py +1581 -0
  802. sage/tensor/modules/free_module_tensor.py +3289 -0
  803. sage/tensor/modules/reflexive_module.py +386 -0
  804. sage/tensor/modules/tensor_free_module.py +780 -0
  805. sage/tensor/modules/tensor_free_submodule.py +538 -0
  806. sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
  807. sage/tensor/modules/tensor_with_indices.py +1043 -0
@@ -0,0 +1,2091 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ # sage.doctest: needs sage.libs.pari
3
+ r"""
4
+ Finitely generated modules over a PID
5
+
6
+ You can use Sage to compute with finitely generated modules (FGM's)
7
+ over a principal ideal domain `R` presented as a quotient `V / W`, where `V`
8
+ and `W` are free.
9
+
10
+ .. NOTE::
11
+
12
+ Currently this is only enabled over ``R=ZZ``, since it has not been
13
+ tested and debugged over more general PIDs. All algorithms make sense
14
+ whenever there is a Hermite form implementation. In theory the
15
+ obstruction to extending the implementation is only that one has to
16
+ decide how elements print.
17
+
18
+ We represent `M = V / W` as a pair `(V, W)` with `W` contained in
19
+ `V`, and we internally represent elements of `M` non-canonically as elements
20
+ `x` of `V`. We also fix independent generators ``g[i]`` for `M` in
21
+ `V`, and when we print out elements of `V` we print their coordinates
22
+ with respect to the ``g[i]``; over `\ZZ` this is canonical, since each
23
+ coefficient is reduced modulo the additive order of ``g[i]``. To obtain
24
+ the vector in `V` corresponding to `x` in `M`, use ``x.lift()``.
25
+
26
+ Morphisms between finitely generated `R`-modules are well supported.
27
+ You create a homomorphism by simply giving the images of generators of
28
+ `M_0` in `M_1`. Given a morphism `\phi: M_0 \to M_1`, you can compute the image of
29
+ `\phi`, the kernel of `\phi`, and using ``y = phi.lift(x)`` you can lift an
30
+ element `x` in `M_1` to an element `y` in `M_0`, if such a `y` exists.
31
+
32
+ TECHNICAL NOTE: For efficiency, we introduce a notion of optimized
33
+ representation for quotient modules. The optimized representation of
34
+ `M=V/W` is the quotient `V'/W'` where `V'` has as basis lifts of the
35
+ generators ``g[i]`` for `M`. We internally store a morphism from `M_0=V_0/W_0`
36
+ to `M_1=V_1/W_1` by giving a morphism from the optimized representation `V_0'`
37
+ of `M_0` to `V_1` that sends `W_0` into `W_1`.
38
+
39
+
40
+ The following TUTORIAL illustrates several of the above points.
41
+
42
+ First we create free modules `V_0` and `W_0` and the quotient module `M_0`.
43
+ Notice that everything works fine even though `V_0` and `W_0` are not
44
+ contained inside `\ZZ^n`, which is extremely convenient. ::
45
+
46
+ sage: V0 = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ)
47
+ sage: W0 = V0.span([V0.0 + 2*V0.1, 9*V0.0 + 2*V0.1, 4*V0.2])
48
+ sage: M0 = V0/W0; M0
49
+ Finitely generated module V/W over Integer Ring with invariants (4, 16)
50
+
51
+ The invariants are computed using the Smith normal form algorithm, and
52
+ determine the structure of this finitely generated module.
53
+
54
+ You can get the `V` and `W` used in constructing the quotient module using
55
+ the methods :meth:`V` and :meth:`W`::
56
+
57
+ sage: M0.V()
58
+ Free module of degree 3 and rank 3 over Integer Ring
59
+ Echelon basis matrix:
60
+ [1/2 0 0]
61
+ [ 0 2 0]
62
+ [ 0 0 1]
63
+ sage: M0.W()
64
+ Free module of degree 3 and rank 3 over Integer Ring
65
+ Echelon basis matrix:
66
+ [1/2 4 0]
67
+ [ 0 32 0]
68
+ [ 0 0 4]
69
+
70
+ We note that the optimized representation of `M_0`, mentioned above in
71
+ the technical note, has a `V` that need not be equal to `V_0`, in general. ::
72
+
73
+ sage: M0.optimized()[0].V()
74
+ Free module of degree 3 and rank 2 over Integer Ring
75
+ User basis matrix:
76
+ [ 0 8 1]
77
+ [ 0 -2 0]
78
+
79
+ Create elements of `M_0` either by coercing in elements of `V_0`, getting generators,
80
+ or coercing in a list or tuple or coercing in 0. Finally, one can express an
81
+ element as a linear combination of the Smith form generators ::
82
+
83
+ sage: M0(V0.0)
84
+ (0, 2)
85
+ sage: M0(V0.0 + W0.0) # no difference modulo W0
86
+ (0, 2)
87
+ sage: M0.linear_combination_of_smith_form_gens([3,20])
88
+ (3, 4)
89
+ sage: 3*M0.0 + 20*M0.1
90
+ (3, 4)
91
+
92
+ We make an element of `M_0` by taking a difference of two generators, and
93
+ lift it. We also illustrate making an element from a list, which
94
+ coerces to `V_0`, then take the equivalence class modulo `W_0`. ::
95
+
96
+ sage: x = M0.0 - M0.1; x
97
+ (1, 15)
98
+ sage: x.lift()
99
+ (0, 10, 1)
100
+ sage: M0(vector([1/2,0,0]))
101
+ (0, 2)
102
+ sage: x.additive_order()
103
+ 16
104
+
105
+ Similarly, we construct `V_1` and `W_1`, and the quotient `M_1`,
106
+ in a completely different 2-dimensional ambient space. ::
107
+
108
+ sage: V1 = span([[1/2,0], [3/2,2]], ZZ); W1 = V1.span([2*V1.0, 3*V1.1])
109
+ sage: M1 = V1/W1; M1
110
+ Finitely generated module V/W over Integer Ring with invariants (6)
111
+
112
+ We create the homomorphism from `M_0` to `M_1` that sends both generators of
113
+ `M_0` to 3 times the generator of `M_1`. This is well-defined since 3 times
114
+ the generator has order 2. ::
115
+
116
+ sage: f = M0.hom([3*M1.0, 3*M1.0]); f
117
+ Morphism from module over Integer Ring with invariants (4, 16)
118
+ to module with invariants (6,) that sends the generators to [(3), (3)]
119
+
120
+ We evaluate the homomorphism on our element `x` of the domain, and on the
121
+ first generator of the domain. We also evaluate at an element of `V_0`,
122
+ which is coerced into `M_0`. ::
123
+
124
+ sage: f(x)
125
+ (0)
126
+ sage: f(M0.0)
127
+ (3)
128
+ sage: f(V0.1)
129
+ (3)
130
+
131
+ Here we illustrate lifting an element of the image of `f`, i.e., finding
132
+ an element of `M_0` that maps to a given element of `M_1`::
133
+
134
+ sage: y = f.lift(3*M1.0)
135
+ sage: y # random
136
+ (0, 13)
137
+ sage: f(y)
138
+ (3)
139
+
140
+ We compute the kernel of `f`, i.e., the submodule of elements of `M_0` that
141
+ map to 0. Note that the kernel is not explicitly represented as a
142
+ submodule, but as another quotient `V/W` where `V` is contained in `V_0`.
143
+ You can explicitly coerce elements of the kernel into `M_0` though. ::
144
+
145
+ sage: K = f.kernel(); K
146
+ Finitely generated module V/W over Integer Ring with invariants (2, 16)
147
+
148
+ sage: M0(K.0)
149
+ (2, 8)
150
+ sage: M0(K.1)
151
+ (1, 5)
152
+ sage: f(M0(K.0))
153
+ (0)
154
+ sage: f(M0(K.1))
155
+ (0)
156
+
157
+ We compute the image of `f`. ::
158
+
159
+ sage: f.image()
160
+ Finitely generated module V/W over Integer Ring with invariants (2)
161
+
162
+ Notice how the elements of the image are written as (0) and (1),
163
+ despite the image being naturally a submodule of `M_1`, which has
164
+ elements (0), (1), (2), (3), (4), (5). However, below we coerce the
165
+ element (1) of the image into the codomain, and get (3)::
166
+
167
+ sage: list(f.image())
168
+ [(0), (1)]
169
+ sage: list(M1)
170
+ [(0), (1), (2), (3), (4), (5)]
171
+ sage: x = f.image().0; x
172
+ (1)
173
+ sage: M1(x)
174
+ (3)
175
+
176
+
177
+ TESTS::
178
+
179
+ sage: from sage.modules.fg_pid.fgp_module import FGP_Module
180
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
181
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
182
+ sage: Q = FGP_Module(V, W); Q
183
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
184
+ sage: Q.linear_combination_of_smith_form_gens([1,3])
185
+ (1, 3)
186
+ sage: Q(V([1,3,4]))
187
+ (0, 1)
188
+ sage: Q(W([1,16,0]))
189
+ (0, 0)
190
+ sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],QQ)
191
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1])
192
+ sage: Q = FGP_Module(V, W); Q
193
+ Finitely generated module V/W over Rational Field with invariants (0)
194
+ sage: q = Q.an_element(); q
195
+ (1)
196
+ sage: q*(1/2)
197
+ (1/2)
198
+ sage: (1/2)*q
199
+ (1/2)
200
+
201
+ AUTHOR:
202
+
203
+ - William Stein, 2009
204
+ """
205
+
206
+ # ****************************************************************************
207
+ # Copyright (C) 2009 William Stein <wstein@gmail.com>
208
+ #
209
+ # This program is free software: you can redistribute it and/or modify
210
+ # it under the terms of the GNU General Public License as published by
211
+ # the Free Software Foundation, either version 2 of the License, or
212
+ # (at your option) any later version.
213
+ # https://www.gnu.org/licenses/
214
+ # ****************************************************************************
215
+ from itertools import product
216
+
217
+ from sage.modules.module import Module
218
+ from sage.modules.free_module import FreeModule_generic
219
+ from sage.structure.all import parent
220
+ from sage.structure.sequence import Sequence
221
+ from .fgp_element import DEBUG, FGP_Element
222
+ from .fgp_morphism import FGP_Morphism, FGP_Homset
223
+ from sage.rings.integer_ring import ZZ
224
+ from sage.rings.integer import Integer
225
+ from sage.arith.functions import lcm, LCM_list
226
+ from sage.misc.cachefunc import cached_method
227
+ from sage.misc.superseded import deprecated_function_alias
228
+ from sage.matrix.constructor import matrix
229
+
230
+ import sage.misc.weak_dict
231
+ from functools import reduce
232
+ _fgp_module = sage.misc.weak_dict.WeakValueDictionary()
233
+
234
+
235
+ def FGP_Module(V, W, check=True):
236
+ """
237
+ INPUT:
238
+
239
+ - ``V`` -- a free `R`-module
240
+
241
+ - ``W`` -- a free `R`-submodule of `V`
242
+
243
+ - ``check`` -- boolean (default: ``True``); if ``True``, more checks
244
+ on correctness are performed. In particular, we check the data
245
+ types of ``V`` and ``W``, and that `W` is a submodule of `V`
246
+ with the same base ring.
247
+
248
+ OUTPUT: the quotient `V/W` as a finitely generated `R`-module
249
+
250
+ EXAMPLES::
251
+
252
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
253
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
254
+ sage: import sage.modules.fg_pid.fgp_module
255
+ sage: Q = sage.modules.fg_pid.fgp_module.FGP_Module(V, W)
256
+ sage: type(Q)
257
+ <class 'sage.modules.fg_pid.fgp_module.FGP_Module_class_with_category'>
258
+ sage: Q is sage.modules.fg_pid.fgp_module.FGP_Module(V, W, check=False)
259
+ True
260
+ """
261
+ key = (V, V.basis_matrix(), W, W.basis_matrix())
262
+ try:
263
+ return _fgp_module[key]
264
+ except KeyError:
265
+ pass
266
+ M = FGP_Module_class(V, W, check=check)
267
+ _fgp_module[key] = M
268
+ return M
269
+
270
+
271
+ def is_FGP_Module(x):
272
+ """
273
+ Return ``True`` if x is an FGP module, i.e., a finitely generated
274
+ module over a PID represented as a quotient of finitely generated
275
+ free modules over a PID.
276
+
277
+ EXAMPLES::
278
+
279
+ sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ)
280
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2]); Q = V/W
281
+ sage: sage.modules.fg_pid.fgp_module.is_FGP_Module(V)
282
+ doctest:warning...
283
+ DeprecationWarning: the function is_FGP_Module is deprecated;
284
+ use 'isinstance(..., FGP_Module_class)' instead
285
+ See https://github.com/sagemath/sage/issues/37924 for details.
286
+ False
287
+ sage: sage.modules.fg_pid.fgp_module.is_FGP_Module(Q)
288
+ True
289
+ """
290
+ from sage.misc.superseded import deprecation
291
+ deprecation(37924, "the function is_FGP_Module is deprecated; use 'isinstance(..., FGP_Module_class)' instead")
292
+ return isinstance(x, FGP_Module_class)
293
+
294
+
295
+ class FGP_Module_class(Module):
296
+ """
297
+ A finitely generated module over a PID presented as a quotient `V/W`.
298
+
299
+ INPUT:
300
+
301
+ - ``V`` -- an `R`-module
302
+
303
+ - ``W`` -- an `R`-submodule of `V`
304
+
305
+ - ``check`` -- boolean (default: ``True``)
306
+
307
+ EXAMPLES::
308
+
309
+ sage: A = (ZZ^1)/span([[100]], ZZ); A
310
+ Finitely generated module V/W over Integer Ring with invariants (100)
311
+ sage: A.V()
312
+ Ambient free module of rank 1 over the principal ideal domain Integer Ring
313
+ sage: A.W()
314
+ Free module of degree 1 and rank 1 over Integer Ring
315
+ Echelon basis matrix:
316
+ [100]
317
+
318
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
319
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
320
+ sage: Q = V/W; Q
321
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
322
+ sage: type(Q)
323
+ <class 'sage.modules.fg_pid.fgp_module.FGP_Module_class_with_category'>
324
+
325
+ TESTS:
326
+
327
+ Make sure that the problems in :issue:`7516` are fixed::
328
+
329
+ sage: V = FreeModule(QQ, 2)
330
+ sage: W = V.submodule([V([1,1])])
331
+ sage: Z = W.submodule([])
332
+ sage: WmodZ = W / Z
333
+ sage: loads(dumps(WmodZ)) == WmodZ
334
+ True
335
+ """
336
+
337
+ # The class to be used for creating elements of this
338
+ # module. Should be overridden in derived classes.
339
+ Element = FGP_Element
340
+
341
+ def __init__(self, V, W, check=True):
342
+ """
343
+ INPUT:
344
+
345
+ - ``V`` -- an `R`-module
346
+
347
+ - ``W`` -- an `R`-submodule of `V`
348
+
349
+ - ``check`` -- boolean (default: ``True``); if ``True``, more checks on
350
+ correctness are performed. In particular, we check the data types of
351
+ ``V`` and ``W``, and that `W` is a submodule of `V` with the same
352
+ base ring `R`.
353
+
354
+ EXAMPLES::
355
+
356
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
357
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
358
+ sage: Q = V/W; Q
359
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
360
+ sage: type(Q)
361
+ <class 'sage.modules.fg_pid.fgp_module.FGP_Module_class_with_category'>
362
+ """
363
+ if check:
364
+ if not isinstance(V, FreeModule_generic):
365
+ raise TypeError("V must be a FreeModule")
366
+ if not isinstance(W, FreeModule_generic):
367
+ raise TypeError("W must be a FreeModule")
368
+ if not W.is_submodule(V):
369
+ raise ValueError("W must be a submodule of V")
370
+ if V.base_ring() != W.base_ring():
371
+ raise ValueError("W and V must have the same base ring")
372
+ self._W = W
373
+ self._V = V
374
+ Module.__init__(self, base=V.base_ring())
375
+
376
+ # Note: There once was a
377
+ # def _subquotient_class():
378
+ # method that returned a functionoid to construct new modules, so
379
+ # you would call module._subquotient_class()(V,W,check). This has
380
+ # been replaced with module._module_constructor(V,W,check).
381
+
382
+ def _module_constructor(self, V, W, check=True):
383
+ r"""
384
+ Construct a quotient module `V/W`.
385
+
386
+ This should be overridden in derived classes.
387
+
388
+ INPUT:
389
+
390
+ - ``V`` -- an `R`-module
391
+
392
+ - ``W`` -- an `R`-submodule of `V`
393
+
394
+ - ``check`` -- boolean (default: ``True``)
395
+
396
+ OUTPUT: the quotient `V/W`
397
+
398
+ EXAMPLES::
399
+
400
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
401
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
402
+ sage: Q = V/W; Q
403
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
404
+ sage: Q._module_constructor(V,W)
405
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
406
+ """
407
+ return FGP_Module(V, W, check)
408
+
409
+ def _coerce_map_from_(self, S):
410
+ """
411
+ Return whether ``S`` canonically coerces to ``self``.
412
+
413
+ INPUT:
414
+
415
+ - ``S`` -- anything
416
+
417
+ OUTPUT: boolean
418
+
419
+ EXAMPLES::
420
+
421
+ sage: V = span([[5, -1/2]], ZZ); W = span([[20,-2]], ZZ)
422
+ sage: Q = V/W; phi = Q.hom([2*Q.0])
423
+ sage: Q._coerce_map_from_(ZZ)
424
+ False
425
+ sage: Q._coerce_map_from_(phi.kernel())
426
+ True
427
+ sage: Q._coerce_map_from_(Q)
428
+ True
429
+ sage: Q._coerce_map_from_(phi.image())
430
+ True
431
+ sage: Q._coerce_map_from_(V/V.zero_submodule())
432
+ True
433
+ sage: Q._coerce_map_from_(V/V)
434
+ False
435
+ sage: Q._coerce_map_from_(ZZ^2)
436
+ False
437
+
438
+ Of course, `V` canonically coerces to `Q`, as does twice `V`::
439
+
440
+ sage: Q._coerce_map_from_(V)
441
+ True
442
+ sage: Q._coerce_map_from_(V.scale(2))
443
+ True
444
+ """
445
+ if isinstance(S, FGP_Module_class):
446
+ return S.has_canonical_map_to(self)
447
+ return self._V.has_coerce_map_from(S)
448
+
449
+ def _mul_(self, other, switch_sides=False):
450
+ r"""
451
+ Return the image of this module under scalar multiplication by ``other``.
452
+
453
+ INPUT:
454
+
455
+ - ``other`` -- an element of the base ring
456
+ - ``switch_sides`` -- boolean (default: ``False``); left or right
457
+ multiplication
458
+
459
+ EXAMPLES::
460
+
461
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
462
+ sage: W = span([2*V.0, 4*V.1, 3*V.2])
463
+ sage: Q = V/W; Q
464
+ Finitely generated module V/W over Integer Ring with invariants (2, 12)
465
+ sage: 2*Q
466
+ Finitely generated module V/W over Integer Ring with invariants (6)
467
+ sage: Q*3
468
+ Finitely generated module V/W over Integer Ring with invariants (2, 4)
469
+ """
470
+ if other in self.base_ring():
471
+ return self._module_constructor(other*self.V() + self.W(), self.W())
472
+ raise ValueError("Scalar multiplication of a module is only " +
473
+ "defined for an element of the base ring.")
474
+
475
+ def _repr_(self):
476
+ """
477
+ Return string representation of this module.
478
+
479
+ EXAMPLES::
480
+
481
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
482
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
483
+ sage: (V/W)._repr_()
484
+ 'Finitely generated module V/W over Integer Ring with invariants (4, 12)'
485
+ """
486
+ I = str(self.invariants()).replace(',)', ')')
487
+ return "Finitely generated module V/W over %s with invariants %s" % (self.base_ring(), I)
488
+
489
+ def __truediv__(self, other):
490
+ """
491
+ Return the quotient ``self`` / ``other``, where ``other`` must be a
492
+ submodule of ``self``.
493
+
494
+ EXAMPLES::
495
+
496
+ sage: V = span([[5, -1/2]], ZZ); W = span([[20,-2]] ,ZZ)
497
+ sage: Q = V/W; phi = Q.hom([2*Q.0])
498
+ sage: Q
499
+ Finitely generated module V/W over Integer Ring with invariants (4)
500
+ sage: Q/phi.kernel()
501
+ Finitely generated module V/W over Integer Ring with invariants (2)
502
+ sage: Q/Q
503
+ Finitely generated module V/W over Integer Ring with invariants ()
504
+ """
505
+ if not isinstance(other, FGP_Module_class):
506
+ if isinstance(other, FreeModule_generic):
507
+ other = other / other.zero_submodule()
508
+ else:
509
+ raise TypeError("other must be an FGP module")
510
+ if not other.is_submodule(self):
511
+ raise ValueError("other must be a submodule of self")
512
+ return self._module_constructor(self._V, other._V+self._W)
513
+
514
+ def __eq__(self, other):
515
+ """
516
+ EXAMPLES::
517
+
518
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
519
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
520
+ sage: Q = V/W
521
+ sage: Q == Q
522
+ True
523
+ sage: loads(dumps(Q)) == Q
524
+ True
525
+ sage: Q == V
526
+ False
527
+ sage: Q == V/V.zero_submodule()
528
+ False
529
+ """
530
+ if not isinstance(other, FGP_Module_class):
531
+ return False
532
+ return self._V == other._V and self._W == other._W
533
+
534
+ def __ne__(self, other):
535
+ """
536
+ Return ``True`` iff ``self`` is not equal to ``other``.
537
+
538
+ This may not be needed for modules created using the function
539
+ :func:`FGP_Module`, since those have uniqueness built into
540
+ them, but if the modules are created directly using the
541
+ ``__init__`` method for this class, then this may fail; in
542
+ particular, for modules ``M`` and ``N`` with ``M == N`` returning
543
+ True, it may be the case that ``M != N`` may also return True.
544
+ In particular, for derived classes whose ``__init__`` methods just
545
+ call the ``__init__`` method for this class need this. See
546
+ :issue:`9940` for illustrations.
547
+
548
+ EXAMPLES:
549
+
550
+ Make sure that the problems in :issue:`9940` are fixed::
551
+
552
+ sage: G = AdditiveAbelianGroup([0,0])
553
+ sage: H = AdditiveAbelianGroup([0,0])
554
+ sage: G == H
555
+ True
556
+ sage: G != H # indirect doctest
557
+ False
558
+
559
+ sage: N1 = ToricLattice(3)
560
+ sage: sublattice1 = N1.submodule([(1,1,0), (3,2,1)])
561
+ sage: Q1 = N1/sublattice1
562
+ sage: N2 = ToricLattice(3)
563
+ sage: sublattice2 = N2.submodule([(1,1,0), (3,2,1)])
564
+ sage: Q2 = N2/sublattice2
565
+ sage: Q1 == Q2
566
+ True
567
+ sage: Q1 != Q2
568
+ False
569
+ """
570
+ return not self == other
571
+
572
+ # __le__ is a synonym for `is_submodule`: see below
573
+
574
+ def __lt__(self, other):
575
+ """
576
+ Return ``True`` iff ``self`` is a proper submodule of ``other``.
577
+
578
+ EXAMPLES::
579
+
580
+ sage: V = ZZ^2; W = V.span([[1,2]]); W2 = W.scale(2)
581
+ sage: A = V/W; B = W/W2
582
+ sage: B < A
583
+ False
584
+ sage: A = V/W2; B = W/W2
585
+ sage: B < A
586
+ True
587
+ sage: A < A
588
+ False
589
+ """
590
+ return self <= other and not self == other
591
+
592
+ def __gt__(self, other):
593
+ """
594
+ Return ``True`` iff ``other`` is a proper submodule of ``self``.
595
+
596
+ EXAMPLES::
597
+
598
+ sage: V = ZZ^2; W = V.span([[1,2]]); W2 = W.scale(2)
599
+ sage: A = V/W; B = W/W2
600
+ sage: A > B
601
+ False
602
+ sage: A = V/W2; B = W/W2
603
+ sage: A > B
604
+ True
605
+ sage: A > A
606
+ False
607
+ """
608
+ return self >= other and not self == other
609
+
610
+ def __ge__(self, other):
611
+ """
612
+ Return ``True`` iff ``other`` is a submodule of ``self``.
613
+
614
+ EXAMPLES::
615
+
616
+ sage: V = ZZ^2; W = V.span([[1,2]]); W2 = W.scale(2)
617
+ sage: A = V/W; B = W/W2
618
+ sage: A >= B
619
+ False
620
+ sage: A = V/W2; B = W/W2
621
+ sage: A >= B
622
+ True
623
+ sage: A >= A
624
+ True
625
+ """
626
+ return other.is_submodule(self)
627
+
628
+ def _element_constructor_(self, x, check=True):
629
+ """
630
+ INPUT:
631
+
632
+ - ``x`` -- a vector or an fgp module element:
633
+
634
+ - vector: coerce vector into `V` and define the
635
+ corresponding element of `V/W`
636
+
637
+ - fgp module element: lift to element of ambient vector
638
+ space and try to put into `V`. If ``x`` is in ``self`` already,
639
+ just return ``x``.
640
+
641
+ - ``check`` -- boolean (default: ``True``)
642
+
643
+ .. SEEALSO:: :meth:`linear_combination_of_smith_form_gens`
644
+
645
+ EXAMPLES::
646
+
647
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
648
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
649
+ sage: Q = V/W
650
+ sage: x = Q(V.0 - V.1); x # indirect doctest
651
+ (0, 9)
652
+ sage: type(x)
653
+ <class 'sage.modules.fg_pid.fgp_module.FGP_Module_class_with_category.element_class'>
654
+ sage: x is Q(x)
655
+ True
656
+ sage: x.parent() is Q
657
+ True
658
+ """
659
+ if isinstance(x, FGP_Element):
660
+ x = x.lift()
661
+ return self.element_class(self, self._V(x))
662
+
663
+ def linear_combination_of_smith_form_gens(self, x):
664
+ r"""
665
+ Compute a linear combination of the optimised generators of this module
666
+ as returned by :meth:`smith_form_gens`.
667
+
668
+ EXAMPLES::
669
+
670
+ sage: X = ZZ**2 / span([[3,0], [0,2]], ZZ)
671
+ sage: X.linear_combination_of_smith_form_gens([1])
672
+ (1)
673
+ """
674
+ try:
675
+ x = self.optimized()[0].V().linear_combination_of_basis(x)
676
+ except ValueError as msg:
677
+ raise TypeError(msg)
678
+ return self.element_class(self, self._V(x))
679
+
680
+ def __contains__(self, x):
681
+ """
682
+ Return true if ``x`` is contained in ``self``.
683
+
684
+ EXAMPLES::
685
+
686
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
687
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
688
+ sage: Q = V/W; Q
689
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
690
+ sage: Q.0 in Q
691
+ True
692
+ sage: 0 in Q
693
+ True
694
+ sage: vector([1,2,3/7]) in Q
695
+ False
696
+ sage: vector([1,2,3]) in Q
697
+ True
698
+ sage: Q.0 - Q.1 in Q
699
+ True
700
+ """
701
+ if parent(x) is self:
702
+ return True
703
+ try:
704
+ self(x)
705
+ return True
706
+ except (TypeError, ValueError):
707
+ return False
708
+
709
+ def submodule(self, x):
710
+ """
711
+ Return the submodule defined by ``x``.
712
+
713
+ INPUT:
714
+
715
+ - ``x`` -- list, tuple, or FGP module
716
+
717
+ EXAMPLES::
718
+
719
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
720
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
721
+ sage: Q = V/W; Q
722
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
723
+ sage: Q.gens()
724
+ ((1, 0), (0, 1))
725
+
726
+ We create submodules generated by a list or tuple of elements::
727
+
728
+ sage: Q.submodule([Q.0])
729
+ Finitely generated module V/W over Integer Ring with invariants (4)
730
+ sage: Q.submodule([Q.1])
731
+ Finitely generated module V/W over Integer Ring with invariants (12)
732
+ sage: Q.submodule((Q.0, Q.0 + 3*Q.1))
733
+ Finitely generated module V/W over Integer Ring with invariants (4, 4)
734
+
735
+ A submodule defined by a submodule::
736
+
737
+ sage: A = Q.submodule((Q.0, Q.0 + 3*Q.1)); A
738
+ Finitely generated module V/W over Integer Ring with invariants (4, 4)
739
+ sage: Q.submodule(A)
740
+ Finitely generated module V/W over Integer Ring with invariants (4, 4)
741
+
742
+ Inclusion is checked::
743
+
744
+ sage: A.submodule(Q)
745
+ Traceback (most recent call last):
746
+ ...
747
+ ValueError: x.V() must be contained in self's V.
748
+ """
749
+ if isinstance(x, FGP_Module_class):
750
+ if not x._W.is_submodule(self._W):
751
+ raise ValueError("x.W() must be contained in self's W.")
752
+
753
+ V = x._V
754
+ if not V.is_submodule(self._V):
755
+ raise ValueError("x.V() must be contained in self's V.")
756
+
757
+ return x
758
+
759
+ if not isinstance(x, (list, tuple)):
760
+ raise TypeError("x must be a list, tuple, or FGP module")
761
+
762
+ x = Sequence(x)
763
+ if isinstance(x.universe(), FGP_Module_class):
764
+ # TODO: possibly inefficient in some cases
765
+ x = [self(v).lift() for v in x]
766
+ V = self._V.submodule(x) + self._W
767
+ return self._module_constructor(V, self._W)
768
+
769
+ def has_canonical_map_to(self, A) -> bool:
770
+ """
771
+ Return ``True`` if ``self`` has a canonical map to ``A``, relative to the
772
+ given presentation of ``A``.
773
+
774
+ This means that ``A`` is a finitely
775
+ generated quotient module, ``self.V()`` is a submodule of ``A.V()``
776
+ and ``self.W()`` is a submodule of ``A.W()``, i.e., that there is a
777
+ natural map induced by inclusion of the V's. Note that we do
778
+ *not* require that this natural map be injective; for this use
779
+ :meth:`is_submodule`.
780
+
781
+ EXAMPLES::
782
+
783
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
784
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
785
+ sage: Q = V/W; Q
786
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
787
+ sage: A = Q.submodule((Q.0, Q.0 + 3*Q.1)); A
788
+ Finitely generated module V/W over Integer Ring with invariants (4, 4)
789
+ sage: A.has_canonical_map_to(Q)
790
+ True
791
+ sage: Q.has_canonical_map_to(A)
792
+ False
793
+ """
794
+ if not isinstance(A, FGP_Module_class):
795
+ return False
796
+ if self.cardinality() == 0 and self.base_ring() == A.base_ring():
797
+ return True
798
+ return self.V().is_submodule(A.V()) and self.W().is_submodule(A.W())
799
+
800
+ def is_submodule(self, A) -> bool:
801
+ """
802
+ Return ``True`` if ``self`` is a submodule of ``A``.
803
+
804
+ More precisely, this returns ``True`` if ``self.V()`` is a
805
+ submodule of ``A.V()``, with ``self.W()`` equal to ``A.W()``.
806
+
807
+ Compare :meth:`has_canonical_map_to`.
808
+
809
+ EXAMPLES::
810
+
811
+ sage: V = ZZ^2; W = V.span([[1,2]]); W2 = W.scale(2)
812
+ sage: A = V/W; B = W/W2
813
+ sage: B.is_submodule(A)
814
+ False
815
+ sage: A = V/W2; B = W/W2
816
+ sage: B.is_submodule(A)
817
+ True
818
+
819
+ This example illustrates that this command works in a subtle cases.::
820
+
821
+ sage: A = ZZ^1
822
+ sage: Q3 = A / A.span([[3]])
823
+ sage: Q6 = A / A.span([[6]])
824
+ sage: Q6.is_submodule(Q3)
825
+ False
826
+ sage: Q6.has_canonical_map_to(Q3)
827
+ True
828
+ sage: Q = A.span([[2]]) / A.span([[6]])
829
+ sage: Q.is_submodule(Q6)
830
+ True
831
+ """
832
+ if not self.has_canonical_map_to(A):
833
+ return False
834
+
835
+ return self.V().is_submodule(A.V()) and self.W() == A.W()
836
+
837
+ __le__ = is_submodule
838
+
839
+ def V(self):
840
+ """
841
+ If this module was constructed as a quotient V/W, return V.
842
+
843
+ EXAMPLES::
844
+
845
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
846
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
847
+ sage: Q = V/W
848
+ sage: Q.V()
849
+ Free module of degree 3 and rank 3 over Integer Ring
850
+ Echelon basis matrix:
851
+ [1/2 0 0]
852
+ [ 0 1 0]
853
+ [ 0 0 1]
854
+ """
855
+ return self._V
856
+
857
+ def cover(self):
858
+ """
859
+ If this module was constructed as `V/W`, return the cover module `V`.
860
+
861
+ This is the same as ``self.V()``.
862
+
863
+ EXAMPLES::
864
+
865
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
866
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
867
+ sage: Q = V/W
868
+ sage: Q.V()
869
+ Free module of degree 3 and rank 3 over Integer Ring
870
+ Echelon basis matrix:
871
+ [1/2 0 0]
872
+ [ 0 1 0]
873
+ [ 0 0 1]
874
+ """
875
+ return self.V()
876
+
877
+ def W(self):
878
+ """
879
+ If this module was constructed as a quotient `V/W`, return `W`.
880
+
881
+ EXAMPLES::
882
+
883
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
884
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
885
+ sage: Q = V/W
886
+ sage: Q.W()
887
+ Free module of degree 3 and rank 3 over Integer Ring
888
+ Echelon basis matrix:
889
+ [1/2 8 0]
890
+ [ 0 12 0]
891
+ [ 0 0 4]
892
+ """
893
+ return self._W
894
+
895
+ def relations(self):
896
+ """
897
+ If ``self`` was constructed as `V / W`, return the
898
+ relations module `W`.
899
+
900
+ This is the same as ``self.W()``.
901
+
902
+ EXAMPLES::
903
+
904
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
905
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
906
+ sage: Q = V / W
907
+ sage: Q.relations()
908
+ Free module of degree 3 and rank 3 over Integer Ring
909
+ Echelon basis matrix:
910
+ [1/2 8 0]
911
+ [ 0 12 0]
912
+ [ 0 0 4]
913
+ """
914
+ return self.W()
915
+
916
+ @cached_method
917
+ def _relative_matrix(self):
918
+ """
919
+ `V` has a fixed choice of basis, and `W` has a fixed choice of
920
+ basis, and both `V` and `W` are free `R`-modules. Since `W` is
921
+ contained in `V`, we can write each basis element of `W` as an
922
+ `R`-linear combination of the basis for `V`. This function
923
+ returns that matrix over `R`, where each row corresponds to a
924
+ basis element of `W`.
925
+
926
+ EXAMPLES::
927
+
928
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
929
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
930
+ sage: Q = V/W
931
+ sage: Q._relative_matrix()
932
+ [ 1 8 0]
933
+ [ 0 12 0]
934
+ [ 0 0 4]
935
+ """
936
+ V = self._V
937
+ W = self._W
938
+ A = V.coordinate_module(W).basis_matrix().change_ring(self.base_ring())
939
+ return A
940
+
941
+ @cached_method
942
+ def _smith_form(self):
943
+ """
944
+ Return matrices `S`, `U`, and `V` such that `S = U*R*V`, and `S` is in
945
+ Smith normal form, and `R` is the relative matrix that defines
946
+ ``self``.
947
+
948
+ See :meth:`_relative_matrix`.
949
+
950
+ EXAMPLES::
951
+
952
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
953
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
954
+ sage: Q = V/W
955
+ sage: Q._smith_form()
956
+ (
957
+ [ 1 0 0] [ 1 0 0] [ 1 0 8]
958
+ [ 0 4 0] [ 0 1 1] [ 0 0 -1]
959
+ [ 0 0 12], [ 0 -1 0], [ 0 1 3]
960
+ )
961
+ """
962
+ return self._relative_matrix().smith_form()
963
+
964
+ def base_ring(self):
965
+ """
966
+ Return the base ring of ``self``.
967
+
968
+ EXAMPLES::
969
+
970
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
971
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
972
+ sage: Q = V/W
973
+ sage: Q.base_ring()
974
+ Integer Ring
975
+ """
976
+ return self._V.base_ring()
977
+
978
+ @cached_method
979
+ def invariants(self, include_ones=False):
980
+ r"""
981
+ Return the diagonal entries of the Smith form of the relative
982
+ matrix that defines ``self`` (see :meth:`._relative_matrix`)
983
+ padded with zeros, excluding 1s by default. Thus if ``v`` is the
984
+ list of integers returned, then ``self`` is abstractly isomorphic to
985
+ the product of cyclic groups `\ZZ/n\ZZ` where `n` is in ``v``.
986
+
987
+ INPUT:
988
+
989
+ - ``include_ones`` -- boolean (default: ``False``); if ``True``, also
990
+ include 1s in the output list
991
+
992
+ EXAMPLES::
993
+
994
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
995
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
996
+ sage: Q = V/W
997
+ sage: Q.invariants()
998
+ (4, 12)
999
+
1000
+ An example with 1 and 0 rows::
1001
+
1002
+ sage: V = ZZ^3; W = V.span([[1,2,0], [0,1,0], [0,2,0]]); Q = V/W; Q
1003
+ Finitely generated module V/W over Integer Ring with invariants (0)
1004
+ sage: Q.invariants()
1005
+ (0,)
1006
+ sage: Q.invariants(include_ones=True)
1007
+ (1, 1, 0)
1008
+ """
1009
+ D, _, _ = self._smith_form()
1010
+
1011
+ v = [D[i, i] for i in range(D.nrows())] + [Integer(0)] * (D.ncols()-D.nrows())
1012
+ w = tuple([x for x in v if x != 1])
1013
+ v = tuple(v)
1014
+ self.invariants.set_cache(v, True)
1015
+ self.invariants.set_cache(w, False)
1016
+ return self.invariants(include_ones)
1017
+
1018
+ def gens(self) -> tuple:
1019
+ """
1020
+ Return tuple of elements `g_0,...,g_n` of ``self`` such that the module generated by
1021
+ the `g_i` is isomorphic to the direct sum of `R/e_i R`, where `e_i` are the
1022
+ invariants of ``self`` and `R` is the base ring.
1023
+
1024
+ Note that these are not generally uniquely determined, and depending on
1025
+ how Smith normal form is implemented for the base ring, they may not
1026
+ even be deterministic.
1027
+
1028
+ This can safely be overridden in all derived classes.
1029
+
1030
+ EXAMPLES::
1031
+
1032
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1033
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1034
+ sage: Q = V/W
1035
+ sage: Q.gens()
1036
+ ((1, 0), (0, 1))
1037
+ sage: Q.0
1038
+ (1, 0)
1039
+ """
1040
+ return self.smith_form_gens()
1041
+
1042
+ @cached_method
1043
+ def smith_form_gens(self):
1044
+ """
1045
+ Return a set of generators for ``self`` which are in Smith normal form.
1046
+
1047
+ EXAMPLES::
1048
+
1049
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1050
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1051
+ sage: Q = V/W
1052
+ sage: Q.smith_form_gens()
1053
+ ((1, 0), (0, 1))
1054
+ sage: [x.lift() for x in Q.smith_form_gens()]
1055
+ [(0, 3, 1), (0, -1, 0)]
1056
+ """
1057
+ # Get the rightmost transformation in the Smith form
1058
+ _, _, X = self._smith_form()
1059
+ # Invert it to get a matrix whose rows (in terms of the basis for V)
1060
+ # are the gi (including 1 invariants).
1061
+ Y = X**(-1)
1062
+ # Get the basis matrix for V
1063
+ B = self._V.basis_matrix()
1064
+ # Multiply to express the gi in terms of the ambient vector space.
1065
+ Z = Y*B
1066
+ # Make gens out of the rows of Z that correspond to non-1 invariants.
1067
+ v = self.invariants(include_ones=True)
1068
+ non1 = [i for i in range(Z.nrows()) if v[i] != 1]
1069
+ Z = Z.matrix_from_rows(non1)
1070
+ self._gens_smith = tuple([self(z, check=DEBUG) for z in Z.rows()])
1071
+ return self._gens_smith
1072
+
1073
+ def gens_to_smith(self):
1074
+ r"""
1075
+ Return the transformation matrix from the user to Smith form generators.
1076
+
1077
+ To go in the other direction, use :meth:`smith_to_gens`.
1078
+
1079
+ OUTPUT: a matrix over the base ring
1080
+
1081
+ EXAMPLES::
1082
+
1083
+ sage: L2 = IntegralLattice(3 * matrix([[-2,0,0], [0,1,0], [0,0,-4]]))
1084
+ sage: D = L2.discriminant_group().normal_form(); D # needs sage.libs.pari sage.rings.padics
1085
+ Finite quadratic module over Integer Ring with invariants (3, 6, 12)
1086
+ Gram matrix of the quadratic form with values in Q/Z:
1087
+ [1/2 0 0 0 0]
1088
+ [ 0 1/4 0 0 0]
1089
+ [ 0 0 1/3 0 0]
1090
+ [ 0 0 0 1/3 0]
1091
+ [ 0 0 0 0 2/3]
1092
+ sage: D.gens_to_smith() # needs sage.libs.pari sage.rings.padics
1093
+ [0 3 0]
1094
+ [0 0 3]
1095
+ [0 4 0]
1096
+ [1 2 0]
1097
+ [0 0 4]
1098
+ sage: T = D.gens_to_smith() * D.smith_to_gens(); T # needs sage.libs.pari sage.rings.padics
1099
+ [ 3 0 3 0 0]
1100
+ [ 0 33 0 0 3]
1101
+ [ 4 0 4 0 0]
1102
+ [ 2 0 3 1 0]
1103
+ [ 0 44 0 0 4]
1104
+
1105
+ The matrix `T` now satisfies a certain congruence::
1106
+
1107
+ sage: for i in range(T.nrows()): # needs sage.libs.pari sage.rings.padics
1108
+ ....: T[:,i] = T[:,i] % D.gens()[i].order()
1109
+ sage: T # needs sage.libs.pari sage.rings.padics
1110
+ [1 0 0 0 0]
1111
+ [0 1 0 0 0]
1112
+ [0 0 1 0 0]
1113
+ [0 0 0 1 0]
1114
+ [0 0 0 0 1]
1115
+ """
1116
+ gens_to_smith = matrix(self.base_ring(),
1117
+ [t.vector() for t in self.gens()])
1118
+ gens_to_smith.set_immutable()
1119
+ return gens_to_smith
1120
+
1121
+ @cached_method
1122
+ def smith_to_gens(self):
1123
+ r"""
1124
+ Return the transformation matrix from Smith form to user generators.
1125
+
1126
+ To go in the other direction, use :meth:`gens_to_smith`.
1127
+
1128
+ OUTPUT: a matrix over the base ring
1129
+
1130
+ EXAMPLES::
1131
+
1132
+ sage: L2 = IntegralLattice(3 * matrix([[-2,0,0], [0,1,0], [0,0,-4]]))
1133
+ sage: D = L2.discriminant_group().normal_form(); D # needs sage.libs.pari sage.rings.padics
1134
+ Finite quadratic module over Integer Ring with invariants (3, 6, 12)
1135
+ Gram matrix of the quadratic form with values in Q/Z:
1136
+ [1/2 0 0 0 0]
1137
+ [ 0 1/4 0 0 0]
1138
+ [ 0 0 1/3 0 0]
1139
+ [ 0 0 0 1/3 0]
1140
+ [ 0 0 0 0 2/3]
1141
+ sage: D.smith_to_gens() # needs sage.libs.pari sage.rings.padics
1142
+ [ 0 0 1 1 0]
1143
+ [ 1 0 1 0 0]
1144
+ [ 0 11 0 0 1]
1145
+ sage: T = D.smith_to_gens() * D.gens_to_smith(); T # needs sage.libs.pari sage.rings.padics
1146
+ [ 1 6 0]
1147
+ [ 0 7 0]
1148
+ [ 0 0 37]
1149
+
1150
+ This matrix satisfies the congruence::
1151
+
1152
+ sage: for i in range(T.ncols()): # needs sage.libs.pari sage.rings.padics
1153
+ ....: T[:, i] = T[:, i] % D.smith_form_gens()[i].order()
1154
+ sage: T # needs sage.libs.pari sage.rings.padics
1155
+ [1 0 0]
1156
+ [0 1 0]
1157
+ [0 0 1]
1158
+
1159
+ We create some element of our FGP module::
1160
+
1161
+ sage: x = D.linear_combination_of_smith_form_gens((1,2,3)); x # needs sage.libs.pari sage.rings.padics
1162
+ (1, 2, 3)
1163
+
1164
+ and want to know some (it is not unique) linear combination
1165
+ of the user defined generators that is ``x``::
1166
+
1167
+ sage: x.vector() * D.smith_to_gens() # needs sage.libs.pari sage.rings.padics
1168
+ (2, 33, 3, 1, 3)
1169
+ """
1170
+ if self.base_ring() != ZZ:
1171
+ # it is not
1172
+ raise NotImplementedError("the base ring must be ZZ")
1173
+ base = self.base_ring()
1174
+ invs = self.invariants()
1175
+ B = self.gens_to_smith()
1176
+ n = len(invs)
1177
+ smith_to_gens = []
1178
+ for k in range(n):
1179
+ R = base.quotient_ring(invs[k])
1180
+ e = (R**n).gen(k) # k-th standard basis vector
1181
+ v = B.change_ring(R).solve_left(e)
1182
+ smith_to_gens.append(v)
1183
+ smith_to_gens = matrix(base, smith_to_gens)
1184
+ smith_to_gens.set_immutable()
1185
+ return smith_to_gens
1186
+
1187
+ def gens_vector(self, x, reduce=False):
1188
+ r"""
1189
+ Return coordinates of ``x`` with respect to the generators.
1190
+
1191
+ INPUT:
1192
+
1193
+ - ``x`` -- element of ``self``
1194
+
1195
+ - ``reduce`` -- (default: ``False``) if ``True``,
1196
+ reduce coefficients modulo invariants; this is
1197
+ ignored if the base ring is not `\ZZ`
1198
+
1199
+ EXAMPLES:
1200
+
1201
+ We create a derived class and overwrite :meth:`gens`::
1202
+
1203
+ sage: from sage.modules.fg_pid.fgp_module import FGP_Module_class
1204
+ sage: W = ZZ^3
1205
+ sage: V = W.span(matrix.diagonal([1/6, 1/3, 1/12]))
1206
+ sage: class FGP_with_gens(FGP_Module_class):
1207
+ ....: def __init__(self, V, W, gens):
1208
+ ....: FGP_Module_class.__init__(self, V, W)
1209
+ ....: self._gens = tuple([self(g) for g in gens])
1210
+ ....: def gens(self):
1211
+ ....: return self._gens
1212
+ sage: gens = [(1/2, 0, 0), (0, 0, 1/4), (1/3, 0, 0), (0, 1/3, 0), (0, 0, 2/3)]
1213
+ sage: gens = [V(g) for g in gens]
1214
+ sage: D = FGP_with_gens(V, W, gens)
1215
+ sage: D.gens()
1216
+ ((0, 3, 0), (0, 0, 3), (0, 4, 0), (1, 2, 0), (0, 0, 8))
1217
+
1218
+
1219
+ We create some element of ``D``::
1220
+
1221
+ sage: x = D.linear_combination_of_smith_form_gens((1,2,3)); x
1222
+ (1, 2, 3)
1223
+
1224
+ In our generators::
1225
+
1226
+ sage: v = D.gens_vector(x); v # needs sage.libs.pari
1227
+ (2, 9, 3, 1, 33)
1228
+
1229
+ The output can be further reduced::
1230
+
1231
+ sage: D.gens_vector(x, reduce=True) # needs sage.libs.pari
1232
+ (0, 1, 0, 1, 0)
1233
+
1234
+ Let us check::
1235
+
1236
+ sage: x == sum(v[i]*D.gen(i) for i in range(len(D.gens()))) # needs sage.libs.pari
1237
+ True
1238
+ """
1239
+ x = self(x)
1240
+ v = x.vector() * self.smith_to_gens()
1241
+ from sage.rings.infinity import infinity
1242
+ if reduce and self.base_ring() == ZZ:
1243
+ orders = [g.order() for g in self.gens()]
1244
+ v = v.parent()([v[i] if orders[i] == infinity
1245
+ else v[i] % orders[i]
1246
+ for i in range(len(self.gens()))])
1247
+ return v
1248
+
1249
+ def coordinate_vector(self, x, reduce=False):
1250
+ """
1251
+ Return coordinates of ``x`` with respect to the optimized
1252
+ representation of ``self``.
1253
+
1254
+ INPUT:
1255
+
1256
+ - ``x`` -- element of ``self``
1257
+
1258
+ - ``reduce`` -- (default: ``False``) if ``True``, reduce
1259
+ coefficients modulo invariants; this is
1260
+ ignored if the base ring is not ``ZZ``
1261
+
1262
+ OUTPUT:
1263
+
1264
+ The coordinates as a vector. That is, the same type as
1265
+ ``self.V()``, but in general with fewer entries.
1266
+
1267
+ EXAMPLES::
1268
+
1269
+ sage: V = span([[1/4,0,0], [3/4,4,2], [0,0,2]], ZZ)
1270
+ sage: W = V.span([4*V.0 + 12*V.1])
1271
+ sage: Q = V/W; Q
1272
+ Finitely generated module V/W over Integer Ring with invariants (4, 0, 0)
1273
+ sage: Q.coordinate_vector(-Q.0)
1274
+ (-1, 0, 0)
1275
+ sage: Q.coordinate_vector(-Q.0, reduce=True)
1276
+ (3, 0, 0)
1277
+
1278
+ If x is not in self, it is coerced in::
1279
+
1280
+ sage: Q.coordinate_vector(V.0)
1281
+ (1, -3, 0)
1282
+ sage: Q.coordinate_vector(Q(V.0))
1283
+ (1, -3, 0)
1284
+
1285
+ TESTS::
1286
+
1287
+ sage: V = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ)
1288
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1289
+ sage: Q = V/W; Q
1290
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
1291
+ sage: Q.coordinate_vector(Q.0 - Q.1, reduce=True)
1292
+ (1, 11)
1293
+ sage: a, b = Q.coordinate_vector(Q.0 - Q.1)
1294
+ sage: (a % 4, b % 12)
1295
+ (1, 11)
1296
+
1297
+ sage: O, X = Q.optimized()
1298
+ sage: O.V()
1299
+ Free module of degree 3 and rank 2 over Integer Ring
1300
+ User basis matrix:
1301
+ [ 0 6 1]
1302
+ [ 0 -2 0]
1303
+ sage: phi = Q.hom([Q.0, 4*Q.1])
1304
+ sage: x = Q(V.0); x
1305
+ (0, 8)
1306
+ sage: Q.coordinate_vector(x, reduce=True)
1307
+ (0, 8)
1308
+ sage: a, b = Q.coordinate_vector(-x, reduce=False)
1309
+ sage: (a % 4, b % 12)
1310
+ (0, 4)
1311
+ sage: x == 8*Q.1
1312
+ True
1313
+ sage: x = Q(V.1); x
1314
+ (0, 11)
1315
+ sage: a, b = Q.coordinate_vector(x)
1316
+ sage: (a % 4, b % 12)
1317
+ (0, 11)
1318
+ sage: x == -Q.1
1319
+ True
1320
+ sage: x = Q(V.2); x
1321
+ (1, 3)
1322
+ sage: Q.coordinate_vector(x)
1323
+ (1, 3)
1324
+ sage: x == Q.0 + 3*Q.1
1325
+ True
1326
+ """
1327
+ try:
1328
+ T = self.__T
1329
+ except AttributeError:
1330
+ self.optimized() # computes T as side effect
1331
+ # see the "optimized" method.
1332
+ T = self.__T
1333
+
1334
+ x = self(x)
1335
+
1336
+ c = self._V.coordinate_vector(x.lift())
1337
+ b = (c * T).change_ring(self.base_ring())
1338
+ if reduce and self.base_ring() == ZZ:
1339
+
1340
+ I = self.invariants()
1341
+ return b.parent()([b[i] if I[i] == 0 else b[i] % I[i]
1342
+ for i in range(len(I))])
1343
+
1344
+ else:
1345
+ # Don't know (or not requested) canonical way to reduce
1346
+ # each entry yet, or how to compute invariants.
1347
+ return b
1348
+
1349
+ def gen(self, i):
1350
+ """
1351
+ Return the ``i``-th generator of ``self``.
1352
+
1353
+ INPUT:
1354
+
1355
+ - ``i`` -- integer
1356
+
1357
+ EXAMPLES::
1358
+
1359
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1360
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1361
+ sage: Q = V/W; Q
1362
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
1363
+ sage: Q.gen(0)
1364
+ (1, 0)
1365
+ sage: Q.gen(1)
1366
+ (0, 1)
1367
+ sage: Q.gen(2)
1368
+ Traceback (most recent call last):
1369
+ ...
1370
+ ValueError: Generator 2 not defined
1371
+ sage: Q.gen(-1)
1372
+ Traceback (most recent call last):
1373
+ ...
1374
+ ValueError: Generator -1 not defined
1375
+ """
1376
+ v = self.gens()
1377
+ if i < 0 or i >= len(v):
1378
+ raise ValueError("Generator %s not defined" % i)
1379
+ return v[i]
1380
+
1381
+ def smith_form_gen(self, i):
1382
+ """
1383
+ Return the ``i``-th generator of ``self``.
1384
+
1385
+ This is a separate method so we can freely override :meth:`gen`
1386
+ in derived classes.
1387
+
1388
+ INPUT:
1389
+
1390
+ - ``i`` -- integer
1391
+
1392
+ EXAMPLES::
1393
+
1394
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1395
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1396
+ sage: Q = V/W; Q
1397
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
1398
+ sage: Q.smith_form_gen(0)
1399
+ (1, 0)
1400
+ sage: Q.smith_form_gen(1)
1401
+ (0, 1)
1402
+ """
1403
+ v = self.smith_form_gens()
1404
+ if i < 0 or i >= len(v):
1405
+ raise ValueError("Smith form generator %s not defined" % i)
1406
+ return v[i]
1407
+
1408
+ def optimized(self):
1409
+ r"""
1410
+ Return a module isomorphic to this one, but with `V` replaced by
1411
+ a submodule of `V` such that the generators of ``self`` all lift
1412
+ trivially to generators of `V`. Replace `W` by the intersection
1413
+ of `V` and `W`. This has the advantage that `V` has small dimension
1414
+ and any homomorphism from ``self`` trivially extends to a
1415
+ homomorphism from `V`.
1416
+
1417
+ OUTPUT:
1418
+
1419
+ - ``Q`` -- an optimized quotient `V_0/W_0` with `V_0` a submodule of `V`
1420
+ such that `\phi: V_0/W_0 \to V/W` is an isomorphism
1421
+
1422
+ - ``Z`` -- matrix such that if `x` is in ``self.V()`` and
1423
+ ``c`` gives the coordinates of `x` in terms of the
1424
+ basis for ``self.V()``, then ``c*Z`` is in `V_0`
1425
+ and ``c*Z`` maps to `x` via `\phi` above.
1426
+
1427
+ EXAMPLES::
1428
+
1429
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1430
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1431
+ sage: Q = V/W
1432
+ sage: O, X = Q.optimized(); O
1433
+ Finitely generated module V/W over Integer Ring with invariants (4, 12)
1434
+ sage: O.V()
1435
+ Free module of degree 3 and rank 2 over Integer Ring
1436
+ User basis matrix:
1437
+ [ 0 3 1]
1438
+ [ 0 -1 0]
1439
+ sage: O.W()
1440
+ Free module of degree 3 and rank 2 over Integer Ring
1441
+ Echelon basis matrix:
1442
+ [ 0 12 0]
1443
+ [ 0 0 4]
1444
+ sage: X # random
1445
+ [0 4 0]
1446
+ [0 1 0]
1447
+ [0 0 1]
1448
+ sage: OV = O.V()
1449
+ sage: Q(OV([0,-8,0])) == V.0
1450
+ True
1451
+ sage: Q(OV([0,1,0])) == V.1
1452
+ True
1453
+ sage: Q(OV([0,0,1])) == V.2
1454
+ True
1455
+ """
1456
+ try:
1457
+ if self.__optimized is True:
1458
+ return self, None
1459
+ return self.__optimized
1460
+ except AttributeError:
1461
+ pass
1462
+ V = self._V.span_of_basis([x.lift() for x in self.smith_form_gens()])
1463
+ M = self._module_constructor(V, self._W.intersection(V))
1464
+ # Compute matrix T of linear transformation from self._V to V.
1465
+ # This matrix T gives each basis element of self._V in terms
1466
+ # of our new optimized V, modulo the W's.
1467
+ A = V.basis_matrix().stack(self._W.basis_matrix())
1468
+ if A.base_ring() is ZZ:
1469
+ B, d = A, 1
1470
+ else:
1471
+ try:
1472
+ # Use fast routine specific to Matrix_rational_dense
1473
+ B, d = A._clear_denom()
1474
+ except AttributeError:
1475
+ d = LCM_list(coeff.denominator()
1476
+ for key, coeff in A.items())
1477
+ B = d * A
1478
+ H, U = B.hermite_form(transformation=True)
1479
+ Y = H.solve_left(d * self._V.basis_matrix())
1480
+ T = Y * U.matrix_from_columns(range(V.rank()))
1481
+ self.__T = T
1482
+
1483
+ # Finally we multiply by V.basis_matrix() so X gives vectors
1484
+ # in the ambient space instead of coefficients of linear
1485
+ # combinations of the basis for V.
1486
+ X = T * V.basis_matrix()
1487
+
1488
+ self.__optimized = M, X
1489
+ return M, X
1490
+
1491
+ def hom(self, im_gens, codomain=None, check=True):
1492
+ """
1493
+ Homomorphism defined by giving the images of ``self.gens()`` in some
1494
+ fixed finitely generated `R`-module.
1495
+
1496
+ .. NOTE::
1497
+
1498
+ We do not assume that the generators given by ``self.gens()`` are
1499
+ the same as the Smith form generators, since this may not be true
1500
+ for a general derived class.
1501
+
1502
+ INPUT:
1503
+
1504
+ - ``im_gens`` -- list of the images of ``self.gens()`` in some
1505
+ `R`-module
1506
+
1507
+ EXAMPLES::
1508
+
1509
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1510
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1511
+ sage: Q = V/W
1512
+ sage: phi = Q.hom([3*Q.1, Q.0])
1513
+ sage: phi
1514
+ Morphism from module over Integer Ring with invariants (4, 12)
1515
+ to module with invariants (4, 12)
1516
+ that sends the generators to [(0, 3), (1, 0)]
1517
+ sage: phi(Q.0)
1518
+ (0, 3)
1519
+ sage: phi(Q.1)
1520
+ (1, 0)
1521
+ sage: Q.0 == phi(Q.1)
1522
+ True
1523
+
1524
+ This example illustrates creating a morphism to a free module.
1525
+ The free module is turned into an FGP module (i.e., quotient
1526
+ `V/W` with `W=0`), and the morphism is constructed::
1527
+
1528
+ sage: V = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ)
1529
+ sage: W = V.span([2*V.0 + 4*V.1])
1530
+ sage: Q = V/W; Q
1531
+ Finitely generated module V/W over Integer Ring with invariants (2, 0, 0)
1532
+ sage: phi = Q.hom([0, V.0, V.1]); phi
1533
+ Morphism from module over Integer Ring with invariants (2, 0, 0)
1534
+ to module with invariants (0, 0, 0)
1535
+ that sends the generators to [(0, 0, 0), (1, 0, 0), (0, 1, 0)]
1536
+ sage: phi.domain()
1537
+ Finitely generated module V/W over Integer Ring with invariants (2, 0, 0)
1538
+ sage: phi.codomain()
1539
+ Finitely generated module V/W over Integer Ring with invariants (0, 0, 0)
1540
+ sage: phi(Q.0)
1541
+ (0, 0, 0)
1542
+ sage: phi(Q.1)
1543
+ (1, 0, 0)
1544
+ sage: phi(Q.2) == V.1
1545
+ True
1546
+
1547
+ Constructing two zero maps from the zero module::
1548
+
1549
+ sage: A = (ZZ^2)/(ZZ^2); A
1550
+ Finitely generated module V/W over Integer Ring with invariants ()
1551
+ sage: A.hom([])
1552
+ Morphism from module over Integer Ring with invariants ()
1553
+ to module with invariants ()
1554
+ that sends the generators to []
1555
+ sage: A.hom([]).codomain() is A
1556
+ True
1557
+ sage: B = (ZZ^3)/(ZZ^3)
1558
+ sage: phi = A.hom([], codomain=B); phi
1559
+ Morphism from module over Integer Ring with invariants ()
1560
+ to module with invariants ()
1561
+ that sends the generators to []
1562
+ sage: phi(A(0))
1563
+ ()
1564
+ sage: phi(A(0)) == B(0)
1565
+ True
1566
+
1567
+ A degenerate case::
1568
+
1569
+ sage: A = (ZZ^2)/(ZZ^2)
1570
+ sage: phi = A.hom([]); phi
1571
+ Morphism from module over Integer Ring with invariants ()
1572
+ to module with invariants ()
1573
+ that sends the generators to []
1574
+ sage: phi(A(0))
1575
+ ()
1576
+
1577
+ The code checks that the morphism is valid. In the example
1578
+ below we try to send a generator of order 2 to an element of
1579
+ order 14::
1580
+
1581
+ sage: V = span([[1/14,3/14], [0,1/2]], ZZ); W = ZZ^2
1582
+ sage: Q = V/W; Q
1583
+ Finitely generated module V/W over Integer Ring with invariants (2, 14)
1584
+ sage: Q.linear_combination_of_smith_form_gens([1,11]).additive_order()
1585
+ 14
1586
+ sage: f = Q.hom([Q.linear_combination_of_smith_form_gens([1,11]),
1587
+ ....: Q.linear_combination_of_smith_form_gens([1,3])]); f
1588
+ Traceback (most recent call last):
1589
+ ...
1590
+ ValueError: phi must send optimized submodule of M.W() into N.W()
1591
+ """
1592
+ if len(im_gens) == 0:
1593
+ # 0 map
1594
+ N = self if codomain is None else codomain
1595
+ else:
1596
+ if codomain is None:
1597
+ im_gens = Sequence(im_gens)
1598
+ N = im_gens.universe()
1599
+ else:
1600
+ N = codomain
1601
+ im_gens = Sequence(im_gens, universe=N)
1602
+
1603
+ if isinstance(N, FreeModule_generic):
1604
+ # If im_smith_gens are not in an R-module, but are in a Free-module,
1605
+ # then we quotient out by the 0 submodule and get an R-module.
1606
+ N = FGP_Module(N, N.zero_submodule(), check=DEBUG)
1607
+ im_gens = Sequence(im_gens, universe=N)
1608
+
1609
+ if len(im_gens) == 0:
1610
+ VO = self.optimized()[0].V()
1611
+ H = VO.Hom(N.V())
1612
+ return FGP_Morphism(self.Hom(N), H(0), check=DEBUG)
1613
+
1614
+ if self.gens() == self.smith_form_gens():
1615
+ return self._hom_from_smith(im_gens, check)
1616
+ else:
1617
+ return self._hom_general(im_gens, check)
1618
+
1619
+ def _hom_general(self, im_gens, check=True):
1620
+ """
1621
+ Homomorphism defined by giving the images of ``self.gens()`` in some
1622
+ fixed finitely generated `R`-module. We do not assume that the generators given by
1623
+ ``self.gens()`` are the same as the Smith form generators, since this
1624
+ may not be true for a general derived class.
1625
+
1626
+ INPUT:
1627
+
1628
+ - ``im_gens`` -- a Sequence object giving the images of ``self.gens()``,
1629
+ whose universe is some fixed finitely generated `R`-module
1630
+
1631
+ EXAMPLES::
1632
+
1633
+ sage: class SillyModule(sage.modules.fg_pid.fgp_module.FGP_Module_class):
1634
+ ....: def gens(self):
1635
+ ....: return tuple(flatten([[x,x] for x in self.smith_form_gens()]))
1636
+ sage: A = SillyModule(ZZ**1, span([[3]], ZZ))
1637
+ sage: A.gen(0)
1638
+ (1)
1639
+ sage: A.gen(1)
1640
+ (1)
1641
+ sage: B = ZZ**1 / span([[3]], ZZ)
1642
+ sage: A.hom([B.0, 2*B.0], B)
1643
+ Traceback (most recent call last):
1644
+ ...
1645
+ ValueError: Images do not determine a valid homomorphism
1646
+ sage: A.hom([B.0, B.0], B) # indirect doctest
1647
+ Morphism from module over Integer Ring with invariants (3,)
1648
+ to module with invariants (3,)
1649
+ that sends the generators to [(1), (1)]
1650
+ """
1651
+ m = self.ngens()
1652
+ A = ZZ**m
1653
+ q = A.hom([x.lift() for x in self.gens()], self.V())
1654
+ B = q.inverse_image(self.W())
1655
+ N = im_gens.universe()
1656
+ r = A.hom([x.lift() for x in im_gens], N.V())
1657
+ if check:
1658
+ if not r(B).is_submodule(N.W()):
1659
+ raise ValueError("Images do not determine a valid homomorphism")
1660
+ smith_images = Sequence([N(r(q.lift(x.lift()))) for x in self.smith_form_gens()])
1661
+ return self._hom_from_smith(smith_images, check=DEBUG)
1662
+
1663
+ def _hom_from_smith(self, im_smith_gens, check=True):
1664
+ """
1665
+ Homomorphism defined by giving the images of the Smith-form generators
1666
+ of ``self`` in some fixed finitely generated `R`-module.
1667
+
1668
+ INPUT:
1669
+
1670
+ - ``im_gens`` -- a Sequence object giving the images of the Smith-form
1671
+ generators of ``self``, whose universe is some fixed finitely generated `R`-module
1672
+
1673
+ EXAMPLES::
1674
+
1675
+ sage: class SillyModule(sage.modules.fg_pid.fgp_module.FGP_Module_class):
1676
+ ....: def gens(self):
1677
+ ....: return tuple(flatten([[x,x] for x in self.smith_form_gens()]))
1678
+ sage: A = SillyModule(ZZ**1, span([[3]], ZZ))
1679
+ sage: A.gen(0)
1680
+ (1)
1681
+ sage: A.gen(1)
1682
+ (1)
1683
+ sage: B = ZZ**1 / span([[3]], ZZ)
1684
+ sage: A._hom_from_smith(Sequence([B.0]))
1685
+ Morphism from module over Integer Ring with invariants (3,)
1686
+ to module with invariants (3,)
1687
+ that sends the generators to [(1), (1)]
1688
+ """
1689
+ if len(im_smith_gens) != len(self.smith_form_gens()):
1690
+ raise ValueError("im_gens must have length the same as self.smith_form_gens()")
1691
+
1692
+ # replace self by representation in which smith-gens g_i are a basis for V.
1693
+ M, _ = self.optimized()
1694
+ # Define morphism from M to N
1695
+ f = M.V().hom([x.lift() for x in im_smith_gens])
1696
+ N = im_smith_gens.universe()
1697
+ homspace = self.Hom(N)
1698
+ phi = FGP_Morphism(homspace, f, check=DEBUG)
1699
+ return phi
1700
+
1701
+ def _Hom_(self, N, category=None):
1702
+ """
1703
+ EXAMPLES::
1704
+
1705
+ sage: V = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ); W = V.span([V.0 + 2*V.1, 9*V.0 + 2*V.1, 4*V.2])
1706
+ sage: Q = V/W
1707
+ sage: Q.Hom(Q) # indirect doctest
1708
+ Set of Morphisms
1709
+ from Finitely generated module V/W over Integer Ring with invariants (4, 16)
1710
+ to Finitely generated module V/W over Integer Ring with invariants (4, 16)
1711
+ in Category of modules over Integer Ring
1712
+ sage: M = V/V.zero_submodule()
1713
+ sage: H = M.Hom(Q); H
1714
+ Set of Morphisms
1715
+ from Finitely generated module V/W over Integer Ring with invariants (0, 0, 0)
1716
+ to Finitely generated module V/W over Integer Ring with invariants (4, 16)
1717
+ in Category of modules over Integer Ring
1718
+ sage: Hom(M, Q) is H
1719
+ True
1720
+ sage: type(Hom(M, Q))
1721
+ <class 'sage.modules.fg_pid.fgp_morphism.FGP_Homset_class_with_category'>
1722
+ sage: H.category()
1723
+ Category of homsets of modules over Integer Ring
1724
+ sage: H.homset_category()
1725
+ Category of modules over Integer Ring
1726
+
1727
+ The category is correctly adjusted when constructing Hom sets
1728
+ with more general codomains (see :issue:`16402`)::
1729
+
1730
+ sage: V = ZZ^2
1731
+ sage: W = V.quotient(V.span([[1, 1]]))
1732
+ sage: H = W.Hom(QQ); H
1733
+ Set of Morphisms
1734
+ from Finitely generated module V/W over Integer Ring with invariants (0)
1735
+ to Rational Field
1736
+ in Category of commutative additive groups
1737
+ sage: type(H)
1738
+ <class 'sage.categories.homset.Homset_with_category'>
1739
+ """
1740
+ if isinstance(N, FGP_Module_class):
1741
+ return FGP_Homset(self, N)
1742
+ return super()._Hom_(N, category=category)
1743
+
1744
+ def random_element(self, *args, **kwds):
1745
+ """
1746
+ Create a random element of ``self`` = `V/W`, by creating a random element of `V` and
1747
+ reducing it modulo `W`.
1748
+
1749
+ All arguments are passed on to the method :meth:`random_element` of `V`.
1750
+
1751
+ EXAMPLES::
1752
+
1753
+ sage: V = span([[1/2,1,1], [3/2,2,1], [0,0,1]], ZZ)
1754
+ sage: W = V.span([2*V.0 + 4*V.1, 9*V.0 + 12*V.1, 4*V.2])
1755
+ sage: Q = V/W
1756
+ sage: Q.random_element().parent() is Q
1757
+ True
1758
+ sage: Q.cardinality()
1759
+ 48
1760
+ sage: S = set()
1761
+ sage: while len(S) < 48:
1762
+ ....: S.add(Q.random_element())
1763
+ """
1764
+ return self(self._V.random_element(*args, **kwds))
1765
+
1766
+ def cardinality(self):
1767
+ """
1768
+ Return the cardinality of this module as a set.
1769
+
1770
+ EXAMPLES::
1771
+
1772
+ sage: V = ZZ^2; W = V.span([[1,2], [3,4]]); A = V/W; A
1773
+ Finitely generated module V/W over Integer Ring with invariants (2)
1774
+ sage: A.cardinality()
1775
+ 2
1776
+ sage: V = ZZ^2; W = V.span([[1,2]]); A = V/W; A
1777
+ Finitely generated module V/W over Integer Ring with invariants (0)
1778
+ sage: A.cardinality()
1779
+ +Infinity
1780
+ sage: V = QQ^2; W = V.span([[1,2]]); A = V/W; A
1781
+ Vector space quotient V/W of dimension 1 over Rational Field where
1782
+ V: Vector space of dimension 2 over Rational Field
1783
+ W: Vector space of degree 2 and dimension 1 over Rational Field
1784
+ Basis matrix:
1785
+ [1 2]
1786
+ sage: A.cardinality()
1787
+ +Infinity
1788
+ """
1789
+ try:
1790
+ return self.__cardinality
1791
+ except AttributeError:
1792
+ pass
1793
+ from sage.rings.infinity import infinity
1794
+ from sage.misc.misc_c import prod
1795
+ v = self.invariants()
1796
+ self.__cardinality = infinity if 0 in v else prod(v)
1797
+ return self.__cardinality
1798
+
1799
+ def list(self):
1800
+ """
1801
+ Return a list of the elements of ``self``.
1802
+
1803
+ EXAMPLES::
1804
+
1805
+ sage: V = ZZ^2; W = V.span([[1,2],[3,4]])
1806
+ sage: list(V/W)
1807
+ [(0), (1)]
1808
+ """
1809
+ return list(self)
1810
+
1811
+ def __iter__(self):
1812
+ """
1813
+ Return iterator over all elements of ``self``.
1814
+
1815
+ EXAMPLES::
1816
+
1817
+ sage: V = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ); W = V.span([V.0 + 2*V.1, 4*V.0 + 2*V.1, 4*V.2])
1818
+ sage: Q = V/W; Q
1819
+ Finitely generated module V/W over Integer Ring with invariants (2, 12)
1820
+ sage: z = list(V/W)
1821
+ sage: z
1822
+ [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (0, 11),
1823
+ (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (1, 11)]
1824
+ sage: len(z)
1825
+ 24
1826
+
1827
+ We test that the trivial module is handled correctly (:issue:`6561`)::
1828
+
1829
+ sage: A = (ZZ**1)/(ZZ**1); list(A) == [A(0)]
1830
+ True
1831
+ """
1832
+ if self.base_ring() != ZZ:
1833
+ raise NotImplementedError("only implemented over ZZ")
1834
+ v = self.invariants()
1835
+ if 0 in v:
1836
+ raise NotImplementedError("currently self must be finite to iterate over")
1837
+ B = self.optimized()[0].V().basis_matrix()
1838
+ V = self.base_ring()**B.nrows()
1839
+ for a in product(*[range(k) for k in v]):
1840
+ b = V(a) * B
1841
+ yield self(b)
1842
+
1843
+ def construction(self):
1844
+ """
1845
+ The construction functor and ambient module for ``self``.
1846
+
1847
+ EXAMPLES::
1848
+
1849
+ sage: W = ZZ^2
1850
+ sage: A1 = W.submodule([[1,0]])
1851
+ sage: B1 = W.submodule([[2,0]])
1852
+ sage: T1 = A1 / B1
1853
+ sage: T1.construction()
1854
+ (QuotientModuleFunctor,
1855
+ Free module of degree 2 and rank 1 over Integer Ring
1856
+ Echelon basis matrix:
1857
+ [1 0])
1858
+
1859
+ TESTS::
1860
+
1861
+ sage: W = ZZ^2
1862
+ sage: A1 = W.submodule([[1,0]])
1863
+ sage: A2 = W.submodule([[0,1]])
1864
+ sage: B1 = W.submodule([[2,0]])
1865
+ sage: B2 = W.submodule([[0,2]])
1866
+ sage: T1 = A1 / B1
1867
+ sage: T2 = A2 / B2
1868
+ sage: t1 = T1.an_element()
1869
+ sage: t2 = T2.an_element()
1870
+
1871
+ sage: # needs sage.libs.flint (o/w infinite recursion)
1872
+ sage: t1 + t2
1873
+ (1, 1)
1874
+ """
1875
+ from sage.modules.module_functors import QuotientModuleFunctor
1876
+ return (QuotientModuleFunctor(self._W), self._V)
1877
+
1878
+ def is_finite(self) -> bool:
1879
+ """
1880
+ Return ``True`` if ``self`` is finite and ``False`` otherwise.
1881
+
1882
+ EXAMPLES::
1883
+
1884
+ sage: V = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ)
1885
+ sage: W = V.span([V.0 + 2*V.1, 9*V.0 + 2*V.1, 4*V.2])
1886
+ sage: Q = V/W; Q
1887
+ Finitely generated module V/W over Integer Ring with invariants (4, 16)
1888
+ sage: Q.is_finite()
1889
+ True
1890
+ sage: Q = V / V.zero_submodule(); Q
1891
+ Finitely generated module V/W over Integer Ring with invariants (0, 0, 0)
1892
+ sage: Q.is_finite()
1893
+ False
1894
+ """
1895
+ return 0 not in self.invariants()
1896
+
1897
+ def annihilator(self):
1898
+ """
1899
+ Return the ideal of the base ring that annihilates ``self``. This
1900
+ is precisely the ideal generated by the LCM of the invariants
1901
+ of ``self`` if ``self`` is finite, and is 0 otherwise.
1902
+
1903
+ EXAMPLES::
1904
+
1905
+ sage: V = span([[1/2,0,0], [3/2,2,1], [0,0,1]], ZZ)
1906
+ sage: W = V.span([V.0 + 2*V.1, 9*V.0 + 2*V.1, 4*V.2])
1907
+ sage: Q = V/W; Q.annihilator()
1908
+ Principal ideal (16) of Integer Ring
1909
+ sage: Q.annihilator().gen()
1910
+ 16
1911
+
1912
+ sage: Q = V / V.span([V.0]); Q
1913
+ Finitely generated module V/W over Integer Ring with invariants (0, 0)
1914
+ sage: Q.annihilator()
1915
+ Principal ideal (0) of Integer Ring
1916
+
1917
+ We check that :issue:`22720` is resolved::
1918
+
1919
+ sage: H = AdditiveAbelianGroup([])
1920
+ sage: H.annihilator()
1921
+ Principal ideal (1) of Integer Ring
1922
+ """
1923
+ if not self.is_finite():
1924
+ g = 0
1925
+ elif self.cardinality() == 1:
1926
+ g = 1
1927
+ else:
1928
+ g = reduce(lcm, self.invariants())
1929
+ return self.base_ring().ideal(g)
1930
+
1931
+ def ngens(self):
1932
+ r"""
1933
+ Return the number of generators of ``self``.
1934
+
1935
+ (Note for developers: This is just the length of :meth:`gens`, rather
1936
+ than of the minimal set of generators as returned by
1937
+ :meth:`.smith_form_gens`; these are the same in the
1938
+ :class:`~sage.modules.fg_pid.fgp_module.FGP_Module_class`, but not
1939
+ necessarily in derived classes.)
1940
+
1941
+ EXAMPLES::
1942
+
1943
+ sage: A = (ZZ**2) / span([[4,0], [0,3]], ZZ)
1944
+ sage: A.ngens()
1945
+ 1
1946
+
1947
+ This works (but please do not do it in production code!) ::
1948
+
1949
+ sage: A.gens = lambda: [1,2,"Barcelona!"]
1950
+ sage: A.ngens()
1951
+ 3
1952
+ """
1953
+ return len(self.gens())
1954
+
1955
+ def __hash__(self):
1956
+ r"""
1957
+ Calculate a hash for ``self``.
1958
+
1959
+ EXAMPLES::
1960
+
1961
+ sage: A = (ZZ**2) / span([[4,0], [0,3]], ZZ)
1962
+ sage: hash(A) == hash(((2, ZZ), ((4, 0), (0, 3))))
1963
+ True
1964
+ """
1965
+ return hash((self.V(), self.W()))
1966
+
1967
+ @cached_method
1968
+ def quotient_map(self):
1969
+ """
1970
+ Given this quotient space `Q = V / W`, return the natural quotient
1971
+ map from `V` to `Q`.
1972
+
1973
+ EXAMPLES::
1974
+
1975
+ sage: A = (ZZ**2) / span([[4,0],[0,3]], ZZ)
1976
+ sage: A.quotient_map()
1977
+ Coercion map:
1978
+ From: Ambient free module of rank 2 over the principal ideal domain Integer Ring
1979
+ To: Finitely generated module V/W over Integer Ring with invariants (12)
1980
+ """
1981
+ return self.coerce_map_from(self._V)
1982
+
1983
+ ##############################################################
1984
+ # Useful for testing
1985
+ ##############################################################
1986
+
1987
+
1988
+ def random_fgp_module(n, R=ZZ, finite=False):
1989
+ """
1990
+ Return a random FGP module inside a rank n free module over R.
1991
+
1992
+ INPUT:
1993
+
1994
+ - ``n`` -- nonnegative integer
1995
+
1996
+ - ``R`` -- base ring (default: ``ZZ``)
1997
+
1998
+ - ``finite`` -- boolean (default: ``True``); if ``True``, make the random
1999
+ module finite
2000
+
2001
+ EXAMPLES::
2002
+
2003
+ sage: import sage.modules.fg_pid.fgp_module as fgp
2004
+ sage: fgp.random_fgp_module(4)
2005
+ Finitely generated module V/W over Integer Ring with invariants (...)
2006
+
2007
+ In most cases the cardinality is small or infinite::
2008
+
2009
+ sage: for g in (1, 2, 3, +Infinity):
2010
+ ....: while fgp.random_fgp_module(4).cardinality() != 1:
2011
+ ....: pass
2012
+
2013
+ One can force a finite module::
2014
+
2015
+ sage: fgp.random_fgp_module(4, finite=True).is_finite()
2016
+ True
2017
+
2018
+ Larger finite modules appear::
2019
+
2020
+ sage: while fgp.random_fgp_module(4, finite=True).cardinality() < 100:
2021
+ ....: pass
2022
+ """
2023
+ K = R.fraction_field()
2024
+ V = K**n
2025
+ i = ZZ.random_element(max(n, 1))
2026
+ A = V.span([V.random_element() for _ in range(i)], R)
2027
+ if not finite:
2028
+ i = ZZ.random_element(i+1)
2029
+ while True:
2030
+ B = A.span([A.random_element() for _ in range(i)], R)
2031
+ # Q = A/B
2032
+ Q = FGP_Module_class(A, B, check=DEBUG)
2033
+ if not finite or Q.is_finite():
2034
+ return Q
2035
+
2036
+
2037
+ def random_fgp_morphism_0(*args, **kwds):
2038
+ """
2039
+ Construct a random fgp module using :func:`random_fgp_module`,
2040
+ then construct a random morphism that sends each generator
2041
+ to a random multiple of itself.
2042
+
2043
+ Inputs are the same as to :func:`random_fgp_module`.
2044
+
2045
+ EXAMPLES::
2046
+
2047
+ sage: import sage.modules.fg_pid.fgp_module as fgp
2048
+ sage: mor = fgp.random_fgp_morphism_0(4)
2049
+ sage: mor.domain() == mor.codomain()
2050
+ True
2051
+ sage: isinstance(mor.domain(), fgp.FGP_Module_class)
2052
+ True
2053
+
2054
+ Each generator is sent to a random multiple of itself::
2055
+
2056
+ sage: gens = mor.domain().gens()
2057
+ sage: im_gens = mor.im_gens()
2058
+ sage: all(im_gens[i] == sum(im_gens[i])*gens[i] for i in range(len(gens)))
2059
+ True
2060
+ """
2061
+ A = random_fgp_module(*args, **kwds)
2062
+ return A.hom([ZZ.random_element() * g for g in A.smith_form_gens()])
2063
+
2064
+
2065
+ def _test_morphism_0(*args, **kwds):
2066
+ """
2067
+ EXAMPLES::
2068
+
2069
+ sage: import sage.modules.fg_pid.fgp_module as fgp
2070
+ sage: s = 0 # we set a seed so results clearly and easily reproducible across runs.
2071
+ sage: set_random_seed(s); v = [fgp._test_morphism_0(1) for _ in range(30)]
2072
+ sage: set_random_seed(s); v = [fgp._test_morphism_0(2) for _ in range(30)]
2073
+ sage: set_random_seed(s); v = [fgp._test_morphism_0(3) for _ in range(10)]
2074
+
2075
+ sage: # needs sage.libs.flint (o/w timeout)
2076
+ sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)]
2077
+ sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time
2078
+ """
2079
+ phi = random_fgp_morphism_0(*args, **kwds)
2080
+ K = phi.kernel()
2081
+ I = phi.image()
2082
+ from sage.misc.misc_c import prod
2083
+ if prod(K.invariants()):
2084
+ assert prod(phi.domain().invariants()) % prod(K.invariants()) == 0
2085
+ assert I.is_submodule(phi.codomain())
2086
+ if len(I.smith_form_gens()) > 0:
2087
+ x = phi.lift(I.smith_form_gen(0))
2088
+ assert phi(x) == I.smith_form_gen(0)
2089
+
2090
+
2091
+ test_morphism_0 = deprecated_function_alias(33617, _test_morphism_0)