passagemath-categories 10.6.32__cp314-cp314t-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.
Files changed (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,2794 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Modules With Basis
4
+
5
+ AUTHORS:
6
+
7
+ - Nicolas M. Thiery (2008-2014): initial revision, axiomatization
8
+ - Jason Bandlow and Florent Hivert (2010): Triangular Morphisms
9
+ - Christian Stump (2010): :issue:`9648` module_morphism's to a wider class
10
+ of codomains
11
+ """
12
+ #*****************************************************************************
13
+ # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr>
14
+ # 2008-2014 Nicolas M. Thiery <nthiery at users.sf.net>
15
+ #
16
+ # Distributed under the terms of the GNU General Public License (GPL)
17
+ # http://www.gnu.org/licenses/
18
+ #******************************************************************************
19
+
20
+ from sage.misc.lazy_import import LazyImport, lazy_import
21
+ from sage.misc.lazy_attribute import lazy_attribute
22
+ from sage.misc.cachefunc import cached_method
23
+ from sage.misc.abstract_method import abstract_method
24
+ from sage.categories.homsets import HomsetsCategory
25
+ from sage.categories.cartesian_product import CartesianProductsCategory
26
+ from sage.categories.tensor import tensor, TensorProductsCategory
27
+ from sage.categories.dual import DualObjectsCategory
28
+ from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring
29
+ from sage.categories.fields import Fields
30
+ from sage.categories.modules import Modules
31
+ from sage.categories.poor_man_map import PoorManMap
32
+ from sage.categories.map import Map
33
+ from sage.structure.element import Element, parent
34
+
35
+
36
+ lazy_import('sage.modules.with_basis.morphism',
37
+ ['ModuleMorphismByLinearity',
38
+ 'ModuleMorphismFromMatrix',
39
+ 'ModuleMorphismFromFunction',
40
+ 'DiagonalModuleMorphism',
41
+ 'TriangularModuleMorphismByLinearity',
42
+ 'TriangularModuleMorphismFromFunction'])
43
+
44
+
45
+ class ModulesWithBasis(CategoryWithAxiom_over_base_ring):
46
+ """
47
+ The category of modules with a distinguished basis.
48
+
49
+ The elements are represented by expanding them in the distinguished basis.
50
+ The morphisms are not required to respect the distinguished basis.
51
+
52
+ EXAMPLES::
53
+
54
+ sage: ModulesWithBasis(ZZ)
55
+ Category of modules with basis over Integer Ring
56
+ sage: ModulesWithBasis(ZZ).super_categories()
57
+ [Category of modules over Integer Ring]
58
+
59
+ If the base ring is actually a field, this constructs instead the
60
+ category of vector spaces with basis::
61
+
62
+ sage: ModulesWithBasis(QQ)
63
+ Category of vector spaces with basis over Rational Field
64
+
65
+ sage: ModulesWithBasis(QQ).super_categories()
66
+ [Category of modules with basis over Rational Field,
67
+ Category of vector spaces over Rational Field]
68
+
69
+ Let `X` and `Y` be two modules with basis. We can build `Hom(X,Y)`::
70
+
71
+ sage: X = CombinatorialFreeModule(QQ, [1,2]); X.rename('X') # needs sage.modules
72
+ sage: Y = CombinatorialFreeModule(QQ, [3,4]); Y.rename('Y') # needs sage.modules
73
+ sage: H = Hom(X, Y); H # needs sage.modules
74
+ Set of Morphisms from X to Y
75
+ in Category of finite dimensional vector spaces with basis over Rational Field
76
+
77
+ The simplest morphism is the zero map::
78
+
79
+ sage: H.zero() # todo: move this test into module once we have an example # needs sage.modules
80
+ Generic morphism:
81
+ From: X
82
+ To: Y
83
+
84
+ which we can apply to elements of `X`::
85
+
86
+ sage: x = X.monomial(1) + 3 * X.monomial(2) # needs sage.modules
87
+ sage: H.zero()(x) # needs sage.modules
88
+ 0
89
+
90
+ EXAMPLES:
91
+
92
+ We now construct a more interesting morphism by extending a
93
+ function by linearity::
94
+
95
+ sage: phi = H(on_basis=lambda i: Y.monomial(i + 2)); phi # needs sage.modules
96
+ Generic morphism:
97
+ From: X
98
+ To: Y
99
+ sage: phi(x) # needs sage.modules
100
+ B[3] + 3*B[4]
101
+
102
+ We can retrieve the function acting on indices of the basis::
103
+
104
+ sage: f = phi.on_basis() # needs sage.modules
105
+ sage: f(1), f(2) # needs sage.modules
106
+ (B[3], B[4])
107
+
108
+ `Hom(X,Y)` has a natural module structure (except for the zero,
109
+ the operations are not yet implemented though). However since the
110
+ dimension is not necessarily finite, it is not a module with
111
+ basis; but see :class:`FiniteDimensionalModulesWithBasis` and
112
+ :class:`GradedModulesWithBasis`::
113
+
114
+ sage: H in ModulesWithBasis(QQ), H in Modules(QQ) # needs sage.modules
115
+ (False, True)
116
+
117
+ Some more playing around with categories and higher order homsets::
118
+
119
+ sage: H.category() # needs sage.modules
120
+ Category of homsets of finite dimensional modules with basis over Rational Field
121
+ sage: Hom(H, H).category() # needs sage.modules
122
+ Category of endsets of
123
+ homsets of finite dimensional modules with basis over Rational Field
124
+
125
+ .. TODO:: ``End(X)`` is an algebra.
126
+
127
+ .. NOTE::
128
+
129
+ This category currently requires an implementation of an
130
+ element method ``support``. Once :issue:`18066` is merged, an
131
+ implementation of an ``items`` method will be required.
132
+
133
+ TESTS::
134
+
135
+ sage: f = H.zero().on_basis() # needs sage.modules
136
+ sage: f(1) # needs sage.modules
137
+ 0
138
+ sage: f(2) # needs sage.modules
139
+ 0
140
+
141
+ sage: TestSuite(ModulesWithBasis(ZZ)).run()
142
+ """
143
+
144
+ def _call_(self, x):
145
+ """
146
+ Construct a module with basis (resp. vector space) from the data in ``x``.
147
+
148
+ EXAMPLES::
149
+
150
+ sage: CZ = ModulesWithBasis(ZZ); CZ
151
+ Category of modules with basis over Integer Ring
152
+ sage: CQ = ModulesWithBasis(QQ); CQ
153
+ Category of vector spaces with basis over Rational Field
154
+
155
+ ``x`` is returned unchanged if it is already in this category::
156
+
157
+ sage: CZ(CombinatorialFreeModule(ZZ, ('a', 'b', 'c'))) # needs sage.modules
158
+ Free module generated by {'a', 'b', 'c'} over Integer Ring
159
+ sage: CZ(ZZ^3) # needs sage.modules
160
+ Ambient free module of rank 3 over the principal ideal domain Integer Ring
161
+
162
+ If needed (and possible) the base ring is changed appropriately::
163
+
164
+ sage: CQ(ZZ^3) # indirect doctest # needs sage.modules
165
+ Vector space of dimension 3 over Rational Field
166
+
167
+ If ``x`` itself is not a module with basis, but there is a
168
+ canonical one associated to it, the latter is returned::
169
+
170
+ sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest # needs sage.libs.flint sage.modular sage.modules
171
+ Vector space of dimension 4 over Rational Field
172
+ """
173
+ try:
174
+ M = x.free_module()
175
+ if M.base_ring() != self.base_ring():
176
+ M = M.change_ring(self.base_ring())
177
+ except (TypeError, AttributeError) as msg:
178
+ raise TypeError("%s\nunable to coerce x (=%s) into %s" % (msg, x, self))
179
+ return M
180
+
181
+ def is_abelian(self):
182
+ """
183
+ Return whether this category is abelian.
184
+
185
+ This is the case if and only if the base ring is a field.
186
+
187
+ EXAMPLES::
188
+
189
+ sage: ModulesWithBasis(QQ).is_abelian()
190
+ True
191
+ sage: ModulesWithBasis(ZZ).is_abelian()
192
+ False
193
+ """
194
+ return self.base_ring().is_field()
195
+
196
+ FiniteDimensional = LazyImport('sage.categories.finite_dimensional_modules_with_basis', 'FiniteDimensionalModulesWithBasis', at_startup=True)
197
+ Filtered = LazyImport('sage.categories.filtered_modules_with_basis', 'FilteredModulesWithBasis')
198
+ Graded = LazyImport('sage.categories.graded_modules_with_basis', 'GradedModulesWithBasis')
199
+ Super = LazyImport('sage.categories.super_modules_with_basis', 'SuperModulesWithBasis')
200
+
201
+ # To implement a module_with_basis you need to implement the
202
+ # following methods:
203
+ # - On the parent class, either basis() or an _indices attribute and
204
+ # monomial().
205
+ # - On the element class, monomial_coefficients().
206
+
207
+ class ParentMethods:
208
+ @cached_method
209
+ def basis(self):
210
+ """
211
+ Return the basis of ``self``.
212
+
213
+ EXAMPLES::
214
+
215
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
216
+ sage: F.basis() # needs sage.modules
217
+ Finite family {'a': B['a'], 'b': B['b'], 'c': B['c']}
218
+
219
+ ::
220
+
221
+ sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # needs sage.combinat sage.groups sage.modules
222
+ sage: list(QS3.basis()) # needs sage.combinat sage.groups sage.modules
223
+ [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
224
+ """
225
+ from sage.sets.family import Family
226
+ return Family(self._indices, self.monomial)
227
+
228
+ def module_morphism(self, on_basis=None, matrix=None, function=None,
229
+ diagonal=None, triangular=None, unitriangular=False,
230
+ **keywords):
231
+ r"""
232
+ Construct a module morphism from ``self`` to ``codomain``.
233
+
234
+ Let ``self`` be a module `X` with a basis indexed by `I`.
235
+ This constructs a morphism `f: X \to Y` by linearity from
236
+ a map `I \to Y` which is to be its restriction to the
237
+ basis `(x_i)_{i \in I}` of `X`. Some variants are possible
238
+ too.
239
+
240
+ INPUT:
241
+
242
+ - ``self`` -- a parent `X` in ``ModulesWithBasis(R)`` with
243
+ basis `x=(x_i)_{i\in I}`
244
+
245
+ Exactly one of the four following options must be
246
+ specified in order to define the morphism:
247
+
248
+ - ``on_basis`` -- a function `f` from `I` to `Y`
249
+ - ``diagonal`` -- a function `d` from `I` to `R`
250
+ - ``function`` -- a function `f` from `X` to `Y`
251
+ - ``matrix`` -- a matrix of size `\dim Y \times \dim X`
252
+ (if the keyword ``side`` is set to ``'left'``) or
253
+ `\dim Y \times \dim X` (if this keyword is ``'right'``)
254
+
255
+ Further options include:
256
+
257
+ - ``codomain`` -- the codomain `Y` of the morphism (default:
258
+ ``f.codomain()`` if it's defined; otherwise it must be specified)
259
+
260
+ - ``category`` -- a category or ``None`` (default: ``None``)
261
+
262
+ - ``zero`` -- the zero of the codomain (default: ``codomain.zero()``);
263
+ can be used (with care) to define affine maps.
264
+ Only meaningful with ``on_basis``.
265
+
266
+ - ``position`` -- nonnegative integer specifying which
267
+ positional argument is used as the input of the function `f`
268
+ (default: 0); this is currently only used with ``on_basis``.
269
+
270
+ - ``triangular`` -- (default: ``None``) ``'upper'`` or
271
+ ``'lower'`` or ``None``:
272
+
273
+ * ``'upper'`` -- if the
274
+ :meth:`~ModulesWithBasis.ElementMethods.leading_support`
275
+ of the image of the basis vector `x_i` is `i`, or
276
+
277
+ * ``'lower'`` -- if the
278
+ :meth:`~ModulesWithBasis.ElementMethods.trailing_support`
279
+ of the image of the basis vector `x_i` is `i`.
280
+
281
+ - ``unitriangular`` -- boolean (default: ``False``);
282
+ only meaningful for a triangular morphism.
283
+ As a shorthand, one may use ``unitriangular="lower"``
284
+ for ``triangular='lower', unitriangular=True``.
285
+
286
+ - ``side`` -- ``'left'`` or ``'right'`` (default: ``'left'``);
287
+ only meaningful for a morphism built from a matrix
288
+
289
+ EXAMPLES:
290
+
291
+ With the ``on_basis`` option, this returns a function `g`
292
+ obtained by extending `f` by linearity on the
293
+ ``position``-th positional argument. For example, for
294
+ ``position == 1`` and a ternary function `f`, one has:
295
+
296
+ .. MATH::
297
+
298
+ g\left( a,\ \sum_i \lambda_i x_i,\ c \right)
299
+ = \sum_i \lambda_i f(a, i, c).
300
+
301
+ ::
302
+
303
+ sage: # needs sage.modules
304
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X')
305
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y')
306
+ sage: def f(i):
307
+ ....: return Y.monomial(i) + 2*Y.monomial(i+1)
308
+ sage: phi = X.module_morphism(f, codomain=Y)
309
+ sage: x = X.basis(); y = Y.basis()
310
+ sage: phi(x[1] + x[3])
311
+ B[1] + 2*B[2] + B[3] + 2*B[4]
312
+ sage: phi
313
+ Generic morphism:
314
+ From: X
315
+ To: Y
316
+
317
+ By default, the category is the first of
318
+ ``Modules(R).WithBasis().FiniteDimensional()``,
319
+ ``Modules(R).WithBasis()``, ``Modules(R)``, and
320
+ ``CommutativeAdditiveMonoids()`` that contains both the
321
+ domain and the codomain::
322
+
323
+ sage: phi.category_for() # needs sage.modules
324
+ Category of finite dimensional vector spaces with basis
325
+ over Rational Field
326
+
327
+ With the ``zero`` argument, one can define affine morphisms::
328
+
329
+ sage: def f(i):
330
+ ....: return Y.monomial(i) + 2*Y.monomial(i+1)
331
+ sage: phi = X.module_morphism(f, codomain=Y, zero=10*y[1]) # needs sage.modules
332
+ sage: phi(x[1] + x[3]) # needs sage.modules
333
+ 11*B[1] + 2*B[2] + B[3] + 2*B[4]
334
+
335
+ In this special case, the default category is ``Sets()``::
336
+
337
+ sage: phi.category_for() # needs sage.modules
338
+ Category of sets
339
+
340
+ One can construct morphisms with the base ring as codomain::
341
+
342
+ sage: # needs sage.modules
343
+ sage: X = CombinatorialFreeModule(ZZ, [1, -1])
344
+ sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=ZZ)
345
+ sage: phi(2 * X.monomial(1) + 3 * X.monomial(-1))
346
+ -1
347
+ sage: phi.category_for()
348
+ Category of commutative additive semigroups
349
+ sage: phi.category_for() # not implemented
350
+ Category of modules over Integer Ring
351
+
352
+ Or more generally any ring admitting a coercion map from
353
+ the base ring::
354
+
355
+ sage: # needs sage.modules
356
+ sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=RR)
357
+ sage: phi(2 * X.monomial(1) + 3 * X.monomial(-1))
358
+ -1.00000000000000
359
+ sage: phi.category_for()
360
+ Category of commutative additive semigroups
361
+ sage: phi.category_for() # not implemented
362
+ Category of modules over Integer Ring
363
+
364
+ sage: phi = X.module_morphism(on_basis=lambda i: i, codomain=Zmod(4)) # needs sage.modules
365
+ sage: phi(2 * X.monomial(1) + 3 * X.monomial(-1)) # needs sage.modules
366
+ 3
367
+
368
+ sage: phi = Y.module_morphism(on_basis=lambda i: i, codomain=Zmod(4)) # needs sage.modules
369
+ Traceback (most recent call last):
370
+ ...
371
+ ValueError: codomain(=Ring of integers modulo 4) should be a module
372
+ over the base ring of the domain(=Y)
373
+
374
+ On can also define module morphisms between free modules
375
+ over different base rings; here we implement the natural
376
+ map from `X = \RR^2` to `Y = \CC`::
377
+
378
+ sage: # needs sage.modules
379
+ sage: X = CombinatorialFreeModule(RR, ['x', 'y'])
380
+ sage: Y = CombinatorialFreeModule(CC, ['z'])
381
+ sage: x = X.monomial('x')
382
+ sage: y = X.monomial('y')
383
+ sage: z = Y.monomial('z')
384
+ sage: def on_basis(a):
385
+ ....: if a == 'x':
386
+ ....: return CC(1) * z
387
+ ....: elif a == 'y':
388
+ ....: return CC(I) * z
389
+ sage: phi = X.module_morphism(on_basis=on_basis, codomain=Y)
390
+ sage: v = 3 * x + 2 * y; v
391
+ 3.00000000000000*B['x'] + 2.00000000000000*B['y']
392
+ sage: phi(v) # needs sage.symbolic
393
+ (3.00000000000000+2.00000000000000*I)*B['z']
394
+ sage: phi.category_for()
395
+ Category of commutative additive semigroups
396
+ sage: phi.category_for() # not implemented
397
+ Category of vector spaces over Real Field with 53 bits of precision
398
+
399
+ sage: # needs sage.modules
400
+ sage: Y = CombinatorialFreeModule(CC['q'], ['z'])
401
+ sage: z = Y.monomial('z')
402
+ sage: phi = X.module_morphism(on_basis=on_basis, codomain=Y)
403
+ sage: phi(v) # needs sage.symbolic
404
+ (3.00000000000000+2.00000000000000*I)*B['z']
405
+
406
+ Of course, there should be a coercion between the
407
+ respective base rings of the domain and the codomain for
408
+ this to be meaningful::
409
+
410
+ sage: Y = CombinatorialFreeModule(QQ, ['z']) # needs sage.modules
411
+ sage: phi = X.module_morphism(on_basis=on_basis, codomain=Y) # needs sage.modules
412
+ Traceback (most recent call last):
413
+ ...
414
+ ValueError: codomain(=Free module generated by {'z'} over Rational Field)
415
+ should be a module over the base ring of the domain(=Free module
416
+ generated by {'x', 'y'} over Real Field with 53 bits of precision)
417
+
418
+ sage: Y = CombinatorialFreeModule(RR['q'], ['z']) # needs sage.modules
419
+ sage: phi = Y.module_morphism(on_basis=on_basis, codomain=X) # needs sage.modules
420
+ Traceback (most recent call last):
421
+ ...
422
+ ValueError: codomain(=Free module generated by {'x', 'y'}
423
+ over Real Field with 53 bits of precision) should be a module over
424
+ the base ring of the domain(=Free module generated by {'z'} over
425
+ Univariate Polynomial Ring in q over Real Field with 53 bits of precision)
426
+
427
+
428
+ With the ``diagonal=d`` argument, this constructs the
429
+ module morphism `g` such that
430
+
431
+ .. MATH::
432
+
433
+ `g(x_i) = d(i) y_i`.
434
+
435
+ This assumes that the respective bases `x` and `y` of `X`
436
+ and `Y` have the same index set `I`::
437
+
438
+ sage: # needs sage.modules
439
+ sage: X = CombinatorialFreeModule(ZZ, [1, 2, 3]); X.rename('X')
440
+ sage: from sage.arith.misc import factorial
441
+ sage: phi = X.module_morphism(diagonal=factorial, codomain=X)
442
+ sage: x = X.basis()
443
+ sage: phi(x[1]), phi(x[2]), phi(x[3])
444
+ (B[1], 2*B[2], 6*B[3])
445
+
446
+ See also: :class:`sage.modules.with_basis.morphism.DiagonalModuleMorphism`.
447
+
448
+ With the ``matrix=m`` argument, this constructs the module
449
+ morphism whose matrix in the distinguished basis of `X`
450
+ and `Y` is `m`::
451
+
452
+ sage: # needs sage.modules
453
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X')
454
+ sage: x = X.basis()
455
+ sage: Y = CombinatorialFreeModule(ZZ, [3,4]); Y.rename('Y')
456
+ sage: y = Y.basis()
457
+ sage: m = matrix([[0,1,2], [3,5,0]])
458
+ sage: phi = X.module_morphism(matrix=m, codomain=Y)
459
+ sage: phi(x[1])
460
+ 3*B[4]
461
+ sage: phi(x[2])
462
+ B[3] + 5*B[4]
463
+
464
+
465
+ See also: :class:`sage.modules.with_basis.morphism.ModuleMorphismFromMatrix`.
466
+
467
+ With ``triangular="upper"``, the constructed module morphism is
468
+ assumed to be upper triangular; that is its matrix in the
469
+ distinguished basis of `X` and `Y` would be upper triangular with
470
+ invertible elements on its diagonal. This is used to compute
471
+ preimages and to invert the morphism::
472
+
473
+ sage: # needs sage.modules
474
+ sage: I = list(range(1, 200))
475
+ sage: X = CombinatorialFreeModule(QQ, I); X.rename('X'); x = X.basis()
476
+ sage: Y = CombinatorialFreeModule(QQ, I); Y.rename('Y'); y = Y.basis()
477
+ sage: f = Y.sum_of_monomials * divisors
478
+ sage: phi = X.module_morphism(f, triangular='upper', codomain=Y)
479
+ sage: phi(x[2])
480
+ B[1] + B[2]
481
+ sage: phi(x[6])
482
+ B[1] + B[2] + B[3] + B[6]
483
+ sage: phi(x[30])
484
+ B[1] + B[2] + B[3] + B[5] + B[6] + B[10] + B[15] + B[30]
485
+ sage: phi.preimage(y[2])
486
+ -B[1] + B[2]
487
+ sage: phi.preimage(y[6])
488
+ B[1] - B[2] - B[3] + B[6]
489
+ sage: phi.preimage(y[30])
490
+ -B[1] + B[2] + B[3] + B[5] - B[6] - B[10] - B[15] + B[30]
491
+ sage: (phi^-1)(y[30])
492
+ -B[1] + B[2] + B[3] + B[5] - B[6] - B[10] - B[15] + B[30]
493
+
494
+ Since :issue:`8678`, one can also define a triangular
495
+ morphism from a function::
496
+
497
+ sage: # needs sage.modules
498
+ sage: X = CombinatorialFreeModule(QQ, [0,1,2,3,4]); x = X.basis()
499
+ sage: from sage.modules.with_basis.morphism import TriangularModuleMorphismFromFunction
500
+ sage: def f(x): return x + X.term(0, sum(x.coefficients()))
501
+ sage: phi = X.module_morphism(function=f, codomain=X,
502
+ ....: triangular='upper')
503
+ sage: phi(x[2] + 3*x[4])
504
+ 4*B[0] + B[2] + 3*B[4]
505
+ sage: phi.preimage(_)
506
+ B[2] + 3*B[4]
507
+
508
+ For details and further optional arguments, see
509
+ :class:`sage.modules.with_basis.morphism.TriangularModuleMorphism`.
510
+
511
+ .. WARNING::
512
+
513
+ As a temporary measure, until multivariate morphisms
514
+ are implemented, the constructed morphism is in
515
+ ``Hom(codomain, domain, category)``. This is only
516
+ correct for unary functions.
517
+
518
+ .. TODO::
519
+
520
+ - Should codomain be ``self`` by default in the
521
+ diagonal, triangular, and matrix cases?
522
+
523
+ - Support for diagonal morphisms between modules not
524
+ sharing the same index set
525
+
526
+ TESTS::
527
+
528
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules
529
+ sage: phi = X.module_morphism(codomain=X) # needs sage.modules
530
+ Traceback (most recent call last):
531
+ ...
532
+ ValueError: module_morphism() takes exactly one option
533
+ out of `matrix`, `on_basis`, `function`, `diagonal`
534
+
535
+ ::
536
+
537
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules
538
+ sage: phi = X.module_morphism(diagonal=factorial, matrix=matrix(), # needs sage.modules
539
+ ....: codomain=X)
540
+ Traceback (most recent call last):
541
+ ...
542
+ ValueError: module_morphism() takes exactly one option
543
+ out of `matrix`, `on_basis`, `function`, `diagonal`
544
+
545
+ ::
546
+
547
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules
548
+ sage: phi = X.module_morphism(matrix=factorial, codomain=X) # needs sage.modules
549
+ Traceback (most recent call last):
550
+ ...
551
+ ValueError: matrix (=...factorial...) should be a matrix
552
+
553
+ ::
554
+
555
+ sage: X = CombinatorialFreeModule(ZZ, [1,2,3]); X.rename('X') # needs sage.modules
556
+ sage: phi = X.module_morphism(diagonal=3, codomain=X) # needs sage.modules
557
+ Traceback (most recent call last):
558
+ ...
559
+ ValueError: diagonal (=3) should be a function
560
+ """
561
+ if len([x for x in [matrix, on_basis, function, diagonal] if x is not None]) != 1:
562
+ raise ValueError("module_morphism() takes exactly one option out of `matrix`, `on_basis`, `function`, `diagonal`")
563
+ if matrix is not None:
564
+ return ModuleMorphismFromMatrix(domain=self, matrix=matrix, **keywords)
565
+ if diagonal is not None:
566
+ return DiagonalModuleMorphism(domain=self, diagonal=diagonal, **keywords)
567
+ if unitriangular in ["upper", "lower"] and triangular is None:
568
+ triangular = unitriangular
569
+ unitriangular = True
570
+ if triangular is not None:
571
+ if on_basis is not None:
572
+ return TriangularModuleMorphismByLinearity(
573
+ domain=self, on_basis=on_basis,
574
+ triangular=triangular, unitriangular=unitriangular,
575
+ **keywords)
576
+ else:
577
+ return TriangularModuleMorphismFromFunction(
578
+ domain=self, function=function,
579
+ triangular=triangular, unitriangular=unitriangular,
580
+ **keywords)
581
+ if on_basis is not None:
582
+ return ModuleMorphismByLinearity(
583
+ domain=self, on_basis=on_basis, **keywords)
584
+ else:
585
+ return ModuleMorphismFromFunction( # Or just SetMorphism?
586
+ domain=self, function=function, **keywords)
587
+
588
+ _module_morphism = module_morphism
589
+
590
+ def _repr_(self):
591
+ """
592
+ EXAMPLES::
593
+
594
+ sage: # needs sage.modules
595
+ sage: class FooBar(CombinatorialFreeModule): pass
596
+ sage: C = FooBar(QQ, (1,2,3)); C # indirect doctest
597
+ Free module generated by {1, 2, 3} over Rational Field
598
+ sage: C._name = "foobar"; C
599
+ foobar over Rational Field
600
+ sage: C.rename('barfoo'); C
601
+ barfoo
602
+
603
+ sage: class FooBar(Parent):
604
+ ....: def basis(self): return Family({1: "foo", 2: "bar"})
605
+ ....: def base_ring(self): return QQ
606
+ sage: FooBar(category=ModulesWithBasis(QQ))
607
+ Free module generated by [1, 2] over Rational Field
608
+ """
609
+ if hasattr(self, "_name"):
610
+ name = self._name
611
+ else:
612
+ name = "Free module generated by {}".format(self.basis().keys())
613
+ return name + " over {}".format(self.base_ring())
614
+
615
+ def _compute_support_order(self, elements, support_order=None):
616
+ """
617
+ Return the support of a set of elements in ``self`` sorted
618
+ in some order.
619
+
620
+ INPUT:
621
+
622
+ - ``elements`` -- the list of elements
623
+ - ``support_order`` -- (optional) either something that can
624
+ be converted into a tuple or a key function
625
+
626
+ EXAMPLES:
627
+
628
+ A finite dimensional module::
629
+
630
+ sage: # needs sage.modules
631
+ sage: V = CombinatorialFreeModule(QQ, range(10), prefix='x')
632
+ sage: B = V.basis()
633
+ sage: elts = [B[0] - 2*B[3], B[5] + 2*B[0],
634
+ ....: B[2], B[3], B[1] + B[2] + B[8]]
635
+ sage: V._compute_support_order(elts)
636
+ (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
637
+ sage: V._compute_support_order(elts, [1,2,0,4,3,5,9,8,7,6])
638
+ (1, 2, 0, 4, 3, 5, 9, 8, 7, 6)
639
+ sage: V._compute_support_order(elts, lambda x: -x)
640
+ (8, 5, 3, 2, 1, 0)
641
+
642
+ An infinite dimensional module::
643
+
644
+ sage: # needs sage.modules
645
+ sage: V = CombinatorialFreeModule(QQ, ZZ, prefix='z')
646
+ sage: B = V.basis()
647
+ sage: elts = [B[0] - 2*B[3], B[5] + 2*B[0],
648
+ ....: B[2], B[3], B[1] + B[2] + B[8]]
649
+ sage: V._compute_support_order(elts)
650
+ (0, 1, 2, 3, 5, 8)
651
+ sage: V._compute_support_order(elts, [1,2,0,4,3,5,9,8,7,6])
652
+ (1, 2, 0, 4, 3, 5, 9, 8, 7, 6)
653
+ sage: V._compute_support_order(elts, lambda x: -x)
654
+ (8, 5, 3, 2, 1, 0)
655
+ """
656
+ if support_order is None:
657
+ try:
658
+ support_order = self.get_order()
659
+ except (ValueError, TypeError, NotImplementedError, AttributeError):
660
+ support_order = set()
661
+ for y in elements:
662
+ support_order.update(y.support())
663
+ try: # Try to sort to make the output more consistent
664
+ support_order = sorted(support_order)
665
+ except (ValueError, TypeError):
666
+ pass
667
+ try:
668
+ support_order = tuple(support_order)
669
+ except (ValueError, TypeError):
670
+ support = set()
671
+ for y in elements:
672
+ support.update(y.support())
673
+ support_order = sorted(support, key=support_order)
674
+ return tuple(support_order)
675
+
676
+ def echelon_form(self, elements, row_reduced=False, order=None):
677
+ r"""
678
+ Return a basis in echelon form of the subspace spanned by
679
+ a finite set of elements.
680
+
681
+ INPUT:
682
+
683
+ - ``elements`` -- list or finite iterable of elements of ``self``
684
+ - ``row_reduced`` -- boolean (default: ``False``); whether to
685
+ compute the basis for the row reduced echelon form
686
+ - ``order`` -- (optional) either something that can
687
+ be converted into a tuple or a key function
688
+
689
+ OUTPUT:
690
+
691
+ A list of elements of ``self`` whose expressions as vectors
692
+ form a matrix in echelon form. If ``base_ring`` is specified,
693
+ then the calculation is achieved in this base ring.
694
+
695
+ EXAMPLES::
696
+
697
+ sage: R.<x,y> = QQ[]
698
+ sage: C = CombinatorialFreeModule(R, ZZ, prefix='z') # needs sage.modules
699
+ sage: z = C.basis() # needs sage.modules
700
+ sage: C.echelon_form([z[0] - z[1], 2*z[1] - 2*z[2], z[0] - z[2]]) # needs sage.libs.singular sage.modules
701
+ [z[0] - z[2], z[1] - z[2]]
702
+
703
+ TESTS:
704
+
705
+ We convert the input elements to ``self``::
706
+
707
+ sage: s = SymmetricFunctions(QQ).s() # needs sage.combinat sage.modules
708
+ sage: s.echelon_form([1, s[1] + 5]) # needs sage.combinat sage.modules
709
+ [s[], s[1]]
710
+ """
711
+ # Make sure elements consists of elements of ``self``
712
+ elements = [self(y) for y in elements]
713
+ order = self._compute_support_order(elements, order)
714
+
715
+ from sage.matrix.constructor import matrix
716
+ mat = matrix(self.base_ring(), [[g[s] for s in order] for g in elements])
717
+ # Echelonizing a matrix over a field returned the rref
718
+ if row_reduced and self.base_ring() not in Fields():
719
+ try:
720
+ mat = mat.rref().change_ring(self.base_ring())
721
+ except (ValueError, TypeError):
722
+ raise ValueError("unable to compute the row reduced echelon form")
723
+ else:
724
+ mat.echelonize()
725
+ return [self._from_dict({order[i]: c for i, c in enumerate(vec) if c},
726
+ remove_zeros=False)
727
+ for vec in mat if vec]
728
+
729
+ def submodule(self, gens, check=True, already_echelonized=False,
730
+ unitriangular=False, support_order=None, category=None,
731
+ submodule_class=None, *args, **opts):
732
+ r"""
733
+ The submodule spanned by a finite set of elements.
734
+
735
+ INPUT:
736
+
737
+ - ``gens`` -- list or family of elements of ``self``
738
+ - ``check`` -- boolean (default: ``True``); whether to verify that
739
+ the elements of ``gens`` are in ``self``
740
+ - ``already_echelonized`` -- boolean (default: ``False``); whether
741
+ the elements of ``gens`` are already in (not necessarily
742
+ reduced) echelon form
743
+ - ``unitriangular`` -- boolean (default: ``False``); whether
744
+ the lift morphism is unitriangular
745
+ - ``support_order`` -- (optional) either something that can
746
+ be converted into a tuple or a key function
747
+ - ``category`` -- (optional) the category of the submodule
748
+ - ``submodule_class`` -- (optional) the class of the submodule
749
+ to return
750
+
751
+ If ``already_echelonized`` is ``False``, then the
752
+ generators are put in reduced echelon form using
753
+ :meth:`echelonize`, and reindexed by `0,1,...`.
754
+
755
+ .. WARNING::
756
+
757
+ At this point, this method only works for finite
758
+ dimensional submodules and if matrices can be
759
+ echelonized over the base ring.
760
+
761
+ If in addition ``unitriangular`` is ``True``, then
762
+ the generators are made such that the coefficients of
763
+ the pivots are 1, so that lifting map is unitriangular.
764
+
765
+ The basis of the submodule uses the same index set as the
766
+ generators, and the lifting map sends `y_i` to `gens[i]`.
767
+
768
+ .. SEEALSO::
769
+
770
+ - :meth:`ModulesWithBasis.FiniteDimensional.ParentMethods.quotient_module`
771
+ - :class:`sage.modules.with_basis.subquotient.SubmoduleWithBasis`
772
+
773
+ EXAMPLES:
774
+
775
+ We construct a submodule of the free `\QQ`-module generated by
776
+ `x_0, x_1, x_2`. The submodule is spanned by `y_0 = x_0 - x_1` and
777
+ `y_1 - x_1 - x_2`, and its basis elements are indexed by `0` and `1`::
778
+
779
+ sage: # needs sage.modules
780
+ sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x')
781
+ sage: x = X.basis()
782
+ sage: gens = [x[0] - x[1], x[1] - x[2]]; gens
783
+ [x[0] - x[1], x[1] - x[2]]
784
+ sage: Y = X.submodule(gens, already_echelonized=True)
785
+ sage: Y.print_options(prefix='y'); Y
786
+ Free module generated by {0, 1} over Rational Field
787
+ sage: y = Y.basis()
788
+ sage: y[1]
789
+ y[1]
790
+ sage: y[1].lift()
791
+ x[1] - x[2]
792
+ sage: Y.retract(x[0] - x[2])
793
+ y[0] + y[1]
794
+ sage: Y.retract(x[0])
795
+ Traceback (most recent call last):
796
+ ...
797
+ ValueError: x[0] is not in the image
798
+
799
+ By using a family to specify a basis of the submodule, we obtain a
800
+ submodule whose index set coincides with the index set of the family::
801
+
802
+ sage: # needs sage.modules
803
+ sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x')
804
+ sage: x = X.basis()
805
+ sage: gens = Family({1: x[0] - x[1], 3: x[1] - x[2]}); gens
806
+ Finite family {1: x[0] - x[1], 3: x[1] - x[2]}
807
+ sage: Y = X.submodule(gens, already_echelonized=True)
808
+ sage: Y.print_options(prefix='y'); Y
809
+ Free module generated by {1, 3} over Rational Field
810
+ sage: y = Y.basis()
811
+ sage: y[1]
812
+ y[1]
813
+ sage: y[1].lift()
814
+ x[0] - x[1]
815
+ sage: y[3].lift()
816
+ x[1] - x[2]
817
+ sage: Y.retract(x[0] - x[2])
818
+ y[1] + y[3]
819
+ sage: Y.retract(x[0])
820
+ Traceback (most recent call last):
821
+ ...
822
+ ValueError: x[0] is not in the image
823
+
824
+ It is not necessary that the generators of the submodule form
825
+ a basis (an explicit basis will be computed)::
826
+
827
+ sage: # needs sage.modules
828
+ sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x')
829
+ sage: x = X.basis()
830
+ sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]; gens
831
+ [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]
832
+ sage: Y = X.submodule(gens, already_echelonized=False)
833
+ sage: Y.print_options(prefix='y')
834
+ sage: Y
835
+ Free module generated by {0, 1} over Rational Field
836
+ sage: [b.lift() for b in Y.basis()]
837
+ [x[0] - x[2], x[1] - x[2]]
838
+
839
+ We now implement by hand the center of the algebra of the
840
+ symmetric group `S_3`::
841
+
842
+ sage: # needs sage.combinat sage.groups sage.modules
843
+ sage: S3 = SymmetricGroup(3)
844
+ sage: S3A = S3.algebra(QQ)
845
+ sage: basis = S3A.annihilator_basis(S3A.algebra_generators(),
846
+ ....: S3A.bracket)
847
+ sage: basis
848
+ ((), (1,2,3) + (1,3,2), (2,3) + (1,2) + (1,3))
849
+ sage: center = S3A.submodule(basis,
850
+ ....: category=AlgebrasWithBasis(QQ).Subobjects(),
851
+ ....: already_echelonized=True)
852
+ sage: center
853
+ Free module generated by {0, 1, 2} over Rational Field
854
+ sage: center in Algebras
855
+ True
856
+ sage: center.print_options(prefix='c')
857
+ sage: c = center.basis()
858
+ sage: c[1].lift()
859
+ (1,2,3) + (1,3,2)
860
+ sage: c[0]^2
861
+ c[0]
862
+ sage: e = 1/6 * (c[0]+c[1]+c[2])
863
+ sage: e.is_idempotent()
864
+ True
865
+
866
+ Of course, this center is best constructed using::
867
+
868
+ sage: center = S3A.center() # needs sage.combinat sage.groups sage.modules
869
+
870
+ We can also automatically construct a basis such that
871
+ the lift morphism is (lower) unitriangular::
872
+
873
+ sage: # needs sage.libs.singular sage.modules
874
+ sage: R.<a,b> = QQ[]
875
+ sage: C = CombinatorialFreeModule(R, range(3), prefix='x')
876
+ sage: x = C.basis()
877
+ sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]
878
+ sage: Y = C.submodule(gens, unitriangular=True)
879
+ sage: Y.lift.matrix()
880
+ [ 1 0]
881
+ [ 0 1]
882
+ [-1 -1]
883
+
884
+ We now construct a (finite-dimensional) submodule of an
885
+ infinite dimensional free module::
886
+
887
+ sage: # needs sage.modules
888
+ sage: C = CombinatorialFreeModule(QQ, ZZ, prefix='z')
889
+ sage: z = C.basis()
890
+ sage: gens = [z[0] - z[1], 2*z[1] - 2*z[2], z[0] - z[2]]
891
+ sage: Y = C.submodule(gens)
892
+ sage: [Y.lift(b) for b in Y.basis()]
893
+ [z[0] - z[2], z[1] - z[2]]
894
+
895
+ TESTS::
896
+
897
+ sage: TestSuite(Y).run() # needs sage.modules
898
+ sage: TestSuite(center).run() # needs sage.combinat sage.groups sage.modules
899
+ """
900
+ # Make sure gens consists of elements of ``self``
901
+ from sage.sets.family import Family, AbstractFamily
902
+ if isinstance(gens, AbstractFamily):
903
+ gens = gens.map(self)
904
+ elif isinstance(gens, dict):
905
+ gens = Family(gens.keys(), gens.__getitem__)
906
+ else:
907
+ gens = [self(y) for y in gens]
908
+ support_order = self._compute_support_order(gens, support_order)
909
+ if not already_echelonized:
910
+ gens = self.echelon_form(gens, unitriangular, order=support_order)
911
+
912
+ if submodule_class is None:
913
+ from sage.modules.with_basis.subquotient import SubmoduleWithBasis as submodule_class
914
+ return submodule_class(gens, ambient=self,
915
+ support_order=support_order,
916
+ unitriangular=unitriangular,
917
+ category=category, *args, **opts)
918
+
919
+ def quotient_module(self, submodule, check=True, already_echelonized=False, category=None):
920
+ r"""
921
+ Construct the quotient module ``self`` / ``submodule``.
922
+
923
+ INPUT:
924
+
925
+ - ``submodule`` -- a submodule with basis of ``self``, or
926
+ something that can be turned into one via
927
+ ``self.submodule(submodule)``
928
+
929
+ - ``check``, ``already_echelonized`` -- passed down to
930
+ :meth:`ModulesWithBasis.ParentMethods.submodule`
931
+
932
+ .. WARNING::
933
+
934
+ At this point, this only supports quotients by free
935
+ submodules admitting a basis in unitriangular echelon
936
+ form. In this case, the quotient is also a free
937
+ module, with a basis consisting of the retract of a
938
+ subset of the basis of ``self``.
939
+
940
+ EXAMPLES::
941
+
942
+ sage: # needs sage.modules
943
+ sage: X = CombinatorialFreeModule(QQ, range(3), prefix='x')
944
+ sage: x = X.basis()
945
+ sage: Y = X.quotient_module([x[0] - x[1], x[1] - x[2]],
946
+ ....: already_echelonized=True)
947
+ sage: Y.print_options(prefix='y'); Y
948
+ Free module generated by {2} over Rational Field
949
+ sage: y = Y.basis()
950
+ sage: y[2]
951
+ y[2]
952
+ sage: y[2].lift()
953
+ x[2]
954
+ sage: Y.retract(x[0] + 2*x[1])
955
+ 3*y[2]
956
+
957
+ sage: # needs sage.libs.singular sage.modules
958
+ sage: R.<a,b> = QQ[]
959
+ sage: C = CombinatorialFreeModule(R, range(3), prefix='x')
960
+ sage: x = C.basis()
961
+ sage: gens = [x[0] - x[1], 2*x[1] - 2*x[2], x[0] - x[2]]
962
+ sage: Y = C.quotient_module(gens)
963
+
964
+ .. SEEALSO::
965
+
966
+ - :meth:`Modules.WithBasis.ParentMethods.submodule`
967
+ - :meth:`Rings.ParentMethods.quotient`
968
+ - :class:`sage.modules.with_basis.subquotient.QuotientModuleWithBasis`
969
+ """
970
+ from sage.modules.with_basis.subquotient import SubmoduleWithBasis, QuotientModuleWithBasis
971
+ if not isinstance(submodule, SubmoduleWithBasis):
972
+ submodule = self.submodule(submodule, check=check,
973
+ unitriangular=True,
974
+ already_echelonized=already_echelonized)
975
+ return QuotientModuleWithBasis(submodule, category=category)
976
+
977
+ def tensor(*parents, **kwargs):
978
+ """
979
+ Return the tensor product of the parents.
980
+
981
+ EXAMPLES::
982
+
983
+ sage: C = AlgebrasWithBasis(QQ)
984
+ sage: A = C.example(); A.rename('A') # needs sage.combinat sage.modules
985
+ sage: A.tensor(A, A) # needs sage.combinat sage.modules
986
+ A # A # A
987
+ sage: A.rename(None) # needs sage.combinat sage.modules
988
+ """
989
+ constructor = kwargs.pop('constructor', tensor)
990
+ cat = constructor.category_from_parents(parents)
991
+ return parents[0].__class__.Tensor(parents, category=cat)
992
+
993
+ def intersection(self, other):
994
+ r"""
995
+ Return the intersection of ``self`` with ``other``.
996
+
997
+ EXAMPLES::
998
+
999
+ sage: # needs sage.modules
1000
+ sage: X = CombinatorialFreeModule(QQ, range(4)); x = X.basis()
1001
+ sage: U = X.submodule([x[0]-x[1], x[1]-x[2], x[2]-x[3]])
1002
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c','d'])
1003
+ sage: G = F.submodule([F.basis()['a']])
1004
+ sage: X.intersection(X) is X
1005
+ True
1006
+ sage: X.intersection(U) is U
1007
+ True
1008
+ sage: X.intersection(F)
1009
+ Traceback (most recent call last):
1010
+ ...
1011
+ TypeError: other must be a submodule
1012
+ sage: X.intersection(G)
1013
+ Traceback (most recent call last):
1014
+ ...
1015
+ ArithmeticError: this module must be the ambient
1016
+ """
1017
+ if other is self:
1018
+ return self
1019
+ if other not in self.category().Subobjects():
1020
+ raise TypeError("other must be a submodule")
1021
+ if other.ambient() != self:
1022
+ raise ArithmeticError("this module must be the ambient")
1023
+ return other
1024
+
1025
+ def cardinality(self):
1026
+ """
1027
+ Return the cardinality of ``self``.
1028
+
1029
+ EXAMPLES::
1030
+
1031
+ sage: # needs sage.combinat sage.groups sage.modules
1032
+ sage: S = SymmetricGroupAlgebra(QQ, 4)
1033
+ sage: S.cardinality()
1034
+ +Infinity
1035
+ sage: S = SymmetricGroupAlgebra(GF(2), 4)
1036
+ sage: S.cardinality()
1037
+ 16777216
1038
+ sage: S.cardinality().factor()
1039
+ 2^24
1040
+
1041
+ sage: # needs sage.modules
1042
+ sage: E.<x,y> = ExteriorAlgebra(QQ)
1043
+ sage: E.cardinality()
1044
+ +Infinity
1045
+ sage: E.<x,y> = ExteriorAlgebra(GF(3))
1046
+ sage: E.cardinality()
1047
+ 81
1048
+
1049
+ sage: s = SymmetricFunctions(GF(2)).s() # needs sage.combinat sage.modules
1050
+ sage: s.cardinality() # needs sage.combinat sage.modules
1051
+ +Infinity
1052
+
1053
+ sage: # needs sage.modules
1054
+ sage: M = CombinatorialFreeModule(QQ, [])
1055
+ sage: M.dimension()
1056
+ 0
1057
+ sage: M.cardinality()
1058
+ 1
1059
+ """
1060
+ from sage.rings.infinity import Infinity
1061
+ if self.dimension() == Infinity:
1062
+ return Infinity
1063
+ if self.dimension() == 0:
1064
+ from sage.rings.integer_ring import ZZ
1065
+ return ZZ.one()
1066
+ return self.base_ring().cardinality() ** self.dimension()
1067
+
1068
+ def is_finite(self):
1069
+ r"""
1070
+ Return whether ``self`` is finite.
1071
+
1072
+ This is true if and only if ``self.basis().keys()`` and
1073
+ ``self.base_ring()`` are both finite.
1074
+
1075
+ EXAMPLES::
1076
+
1077
+ sage: GroupAlgebra(SymmetricGroup(2), IntegerModRing(10)).is_finite() # needs sage.combinat sage.groups sage.modules
1078
+ True
1079
+ sage: GroupAlgebra(SymmetricGroup(2)).is_finite() # needs sage.combinat sage.groups sage.modules
1080
+ False
1081
+ sage: GroupAlgebra(AbelianGroup(1), IntegerModRing(10)).is_finite() # needs sage.groups sage.modules
1082
+ False
1083
+ """
1084
+ return (self.base_ring().is_finite() and self.basis().keys().is_finite())
1085
+
1086
+ def monomial(self, i):
1087
+ """
1088
+ Return the basis element indexed by ``i``.
1089
+
1090
+ INPUT:
1091
+
1092
+ - ``i`` -- an element of the index set
1093
+
1094
+ EXAMPLES::
1095
+
1096
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
1097
+ sage: F.monomial('a') # needs sage.modules
1098
+ B['a']
1099
+
1100
+ ``F.monomial`` is in fact (almost) a map::
1101
+
1102
+ sage: F.monomial # needs sage.modules
1103
+ Term map from {'a', 'b', 'c'}
1104
+ to Free module generated by {'a', 'b', 'c'} over Rational Field
1105
+ """
1106
+ return self.basis()[i]
1107
+
1108
+ def _sum_of_monomials(self, indices):
1109
+ """
1110
+ TESTS::
1111
+
1112
+ sage: R.<x,y> = QQ[]
1113
+ sage: W = DifferentialWeylAlgebra(R) # needs sage.modules
1114
+ sage: W._sum_of_monomials([((1,0), (1,0)), ((0,0), (0,1))]) # needs sage.modules
1115
+ dy + x*dx
1116
+ """
1117
+ # This is the generic implementation. When implementing a
1118
+ # concrete instance of a module with basis, you probably want
1119
+ # to override it with something faster.
1120
+ return self.sum(self.monomial(index) for index in indices)
1121
+
1122
+ @lazy_attribute
1123
+ def sum_of_monomials(self):
1124
+ """
1125
+ Return the sum of the basis elements with indices in
1126
+ ``indices``.
1127
+
1128
+ INPUT:
1129
+
1130
+ - ``indices`` -- list (or iterable) of indices of basis
1131
+ elements
1132
+
1133
+ EXAMPLES::
1134
+
1135
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
1136
+ sage: F.sum_of_monomials(['a', 'b']) # needs sage.modules
1137
+ B['a'] + B['b']
1138
+
1139
+ sage: F.sum_of_monomials(['a', 'b', 'a']) # needs sage.modules
1140
+ 2*B['a'] + B['b']
1141
+
1142
+ ``F.sum_of_monomials`` is in fact (almost) a map::
1143
+
1144
+ sage: F.sum_of_monomials # needs sage.modules
1145
+ A map to Free module generated by {'a', 'b', 'c'} over Rational Field
1146
+ """
1147
+ # domain = iterables of basis indices of self.
1148
+ return PoorManMap(self._sum_of_monomials, codomain=self)
1149
+
1150
+ def monomial_or_zero_if_none(self, i):
1151
+ """
1152
+ EXAMPLES::
1153
+
1154
+ sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # needs sage.modules
1155
+ sage: F.monomial_or_zero_if_none('a') # needs sage.modules
1156
+ B['a']
1157
+ sage: F.monomial_or_zero_if_none(None) # needs sage.modules
1158
+ 0
1159
+ """
1160
+ if i is None:
1161
+ return self.zero()
1162
+ return self.monomial(i)
1163
+
1164
+ def term(self, index, coeff=None):
1165
+ """
1166
+ Construct a term in ``self``.
1167
+
1168
+ INPUT:
1169
+
1170
+ - ``index`` -- the index of a basis element
1171
+ - ``coeff`` -- an element of the coefficient ring (default: one)
1172
+
1173
+ OUTPUT: ``coeff * B[index]``, where ``B`` is the basis of ``self``
1174
+
1175
+ EXAMPLES::
1176
+
1177
+ sage: m = matrix([[0,1], [1,1]]) # needs sage.modules
1178
+ sage: J.<a,b,c> = JordanAlgebra(m) # needs sage.combinat sage.modules
1179
+ sage: J.term(1, -2) # needs sage.combinat sage.modules
1180
+ 0 + (-2, 0)
1181
+
1182
+ Design: should this do coercion on the coefficient ring?
1183
+ """
1184
+ if coeff is None:
1185
+ coeff = self.base_ring().one()
1186
+ return coeff * self.monomial(index)
1187
+
1188
+ def sum_of_terms(self, terms):
1189
+ """
1190
+ Construct a sum of terms of ``self``.
1191
+
1192
+ INPUT:
1193
+
1194
+ - ``terms`` -- list (or iterable) of pairs ``(index, coeff)``
1195
+
1196
+ OUTPUT:
1197
+
1198
+ Sum of ``coeff * B[index]`` over all ``(index, coeff)`` in
1199
+ ``terms``, where ``B`` is the basis of ``self``.
1200
+
1201
+ EXAMPLES::
1202
+
1203
+ sage: m = matrix([[0,1], [1,1]]) # needs sage.modules
1204
+ sage: J.<a,b,c> = JordanAlgebra(m) # needs sage.combinat sage.modules
1205
+ sage: J.sum_of_terms([(0, 2), (2, -3)]) # needs sage.combinat sage.modules
1206
+ 2 + (0, -3)
1207
+ """
1208
+ return self.sum(self.term(index, coeff) for (index, coeff) in terms)
1209
+
1210
+ def _apply_module_morphism(self, x, on_basis, codomain=False):
1211
+ """
1212
+ Return the image of ``x`` under the module morphism defined by
1213
+ extending :func:`on_basis` by linearity.
1214
+
1215
+ INPUT:
1216
+
1217
+ - ``x`` -- a element of ``self``
1218
+
1219
+ - ``on_basis`` -- a function that takes in an object indexing
1220
+ a basis element and returns an element of the codomain
1221
+
1222
+ - ``codomain`` -- (optional) the codomain of the morphism (by
1223
+ default, it is computed using :func:`on_basis`)
1224
+
1225
+ If ``codomain`` is not specified, then the function tries to
1226
+ compute the codomain of the module morphism by finding the image
1227
+ of one of the elements in the support; hence :func:`on_basis`
1228
+ should return an element whose parent is the codomain.
1229
+
1230
+ EXAMPLES::
1231
+
1232
+ sage: # needs sage.combinat sage.modules
1233
+ sage: s = SymmetricFunctions(QQ).schur()
1234
+ sage: a = s([3]) + s([2,1]) + s([1,1,1])
1235
+ sage: b = 2*a
1236
+ sage: f = lambda part: Integer(len(part))
1237
+ sage: s._apply_module_morphism(a, f) #1+2+3
1238
+ 6
1239
+ sage: s._apply_module_morphism(b, f) #2*(1+2+3)
1240
+ 12
1241
+ sage: s._apply_module_morphism(s(0), f)
1242
+ 0
1243
+ sage: s._apply_module_morphism(s(1), f)
1244
+ 0
1245
+ sage: s._apply_module_morphism(s(1), lambda part: len(part), ZZ)
1246
+ 0
1247
+ sage: s._apply_module_morphism(s(1), lambda part: len(part))
1248
+ Traceback (most recent call last):
1249
+ ...
1250
+ ValueError: codomain could not be determined
1251
+ """
1252
+ if x == self.zero():
1253
+ if not codomain:
1254
+ from sage.sets.family import Family
1255
+ B = Family(self.basis())
1256
+ try:
1257
+ z = B.first()
1258
+ except StopIteration:
1259
+ raise ValueError('codomain could not be determined')
1260
+ codomain = on_basis(z).parent()
1261
+ return codomain.zero()
1262
+
1263
+ if not codomain:
1264
+ keys = x.support()
1265
+ key = keys[0]
1266
+ try:
1267
+ codomain = on_basis(key).parent()
1268
+ except Exception:
1269
+ raise ValueError('codomain could not be determined')
1270
+
1271
+ if hasattr(codomain, 'linear_combination'):
1272
+ mc = x.monomial_coefficients(copy=False)
1273
+ return codomain.linear_combination((on_basis(key), coeff)
1274
+ for key, coeff in mc.items())
1275
+ else:
1276
+ return_sum = codomain.zero()
1277
+ mc = x.monomial_coefficients(copy=False)
1278
+ for key, coeff in mc.items():
1279
+ return_sum += coeff * on_basis(key)
1280
+ return return_sum
1281
+
1282
+ def _apply_module_endomorphism(self, x, on_basis):
1283
+ """
1284
+ This takes in a function ``on_basis`` from the basis indices
1285
+ to the elements of ``self``, and applies it linearly to ``x``.
1286
+
1287
+ EXAMPLES::
1288
+
1289
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1290
+ sage: f = lambda part: 2 * s(part.conjugate())
1291
+ sage: s._apply_module_endomorphism(s([2,1]) + s([1,1,1]), f) # needs sage.combinat sage.modules
1292
+ 2*s[2, 1] + 2*s[3]
1293
+ """
1294
+ mc = x.monomial_coefficients(copy=False)
1295
+ return self.linear_combination((on_basis(key), coeff)
1296
+ for key, coeff in mc.items())
1297
+
1298
+ def dimension(self):
1299
+ """
1300
+ Return the dimension of ``self``.
1301
+
1302
+ EXAMPLES::
1303
+
1304
+ sage: A.<x,y> = algebras.DifferentialWeyl(QQ) # needs sage.modules
1305
+ sage: A.dimension() # needs sage.modules
1306
+ +Infinity
1307
+ """
1308
+ try:
1309
+ return self.basis().cardinality()
1310
+ except (AttributeError, TypeError):
1311
+ from sage.rings.integer_ring import ZZ
1312
+ return ZZ(len(self.basis()))
1313
+
1314
+ def rank(self):
1315
+ """
1316
+ Return the rank of ``self``.
1317
+
1318
+ Since there is a (distinguished) basis, the rank of ``self``
1319
+ is equal to the cardinality of the basis (which equals
1320
+ the :meth:`dimension` of ``self``).
1321
+
1322
+ EXAMPLES::
1323
+
1324
+ sage: A.<x,y> = algebras.DifferentialWeyl(QQ) # needs sage.modules
1325
+ sage: A.rank() # needs sage.modules
1326
+ +Infinity
1327
+
1328
+ sage: R.<x,y> = QQ[]
1329
+ sage: R.rank()
1330
+ +Infinity
1331
+
1332
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c']) # needs sage.modules
1333
+ sage: F.rank() # needs sage.modules
1334
+ 3
1335
+ """
1336
+ return self.dimension()
1337
+
1338
+ def _from_dict(self, d, coerce=True, remove_zeros=True):
1339
+ """
1340
+ Construct an element of ``self`` from the dictionary ``d``.
1341
+
1342
+ INPUT:
1343
+
1344
+ - ``coerce`` -- boolean; coerce the coefficients to the base ring
1345
+ - ``remove_zeroes`` -- boolean; remove zeros from the dictionary
1346
+
1347
+ EXAMPLES::
1348
+
1349
+ sage: # needs sage.modules
1350
+ sage: A.<x,y> = algebras.DifferentialWeyl(QQ)
1351
+ sage: K = A.basis().keys()
1352
+ sage: d = {K[0]: 3, K[12]: -4/3}
1353
+ sage: A._from_dict(d)
1354
+ -4/3*dx^2 + 3
1355
+
1356
+ sage: R.<x,y> = QQ[]
1357
+ sage: d = {K[0]: y, K[12]: -4/3} # needs sage.modules
1358
+ sage: A._from_dict(d, coerce=False) # needs sage.modules
1359
+ -4/3*dx^2 + y
1360
+ sage: A._from_dict(d, coerce=True) # needs sage.modules
1361
+ Traceback (most recent call last):
1362
+ ...
1363
+ TypeError: y is not a constant polynomial
1364
+ """
1365
+ R = self.base_ring()
1366
+ B = self.basis()
1367
+ if coerce:
1368
+ zero = R.zero()
1369
+ temp = {}
1370
+ if remove_zeros:
1371
+ for k in d:
1372
+ y = R(d[k])
1373
+ if y != zero:
1374
+ temp[k] = y
1375
+ else:
1376
+ for k in d:
1377
+ temp[k] = R(d[k])
1378
+ return self.sum(temp[i] * B[i] for i in temp)
1379
+ if remove_zeros:
1380
+ return self.sum(d[i] * B[i] for i in d if d[i] != 0)
1381
+ return self.sum(d[i] * B[i] for i in d)
1382
+
1383
+ def random_element(self, n=2):
1384
+ r"""
1385
+ Return a 'random' element of ``self``.
1386
+
1387
+ INPUT:
1388
+
1389
+ - ``n`` -- integer (default: 2); number of summands
1390
+
1391
+ ALGORITHM:
1392
+
1393
+ Return a sum of `n` terms, each of which is formed by
1394
+ multiplying a random element of the base ring by a random
1395
+ element of the group.
1396
+
1397
+ EXAMPLES::
1398
+
1399
+ sage: x = DihedralGroup(6).algebra(QQ).random_element() # needs sage.groups sage.modules
1400
+ sage: x.parent() is DihedralGroup(6).algebra(QQ) # needs sage.groups sage.modules
1401
+ True
1402
+
1403
+ Note, this result can depend on the PRNG state in libgap in a way
1404
+ that depends on which packages are loaded, so we must re-seed GAP
1405
+ to ensure a consistent result for this example::
1406
+
1407
+ sage: libgap.set_seed(0) # needs sage.libs.gap
1408
+ 0
1409
+ sage: m = SU(2, 13).algebra(QQ).random_element(1) # needs sage.groups sage.libs.pari sage.modules
1410
+ sage: m.parent() is SU(2, 13).algebra(QQ) # needs sage.groups sage.libs.pari sage.modules
1411
+ True
1412
+ sage: p = CombinatorialFreeModule(ZZ, Partitions(4)).random_element() # needs sage.combinat sage.libs.flint sage.modules
1413
+ sage: p.parent() is CombinatorialFreeModule(ZZ, Partitions(4)) # needs sage.combinat sage.libs.flint sage.modules
1414
+ True
1415
+
1416
+ TESTS:
1417
+
1418
+ Ensure that the two issues reported in :issue:`28327` are
1419
+ fixed; that we don't rely unnecessarily on being able to
1420
+ coerce the base ring's zero into the algebra, and that
1421
+ we can find a random element in a trivial module::
1422
+
1423
+ sage: class Foo(CombinatorialFreeModule): # needs sage.modules
1424
+ ....: def _element_constructor_(self, x):
1425
+ ....: if x in self:
1426
+ ....: return x
1427
+ ....: else:
1428
+ ....: raise ValueError
1429
+ sage: from sage.categories.magmatic_algebras import MagmaticAlgebras
1430
+ sage: C = MagmaticAlgebras(QQ).WithBasis().Unital()
1431
+ sage: F = Foo(QQ, tuple(), category=C) # needs sage.modules
1432
+ sage: F.random_element() == F.zero() # needs sage.modules
1433
+ True
1434
+ """
1435
+ indices = self.basis().keys()
1436
+ a = self.zero()
1437
+ if not indices.is_empty():
1438
+ for i in range(n):
1439
+ a += self.term(indices.random_element(),
1440
+ self.base_ring().random_element())
1441
+ return a
1442
+
1443
+ class ElementMethods:
1444
+ # TODO: Define the appropriate element methods here (instead of in
1445
+ # subclasses). These methods should be consistent with those on
1446
+ # polynomials.
1447
+
1448
+ # def _neg_(self):
1449
+ # """
1450
+ # Default implementation of negation by trying to multiply by -1.
1451
+ # TODO: doctest
1452
+ # """
1453
+ # return self._lmul_(-self.parent().base_ring().one(), self)
1454
+
1455
+ @abstract_method
1456
+ def monomial_coefficients(self, copy=True):
1457
+ """
1458
+ Return a dictionary whose keys are indices of basis elements
1459
+ in the support of ``self`` and whose values are the
1460
+ corresponding coefficients.
1461
+
1462
+ INPUT:
1463
+
1464
+ - ``copy`` -- boolean (default: ``True``); if ``self`` is
1465
+ internally represented by a dictionary ``d``, then make a copy of
1466
+ ``d``; if ``False``, then this can cause undesired behavior by
1467
+ mutating ``d``
1468
+
1469
+ EXAMPLES::
1470
+
1471
+ sage: # needs sage.modules
1472
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1473
+ sage: B = F.basis()
1474
+ sage: f = B['a'] + 3*B['c']
1475
+ sage: d = f.monomial_coefficients()
1476
+ sage: d['a']
1477
+ 1
1478
+ sage: d['c']
1479
+ 3
1480
+
1481
+ TESTS:
1482
+
1483
+ We check that we make a copy of the coefficient dictionary::
1484
+
1485
+ sage: # needs sage.modules
1486
+ sage: F = CombinatorialFreeModule(ZZ, ['a','b','c'])
1487
+ sage: B = F.basis()
1488
+ sage: f = B['a'] + 3*B['c']
1489
+ sage: d = f.monomial_coefficients()
1490
+ sage: d['a'] = 5
1491
+ sage: f
1492
+ B['a'] + 3*B['c']
1493
+ """
1494
+
1495
+ def _test_monomial_coefficients(self, **options):
1496
+ r"""
1497
+ Test that :meth:`monomial_coefficients` works correctly if it is implemented.
1498
+
1499
+ INPUT:
1500
+
1501
+ - ``options`` -- any keyword arguments accepted by :meth:`_tester`
1502
+
1503
+ EXAMPLES:
1504
+
1505
+ By default, this method tests only the elements returned by
1506
+ ``self.some_elements()``::
1507
+
1508
+ sage: # needs sage.combinat sage.modules
1509
+ sage: A = AlgebrasWithBasis(QQ).example(); A
1510
+ An example of an algebra with basis:
1511
+ the free algebra on the generators ('a', 'b', 'c') over Rational Field
1512
+ sage: A.an_element()._test_monomial_coefficients()
1513
+
1514
+ See the documentation for :class:`TestSuite` for more information.
1515
+ """
1516
+ tester = self._tester(**options)
1517
+ base_ring = self.parent().base_ring()
1518
+ basis = self.parent().basis()
1519
+ try:
1520
+ d = self.monomial_coefficients()
1521
+ except NotImplementedError:
1522
+ return
1523
+ tester.assertTrue(all(value.parent() == base_ring
1524
+ for value in d.values()))
1525
+ tester.assertEqual(self, self.parent().linear_combination(
1526
+ (basis[index], coefficient)
1527
+ for index, coefficient in d.items()))
1528
+
1529
+ def __getitem__(self, m):
1530
+ """
1531
+ Return the coefficient of ``m`` in ``self``.
1532
+
1533
+ EXAMPLES::
1534
+
1535
+ sage: W.<x,y,z> = DifferentialWeylAlgebra(QQ) # needs sage.modules
1536
+ sage: x[((0,0,0), (0,0,0))] # needs sage.modules
1537
+ 0
1538
+ sage: x[((1,0,0), (0,0,0))] # needs sage.modules
1539
+ 1
1540
+ """
1541
+ res = self.monomial_coefficients(copy=False).get(m)
1542
+ if res is None:
1543
+ return self.base_ring().zero()
1544
+ else:
1545
+ return res
1546
+
1547
+ def coefficient(self, m):
1548
+ """
1549
+ Return the coefficient of ``m`` in ``self`` and raise an error
1550
+ if ``m`` is not in the basis indexing set.
1551
+
1552
+ INPUT:
1553
+
1554
+ - ``m`` -- a basis index of the parent of ``self``
1555
+
1556
+ OUTPUT:
1557
+
1558
+ The ``B[m]``-coordinate of ``self`` with respect to the basis
1559
+ ``B``. Here, ``B`` denotes the given basis of the parent of
1560
+ ``self``.
1561
+
1562
+ EXAMPLES::
1563
+
1564
+ sage: # needs sage.combinat sage.modules
1565
+ sage: s = CombinatorialFreeModule(QQ, Partitions())
1566
+ sage: z = s([4]) - 2*s([2,1]) + s([1,1,1]) + s([1])
1567
+ sage: z.coefficient([4])
1568
+ 1
1569
+ sage: z.coefficient([2,1])
1570
+ -2
1571
+ sage: z.coefficient(Partition([2,1]))
1572
+ -2
1573
+ sage: z.coefficient([1,2])
1574
+ Traceback (most recent call last):
1575
+ ...
1576
+ AssertionError: [1, 2] should be an element of Partitions
1577
+ sage: z.coefficient(Composition([2,1]))
1578
+ Traceback (most recent call last):
1579
+ ...
1580
+ AssertionError: [2, 1] should be an element of Partitions
1581
+
1582
+ Test that ``coefficient`` also works for those parents that do
1583
+ not have an ``element_class``::
1584
+
1585
+ sage: # needs sage.modules sage.rings.padics sage.schemes
1586
+ sage: H = pAdicWeightSpace(3)
1587
+ sage: F = CombinatorialFreeModule(QQ, H)
1588
+ sage: hasattr(H, "element_class")
1589
+ False
1590
+ sage: h = H.an_element()
1591
+ sage: (2*F.monomial(h)).coefficient(h)
1592
+ 2
1593
+ """
1594
+ # NT: coefficient_fast should be the default, just with appropriate assertions
1595
+ # that can be turned on or off
1596
+ C = self.parent().basis().keys()
1597
+ # TODO: This should raise a ValueError - TS
1598
+ assert m in C, "%s should be an element of %s" % (m, C)
1599
+ if hasattr(C, "element_class") and not isinstance(m, C.element_class):
1600
+ m = C(m)
1601
+ return self[m]
1602
+
1603
+ def items(self):
1604
+ r"""
1605
+ Return a list of pairs ``(i, c)``, where ``c`` is the
1606
+ ``i``-th coefficient of ``i`` in the standard basis.
1607
+
1608
+
1609
+ EXAMPLES::
1610
+
1611
+ sage: # needs sage.algebras
1612
+ sage: B = FiniteDimensionalAlgebra(QQ, [Matrix([[1,0], [0,1]]),
1613
+ ....: Matrix([[0,1], [-1,0]])])
1614
+ sage: elt = B(Matrix([[1,2], [-2,1]]))
1615
+ sage: elt.items()
1616
+ dict_items([(0, 1), (1, 2)])
1617
+
1618
+ ::
1619
+
1620
+ sage: # needs sage.combinat sage.modules
1621
+ sage: h = SymmetricFunctions(QQ).h()
1622
+ sage: (h[2]+3*h[3]).items()
1623
+ dict_items([([2], 1), ([3], 3)])
1624
+ """
1625
+ return self.monomial_coefficients(copy=False).items()
1626
+
1627
+ def is_zero(self):
1628
+ """
1629
+ Return ``True`` if and only if ``self == 0``.
1630
+
1631
+ EXAMPLES::
1632
+
1633
+ sage: # needs sage.modules
1634
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1635
+ sage: B = F.basis()
1636
+ sage: f = B['a'] - 3*B['c']
1637
+ sage: f.is_zero()
1638
+ False
1639
+ sage: F.zero().is_zero()
1640
+ True
1641
+
1642
+ ::
1643
+
1644
+ sage: # needs sage.combinat sage.modules
1645
+ sage: s = SymmetricFunctions(QQ).schur()
1646
+ sage: s([2,1]).is_zero()
1647
+ False
1648
+ sage: s(0).is_zero()
1649
+ True
1650
+ sage: (s([2,1]) - s([2,1])).is_zero()
1651
+ True
1652
+ """
1653
+ zero = self.parent().base_ring().zero()
1654
+ return all(v == zero for v in self.monomial_coefficients(copy=False).values())
1655
+
1656
+ def __len__(self):
1657
+ """
1658
+ Return the number of basis elements whose coefficients in
1659
+ ``self`` are nonzero.
1660
+
1661
+ EXAMPLES::
1662
+
1663
+ sage: # needs sage.modules
1664
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1665
+ sage: B = F.basis()
1666
+ sage: f = B['a'] - 3*B['c']
1667
+ sage: len(f)
1668
+ 2
1669
+
1670
+ ::
1671
+
1672
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1673
+ sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # needs sage.combinat sage.modules
1674
+ sage: len(z) # needs sage.combinat sage.modules
1675
+ 4
1676
+ """
1677
+ return len(self.support())
1678
+
1679
+ def length(self):
1680
+ """
1681
+ Return the number of basis elements whose coefficients in
1682
+ ``self`` are nonzero.
1683
+
1684
+ EXAMPLES::
1685
+
1686
+ sage: # needs sage.modules
1687
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1688
+ sage: B = F.basis()
1689
+ sage: f = B['a'] - 3*B['c']
1690
+ sage: f.length()
1691
+ 2
1692
+
1693
+ ::
1694
+
1695
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1696
+ sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # needs sage.combinat sage.modules
1697
+ sage: z.length() # needs sage.combinat sage.modules
1698
+ 4
1699
+ """
1700
+ return len(self)
1701
+
1702
+ def support(self):
1703
+ """
1704
+ Return an iterable of the objects indexing the basis of
1705
+ ``self.parent()`` whose corresponding coefficients of
1706
+ ``self`` are nonzero.
1707
+
1708
+ This method returns these objects in an arbitrary order.
1709
+
1710
+ EXAMPLES::
1711
+
1712
+ sage: # needs sage.modules
1713
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1714
+ sage: B = F.basis()
1715
+ sage: f = B['a'] - 3*B['c']
1716
+ sage: sorted(f.support())
1717
+ ['a', 'c']
1718
+
1719
+ ::
1720
+
1721
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1722
+ sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # needs sage.combinat sage.modules
1723
+ sage: sorted(z.support()) # needs sage.combinat sage.modules
1724
+ [[1], [1, 1, 1], [2, 1], [4]]
1725
+ """
1726
+ try:
1727
+ return self._support_view
1728
+ except AttributeError:
1729
+ from sage.structure.support_view import SupportView
1730
+ zero = self.parent().base_ring().zero()
1731
+ mc = self.monomial_coefficients(copy=False)
1732
+ support_view = SupportView(mc, zero=zero)
1733
+ try:
1734
+ # Try to cache it for next time, but this may fail for Cython classes
1735
+ self._support_view = support_view
1736
+ except AttributeError:
1737
+ pass
1738
+ return support_view
1739
+
1740
+ def monomials(self):
1741
+ """
1742
+ Return a list of the monomials of ``self`` (in an arbitrary
1743
+ order).
1744
+
1745
+ The monomials of an element `a` are defined to be the basis
1746
+ elements whose corresponding coefficients of `a` are
1747
+ nonzero.
1748
+
1749
+ EXAMPLES::
1750
+
1751
+ sage: # needs sage.modules
1752
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1753
+ sage: B = F.basis()
1754
+ sage: f = B['a'] + 2*B['c']
1755
+ sage: f.monomials()
1756
+ [B['a'], B['c']]
1757
+
1758
+ sage: (F.zero()).monomials() # needs sage.modules
1759
+ []
1760
+ """
1761
+ P = self.parent()
1762
+ return [P.monomial(key) for key in self.support()]
1763
+
1764
+ def terms(self):
1765
+ """
1766
+ Return a list of the (nonzero) terms of ``self`` (in an
1767
+ arbitrary order).
1768
+
1769
+ .. SEEALSO:: :meth:`monomials`
1770
+
1771
+ EXAMPLES::
1772
+
1773
+ sage: # needs sage.modules
1774
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1775
+ sage: B = F.basis()
1776
+ sage: f = B['a'] + 2*B['c']
1777
+ sage: f.terms()
1778
+ [B['a'], 2*B['c']]
1779
+ """
1780
+ P = self.parent()
1781
+ zero = P.base_ring().zero()
1782
+ return [P.term(key, value)
1783
+ for key, value in self.monomial_coefficients(copy=False).items()
1784
+ if value != zero]
1785
+
1786
+ def coefficients(self, sort=True):
1787
+ """
1788
+ Return a list of the (nonzero) coefficients appearing on
1789
+ the basis elements in ``self`` (in an arbitrary order).
1790
+
1791
+ INPUT:
1792
+
1793
+ - ``sort`` -- boolean (default: ``True``); to sort the coefficients
1794
+ based upon the default ordering of the indexing set
1795
+
1796
+ .. SEEALSO::
1797
+
1798
+ :meth:`~sage.categories.finite_dimensional_modules_with_basis.FiniteDimensionalModulesWithBasis.ElementMethods.dense_coefficient_list`
1799
+
1800
+ EXAMPLES::
1801
+
1802
+ sage: # needs sage.modules
1803
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
1804
+ sage: B = F.basis()
1805
+ sage: f = B['a'] - 3*B['c']
1806
+ sage: f.coefficients()
1807
+ [1, -3]
1808
+ sage: f = B['c'] - 3*B['a']
1809
+ sage: f.coefficients()
1810
+ [-3, 1]
1811
+
1812
+ ::
1813
+
1814
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1815
+ sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) # needs sage.combinat sage.modules
1816
+ sage: z.coefficients() # needs sage.combinat sage.modules
1817
+ [1, 1, 1, 1]
1818
+ """
1819
+ zero = self.parent().base_ring().zero()
1820
+ mc = self.monomial_coefficients(copy=False)
1821
+ if not sort:
1822
+ return [value for key, value in mc.items() if value != zero]
1823
+
1824
+ v = sorted([(key, value) for key, value in mc.items()
1825
+ if value != zero])
1826
+ return [value for key, value in v]
1827
+
1828
+ def support_of_term(self):
1829
+ """
1830
+ Return the support of ``self``, where ``self`` is a monomial
1831
+ (possibly with coefficient).
1832
+
1833
+ EXAMPLES::
1834
+
1835
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename('X') # needs sage.modules
1836
+ sage: X.monomial(2).support_of_term() # needs sage.modules
1837
+ 2
1838
+ sage: X.term(3, 2).support_of_term() # needs sage.modules
1839
+ 3
1840
+
1841
+ An exception is raised if ``self`` has more than one term::
1842
+
1843
+ sage: (X.monomial(2) + X.monomial(3)).support_of_term() # needs sage.modules
1844
+ Traceback (most recent call last):
1845
+ ...
1846
+ ValueError: B[2] + B[3] is not a single term
1847
+ """
1848
+ if len(self) == 1:
1849
+ return self.support()[0]
1850
+ else:
1851
+ raise ValueError("{} is not a single term".format(self))
1852
+
1853
+ def leading_support(self, *args, **kwds):
1854
+ r"""
1855
+ Return the maximal element of the support of ``self``.
1856
+
1857
+ Note that this may not be the term which actually appears
1858
+ first when ``self`` is printed.
1859
+
1860
+ If the default ordering of the basis elements is not what is
1861
+ desired, a comparison key, ``key(x)``, can be provided.
1862
+
1863
+ EXAMPLES::
1864
+
1865
+ sage: # needs sage.modules
1866
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3])
1867
+ sage: X.rename('X'); x = X.basis()
1868
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3)
1869
+ sage: x.leading_support()
1870
+ 3
1871
+ sage: def key(x): return -x
1872
+ sage: x.leading_support(key=key)
1873
+ 1
1874
+
1875
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1876
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
1877
+ sage: f.leading_support() # needs sage.combinat sage.modules
1878
+ [3]
1879
+ """
1880
+ return max(self.support(), *args, **kwds)
1881
+
1882
+ def leading_item(self, *args, **kwds):
1883
+ r"""
1884
+ Return the pair ``(k, c)`` where
1885
+
1886
+ .. MATH::
1887
+
1888
+ c \cdot (\mbox{the basis element indexed by } k)
1889
+
1890
+ is the leading term of ``self``.
1891
+
1892
+ Here 'leading term' means that the corresponding basis element is
1893
+ maximal. Note that this may not be the term which actually appears
1894
+ first when ``self`` is printed.
1895
+
1896
+ If the default term ordering is not what is desired, a
1897
+ comparison function, ``key(x)``, can be provided.
1898
+
1899
+ EXAMPLES::
1900
+
1901
+ sage: # needs sage.modules
1902
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
1903
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3)
1904
+ sage: x.leading_item()
1905
+ (3, 4)
1906
+ sage: def key(x): return -x
1907
+ sage: x.leading_item(key=key)
1908
+ (1, 3)
1909
+
1910
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1911
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
1912
+ sage: f.leading_item() # needs sage.combinat sage.modules
1913
+ ([3], -5)
1914
+
1915
+ The term ordering of polynomial rings is taken into account::
1916
+
1917
+ sage: R.<x,y,z> = QQ[]
1918
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_item()
1919
+ ((0, 4, 0), 1)
1920
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
1921
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_item()
1922
+ ((1, 2, 0), 3)
1923
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
1924
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_item()
1925
+ ((0, 1, 3), 2)
1926
+ """
1927
+ k = self.leading_support(*args, **kwds)
1928
+ return k, self[k]
1929
+
1930
+ def leading_monomial(self, *args, **kwds):
1931
+ r"""
1932
+ Return the leading monomial of ``self``.
1933
+
1934
+ This is the monomial whose corresponding basis element is
1935
+ maximal. Note that this may not be the term which actually appears
1936
+ first when ``self`` is printed.
1937
+
1938
+ If the default term ordering is not
1939
+ what is desired, a comparison key, ``key(x)``, can be provided.
1940
+
1941
+ EXAMPLES::
1942
+
1943
+ sage: # needs sage.modules
1944
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
1945
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
1946
+ sage: x.leading_monomial()
1947
+ B[3]
1948
+ sage: def key(x): return -x
1949
+ sage: x.leading_monomial(key=key)
1950
+ B[1]
1951
+
1952
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1953
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
1954
+ sage: f.leading_monomial() # needs sage.combinat sage.modules
1955
+ s[3]
1956
+
1957
+ The term ordering of polynomial rings is taken into account::
1958
+
1959
+ sage: R.<x,y,z> = QQ[]
1960
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_monomial()
1961
+ y^4
1962
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
1963
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_monomial()
1964
+ x*y^2
1965
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
1966
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_monomial()
1967
+ y*z^3
1968
+ """
1969
+ return self.parent().monomial(self.leading_support(*args, **kwds))
1970
+
1971
+ def leading_coefficient(self, *args, **kwds):
1972
+ r"""
1973
+ Return the leading coefficient of ``self``.
1974
+
1975
+ This is the coefficient of the term whose corresponding basis element is
1976
+ maximal. Note that this may not be the term which actually appears
1977
+ first when ``self`` is printed.
1978
+
1979
+ If the default term ordering is not
1980
+ what is desired, a comparison key, ``key(x,y)``, can be provided.
1981
+
1982
+ EXAMPLES::
1983
+
1984
+ sage: # needs sage.modules
1985
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
1986
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
1987
+ sage: x.leading_coefficient()
1988
+ 1
1989
+ sage: def key(x): return -x
1990
+ sage: x.leading_coefficient(key=key)
1991
+ 3
1992
+
1993
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
1994
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
1995
+ sage: f.leading_coefficient() # needs sage.combinat sage.modules
1996
+ -5
1997
+
1998
+ The term ordering of polynomial rings is taken into account::
1999
+
2000
+ sage: R.<x,y,z> = QQ[]
2001
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_coefficient()
2002
+ 1
2003
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
2004
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_coefficient()
2005
+ 3
2006
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
2007
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_coefficient()
2008
+ 2
2009
+ """
2010
+ return self.leading_item(*args, **kwds)[1]
2011
+
2012
+ def leading_term(self, *args, **kwds):
2013
+ r"""
2014
+ Return the leading term of ``self``.
2015
+
2016
+ This is the term whose corresponding basis element is
2017
+ maximal. Note that this may not be the term which actually appears
2018
+ first when ``self`` is printed.
2019
+
2020
+ If the default term ordering is not
2021
+ what is desired, a comparison key, ``key(x)``, can be provided.
2022
+
2023
+ EXAMPLES::
2024
+
2025
+ sage: # needs sage.modules
2026
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
2027
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
2028
+ sage: x.leading_term()
2029
+ B[3]
2030
+ sage: def key(x): return -x
2031
+ sage: x.leading_term(key=key)
2032
+ 3*B[1]
2033
+
2034
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2035
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
2036
+ sage: f.leading_term() # needs sage.combinat sage.modules
2037
+ -5*s[3]
2038
+
2039
+ The term ordering of polynomial rings is taken into account::
2040
+
2041
+ sage: R.<x,y,z> = QQ[]
2042
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_term()
2043
+ y^4
2044
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
2045
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_term()
2046
+ 3*x*y^2
2047
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
2048
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).leading_term()
2049
+ 2*y*z^3
2050
+ """
2051
+ return self.parent().term(*self.leading_item(*args, **kwds))
2052
+
2053
+ def trailing_support(self, *args, **kwds):
2054
+ r"""
2055
+ Return the minimal element of the support of ``self``. Note
2056
+ that this may not be the term which actually appears last when
2057
+ ``self`` is printed.
2058
+
2059
+ If the default ordering of the basis elements is not what is
2060
+ desired, a comparison key, ``key(x)``, can be provided.
2061
+
2062
+ EXAMPLES::
2063
+
2064
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X') # needs sage.modules
2065
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + 4*X.monomial(3) # needs sage.modules
2066
+ sage: x.trailing_support() # needs sage.modules
2067
+ 1
2068
+
2069
+ sage: def key(x): return -x
2070
+ sage: x.trailing_support(key=key) # needs sage.modules
2071
+ 3
2072
+
2073
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2074
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
2075
+ sage: f.trailing_support() # needs sage.combinat sage.modules
2076
+ [1]
2077
+ """
2078
+ return min(self.support(), *args, **kwds)
2079
+
2080
+ def trailing_item(self, *args, **kwds):
2081
+ r"""
2082
+ Return the pair ``(c, k)`` where ``c*self.parent().monomial(k)``
2083
+ is the trailing term of ``self``.
2084
+
2085
+ This is the monomial whose corresponding basis element is
2086
+ minimal. Note that this may not be the term which actually appears
2087
+ last when ``self`` is printed.
2088
+
2089
+ If the default term ordering is not
2090
+ what is desired, a comparison key ``key(x)``, can be provided.
2091
+
2092
+ EXAMPLES::
2093
+
2094
+ sage: # needs sage.modules
2095
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
2096
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
2097
+ sage: x.trailing_item()
2098
+ (1, 3)
2099
+ sage: def key(x): return -x
2100
+ sage: x.trailing_item(key=key)
2101
+ (3, 1)
2102
+
2103
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2104
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
2105
+ sage: f.trailing_item() # needs sage.combinat sage.modules
2106
+ ([1], 2)
2107
+
2108
+ The term ordering of polynomial rings is taken into account::
2109
+
2110
+ sage: R.<x,y,z> = QQ[]
2111
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_item()
2112
+ ((1, 1, 1), 4)
2113
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
2114
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_item()
2115
+ ((0, 1, 3), 2)
2116
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
2117
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_item()
2118
+ ((1, 2, 0), 3)
2119
+ """
2120
+ k = self.trailing_support(*args, **kwds)
2121
+ return k, self[k]
2122
+
2123
+ def trailing_monomial(self, *args, **kwds):
2124
+ r"""
2125
+ Return the trailing monomial of ``self``.
2126
+
2127
+ This is the monomial whose corresponding basis element is
2128
+ minimal. Note that this may not be the term which actually appears
2129
+ last when ``self`` is printed.
2130
+
2131
+ If the default term ordering is not
2132
+ what is desired, a comparison key ``key(x)``, can be provided.
2133
+
2134
+ EXAMPLES::
2135
+
2136
+ sage: # needs sage.modules
2137
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
2138
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
2139
+ sage: x.trailing_monomial()
2140
+ B[1]
2141
+ sage: def key(x): return -x
2142
+ sage: x.trailing_monomial(key=key)
2143
+ B[3]
2144
+
2145
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2146
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
2147
+ sage: f.trailing_monomial() # needs sage.combinat sage.modules
2148
+ s[1]
2149
+
2150
+ The term ordering of polynomial rings is taken into account::
2151
+
2152
+ sage: R.<x,y,z> = QQ[]
2153
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_monomial()
2154
+ x*y*z
2155
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
2156
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_monomial()
2157
+ y*z^3
2158
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
2159
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_monomial()
2160
+ x*y^2
2161
+ """
2162
+ return self.parent().monomial(self.trailing_support(*args, **kwds))
2163
+
2164
+ def trailing_coefficient(self, *args, **kwds):
2165
+ r"""
2166
+ Return the trailing coefficient of ``self``.
2167
+
2168
+ This is the coefficient of the monomial whose corresponding basis element is
2169
+ minimal. Note that this may not be the term which actually appears
2170
+ last when ``self`` is printed.
2171
+
2172
+ If the default term ordering is not
2173
+ what is desired, a comparison key ``key(x)``, can be provided.
2174
+
2175
+ EXAMPLES::
2176
+
2177
+ sage: # needs sage.modules
2178
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
2179
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
2180
+ sage: x.trailing_coefficient()
2181
+ 3
2182
+ sage: def key(x): return -x
2183
+ sage: x.trailing_coefficient(key=key)
2184
+ 1
2185
+
2186
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2187
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
2188
+ sage: f.trailing_coefficient() # needs sage.combinat sage.modules
2189
+ 2
2190
+
2191
+ The term ordering of polynomial rings is taken into account::
2192
+
2193
+ sage: R.<x,y,z> = QQ[]
2194
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_coefficient()
2195
+ 4
2196
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
2197
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_coefficient()
2198
+ 2
2199
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
2200
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_coefficient()
2201
+ 3
2202
+ """
2203
+ return self.trailing_item(*args, **kwds)[1]
2204
+
2205
+ def trailing_term(self, *args, **kwds):
2206
+ r"""
2207
+ Return the trailing term of ``self``.
2208
+
2209
+ This is the term whose corresponding basis element is
2210
+ minimal. Note that this may not be the term which actually appears
2211
+ last when ``self`` is printed.
2212
+
2213
+ If the default term ordering is not
2214
+ what is desired, a comparison key ``key(x)``, can be provided.
2215
+
2216
+ EXAMPLES::
2217
+
2218
+ sage: # needs sage.modules
2219
+ sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename('X')
2220
+ sage: x = 3*X.monomial(1) + 2*X.monomial(2) + X.monomial(3)
2221
+ sage: x.trailing_term()
2222
+ 3*B[1]
2223
+ sage: def key(x): return -x
2224
+ sage: x.trailing_term(key=key)
2225
+ B[3]
2226
+
2227
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2228
+ sage: f = 2*s[1] + 3*s[2,1] - 5*s[3] # needs sage.combinat sage.modules
2229
+ sage: f.trailing_term() # needs sage.combinat sage.modules
2230
+ 2*s[1]
2231
+
2232
+ The term ordering of polynomial rings is taken into account::
2233
+
2234
+ sage: R.<x,y,z> = QQ[]
2235
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_term()
2236
+ 4*x*y*z
2237
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='lex')
2238
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_term()
2239
+ 2*y*z^3
2240
+ sage: R.<x,y,z> = PolynomialRing(QQ, order='invlex')
2241
+ sage: (3*x*y^2 + 2*y*z^3 + y^4 + 4*x*y*z).trailing_term()
2242
+ 3*x*y^2
2243
+ """
2244
+ return self.parent().term(*self.trailing_item(*args, **kwds))
2245
+
2246
+ def map_coefficients(self, f, new_base_ring=None):
2247
+ """
2248
+ Return the element obtained by applying ``f`` to the nonzero
2249
+ coefficients of ``self``.
2250
+
2251
+ If ``f`` is a :class:`sage.categories.map.Map`, then the resulting
2252
+ polynomial will be defined over the codomain of ``f``. Otherwise, the
2253
+ resulting polynomial will be over the same ring as ``self``. Set
2254
+ ``new_base_ring`` to override this behaviour.
2255
+
2256
+ An error is raised if the coefficients cannot be
2257
+ converted to the new base ring.
2258
+
2259
+ INPUT:
2260
+
2261
+ - ``f`` -- a callable that will be applied to the
2262
+ coefficients of ``self``
2263
+
2264
+ - ``new_base_ring`` -- (optional) if given, the resulting element
2265
+ will be defined over this ring
2266
+
2267
+ EXAMPLES::
2268
+
2269
+ sage: # needs sage.modules
2270
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
2271
+ sage: B = F.basis()
2272
+ sage: f = B['a'] - 3*B['c']
2273
+ sage: f.map_coefficients(lambda x: x + 5)
2274
+ 6*B['a'] + 2*B['c']
2275
+
2276
+ Killed coefficients are handled properly::
2277
+
2278
+ sage: f.map_coefficients(lambda x: 0) # needs sage.modules
2279
+ 0
2280
+ sage: list(f.map_coefficients(lambda x: 0)) # needs sage.modules
2281
+ []
2282
+
2283
+ ::
2284
+
2285
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2286
+ sage: a = s([2,1]) + 2*s([3,2]) # needs sage.combinat sage.modules
2287
+ sage: a.map_coefficients(lambda x: x * 2) # needs sage.combinat sage.modules
2288
+ 2*s[2, 1] + 4*s[3, 2]
2289
+
2290
+ We can map into a different base ring::
2291
+
2292
+ sage: # needs sage.modules
2293
+ sage: F = CombinatorialFreeModule(QQ, ['a','b','c'])
2294
+ sage: B = F.basis()
2295
+ sage: a = 1/2*(B['a'] + 3*B['c']); a
2296
+ 1/2*B['a'] + 3/2*B['c']
2297
+ sage: b = a.map_coefficients(lambda c: 2*c, ZZ); b
2298
+ B['a'] + 3*B['c']
2299
+ sage: b.parent()
2300
+ Free module generated by {'a', 'b', 'c'} over Integer Ring
2301
+ sage: b.map_coefficients(lambda c: 1/2*c, ZZ)
2302
+ Traceback (most recent call last):
2303
+ ...
2304
+ TypeError: no conversion of this rational to integer
2305
+
2306
+ Coefficients are converted to the new base ring after
2307
+ applying the map::
2308
+
2309
+ sage: B['a'].map_coefficients(lambda c: 2*c, GF(2)) # needs sage.modules
2310
+ 0
2311
+ sage: B['a'].map_coefficients(lambda c: GF(2)(c), QQ) # needs sage.modules
2312
+ B['a']
2313
+ """
2314
+ R = self.parent()
2315
+ if isinstance(f, Map):
2316
+ B = f.codomain()
2317
+ else:
2318
+ B = self.base_ring()
2319
+ if new_base_ring is not None:
2320
+ B = new_base_ring
2321
+ if B is not self.base_ring():
2322
+ R = R.change_ring(B)
2323
+ mc = self.monomial_coefficients(copy=False)
2324
+ return R.sum_of_terms((m, B(f(c))) for m, c in mc.items())
2325
+
2326
+ def map_support(self, f):
2327
+ """
2328
+ Mapping a function on the support.
2329
+
2330
+ INPUT:
2331
+
2332
+ - ``f`` -- an endofunction on the indices of the free module
2333
+
2334
+ Return a new element of ``self.parent()`` obtained by
2335
+ applying the function ``f`` to all of the objects indexing
2336
+ the basis elements.
2337
+
2338
+ EXAMPLES::
2339
+
2340
+ sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) # needs sage.modules
2341
+ sage: x = B.an_element(); x # needs sage.modules
2342
+ 2*B[-1] + 2*B[0] + 3*B[1]
2343
+ sage: x.map_support(lambda i: -i) # needs sage.modules
2344
+ 3*B[-1] + 2*B[0] + 2*B[1]
2345
+
2346
+ ``f`` needs not be injective::
2347
+
2348
+ sage: x.map_support(lambda i: 1) # needs sage.modules
2349
+ 7*B[1]
2350
+
2351
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2352
+ sage: a = s([2,1]) + 2*s([3,2]) # needs sage.combinat sage.modules
2353
+ sage: a.map_support(lambda x: x.conjugate()) # needs sage.combinat sage.modules
2354
+ s[2, 1] + 2*s[2, 2, 1]
2355
+
2356
+ TESTS::
2357
+
2358
+ sage: B.zero() # This actually failed at some point!!! See #8890 # needs sage.modules
2359
+ 0
2360
+
2361
+ sage: y = B.zero().map_support(lambda i: i/0); y # needs sage.modules
2362
+ 0
2363
+ sage: y.parent() is B # needs sage.modules
2364
+ True
2365
+ """
2366
+ return self.parent().sum_of_terms((f(m), c) for m, c in self.items())
2367
+
2368
+ def map_support_skip_none(self, f):
2369
+ """
2370
+ Mapping a function on the support.
2371
+
2372
+ INPUT:
2373
+
2374
+ - ``f`` -- an endofunction on the indices of the free module
2375
+
2376
+ Returns a new element of ``self.parent()`` obtained by
2377
+ applying the function `f` to all of the objects indexing
2378
+ the basis elements.
2379
+
2380
+ EXAMPLES::
2381
+
2382
+ sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) # needs sage.modules
2383
+ sage: x = B.an_element(); x # needs sage.modules
2384
+ 2*B[-1] + 2*B[0] + 3*B[1]
2385
+ sage: x.map_support_skip_none(lambda i: -i if i else None) # needs sage.modules
2386
+ 3*B[-1] + 2*B[1]
2387
+
2388
+ ``f`` needs not be injective::
2389
+
2390
+ sage: x.map_support_skip_none(lambda i: 1 if i else None) # needs sage.modules
2391
+ 5*B[1]
2392
+
2393
+ TESTS::
2394
+
2395
+ sage: y = x.map_support_skip_none(lambda i: None); y # needs sage.modules
2396
+ 0
2397
+ sage: y.parent() is B # needs sage.modules
2398
+ True
2399
+ """
2400
+ return self.parent().sum_of_terms((fm, c)
2401
+ for fm, c in ((f(m), c) for m, c in self.items())
2402
+ if fm is not None)
2403
+
2404
+ def map_item(self, f):
2405
+ """
2406
+ Mapping a function on items.
2407
+
2408
+ INPUT:
2409
+
2410
+ - ``f`` -- a function mapping pairs ``(index, coeff)`` to
2411
+ other such pairs
2412
+
2413
+ Return a new element of ``self.parent()`` obtained by
2414
+ applying the function `f` to all items ``(index, coeff)`` of
2415
+ ``self``.
2416
+
2417
+ EXAMPLES::
2418
+
2419
+ sage: B = CombinatorialFreeModule(ZZ, [-1, 0, 1]) # needs sage.modules
2420
+ sage: x = B.an_element(); x # needs sage.modules
2421
+ 2*B[-1] + 2*B[0] + 3*B[1]
2422
+ sage: x.map_item(lambda i, c: (-i, 2*c)) # needs sage.modules
2423
+ 6*B[-1] + 4*B[0] + 4*B[1]
2424
+
2425
+ ``f`` needs not be injective::
2426
+
2427
+ sage: x.map_item(lambda i, c: (1, 2*c)) # needs sage.modules
2428
+ 14*B[1]
2429
+
2430
+ sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat sage.modules
2431
+ sage: f = lambda m, c: (m.conjugate(), 2 * c)
2432
+ sage: a = s([2,1]) + s([1,1,1]) # needs sage.combinat sage.modules
2433
+ sage: a.map_item(f) # needs sage.combinat sage.modules
2434
+ 2*s[2, 1] + 2*s[3]
2435
+ """
2436
+ return self.parent().sum_of_terms(f(m, c) for m, c in self.items())
2437
+
2438
+ def tensor(*elements):
2439
+ """
2440
+ Return the tensor product of its arguments, as an element of
2441
+ the tensor product of the parents of those elements.
2442
+
2443
+ EXAMPLES::
2444
+
2445
+ sage: C = AlgebrasWithBasis(QQ)
2446
+ sage: A = C.example() # needs sage.combinat sage.modules
2447
+ sage: a, b, c = A.algebra_generators() # needs sage.combinat sage.modules
2448
+ sage: a.tensor(b, c) # needs sage.combinat sage.modules
2449
+ B[word: a] # B[word: b] # B[word: c]
2450
+
2451
+ FIXME: is this a policy that we want to enforce on all parents?
2452
+ """
2453
+ assert all(isinstance(element, Element) for element in elements)
2454
+ parents = [parent(element) for element in elements]
2455
+ return tensor(parents)._tensor_of_elements(elements) # good name ?
2456
+
2457
+ class Homsets(HomsetsCategory):
2458
+ class ParentMethods:
2459
+ def __call_on_basis__(self, **options):
2460
+ """
2461
+ Construct a morphism in this homset from a function defined
2462
+ on the basis.
2463
+
2464
+ INPUT:
2465
+
2466
+ - ``on_basis`` -- a function from the indices of the
2467
+ basis of the domain of ``self`` to the codomain of
2468
+ ``self``
2469
+
2470
+ This method simply delegates the work to
2471
+ :meth:`ModulesWithBasis.ParentMethods.module_morphism`. It
2472
+ is used by :meth:`Homset.__call__` to handle the
2473
+ ``on_basis`` argument, and will disappear as soon as
2474
+ the logic will be generalized.
2475
+
2476
+ EXAMPLES::
2477
+
2478
+ sage: # needs sage.modules
2479
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X')
2480
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y')
2481
+ sage: H = Hom(X, Y)
2482
+ sage: x = X.basis()
2483
+ sage: def on_basis(i):
2484
+ ....: return Y.monomial(i) + 2*Y.monomial(i + 1)
2485
+ sage: phi = H(on_basis=on_basis) # indirect doctest
2486
+ sage: phi
2487
+ Generic morphism:
2488
+ From: X
2489
+ To: Y
2490
+ sage: phi(x[1] + x[3])
2491
+ B[1] + 2*B[2] + B[3] + 2*B[4]
2492
+
2493
+ Diagonal functions can be constructed using the ``diagonal`` option::
2494
+
2495
+ sage: # needs sage.modules
2496
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3,4]); X.rename('X')
2497
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4],
2498
+ ....: key='Y'); Y.rename('Y')
2499
+ sage: H = Hom(X, Y)
2500
+ sage: x = X.basis()
2501
+ sage: phi = H(diagonal=lambda x: x^2)
2502
+ sage: phi(x[1] + x[2] + x[3])
2503
+ B[1] + 4*B[2] + 9*B[3]
2504
+
2505
+ TESTS:
2506
+
2507
+ As for usual homsets, the argument can be a Python function::
2508
+
2509
+ sage: phi = H(lambda x: Y.zero()); phi # needs sage.modules
2510
+ Generic morphism:
2511
+ From: X
2512
+ To: Y
2513
+ sage: phi(x[1] + x[3]) # needs sage.modules
2514
+ 0
2515
+
2516
+ We check that the homset category is properly set up::
2517
+
2518
+ sage: # needs sage.modules
2519
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X')
2520
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y')
2521
+ sage: H = Hom(X, Y)
2522
+ sage: H.zero().category_for()
2523
+ Category of finite dimensional vector spaces with basis over Rational Field
2524
+ """
2525
+ return self.domain().module_morphism(codomain=self.codomain(),
2526
+ **options)
2527
+
2528
+ class MorphismMethods:
2529
+ @cached_method
2530
+ def on_basis(self):
2531
+ """
2532
+ Return the action of this morphism on basis elements.
2533
+
2534
+ OUTPUT:
2535
+
2536
+ - a function from the indices of the basis of the domain to
2537
+ the codomain
2538
+
2539
+ EXAMPLES::
2540
+
2541
+ sage: # needs sage.modules
2542
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X')
2543
+ sage: Y = CombinatorialFreeModule(QQ, [1,2,3,4]); Y.rename('Y')
2544
+ sage: H = Hom(X, Y)
2545
+ sage: x = X.basis()
2546
+ sage: f = H(lambda x: Y.zero()).on_basis()
2547
+ sage: f(2)
2548
+ 0
2549
+ sage: f = lambda i: Y.monomial(i) + 2*Y.monomial(i+1)
2550
+ sage: g = H(on_basis=f).on_basis()
2551
+ sage: g(2)
2552
+ B[2] + 2*B[3]
2553
+ sage: g == f
2554
+ True
2555
+ """
2556
+ return self._on_basis
2557
+
2558
+ def _on_basis(self, i):
2559
+ """
2560
+ Return the image of ``self`` on the basis element indexed by ``i``.
2561
+
2562
+ INPUT:
2563
+
2564
+ - ``i`` -- the index of an element of the basis of the domain of ``self``
2565
+
2566
+ EXAMPLES::
2567
+
2568
+ sage: X = CombinatorialFreeModule(QQ, [1,2,3]); X.rename('X') # needs sage.modules
2569
+ sage: phi = End(X)(lambda x: 2*x) # needs sage.modules
2570
+ sage: phi._on_basis(3) # needs sage.modules
2571
+ 2*B[3]
2572
+ """
2573
+ return self(self.domain().monomial(i))
2574
+
2575
+ class CartesianProducts(CartesianProductsCategory):
2576
+ """
2577
+ The category of modules with basis constructed by Cartesian products
2578
+ of modules with basis.
2579
+ """
2580
+ @cached_method
2581
+ def extra_super_categories(self):
2582
+ """
2583
+ EXAMPLES::
2584
+
2585
+ sage: ModulesWithBasis(QQ).CartesianProducts().extra_super_categories()
2586
+ [Category of vector spaces with basis over Rational Field]
2587
+ sage: ModulesWithBasis(QQ).CartesianProducts().super_categories()
2588
+ [Category of Cartesian products of modules with basis over Rational Field,
2589
+ Category of vector spaces with basis over Rational Field,
2590
+ Category of Cartesian products of vector spaces over Rational Field]
2591
+ """
2592
+ return [self.base_category()]
2593
+
2594
+ class ParentMethods:
2595
+
2596
+ def _an_element_(self):
2597
+ """
2598
+ EXAMPLES::
2599
+
2600
+ sage: # needs sage.combinat sage.groups sage.modules
2601
+ sage: A = AlgebrasWithBasis(QQ).example(); A
2602
+ An example of an algebra with basis:
2603
+ the free algebra on the generators ('a', 'b', 'c')
2604
+ over Rational Field
2605
+ sage: B = HopfAlgebrasWithBasis(QQ).example(); B
2606
+ An example of Hopf algebra with basis:
2607
+ the group algebra of the Dihedral group of order 6
2608
+ as a permutation group over Rational Field
2609
+ sage: A.an_element()
2610
+ B[word: ] + 2*B[word: a] + 3*B[word: b] + B[word: bab]
2611
+ sage: B.an_element()
2612
+ B[()] + B[(1,2)] + 3*B[(1,2,3)] + 2*B[(1,3,2)]
2613
+ sage: ABA = cartesian_product((A, B, A))
2614
+ sage: ABA.an_element() # indirect doctest
2615
+ 2*B[(0, word: )] + 2*B[(0, word: a)] + 3*B[(0, word: b)]
2616
+ """
2617
+ from .cartesian_product import cartesian_product
2618
+ return cartesian_product([module.an_element() for module in self.modules])
2619
+
2620
+ class TensorProducts(TensorProductsCategory):
2621
+ """
2622
+ The category of modules with basis constructed by tensor product of
2623
+ modules with basis.
2624
+ """
2625
+ @cached_method
2626
+ def extra_super_categories(self):
2627
+ """
2628
+ EXAMPLES::
2629
+
2630
+ sage: ModulesWithBasis(QQ).TensorProducts().extra_super_categories()
2631
+ [Category of vector spaces with basis over Rational Field]
2632
+ sage: ModulesWithBasis(QQ).TensorProducts().super_categories()
2633
+ [Category of tensor products of modules with basis over Rational Field,
2634
+ Category of vector spaces with basis over Rational Field,
2635
+ Category of tensor products of vector spaces over Rational Field]
2636
+ """
2637
+ return [self.base_category()]
2638
+
2639
+ class ParentMethods:
2640
+ """
2641
+ Implement operations on tensor products of modules with basis.
2642
+ """
2643
+ pass
2644
+
2645
+ class ElementMethods:
2646
+ """
2647
+ Implement operations on elements of tensor products of modules
2648
+ with basis.
2649
+ """
2650
+
2651
+ def apply_multilinear_morphism(self, f, codomain=None):
2652
+ r"""
2653
+ Return the result of applying the morphism induced by ``f``
2654
+ to ``self``.
2655
+
2656
+ INPUT:
2657
+
2658
+ - ``f`` -- a multilinear morphism from the component
2659
+ modules of the parent tensor product to any module
2660
+
2661
+ - ``codomain`` -- the codomain of ``f`` (optional)
2662
+
2663
+ By the universal property of the tensor product, ``f``
2664
+ induces a linear morphism from `self.parent()` to the
2665
+ target module. Returns the result of applying that
2666
+ morphism to ``self``.
2667
+
2668
+ The codomain is used for optimizations purposes
2669
+ only. If it's not provided, it's recovered by calling
2670
+ ``f`` on the zero input.
2671
+
2672
+ EXAMPLES:
2673
+
2674
+ We start with simple (admittedly not so interesting)
2675
+ examples, with two modules `A` and `B`::
2676
+
2677
+ sage: # needs sage.modules
2678
+ sage: A = CombinatorialFreeModule(ZZ, [1,2], prefix='A')
2679
+ sage: A.rename('A')
2680
+ sage: B = CombinatorialFreeModule(ZZ, [3,4], prefix='B')
2681
+ sage: B.rename('B')
2682
+
2683
+ and `f` the bilinear morphism `(a,b) \mapsto b \otimes a`
2684
+ from `A \times B` to `B \otimes A`::
2685
+
2686
+ sage: def f(a, b):
2687
+ ....: return tensor([b,a])
2688
+
2689
+ Now, calling applying `f` on `a \otimes b` returns the same
2690
+ as `f(a,b)`::
2691
+
2692
+ sage: # needs sage.modules
2693
+ sage: a = A.monomial(1) + 2 * A.monomial(2); a
2694
+ A[1] + 2*A[2]
2695
+ sage: b = B.monomial(3) - 2 * B.monomial(4); b
2696
+ B[3] - 2*B[4]
2697
+ sage: f(a, b)
2698
+ B[3] # A[1] + 2*B[3] # A[2] - 2*B[4] # A[1] - 4*B[4] # A[2]
2699
+ sage: tensor([a, b]).apply_multilinear_morphism(f)
2700
+ B[3] # A[1] + 2*B[3] # A[2] - 2*B[4] # A[1] - 4*B[4] # A[2]
2701
+
2702
+ `f` may be a bilinear morphism to any module over the
2703
+ base ring of `A` and `B`. Here the codomain is `\ZZ`::
2704
+
2705
+ sage: def f(a, b):
2706
+ ....: return sum(a.coefficients(), 0) * sum(b.coefficients(), 0)
2707
+ sage: f(a, b) # needs sage.modules
2708
+ -3
2709
+ sage: tensor([a, b]).apply_multilinear_morphism(f) # needs sage.modules
2710
+ -3
2711
+
2712
+ Mind the `0` in the sums above; otherwise `f` would
2713
+ not return `0` in `\ZZ`::
2714
+
2715
+ sage: def f(a, b):
2716
+ ....: return sum(a.coefficients()) * sum(b.coefficients())
2717
+ sage: type(f(A.zero(), B.zero())) # needs sage.modules
2718
+ <... 'int'>
2719
+
2720
+ Which would be wrong and break this method::
2721
+
2722
+ sage: tensor([a, b]).apply_multilinear_morphism(f) # needs sage.modules
2723
+ Traceback (most recent call last):
2724
+ ...
2725
+ AttributeError: 'int' object has no attribute 'parent'...
2726
+
2727
+ Here we consider an example where the codomain is a
2728
+ module with basis with a different base ring::
2729
+
2730
+ sage: # needs sage.modules
2731
+ sage: C = CombinatorialFreeModule(QQ, [(1,3),(2,4)], prefix='C')
2732
+ sage: C.rename('C')
2733
+ sage: def f(a, b):
2734
+ ....: return C.sum_of_terms([((1,3), QQ(a[1]*b[3])),
2735
+ ....: ((2,4), QQ(a[2]*b[4]))])
2736
+ sage: f(a,b)
2737
+ C[(1, 3)] - 4*C[(2, 4)]
2738
+ sage: tensor([a, b]).apply_multilinear_morphism(f)
2739
+ C[(1, 3)] - 4*C[(2, 4)]
2740
+
2741
+ We conclude with a real life application, where we
2742
+ check that the antipode of the Hopf algebra of
2743
+ Symmetric functions on the Schur basis satisfies its
2744
+ defining formula::
2745
+
2746
+ sage: # needs lrcalc_python sage.combinat sage.modules
2747
+ sage: Sym = SymmetricFunctions(QQ)
2748
+ sage: s = Sym.schur()
2749
+ sage: def f(a, b): return a * b.antipode()
2750
+ sage: x = 4 * s.an_element(); x
2751
+ 8*s[] + 8*s[1] + 12*s[2]
2752
+ sage: x.coproduct().apply_multilinear_morphism(f)
2753
+ 8*s[]
2754
+ sage: x.coproduct().apply_multilinear_morphism(f) == x.counit()
2755
+ True
2756
+
2757
+ We recover the constant term of `x`, as desired.
2758
+
2759
+ .. TODO::
2760
+
2761
+ Extract a method to linearize a multilinear
2762
+ morphism, and delegate the work there.
2763
+ """
2764
+ K = self.parent().base_ring()
2765
+ modules = self.parent()._sets
2766
+ if codomain is None:
2767
+ try:
2768
+ codomain = f.codomain()
2769
+ except AttributeError:
2770
+ codomain = f(*[module.zero() for module in modules]).parent()
2771
+ if codomain in ModulesWithBasis(K):
2772
+ return codomain.linear_combination((f(*[module.monomial(t)
2773
+ for module, t in zip(modules, m)]), c)
2774
+ for m, c in self.items())
2775
+ else:
2776
+ return sum((c * f(*[module.monomial(t)
2777
+ for module, t in zip(modules, m)])
2778
+ for m, c in self.items()),
2779
+ codomain.zero())
2780
+
2781
+ class DualObjects(DualObjectsCategory):
2782
+
2783
+ @cached_method
2784
+ def extra_super_categories(self):
2785
+ """
2786
+ EXAMPLES::
2787
+
2788
+ sage: ModulesWithBasis(ZZ).DualObjects().extra_super_categories()
2789
+ [Category of modules over Integer Ring]
2790
+ sage: ModulesWithBasis(QQ).DualObjects().super_categories()
2791
+ [Category of duals of vector spaces over Rational Field,
2792
+ Category of duals of modules with basis over Rational Field]
2793
+ """
2794
+ return [Modules(self.base_category().base_ring())]