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