passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,2192 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Integer compositions
4
+
5
+ A composition `c` of a nonnegative integer `n` is a list of positive integers
6
+ (the *parts* of the composition) with total sum `n`.
7
+
8
+ This module provides tools for manipulating compositions and enumerated
9
+ sets of compositions.
10
+
11
+ EXAMPLES::
12
+
13
+ sage: Composition([5, 3, 1, 3])
14
+ [5, 3, 1, 3]
15
+ sage: list(Compositions(4))
16
+ [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]
17
+
18
+ AUTHORS:
19
+
20
+ - Mike Hansen, Nicolas M. Thiéry
21
+ - MuPAD-Combinat developers (algorithms and design inspiration)
22
+ - Travis Scrimshaw (2013-02-03): Removed ``CombinatorialClass``
23
+ """
24
+ # ****************************************************************************
25
+ # Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>
26
+ # 2009 Nicolas M. Thiery <nthiery at users.sf.net>
27
+ #
28
+ # Distributed under the terms of the GNU General Public License (GPL)
29
+ # https://www.gnu.org/licenses/
30
+ # ****************************************************************************
31
+ from __future__ import annotations
32
+ from itertools import accumulate
33
+ from collections.abc import Sequence
34
+
35
+ from sage.categories.enumerated_sets import EnumeratedSets
36
+ from sage.categories.additive_monoids import AdditiveMonoids
37
+ from sage.structure.unique_representation import UniqueRepresentation
38
+ from sage.structure.parent import Parent
39
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
40
+ from sage.rings.integer_ring import ZZ
41
+ from .combinat import CombinatorialElement
42
+ from sage.categories.cartesian_product import cartesian_product
43
+
44
+ from .integer_lists import IntegerListsLex
45
+ from sage.rings.integer import Integer
46
+ from sage.combinat.combinatorial_map import combinatorial_map
47
+ from sage.misc.persist import register_unpickle_override
48
+
49
+ from sage.misc.lazy_import import lazy_import
50
+ lazy_import("sage.combinat.partition", "Partition")
51
+
52
+
53
+ class Composition(CombinatorialElement):
54
+ r"""
55
+ Integer compositions.
56
+
57
+ A composition of a nonnegative integer `n` is a list
58
+ `(i_1, \ldots, i_k)` of positive integers with total sum `n`.
59
+
60
+ EXAMPLES:
61
+
62
+ The simplest way to create a composition is by specifying its
63
+ entries as a list, tuple (or other iterable)::
64
+
65
+ sage: Composition([3,1,2])
66
+ [3, 1, 2]
67
+ sage: Composition((3,1,2))
68
+ [3, 1, 2]
69
+ sage: Composition(i for i in range(2,5))
70
+ [2, 3, 4]
71
+
72
+ You can also create a composition from its code. The *code* of
73
+ a composition `(i_1, i_2, \ldots, i_k)` of `n` is a list of length `n`
74
+ that consists of a `1` followed by `i_1-1` zeros, then a `1` followed
75
+ by `i_2-1` zeros, and so on.
76
+
77
+ ::
78
+
79
+ sage: Composition([4,1,2,3,5]).to_code()
80
+ [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
81
+ sage: Composition(code=_)
82
+ [4, 1, 2, 3, 5]
83
+ sage: Composition([3,1,2,3,5]).to_code()
84
+ [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
85
+ sage: Composition(code=_)
86
+ [3, 1, 2, 3, 5]
87
+
88
+ You can also create the composition of `n` corresponding to a subset of
89
+ `\{1, 2, \ldots, n-1\}` under the bijection that maps the composition
90
+ `(i_1, i_2, \ldots, i_k)` of `n` to the subset
91
+ `\{i_1, i_1 + i_2, i_1 + i_2 + i_3, \ldots, i_1 + \cdots + i_{k-1}\}`
92
+ (see :meth:`to_subset`)::
93
+
94
+ sage: Composition(from_subset=({1, 2, 4}, 5))
95
+ [1, 1, 2, 1]
96
+ sage: Composition([1, 1, 2, 1]).to_subset()
97
+ {1, 2, 4}
98
+
99
+ The following notation equivalently specifies the composition from the
100
+ set `\{i_1 - 1, i_1 + i_2 - 1, i_1 + i_2 + i_3 - 1, \dots, i_1 + \cdots
101
+ + i_{k-1} - 1, n-1\}` or `\{i_1 - 1, i_1 + i_2 - 1, i_1 + i_2 + i_3
102
+ - 1, \dots, i_1 + \cdots + i_{k-1} - 1\}` and `n`. This provides
103
+ compatibility with Python's `0`-indexing.
104
+
105
+ ::
106
+
107
+ sage: Composition(descents=[1,0,4,8,11])
108
+ [1, 1, 3, 4, 3]
109
+ sage: Composition(descents=[0,1,3,4])
110
+ [1, 1, 2, 1]
111
+ sage: Composition(descents=([0,1,3],5))
112
+ [1, 1, 2, 1]
113
+ sage: Composition(descents=({0,1,3},5))
114
+ [1, 1, 2, 1]
115
+
116
+ An integer composition may be regarded as a sequence. Thus it is an
117
+ instance of the Python abstract base class ``Sequence`` allows us to check if objects
118
+ behave "like" sequences based on implemented methods. Note that
119
+ ``collections.abc.Sequence`` is not the same as
120
+ :class:`sage.structure.sequence.Sequence`::
121
+
122
+ sage: import collections.abc
123
+ sage: C = Composition([3,2,3])
124
+ sage: isinstance(C, collections.abc.Sequence)
125
+ True
126
+ sage: issubclass(C.__class__, collections.abc.Sequence)
127
+ True
128
+
129
+ Typically, instances of ``collections.abc.Sequence`` have a ``.count`` method.
130
+ ``Composition.count`` counts the number of parts of a specified size::
131
+
132
+ sage: C.count(3)
133
+ 2
134
+
135
+ EXAMPLES::
136
+
137
+ sage: C = Composition([3,1,2])
138
+ sage: TestSuite(C).run()
139
+ """
140
+ @staticmethod
141
+ def __classcall_private__(cls, co=None, descents=None, code=None, from_subset=None):
142
+ """
143
+ This constructs a list from optional arguments and delegates the
144
+ construction of a :class:`Composition` to the ``element_class()`` call
145
+ of the appropriate parent.
146
+
147
+ EXAMPLES::
148
+
149
+ sage: Composition([3,2,1])
150
+ [3, 2, 1]
151
+ sage: Composition(from_subset=({1, 2, 4}, 5))
152
+ [1, 1, 2, 1]
153
+ sage: Composition(descents=[1,0,4,8,11])
154
+ [1, 1, 3, 4, 3]
155
+ sage: Composition([4,1,2,3,5]).to_code()
156
+ [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
157
+ sage: Composition(code=_)
158
+ [4, 1, 2, 3, 5]
159
+
160
+ TESTS:
161
+
162
+ Let us check that :issue:`14862` is solved::
163
+
164
+ sage: C = Compositions()
165
+ sage: C([3,-1,1])
166
+ Traceback (most recent call last):
167
+ ...
168
+ ValueError: not a composition
169
+ sage: C("strawberry")
170
+ Traceback (most recent call last):
171
+ ...
172
+ ValueError: not a composition
173
+ """
174
+ if descents is not None:
175
+ if isinstance(descents, tuple):
176
+ return Compositions().from_descents(descents[0],
177
+ nps=descents[1])
178
+ else:
179
+ return Compositions().from_descents(descents)
180
+ elif code is not None:
181
+ return Compositions().from_code(code)
182
+ elif from_subset is not None:
183
+ return Compositions().from_subset(*from_subset)
184
+ elif isinstance(co, Composition):
185
+ return co
186
+
187
+ return Compositions()(co)
188
+
189
+ def __init__(self, parent, lst):
190
+ """
191
+ Initialize ``self``.
192
+
193
+ EXAMPLES::
194
+
195
+ sage: C = Composition([3,1,2])
196
+ sage: TestSuite(C).run()
197
+ """
198
+ lst = [Integer(u) for u in lst]
199
+ if not all(u >= 0 for u in lst):
200
+ raise ValueError("elements must be nonnegative integers")
201
+ CombinatorialElement.__init__(self, parent, lst)
202
+
203
+ def _ascii_art_(self):
204
+ """
205
+ TESTS::
206
+
207
+ sage: # needs sage.combinat
208
+ sage: ascii_art(Compositions(4).list())
209
+ [ * ]
210
+ [ * ** * * ]
211
+ [ * * ** *** * ** * ]
212
+ [ *, * , * , * , **, ** , ***, **** ]
213
+ sage: Partitions.options(diagram_str='#', convention='French')
214
+ sage: ascii_art(Compositions(4).list())
215
+ [ # ]
216
+ [ # # # ## ]
217
+ [ # # ## # # ## ### ]
218
+ [ #, ##, #, ###, #, ##, #, #### ]
219
+ sage: Partitions.options._reset()
220
+ """
221
+ from sage.typeset.ascii_art import ascii_art
222
+ return ascii_art(self.to_skew_partition())
223
+
224
+ def _unicode_art_(self):
225
+ """
226
+ TESTS::
227
+
228
+ sage: # needs sage.combinat
229
+ sage: unicode_art(Compositions(4).list())
230
+ ⎡ ┌┐ ⎤
231
+ ⎢ ├┤ ┌┬┐ ┌┐ ┌┐ ⎥
232
+ ⎢ ├┤ ├┼┘ ┌┼┤ ┌┬┬┐ ├┤ ┌┬┐ ┌┐ ⎥
233
+ ⎢ ├┤ ├┤ ├┼┘ ├┼┴┘ ┌┼┤ ┌┼┼┘ ┌┬┼┤ ┌┬┬┬┐ ⎥
234
+ ⎣ └┘, └┘ , └┘ , └┘ , └┴┘, └┴┘ , └┴┴┘, └┴┴┴┘ ⎦
235
+ sage: Partitions.options(diagram_str='#', convention='French')
236
+ sage: unicode_art(Compositions(4).list())
237
+ ⎡ ┌┐ ⎤
238
+ ⎢ ├┤ ┌┐ ┌┐ ┌┬┐ ⎥
239
+ ⎢ ├┤ ├┤ ├┼┐ ┌┐ └┼┤ ┌┬┐ ┌┬┬┐ ⎥
240
+ ⎢ ├┤ ├┼┐ └┼┤ ├┼┬┐ ├┤ └┼┼┐ └┴┼┤ ┌┬┬┬┐ ⎥
241
+ ⎣ └┘, └┴┘, └┘, └┴┴┘, └┘, └┴┘, └┘, └┴┴┴┘ ⎦
242
+ sage: Partitions.options._reset()
243
+ """
244
+ from sage.typeset.unicode_art import unicode_art
245
+ return unicode_art(self.to_skew_partition())
246
+
247
+ def __setstate__(self, state):
248
+ r"""
249
+ In order to maintain backwards compatibility and be able to unpickle a
250
+ old pickle from ``Composition_class`` we have to override the default
251
+ ``__setstate__``.
252
+
253
+ EXAMPLES::
254
+
255
+ sage: loads(b"x\x9ck`J.NLO\xd5K\xce\xcfM\xca\xccK,\x011\n\xf2\x8b3K2\xf3\xf3\xb8\x9c\x11\xec\xf8\xe4\x9c\xc4\xe2b\xaeBF\xcd\xc6B\xa6\xdaBf\x8dP\xd6\xf8\x8c\xc4\xe2\x8cB\x16? +'\xb3\xb8\xa4\x905\xb6\x90M\x03bZQf^z\xb1^f^Ijzj\x11Wnbvj<\x8cS\xc8\x1e\xcah\xd8\x1aT\xc8\x91\x01d\x18\x01\x19\x9c\x19P\x11\xae\xd4\xd2$=\x00eW0g")
256
+ [1, 2, 1]
257
+ sage: loads(dumps( Composition([1,2,1]) )) # indirect doctest
258
+ [1, 2, 1]
259
+ """
260
+ if isinstance(state, dict): # for old pickles from Composition_class
261
+ self._set_parent(Compositions())
262
+ self.__dict__ = state
263
+ else:
264
+ self._set_parent(state[0])
265
+ self.__dict__ = state[1]
266
+
267
+ @combinatorial_map(order=2, name='conjugate')
268
+ def conjugate(self) -> Composition:
269
+ r"""
270
+ Return the conjugate of the composition ``self``.
271
+
272
+ The conjugate of a composition `I` is defined as the
273
+ complement (see :meth:`complement`) of the reverse composition
274
+ (see :meth:`reversed`) of `I`.
275
+
276
+ An equivalent definition of the conjugate goes by saying that
277
+ the ribbon shape of the conjugate of a composition `I` is the
278
+ conjugate of the ribbon shape of `I`. (The ribbon shape of a
279
+ composition is returned by :meth:`to_skew_partition`.)
280
+
281
+ This implementation uses the algorithm from mupad-combinat.
282
+
283
+ EXAMPLES::
284
+
285
+ sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate()
286
+ [1, 1, 3, 3, 1, 3]
287
+
288
+ The ribbon shape of the conjugate of `I` is the conjugate of
289
+ the ribbon shape of `I`::
290
+
291
+ sage: all( I.conjugate().to_skew_partition() # needs sage.combinat
292
+ ....: == I.to_skew_partition().conjugate()
293
+ ....: for I in Compositions(4) )
294
+ True
295
+
296
+ TESTS::
297
+
298
+ sage: parent(list(Compositions(1))[0].conjugate())
299
+ Compositions of 1
300
+ sage: parent(list(Compositions(0))[0].conjugate())
301
+ Compositions of 0
302
+ """
303
+ comp = self
304
+ if not comp:
305
+ return self
306
+ n = len(comp)
307
+ coofcp = [sigmaj - j for j, sigmaj in enumerate(accumulate(comp))]
308
+
309
+ cocjg = []
310
+ for i in range(n - 1):
311
+ ni = n - i
312
+ cocjg += [i + 1 for _ in range(coofcp[ni - 1] - coofcp[ni - 2])]
313
+ cocjg += [n for j in range(coofcp[0])]
314
+
315
+ return self.parent()([cocjg[0]] + [cocjg[i] - cocjg[i - 1] + 1
316
+ for i in range(1, len(cocjg))])
317
+
318
+ @combinatorial_map(order=2, name='reversed')
319
+ def reversed(self) -> Composition:
320
+ r"""
321
+ Return the reverse composition of ``self``.
322
+
323
+ The reverse composition of a composition `(i_1, i_2, \ldots, i_k)`
324
+ is defined as the composition `(i_k, i_{k-1}, \ldots, i_1)`.
325
+
326
+ EXAMPLES::
327
+
328
+ sage: Composition([1, 1, 3, 1, 2, 1, 3]).reversed()
329
+ [3, 1, 2, 1, 3, 1, 1]
330
+ """
331
+ return self.parent()(reversed(self))
332
+
333
+ @combinatorial_map(order=2, name='complement')
334
+ def complement(self) -> Composition:
335
+ r"""
336
+ Return the complement of the composition ``self``.
337
+
338
+ The complement of a composition `I` is defined as follows:
339
+
340
+ If `I` is the empty composition, then the complement is the empty
341
+ composition as well. Otherwise, let `S` be the descent set of `I`
342
+ (that is, the subset
343
+ `\{ i_1, i_1 + i_2, \ldots, i_1 + i_2 + \cdots + i_{k-1} \}`
344
+ of `\{ 1, 2, \ldots, |I|-1 \}`, where `I` is written as
345
+ `(i_1, i_2, \ldots, i_k)`). Then, the complement of `I` is
346
+ defined as the composition of size `|I|` whose descent set is
347
+ `\{ 1, 2, \ldots, |I|-1 \} \setminus S`.
348
+
349
+ The complement of a composition `I` also is the reverse
350
+ composition (:meth:`reversed`) of the conjugate
351
+ (:meth:`conjugate`) of `I`.
352
+
353
+ EXAMPLES::
354
+
355
+ sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate()
356
+ [1, 1, 3, 3, 1, 3]
357
+ sage: Composition([1, 1, 3, 1, 2, 1, 3]).complement()
358
+ [3, 1, 3, 3, 1, 1]
359
+ """
360
+ return self.conjugate().reversed()
361
+
362
+ def __add__(self, other) -> Composition:
363
+ """
364
+ Return the concatenation of two compositions.
365
+
366
+ EXAMPLES::
367
+
368
+ sage: Composition([1, 1, 3]) + Composition([4, 1, 2])
369
+ [1, 1, 3, 4, 1, 2]
370
+
371
+ TESTS::
372
+
373
+ sage: Composition([]) + Composition([]) == Composition([])
374
+ True
375
+ """
376
+ return Compositions()(list(self) + list(other))
377
+
378
+ def size(self) -> int:
379
+ """
380
+ Return the size of ``self``, that is the sum of its parts.
381
+
382
+ EXAMPLES::
383
+
384
+ sage: Composition([7,1,3]).size()
385
+ 11
386
+ """
387
+ return sum(self)
388
+
389
+ @staticmethod
390
+ def sum(compositions) -> Composition:
391
+ """
392
+ Return the concatenation of the given compositions.
393
+
394
+ INPUT:
395
+
396
+ - ``compositions`` -- list (or iterable) of compositions
397
+
398
+ EXAMPLES::
399
+
400
+ sage: Composition.sum([Composition([1, 1, 3]), Composition([4, 1, 2]), Composition([3,1])])
401
+ [1, 1, 3, 4, 1, 2, 3, 1]
402
+
403
+ Any iterable can be provided as input::
404
+
405
+ sage: Composition.sum([Composition([i,i]) for i in [4,1,3]])
406
+ [4, 4, 1, 1, 3, 3]
407
+
408
+ Empty inputs are handled gracefully::
409
+
410
+ sage: Composition.sum([]) == Composition([])
411
+ True
412
+ """
413
+ return sum(compositions, Compositions()([]))
414
+
415
+ def near_concatenation(self, other):
416
+ r"""
417
+ Return the near-concatenation of two nonempty compositions
418
+ ``self`` and ``other``.
419
+
420
+ The near-concatenation `I \odot J` of two nonempty compositions
421
+ `I` and `J` is defined as the composition
422
+ `(i_1, i_2, \ldots , i_{n-1}, i_n + j_1, j_2, j_3, \ldots , j_m)`,
423
+ where `(i_1, i_2, \ldots , i_n) = I` and
424
+ `(j_1, j_2, \ldots , j_m) = J`.
425
+
426
+ This method returns ``None`` if one of the two input
427
+ compositions is empty.
428
+
429
+ EXAMPLES::
430
+
431
+ sage: Composition([1, 1, 3]).near_concatenation(Composition([4, 1, 2]))
432
+ [1, 1, 7, 1, 2]
433
+ sage: Composition([6]).near_concatenation(Composition([1, 5]))
434
+ [7, 5]
435
+ sage: Composition([1, 5]).near_concatenation(Composition([6]))
436
+ [1, 11]
437
+
438
+ TESTS::
439
+
440
+ sage: Composition([]).near_concatenation(Composition([]))
441
+ <BLANKLINE>
442
+ sage: Composition([]).near_concatenation(Composition([2, 1]))
443
+ <BLANKLINE>
444
+ sage: Composition([3, 2]).near_concatenation(Composition([]))
445
+ <BLANKLINE>
446
+ """
447
+ if not self or not other:
448
+ return None
449
+ return Compositions()(list(self)[:-1] + [self[-1] + other[0]] + list(other)[1:])
450
+
451
+ def ribbon_decomposition(self, other, check=True):
452
+ r"""
453
+ Return a pair describing the ribbon decomposition of a composition
454
+ ``self`` with respect to a composition ``other`` of the same size.
455
+
456
+ If `I` and `J` are two compositions of the same nonzero size, then
457
+ the ribbon decomposition of `I` with respect to `J` is defined as
458
+ follows: Write `I` and `J` as `I = (i_1, i_2, \ldots , i_n)` and
459
+ `J = (j_1, j_2, \ldots , j_m)`. Then, the equality
460
+ `I = I_1 \bullet I_2 \bullet \ldots \bullet I_m` holds for a
461
+ unique `m`-tuple `(I_1, I_2, \ldots , I_m)` of compositions such
462
+ that each `I_k` has size `j_k` and for a unique choice of `m-1`
463
+ signs `\bullet` each of which is either the concatenation sign
464
+ `\cdot` or the near-concatenation sign `\odot` (see
465
+ :meth:`__add__` and :meth:`near_concatenation` for the definitions
466
+ of these two signs). This `m`-tuple and this choice of signs
467
+ together are said to form the ribbon decomposition of `I` with
468
+ respect to `J`. If `I` and `J` are empty, then the same definition
469
+ applies, except that there are `0` rather than `m-1` signs.
470
+
471
+ See Section 4.8 of [NCSF1]_.
472
+
473
+ INPUT:
474
+
475
+ - ``other`` -- composition of same size as ``self``
476
+
477
+ - ``check`` -- boolean (default: ``True``); whether to check the input
478
+ compositions for having the same size
479
+
480
+ OUTPUT:
481
+
482
+ - a pair ``(u, v)``, where ``u`` is a tuple of compositions
483
+ (corresponding to the `m`-tuple `(I_1, I_2, \ldots , I_m)` in
484
+ the above definition), and ``v`` is a tuple of `0`s and `1`s
485
+ (encoding the choice of signs `\bullet` in the above definition,
486
+ with a `0` standing for `\cdot` and a `1` standing for `\odot`).
487
+
488
+ EXAMPLES::
489
+
490
+ sage: Composition([3, 1, 1, 3, 1]).ribbon_decomposition([4, 3, 2])
491
+ (([3, 1], [1, 2], [1, 1]), (0, 1))
492
+ sage: Composition([9, 6]).ribbon_decomposition([1, 3, 6, 3, 2])
493
+ (([1], [3], [5, 1], [3], [2]), (1, 1, 1, 1))
494
+ sage: Composition([9, 6]).ribbon_decomposition([1, 3, 5, 1, 3, 2])
495
+ (([1], [3], [5], [1], [3], [2]), (1, 1, 0, 1, 1))
496
+ sage: Composition([1, 1, 1, 1, 1]).ribbon_decomposition([3, 2])
497
+ (([1, 1, 1], [1, 1]), (0,))
498
+ sage: Composition([4, 2]).ribbon_decomposition([6])
499
+ (([4, 2],), ())
500
+ sage: Composition([]).ribbon_decomposition([])
501
+ ((), ())
502
+
503
+ Let us check that the defining property
504
+ `I = I_1 \bullet I_2 \bullet \ldots \bullet I_m` is satisfied::
505
+
506
+ sage: def compose_back(u, v):
507
+ ....: comp = u[0]
508
+ ....: r = len(v)
509
+ ....: if len(u) != r + 1:
510
+ ....: raise ValueError("something is wrong")
511
+ ....: for i in range(r):
512
+ ....: if v[i] == 0:
513
+ ....: comp += u[i + 1]
514
+ ....: else:
515
+ ....: comp = comp.near_concatenation(u[i + 1])
516
+ ....: return comp
517
+ sage: all( all( all( compose_back(*(I.ribbon_decomposition(J))) == I
518
+ ....: for J in Compositions(n) )
519
+ ....: for I in Compositions(n) )
520
+ ....: for n in range(1, 5) )
521
+ True
522
+
523
+ TESTS::
524
+
525
+ sage: Composition([3, 1, 1, 3, 1]).ribbon_decomposition([4, 3, 1])
526
+ Traceback (most recent call last):
527
+ ...
528
+ ValueError: [3, 1, 1, 3, 1] is not the same size as [4, 3, 1]
529
+
530
+ AUTHORS:
531
+
532
+ - Darij Grinberg (2013-08-29)
533
+ """
534
+ # Speaking in terms of the definition in the docstring, we have
535
+ # I = self and J = other.
536
+
537
+ if check and (sum(self) != sum(other)):
538
+ raise ValueError("{} is not the same size as {}".format(self, other))
539
+
540
+ factors = []
541
+ signs = []
542
+
543
+ I_iter = iter(self)
544
+ i = 0
545
+ for j in other:
546
+ current_factor = []
547
+ current_factor_size = 0
548
+ while True:
549
+ if i == 0:
550
+ try:
551
+ i = next(I_iter)
552
+ except StopIteration:
553
+ factors.append(Compositions()(current_factor))
554
+ return (tuple(factors), tuple(signs))
555
+ if current_factor_size + i <= j:
556
+ current_factor.append(i)
557
+ current_factor_size += i
558
+ i = 0
559
+ else:
560
+ if j == current_factor_size:
561
+ signs.append(0)
562
+ else:
563
+ current_factor.append(j - current_factor_size)
564
+ i -= j - current_factor_size
565
+ signs.append(1)
566
+ factors.append(Compositions()(current_factor))
567
+ break
568
+
569
+ return (tuple(factors), tuple(signs))
570
+
571
+ def join(self, other, check=True) -> Composition:
572
+ r"""
573
+ Return the join of ``self`` with a composition ``other`` of the
574
+ same size.
575
+
576
+ The join of two compositions `I` and `J` of size `n` is the
577
+ coarsest composition of `n` which refines each of `I` and `J`. It
578
+ can be described as the composition whose descent set is the
579
+ union of the descent sets of `I` and `J`. It is also the
580
+ concatenation of `I_1, I_2, \cdots , I_m`, where
581
+ `I = I_1 \bullet I_2 \bullet \ldots \bullet I_m` is the ribbon
582
+ decomposition of `I` with respect to `J` (see
583
+ :meth:`ribbon_decomposition`).
584
+
585
+ INPUT:
586
+
587
+ - ``other`` -- composition of same size as ``self``
588
+
589
+ - ``check`` -- boolean (default: ``True``); whether to check the input
590
+ compositions for having the same size
591
+
592
+ OUTPUT: the join of the compositions ``self`` and ``other``
593
+
594
+ EXAMPLES::
595
+
596
+ sage: Composition([3, 1, 1, 3, 1]).join([4, 3, 2])
597
+ [3, 1, 1, 2, 1, 1]
598
+ sage: Composition([9, 6]).join([1, 3, 6, 3, 2])
599
+ [1, 3, 5, 1, 3, 2]
600
+ sage: Composition([9, 6]).join([1, 3, 5, 1, 3, 2])
601
+ [1, 3, 5, 1, 3, 2]
602
+ sage: Composition([1, 1, 1, 1, 1]).join([3, 2])
603
+ [1, 1, 1, 1, 1]
604
+ sage: Composition([4, 2]).join([3, 3])
605
+ [3, 1, 2]
606
+ sage: Composition([]).join([])
607
+ []
608
+
609
+ Let us verify on small examples that the join
610
+ of `I` and `J` refines both of `I` and `J`::
611
+
612
+ sage: all( all( I.join(J).is_finer(I) and
613
+ ....: I.join(J).is_finer(J)
614
+ ....: for J in Compositions(4) )
615
+ ....: for I in Compositions(4) )
616
+ True
617
+
618
+ and is the coarsest composition to do so::
619
+
620
+ sage: all( all( all( K.is_finer(I.join(J))
621
+ ....: for K in I.finer()
622
+ ....: if K.is_finer(J) )
623
+ ....: for J in Compositions(3) )
624
+ ....: for I in Compositions(3) )
625
+ True
626
+
627
+ Let us check that the join of `I` and `J` is indeed the
628
+ concatenation of `I_1, I_2, \cdots , I_m`, where
629
+ `I = I_1 \bullet I_2 \bullet \ldots \bullet I_m` is the ribbon
630
+ decomposition of `I` with respect to `J`::
631
+
632
+ sage: all( all( Composition.sum(I.ribbon_decomposition(J)[0])
633
+ ....: == I.join(J) for J in Compositions(4) )
634
+ ....: for I in Compositions(4) )
635
+ True
636
+
637
+ Also, the descent set of the join of `I` and `J` is the
638
+ union of the descent sets of `I` and `J`::
639
+
640
+ sage: all( all( I.to_subset().union(J.to_subset())
641
+ ....: == I.join(J).to_subset()
642
+ ....: for J in Compositions(4) )
643
+ ....: for I in Compositions(4) )
644
+ True
645
+
646
+ TESTS::
647
+
648
+ sage: Composition([3, 1, 1, 3, 1]).join([4, 3, 1])
649
+ Traceback (most recent call last):
650
+ ...
651
+ ValueError: [3, 1, 1, 3, 1] is not the same size as [4, 3, 1]
652
+
653
+ .. SEEALSO::
654
+
655
+ :meth:`meet`, :meth:`ribbon_decomposition`
656
+
657
+ AUTHORS:
658
+
659
+ - Darij Grinberg (2013-09-05)
660
+ """
661
+ # The following code is a slimmed down version of the
662
+ # ribbon_decomposition method. It is a lot faster than
663
+ # using to_subset() and from_subset, and also a lot
664
+ # faster than ribbon_decomposition.
665
+
666
+ # Speaking in terms of the definition in the docstring, we have
667
+ # I = self and J = other.
668
+
669
+ if check and (sum(self) != sum(other)):
670
+ raise ValueError("{} is not the same size as {}".format(self, other))
671
+
672
+ factors: list[int] = []
673
+
674
+ I_iter = iter(self)
675
+ i = 0
676
+ for j in other:
677
+ current_factor_size = 0
678
+ while True:
679
+ if i == 0:
680
+ try:
681
+ i = next(I_iter)
682
+ except StopIteration:
683
+ return Compositions()(factors)
684
+ if current_factor_size + i <= j:
685
+ factors.append(i)
686
+ current_factor_size += i
687
+ i = 0
688
+ else:
689
+ if not j == current_factor_size:
690
+ factors.append(j - current_factor_size)
691
+ i -= j - current_factor_size
692
+ break
693
+
694
+ return self.parent()(factors)
695
+
696
+ sup = join
697
+
698
+ def meet(self, other, check=True) -> Composition:
699
+ r"""
700
+ Return the meet of ``self`` with a composition ``other`` of the
701
+ same size.
702
+
703
+ The meet of two compositions `I` and `J` of size `n` is the
704
+ finest composition of `n` which is coarser than each of `I` and
705
+ `J`. It can be described as the composition whose descent set is
706
+ the intersection of the descent sets of `I` and `J`.
707
+
708
+ INPUT:
709
+
710
+ - ``other`` -- composition of same size as ``self``
711
+
712
+ - ``check`` -- boolean (default: ``True``); whether to check the input
713
+ compositions for having the same size
714
+
715
+ OUTPUT: the meet of the compositions ``self`` and ``other``
716
+
717
+ EXAMPLES::
718
+
719
+ sage: Composition([3, 1, 1, 3, 1]).meet([4, 3, 2])
720
+ [4, 5]
721
+ sage: Composition([9, 6]).meet([1, 3, 6, 3, 2])
722
+ [15]
723
+ sage: Composition([9, 6]).meet([1, 3, 5, 1, 3, 2])
724
+ [9, 6]
725
+ sage: Composition([1, 1, 1, 1, 1]).meet([3, 2])
726
+ [3, 2]
727
+ sage: Composition([4, 2]).meet([3, 3])
728
+ [6]
729
+ sage: Composition([]).meet([])
730
+ []
731
+ sage: Composition([1]).meet([1])
732
+ [1]
733
+
734
+ Let us verify on small examples that the meet
735
+ of `I` and `J` is coarser than both of `I` and `J`::
736
+
737
+ sage: all( all( I.is_finer(I.meet(J)) and
738
+ ....: J.is_finer(I.meet(J))
739
+ ....: for J in Compositions(4) )
740
+ ....: for I in Compositions(4) )
741
+ True
742
+
743
+ and is the finest composition to do so::
744
+
745
+ sage: all( all( all( I.meet(J).is_finer(K)
746
+ ....: for K in I.fatter()
747
+ ....: if J.is_finer(K) )
748
+ ....: for J in Compositions(3) )
749
+ ....: for I in Compositions(3) )
750
+ True
751
+
752
+ The descent set of the meet of `I` and `J` is the
753
+ intersection of the descent sets of `I` and `J`::
754
+
755
+ sage: def test_meet(n):
756
+ ....: return all( all( I.to_subset().intersection(J.to_subset())
757
+ ....: == I.meet(J).to_subset()
758
+ ....: for J in Compositions(n) )
759
+ ....: for I in Compositions(n) )
760
+ sage: all( test_meet(n) for n in range(1, 5) )
761
+ True
762
+
763
+ TESTS::
764
+
765
+ sage: Composition([3, 1, 1, 3, 1]).meet([4, 3, 1])
766
+ Traceback (most recent call last):
767
+ ...
768
+ ValueError: [3, 1, 1, 3, 1] is not the same size as [4, 3, 1]
769
+
770
+ .. SEEALSO::
771
+
772
+ :meth:`join`
773
+
774
+ AUTHORS:
775
+
776
+ - Darij Grinberg (2013-09-05)
777
+ """
778
+ # The following code is much faster than using to_subset()
779
+ # and from_subset.
780
+
781
+ # Speaking in terms of the definition in the docstring, we have
782
+ # I = self and J = other.
783
+
784
+ if check and (sum(self) != sum(other)):
785
+ raise ValueError("{} is not the same size as {}".format(self, other))
786
+
787
+ factors = []
788
+ current_part = 0
789
+
790
+ I_iter = iter(self)
791
+ i = 0
792
+ for j in other:
793
+ current_factor_size = 0
794
+ while True:
795
+ if i == 0:
796
+ try:
797
+ i = next(I_iter)
798
+ except StopIteration:
799
+ factors.append(current_part)
800
+ return Compositions()(factors)
801
+ if current_factor_size + i <= j:
802
+ current_part += i
803
+ current_factor_size += i
804
+ i = 0
805
+ else:
806
+ if j == current_factor_size:
807
+ factors.append(current_part)
808
+ current_part = 0
809
+ else:
810
+ i -= j - current_factor_size
811
+ current_part += j - current_factor_size
812
+ break
813
+
814
+ return self.parent()(factors)
815
+
816
+ inf = meet
817
+
818
+ def finer(self):
819
+ """
820
+ Return the set of compositions which are finer than ``self``.
821
+
822
+ EXAMPLES::
823
+
824
+ sage: C = Composition([3,2]).finer()
825
+ sage: C.cardinality()
826
+ 8
827
+ sage: C.list()
828
+ [[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 1, 1], [1, 2, 2], [2, 1, 1, 1], [2, 1, 2], [3, 1, 1], [3, 2]]
829
+
830
+ sage: Composition([]).finer()
831
+ {[]}
832
+ """
833
+ if not self:
834
+ return FiniteEnumeratedSet([self])
835
+ else:
836
+ return cartesian_product([Compositions(i) for i in self]).map(Composition.sum)
837
+
838
+ def is_finer(self, co2) -> bool:
839
+ """
840
+ Return ``True`` if the composition ``self`` is finer than the
841
+ composition ``co2``; otherwise, return ``False``.
842
+
843
+ EXAMPLES::
844
+
845
+ sage: Composition([4,1,2]).is_finer([3,1,3])
846
+ False
847
+ sage: Composition([3,1,3]).is_finer([4,1,2])
848
+ False
849
+ sage: Composition([1,2,2,1,1,2]).is_finer([5,1,3])
850
+ True
851
+ sage: Composition([2,2,2]).is_finer([4,2])
852
+ True
853
+ """
854
+ co1 = self
855
+ if sum(co1) != sum(co2):
856
+ raise ValueError("compositions self (= %s) and co2 (= %s) must be of the same size" % (self, co2))
857
+
858
+ sum1 = 0
859
+ sum2 = 0
860
+ i1 = 0
861
+ for j2 in co2:
862
+ sum2 += j2
863
+ while sum1 < sum2:
864
+ sum1 += co1[i1]
865
+ i1 += 1
866
+ if sum1 > sum2:
867
+ return False
868
+
869
+ return True
870
+
871
+ def fatten(self, grouping) -> Composition:
872
+ r"""
873
+ Return the composition fatter than ``self``, obtained by grouping
874
+ together consecutive parts according to ``grouping``.
875
+
876
+ INPUT:
877
+
878
+ - ``grouping`` -- a composition whose sum is the length of ``self``
879
+
880
+ EXAMPLES:
881
+
882
+ Let us start with the composition::
883
+
884
+ sage: c = Composition([4,5,2,7,1])
885
+
886
+ With ``grouping`` equal to `(1, \ldots, 1)`, `c` is left unchanged::
887
+
888
+ sage: c.fatten(Composition([1,1,1,1,1]))
889
+ [4, 5, 2, 7, 1]
890
+
891
+ With ``grouping`` equal to `(\ell)` where `\ell` is the length of
892
+ `c`, this yields the coarsest composition above `c`::
893
+
894
+ sage: c.fatten(Composition([5]))
895
+ [19]
896
+
897
+ Other values for ``grouping`` yield (all the) other compositions
898
+ coarser than `c`::
899
+
900
+ sage: c.fatten(Composition([2,1,2]))
901
+ [9, 2, 8]
902
+ sage: c.fatten(Composition([3,1,1]))
903
+ [11, 7, 1]
904
+
905
+ TESTS::
906
+
907
+ sage: Composition([]).fatten(Composition([]))
908
+ []
909
+ sage: c.fatten(Composition([3,1,1])).__class__ == c.__class__
910
+ True
911
+ """
912
+ parent = self.parent()
913
+ result = [0] * len(grouping)
914
+ j = 0
915
+ for i, gi in enumerate(grouping):
916
+ result[i] = sum(self[j:j + gi])
917
+ j += gi
918
+ return parent(result)
919
+
920
+ def fatter(self):
921
+ """
922
+ Return the set of compositions which are fatter than ``self``.
923
+
924
+ Complexity for generation: `O(|c|)` memory, `O(|r|)` time where `|c|`
925
+ is the size of ``self`` and `r` is the result.
926
+
927
+ EXAMPLES::
928
+
929
+ sage: C = Composition([4,5,2]).fatter()
930
+ sage: C.cardinality()
931
+ 4
932
+ sage: list(C)
933
+ [[4, 5, 2], [4, 7], [9, 2], [11]]
934
+
935
+ Some extreme cases::
936
+
937
+ sage: list(Composition([5]).fatter())
938
+ [[5]]
939
+ sage: list(Composition([]).fatter())
940
+ [[]]
941
+ sage: list(Composition([1,1,1,1]).fatter()) == list(Compositions(4))
942
+ True
943
+ """
944
+ return Compositions(len(self)).map(self.fatten)
945
+
946
+ def refinement_splitting(self, J) -> list[Composition]:
947
+ r"""
948
+ Return the refinement splitting of ``self`` according to ``J``.
949
+
950
+ INPUT:
951
+
952
+ - ``J`` -- a composition such that ``self`` is finer than ``J``
953
+
954
+ OUTPUT:
955
+
956
+ - the unique list of compositions `(I^{(p)})_{p=1, \ldots , m}`,
957
+ obtained by splitting `I`, such that
958
+ `|I^{(p)}| = J_p` for all `p = 1, \ldots, m`.
959
+
960
+ .. SEEALSO::
961
+
962
+ :meth:`refinement_splitting_lengths`
963
+
964
+ EXAMPLES::
965
+
966
+ sage: Composition([1,2,2,1,1,2]).refinement_splitting([5,1,3])
967
+ [[1, 2, 2], [1], [1, 2]]
968
+ sage: Composition([]).refinement_splitting([])
969
+ []
970
+ sage: Composition([3]).refinement_splitting([2])
971
+ Traceback (most recent call last):
972
+ ...
973
+ ValueError: compositions self (= [3]) and J (= [2]) must be of the same size
974
+ sage: Composition([2,1]).refinement_splitting([1,2])
975
+ Traceback (most recent call last):
976
+ ...
977
+ ValueError: composition J (= [2, 1]) does not refine self (= [1, 2])
978
+ """
979
+ I = self
980
+ if sum(I) != sum(J):
981
+ # Error: compositions are not of the same size
982
+ raise ValueError("compositions self (= %s) and J (= %s) must be of the same size" % (I, J))
983
+ sum1 = 0
984
+ sum2 = 0
985
+ i1 = -1
986
+ decomp = []
987
+ for j2 in J:
988
+ new_comp = []
989
+ sum2 += j2
990
+ while sum1 < sum2:
991
+ i1 += 1
992
+ new_comp.append(I[i1])
993
+ sum1 += new_comp[-1]
994
+ if sum1 > sum2:
995
+ raise ValueError("composition J (= %s) does not refine self (= %s)" % (I, J))
996
+ decomp.append(Compositions()(new_comp))
997
+ return decomp
998
+
999
+ def refinement_splitting_lengths(self, J):
1000
+ """
1001
+ Return the lengths of the compositions in the refinement splitting of
1002
+ ``self`` according to ``J``.
1003
+
1004
+ .. SEEALSO::
1005
+
1006
+ :meth:`refinement_splitting` for the definition of refinement splitting
1007
+
1008
+ EXAMPLES::
1009
+
1010
+ sage: Composition([1,2,2,1,1,2]).refinement_splitting_lengths([5,1,3])
1011
+ [3, 1, 2]
1012
+ sage: Composition([]).refinement_splitting_lengths([])
1013
+ []
1014
+ sage: Composition([3]).refinement_splitting_lengths([2])
1015
+ Traceback (most recent call last):
1016
+ ...
1017
+ ValueError: compositions self (= [3]) and J (= [2]) must be of the same size
1018
+ sage: Composition([2,1]).refinement_splitting_lengths([1,2])
1019
+ Traceback (most recent call last):
1020
+ ...
1021
+ ValueError: composition J (= [2, 1]) does not refine self (= [1, 2])
1022
+ """
1023
+ return Compositions()([len(p) for p in self.refinement_splitting(J)])
1024
+
1025
+ def major_index(self) -> int:
1026
+ """
1027
+ Return the major index of ``self``. The major index is
1028
+ defined as the sum of the descents.
1029
+
1030
+ EXAMPLES::
1031
+
1032
+ sage: Composition([1, 1, 3, 1, 2, 1, 3]).major_index()
1033
+ 31
1034
+ """
1035
+ lv = len(self)
1036
+ if lv == 1:
1037
+ return 0
1038
+ return sum([(lv - (i + 1)) * ci
1039
+ for i, ci in enumerate(self)])
1040
+
1041
+ def to_code(self) -> list:
1042
+ r"""
1043
+ Return the code of the composition ``self``.
1044
+
1045
+ The code of a composition `I` is a list of length
1046
+ `\mathrm{size}(I)` of 1s and 0s such that there is a 1
1047
+ wherever a new part starts. (Exceptional case: When the
1048
+ composition is empty, the code is ``[0]``.)
1049
+
1050
+ EXAMPLES::
1051
+
1052
+ sage: Composition([4,1,2,3,5]).to_code()
1053
+ [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
1054
+
1055
+ TESTS::
1056
+
1057
+ sage: Composition([]).to_code()
1058
+ [0]
1059
+ """
1060
+ if not self:
1061
+ return [0]
1062
+
1063
+ code = []
1064
+ for i in self:
1065
+ code += [1] + [0] * (i - 1)
1066
+
1067
+ return code
1068
+
1069
+ def partial_sums(self, final=True) -> list:
1070
+ r"""
1071
+ The partial sums of the sequence defined by the entries of the
1072
+ composition.
1073
+
1074
+ If `I = (i_1, \ldots, i_m)` is a composition, then the partial sums of
1075
+ the entries of the composition are
1076
+ `[i_1, i_1 + i_2, \ldots, i_1 + i_2 + \cdots + i_m]`.
1077
+
1078
+ INPUT:
1079
+
1080
+ - ``final`` -- boolean (default: ``True``); whether or not to include
1081
+ the final partial sum, which is always the size of the composition
1082
+
1083
+ .. SEEALSO::
1084
+
1085
+ :meth:`to_subset`
1086
+
1087
+ EXAMPLES::
1088
+
1089
+ sage: Composition([1,1,3,1,2,1,3]).partial_sums()
1090
+ [1, 2, 5, 6, 8, 9, 12]
1091
+
1092
+ With ``final = False``, the last partial sum is not included::
1093
+
1094
+ sage: Composition([1,1,3,1,2,1,3]).partial_sums(final=False)
1095
+ [1, 2, 5, 6, 8, 9]
1096
+ """
1097
+ s = 0
1098
+ partial_sums = []
1099
+ for i in self:
1100
+ s += i
1101
+ partial_sums.append(s)
1102
+ if final is False:
1103
+ partial_sums.pop()
1104
+ return partial_sums
1105
+
1106
+ def to_subset(self, final=False):
1107
+ r"""
1108
+ The subset corresponding to ``self`` under the bijection (see below)
1109
+ between compositions of `n` and subsets of `\{1, 2, \ldots, n-1\}`.
1110
+
1111
+ The bijection maps a composition `(i_1, \ldots, i_k)` of `n` to
1112
+ `\{i_1, i_1 + i_2, i_1 + i_2 + i_3, \ldots, i_1 + \cdots + i_{k-1}\}`.
1113
+
1114
+ INPUT:
1115
+
1116
+ - ``final`` -- boolean (default: ``False``); whether or not to include
1117
+ the final partial sum, which is always the size of the composition
1118
+
1119
+ .. SEEALSO::
1120
+
1121
+ :meth:`partial_sums`
1122
+
1123
+ EXAMPLES::
1124
+
1125
+ sage: Composition([1,1,3,1,2,1,3]).to_subset()
1126
+ {1, 2, 5, 6, 8, 9}
1127
+ sage: for I in Compositions(3): print(I.to_subset())
1128
+ {1, 2}
1129
+ {1}
1130
+ {2}
1131
+ {}
1132
+
1133
+ With ``final=True``, the sum of all the elements of the composition is
1134
+ included in the subset::
1135
+
1136
+ sage: Composition([1,1,3,1,2,1,3]).to_subset(final=True)
1137
+ {1, 2, 5, 6, 8, 9, 12}
1138
+
1139
+ TESTS:
1140
+
1141
+ We verify that ``to_subset`` is indeed a bijection for compositions of
1142
+ size `n = 8`::
1143
+
1144
+ sage: n = 8
1145
+ sage: all(Composition(from_subset=(S, n)).to_subset() == S
1146
+ ....: for S in Subsets(n-1))
1147
+ True
1148
+ sage: all(Composition(from_subset=(I.to_subset(), n)) == I
1149
+ ....: for I in Compositions(n))
1150
+ True
1151
+ """
1152
+ from sage.sets.set import Set
1153
+ return Set(self.partial_sums(final=final))
1154
+
1155
+ def descents(self, final_descent=False) -> list:
1156
+ r"""
1157
+ This gives one fewer than the partial sums of the composition.
1158
+
1159
+ This is here to maintain some sort of backward compatibility, even
1160
+ through the original implementation was broken (it gave the wrong
1161
+ answer). The same information can be found in :meth:`partial_sums`.
1162
+
1163
+ .. SEEALSO::
1164
+
1165
+ :meth:`partial_sums`
1166
+
1167
+ INPUT:
1168
+
1169
+ - ``final_descent`` -- boolean (default: ``False``)
1170
+
1171
+ OUTPUT:
1172
+
1173
+ - the list of partial sums of ``self`` with each part
1174
+ decremented by `1`. This includes the sum of all entries when
1175
+ ``final_descent`` is ``True``.
1176
+
1177
+ EXAMPLES::
1178
+
1179
+ sage: c = Composition([2,1,3,2])
1180
+ sage: c.descents()
1181
+ [1, 2, 5]
1182
+ sage: c.descents(final_descent=True)
1183
+ [1, 2, 5, 7]
1184
+ """
1185
+ return [i - 1 for i in self.partial_sums(final=final_descent)]
1186
+
1187
+ def peaks(self) -> list:
1188
+ """
1189
+ Return a list of the peaks of the composition ``self``.
1190
+
1191
+ The peaks of a composition are the descents which do not
1192
+ immediately follow another descent.
1193
+
1194
+ EXAMPLES::
1195
+
1196
+ sage: Composition([1, 1, 3, 1, 2, 1, 3]).peaks()
1197
+ [4, 7]
1198
+ """
1199
+ descents = set(d - 1 for d in self.to_subset(final=True))
1200
+ return [i + 1 for i in range(len(self))
1201
+ if i not in descents and i + 1 in descents]
1202
+
1203
+ @combinatorial_map(name='to partition')
1204
+ def to_partition(self):
1205
+ """
1206
+ Return the partition obtained by sorting ``self`` into decreasing
1207
+ order.
1208
+
1209
+ EXAMPLES::
1210
+
1211
+ sage: Composition([2,1,3]).to_partition() # needs sage.combinat
1212
+ [3, 2, 1]
1213
+ sage: Composition([4,2,2]).to_partition() # needs sage.combinat
1214
+ [4, 2, 2]
1215
+ sage: Composition([]).to_partition() # needs sage.combinat
1216
+ []
1217
+ """
1218
+ return Partition(sorted(self, reverse=True))
1219
+
1220
+ def to_skew_partition(self, overlap=1):
1221
+ """
1222
+ Return the skew partition obtained from ``self``.
1223
+
1224
+ This is a skew partition whose rows have the entries of
1225
+ ``self`` as their length, taken in reverse order (so the first
1226
+ entry of ``self`` is the length of the lowermost row,
1227
+ etc.). The parameter ``overlap`` indicates the number of cells
1228
+ on each row that are directly below cells of the previous
1229
+ row. When it is set to `1` (its default value), the result is
1230
+ the ribbon shape of ``self``.
1231
+
1232
+ EXAMPLES::
1233
+
1234
+ sage: # needs sage.combinat
1235
+ sage: Composition([3,4,1]).to_skew_partition()
1236
+ [6, 6, 3] / [5, 2]
1237
+ sage: Composition([3,4,1]).to_skew_partition(overlap=0)
1238
+ [8, 7, 3] / [7, 3]
1239
+ sage: Composition([]).to_skew_partition()
1240
+ [] / []
1241
+ sage: Composition([1,2]).to_skew_partition()
1242
+ [2, 1] / []
1243
+ sage: Composition([2,1]).to_skew_partition()
1244
+ [2, 2] / [1]
1245
+ """
1246
+ from sage.combinat.skew_partition import SkewPartition
1247
+ outer = []
1248
+ inner = []
1249
+ sum_outer = -overlap
1250
+
1251
+ for k in self[:-1]:
1252
+ outer.append(k + sum_outer + overlap)
1253
+ sum_outer += k - overlap
1254
+ inner.append(sum_outer + overlap)
1255
+
1256
+ if self:
1257
+ outer.append(self[-1] + sum_outer + overlap)
1258
+ else:
1259
+ return SkewPartition([[], []])
1260
+
1261
+ return SkewPartition(
1262
+ [[x for x in reversed(outer) if x != 0],
1263
+ [x for x in reversed(inner) if x != 0]])
1264
+
1265
+ def shuffle_product(self, other, overlap=False):
1266
+ r"""
1267
+ The (overlapping) shuffles of ``self`` and ``other``.
1268
+
1269
+ Suppose `I = (i_1, \ldots, i_k)` and `J = (j_1, \ldots, j_l)` are two
1270
+ compositions. A *shuffle* of `I` and `J` is a composition of length
1271
+ `k + l` that contains both `I` and `J` as subsequences.
1272
+
1273
+ More generally, an *overlapping shuffle* of `I` and `J` is obtained by
1274
+ distributing the elements of `I` and `J` (preserving the relative
1275
+ ordering of these elements) among the positions of an empty list; an
1276
+ element of `I` and an element of `J` are permitted to share the same
1277
+ position, in which case they are replaced by their sum. In particular,
1278
+ a shuffle of `I` and `J` is an overlapping shuffle of `I` and `J`.
1279
+
1280
+ INPUT:
1281
+
1282
+ - ``other`` -- composition
1283
+
1284
+ - ``overlap`` -- boolean (default: ``False``); if ``True``, the
1285
+ overlapping shuffle product is returned
1286
+
1287
+ OUTPUT:
1288
+
1289
+ An enumerated set (allowing for multiplicities)
1290
+
1291
+ EXAMPLES:
1292
+
1293
+ The shuffle product of `[2,2]` and `[1,1,3]`::
1294
+
1295
+ sage: alph = Composition([2,2])
1296
+ sage: beta = Composition([1,1,3])
1297
+ sage: S = alph.shuffle_product(beta); S # needs sage.combinat
1298
+ Shuffle product of [2, 2] and [1, 1, 3]
1299
+ sage: S.list() # needs sage.combinat
1300
+ [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2],
1301
+ [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3],
1302
+ [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]]
1303
+
1304
+ The *overlapping* shuffle product of `[2,2]` and `[1,1,3]`::
1305
+
1306
+ sage: alph = Composition([2,2])
1307
+ sage: beta = Composition([1,1,3])
1308
+ sage: O = alph.shuffle_product(beta, overlap=True); O # needs sage.combinat
1309
+ Overlapping shuffle product of [2, 2] and [1, 1, 3]
1310
+ sage: O.list() # needs sage.combinat
1311
+ [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2],
1312
+ [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3],
1313
+ [1, 1, 2, 3, 2], [1, 1, 3, 2, 2],
1314
+ [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2],
1315
+ [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5],
1316
+ [1, 1, 5, 2], [1, 1, 2, 5],
1317
+ [3, 3, 3], [3, 1, 5], [1, 3, 5]]
1318
+
1319
+ Note that the shuffle product of two compositions can include the same
1320
+ composition more than once since a composition can be a shuffle of two
1321
+ compositions in several ways. For example::
1322
+
1323
+ sage: # needs sage.combinat
1324
+ sage: w1 = Composition([1])
1325
+ sage: S = w1.shuffle_product(w1); S
1326
+ Shuffle product of [1] and [1]
1327
+ sage: S.list()
1328
+ [[1, 1], [1, 1]]
1329
+ sage: O = w1.shuffle_product(w1, overlap=True); O
1330
+ Overlapping shuffle product of [1] and [1]
1331
+ sage: O.list()
1332
+ [[1, 1], [1, 1], [2]]
1333
+
1334
+ TESTS::
1335
+
1336
+ sage: empty = Composition([])
1337
+ sage: empty.shuffle_product(empty).list() # needs sage.combinat
1338
+ [[]]
1339
+ """
1340
+ if overlap:
1341
+ from sage.combinat.shuffle import ShuffleProduct_overlapping
1342
+ return ShuffleProduct_overlapping(self, other,
1343
+ Compositions())
1344
+ else:
1345
+ from sage.combinat.words.shuffle_product import ShuffleProduct_w1w2
1346
+ return ShuffleProduct_w1w2(self, other)
1347
+
1348
+ def wll_gt(self, co2) -> bool:
1349
+ """
1350
+ Return ``True`` if the composition ``self`` is greater than the
1351
+ composition ``co2`` with respect to the wll-ordering; otherwise,
1352
+ return ``False``.
1353
+
1354
+ The wll-ordering is a total order on the set of all compositions
1355
+ defined as follows: A composition `I` is greater than a
1356
+ composition `J` if and only if one of the following conditions
1357
+ holds:
1358
+
1359
+ - The size of `I` is greater than the size of `J`.
1360
+
1361
+ - The size of `I` equals the size of `J`, but the length of `I`
1362
+ is greater than the length of `J`.
1363
+
1364
+ - The size of `I` equals the size of `J`, and the length of `I`
1365
+ equals the length of `J`, but `I` is lexicographically
1366
+ greater than `J`.
1367
+
1368
+ ("wll-ordering" is short for "weight, length, lexicographic
1369
+ ordering".)
1370
+
1371
+ EXAMPLES::
1372
+
1373
+ sage: Composition([4,1,2]).wll_gt([3,1,3])
1374
+ True
1375
+ sage: Composition([7]).wll_gt([4,1,2])
1376
+ False
1377
+ sage: Composition([8]).wll_gt([4,1,2])
1378
+ True
1379
+ sage: Composition([3,2,2,2]).wll_gt([5,2])
1380
+ True
1381
+ sage: Composition([]).wll_gt([3])
1382
+ False
1383
+ sage: Composition([2,1]).wll_gt([2,1])
1384
+ False
1385
+ sage: Composition([2,2,2]).wll_gt([4,2])
1386
+ True
1387
+ sage: Composition([4,2]).wll_gt([2,2,2])
1388
+ False
1389
+ sage: Composition([1,1,2]).wll_gt([2,2])
1390
+ True
1391
+ sage: Composition([2,2]).wll_gt([1,3])
1392
+ True
1393
+ sage: Composition([2,1,2]).wll_gt([])
1394
+ True
1395
+ """
1396
+ co1 = self
1397
+ if sum(co1) > sum(co2):
1398
+ return True
1399
+ elif sum(co1) < sum(co2):
1400
+ return False
1401
+ if len(co1) > len(co2):
1402
+ return True
1403
+ if len(co1) < len(co2):
1404
+ return False
1405
+ for i in range(len(co1)):
1406
+ if co1[i] > co2[i]:
1407
+ return True
1408
+ elif co1[i] < co2[i]:
1409
+ return False
1410
+ return False
1411
+
1412
+ def count(self, n):
1413
+ r"""
1414
+ Return the number of parts of size ``n``.
1415
+
1416
+ EXAMPLES::
1417
+
1418
+ sage: C = Composition([3,2,3])
1419
+ sage: C.count(3)
1420
+ 2
1421
+ sage: C.count(2)
1422
+ 1
1423
+ sage: C.count(1)
1424
+ 0
1425
+ """
1426
+ return sum(i == n for i in self)
1427
+
1428
+ def specht_module(self, base_ring=None):
1429
+ r"""
1430
+ Return the Specht module corresponding to ``self``.
1431
+
1432
+ EXAMPLES::
1433
+
1434
+ sage: SM = Composition([1,2,2]).specht_module(QQ); SM # needs sage.combinat sage.modules
1435
+ Specht module of [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] over Rational Field
1436
+ sage: s = SymmetricFunctions(QQ).s() # needs sage.combinat sage.modules
1437
+ sage: s(SM.frobenius_image()) # needs sage.combinat sage.libs.flint sage.modules
1438
+ s[2, 2, 1]
1439
+ """
1440
+ from sage.combinat.specht_module import SpechtModule
1441
+ from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra
1442
+ if base_ring is None:
1443
+ from sage.rings.rational_field import QQ
1444
+ base_ring = QQ
1445
+ R = SymmetricGroupAlgebra(base_ring, sum(self))
1446
+ cells = [(i, j) for i, row in enumerate(self) for j in range(row)]
1447
+ return SpechtModule(R, cells)
1448
+
1449
+ def specht_module_dimension(self, base_ring=None):
1450
+ r"""
1451
+ Return the dimension of the Specht module corresponding to ``self``.
1452
+
1453
+ INPUT:
1454
+
1455
+ - ``base_ring`` -- (default: `\QQ`) the base ring
1456
+
1457
+ EXAMPLES::
1458
+
1459
+ sage: Composition([1,2,2]).specht_module_dimension() # needs sage.combinat sage.modules
1460
+ 5
1461
+ sage: Composition([1,2,2]).specht_module_dimension(GF(2)) # needs sage.combinat sage.modules sage.rings.finite_rings
1462
+ 5
1463
+ """
1464
+ from sage.combinat.specht_module import specht_module_rank
1465
+ return specht_module_rank(self, base_ring)
1466
+
1467
+
1468
+ Sequence.register(Composition)
1469
+ ##############################################################
1470
+
1471
+
1472
+ class Compositions(UniqueRepresentation, Parent):
1473
+ r"""
1474
+ Set of integer compositions.
1475
+
1476
+ A composition `c` of a nonnegative integer `n` is a list of
1477
+ positive integers with total sum `n`.
1478
+
1479
+ .. SEEALSO::
1480
+
1481
+ - :class:`Composition`
1482
+ - :class:`Partitions`
1483
+ - :class:`IntegerVectors`
1484
+
1485
+ EXAMPLES:
1486
+
1487
+ There are 8 compositions of 4::
1488
+
1489
+ sage: Compositions(4).cardinality()
1490
+ 8
1491
+
1492
+ Here is the list of them::
1493
+
1494
+ sage: Compositions(4).list()
1495
+ [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]
1496
+
1497
+ You can use the ``.first()`` method to get the 'first' composition of
1498
+ a number::
1499
+
1500
+ sage: Compositions(4).first()
1501
+ [1, 1, 1, 1]
1502
+
1503
+ You can also calculate the 'next' composition given the current
1504
+ one::
1505
+
1506
+ sage: Compositions(4).next([1,1,2])
1507
+ [1, 2, 1]
1508
+
1509
+ If `n` is not specified, this returns the combinatorial class of
1510
+ all (nonnegative) integer compositions::
1511
+
1512
+ sage: Compositions()
1513
+ Compositions of nonnegative integers
1514
+ sage: [] in Compositions()
1515
+ True
1516
+ sage: [2,3,1] in Compositions()
1517
+ True
1518
+ sage: [-2,3,1] in Compositions()
1519
+ False
1520
+
1521
+ If `n` is specified, it returns the class of compositions of `n`::
1522
+
1523
+ sage: Compositions(3)
1524
+ Compositions of 3
1525
+ sage: list(Compositions(3))
1526
+ [[1, 1, 1], [1, 2], [2, 1], [3]]
1527
+ sage: Compositions(3).cardinality()
1528
+ 4
1529
+
1530
+ The following examples show how to test whether or not an object
1531
+ is a composition::
1532
+
1533
+ sage: [3,4] in Compositions()
1534
+ True
1535
+ sage: [3,4] in Compositions(7)
1536
+ True
1537
+ sage: [3,4] in Compositions(5)
1538
+ False
1539
+
1540
+ Similarly, one can check whether or not an object is a composition
1541
+ which satisfies further constraints::
1542
+
1543
+ sage: [4,2] in Compositions(6, inner=[2,2])
1544
+ True
1545
+ sage: [4,2] in Compositions(6, inner=[2,3])
1546
+ False
1547
+ sage: [4,1] in Compositions(5, inner=[2,1], max_slope = 0)
1548
+ True
1549
+
1550
+ An example with incompatible constraints::
1551
+
1552
+ sage: [4,2] in Compositions(6, inner=[2,2], min_part=3)
1553
+ False
1554
+
1555
+ The options ``length``, ``min_length``, and ``max_length`` can be used
1556
+ to set length constraints on the compositions. For example, the
1557
+ compositions of 4 of length equal to, at least, and at most 2 are
1558
+ given by::
1559
+
1560
+ sage: Compositions(4, length=2).list()
1561
+ [[3, 1], [2, 2], [1, 3]]
1562
+ sage: Compositions(4, min_length=2).list()
1563
+ [[3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1564
+ sage: Compositions(4, max_length=2).list()
1565
+ [[4], [3, 1], [2, 2], [1, 3]]
1566
+
1567
+ Setting both ``min_length`` and ``max_length`` to the same value is
1568
+ equivalent to setting ``length`` to this value::
1569
+
1570
+ sage: Compositions(4, min_length=2, max_length=2).list()
1571
+ [[3, 1], [2, 2], [1, 3]]
1572
+
1573
+ The options ``inner`` and ``outer`` can be used to set part-by-part
1574
+ containment constraints. The list of compositions of 4 bounded
1575
+ above by ``[3,1,2]`` is given by::
1576
+
1577
+ sage: list(Compositions(4, outer=[3,1,2]))
1578
+ [[3, 1], [2, 1, 1], [1, 1, 2]]
1579
+
1580
+ ``outer`` sets ``max_length`` to the length of its argument. Moreover, the
1581
+ parts of ``outer`` may be infinite to clear the constraint on specific
1582
+ parts. This is the list of compositions of 4 of length at most 3
1583
+ such that the first and third parts are at most 1::
1584
+
1585
+ sage: Compositions(4, outer=[1,oo,1]).list()
1586
+ [[1, 3], [1, 2, 1]]
1587
+
1588
+ This is the list of compositions of 4 bounded below by ``[1,1,1]``::
1589
+
1590
+ sage: Compositions(4, inner=[1,1,1]).list()
1591
+ [[2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1592
+
1593
+ The options ``min_slope`` and ``max_slope`` can be used to set constraints
1594
+ on the slope, that is the difference ``p[i+1]-p[i]`` of two
1595
+ consecutive parts. The following is the list of weakly increasing
1596
+ compositions of 4::
1597
+
1598
+ sage: Compositions(4, min_slope=0).list()
1599
+ [[4], [2, 2], [1, 3], [1, 1, 2], [1, 1, 1, 1]]
1600
+
1601
+ Here are the weakly decreasing ones::
1602
+
1603
+ sage: Compositions(4, max_slope=0).list()
1604
+ [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]
1605
+
1606
+ The following is the list of compositions of 4 such that two
1607
+ consecutive parts differ by at most one::
1608
+
1609
+ sage: Compositions(4, min_slope=-1, max_slope=1).list()
1610
+ [[4], [2, 2], [2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1611
+
1612
+ The constraints can be combined together in all reasonable ways.
1613
+ This is the list of compositions of 5 of length between 2 and 4
1614
+ such that the difference between consecutive parts is between -2
1615
+ and 1::
1616
+
1617
+ sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4).list()
1618
+ [[3, 2], [3, 1, 1], [2, 3], [2, 2, 1], [2, 1, 2], [2, 1, 1, 1], [1, 2, 2], [1, 2, 1, 1], [1, 1, 2, 1], [1, 1, 1, 2]]
1619
+
1620
+ We can do the same thing with an outer constraint::
1621
+
1622
+ sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4, outer=[2,5,2]).list()
1623
+ [[2, 3], [2, 2, 1], [2, 1, 2], [1, 2, 2]]
1624
+
1625
+ However, providing incoherent constraints may yield strange
1626
+ results. It is up to the user to ensure that the inner and outer
1627
+ compositions themselves satisfy the parts and slope constraints.
1628
+
1629
+ Note that setting ``min_part=0`` is not allowed::
1630
+
1631
+ sage: Compositions(2, length=3, min_part=0)
1632
+ Traceback (most recent call last):
1633
+ ...
1634
+ ValueError: setting min_part=0 is not allowed for Compositions
1635
+
1636
+ Instead you must use ``IntegerVectors``::
1637
+
1638
+ sage: list(IntegerVectors(2, 3))
1639
+ [[2, 0, 0], [1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1], [0, 0, 2]]
1640
+
1641
+ The generation algorithm is constant amortized time, and handled
1642
+ by the generic tool :class:`IntegerListsLex`.
1643
+
1644
+ TESTS::
1645
+
1646
+ sage: C = Compositions(4, length=2)
1647
+ sage: C == loads(dumps(C))
1648
+ True
1649
+
1650
+ sage: Compositions(6, min_part=2, length=3)
1651
+ Compositions of the integer 6 satisfying constraints length=3, min_part=2
1652
+
1653
+ sage: [2, 1] in Compositions(3, length=2)
1654
+ True
1655
+ sage: [2,1,2] in Compositions(5, min_part=1)
1656
+ True
1657
+ sage: [2,1,2] in Compositions(5, min_part=2)
1658
+ False
1659
+
1660
+ sage: Compositions(4, length=2).cardinality()
1661
+ 3
1662
+ sage: Compositions(4, min_length=2).cardinality()
1663
+ 7
1664
+ sage: Compositions(4, max_length=2).cardinality()
1665
+ 4
1666
+ sage: Compositions(4, max_part=2).cardinality()
1667
+ 5
1668
+ sage: Compositions(4, min_part=2).cardinality()
1669
+ 2
1670
+ sage: Compositions(4, outer=[3,1,2]).cardinality()
1671
+ 3
1672
+
1673
+ sage: Compositions(4, length=2).list()
1674
+ [[3, 1], [2, 2], [1, 3]]
1675
+ sage: Compositions(4, min_length=2).list()
1676
+ [[3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1677
+ sage: Compositions(4, max_length=2).list()
1678
+ [[4], [3, 1], [2, 2], [1, 3]]
1679
+ sage: Compositions(4, max_part=2).list()
1680
+ [[2, 2], [2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1681
+ sage: Compositions(4, min_part=2).list()
1682
+ [[4], [2, 2]]
1683
+ sage: Compositions(4, outer=[3,1,2]).list()
1684
+ [[3, 1], [2, 1, 1], [1, 1, 2]]
1685
+ sage: Compositions(3, outer = Composition([3,2])).list()
1686
+ [[3], [2, 1], [1, 2]]
1687
+ sage: Compositions(4, outer=[1,oo,1]).list()
1688
+ [[1, 3], [1, 2, 1]]
1689
+ sage: Compositions(4, inner=[1,1,1]).list()
1690
+ [[2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1691
+ sage: Compositions(4, inner=Composition([1,2])).list()
1692
+ [[2, 2], [1, 3], [1, 2, 1]]
1693
+ sage: Compositions(4, min_slope=0).list()
1694
+ [[4], [2, 2], [1, 3], [1, 1, 2], [1, 1, 1, 1]]
1695
+ sage: Compositions(4, min_slope=-1, max_slope=1).list()
1696
+ [[4], [2, 2], [2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1697
+ sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4).list()
1698
+ [[3, 2], [3, 1, 1], [2, 3], [2, 2, 1], [2, 1, 2], [2, 1, 1, 1], [1, 2, 2], [1, 2, 1, 1], [1, 1, 2, 1], [1, 1, 1, 2]]
1699
+ sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4, outer=[2,5,2]).list()
1700
+ [[2, 3], [2, 2, 1], [2, 1, 2], [1, 2, 2]]
1701
+ """
1702
+ @staticmethod
1703
+ def __classcall_private__(self, n=None, **kwargs):
1704
+ """
1705
+ Return the correct parent based upon the input.
1706
+
1707
+ EXAMPLES::
1708
+
1709
+ sage: C = Compositions(3)
1710
+ sage: C2 = Compositions(int(3))
1711
+ sage: C is C2
1712
+ True
1713
+ """
1714
+ if n is None:
1715
+ if kwargs:
1716
+ raise ValueError("incorrect number of arguments")
1717
+ return Compositions_all()
1718
+ else:
1719
+ if not kwargs:
1720
+ if isinstance(n, (int, Integer)):
1721
+ return Compositions_n(n)
1722
+ else:
1723
+ raise ValueError("n must be an integer")
1724
+ else:
1725
+ # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute
1726
+ txt = "Compositions of the integer %s satisfying constraints %s"
1727
+ kwargs['name'] = txt % (n, ", ".join(f"{key}={kwargs[key]}"
1728
+ for key in sorted(kwargs)))
1729
+ kwargs['element_class'] = Composition
1730
+ if 'min_part' not in kwargs:
1731
+ kwargs['min_part'] = 1
1732
+ elif kwargs['min_part'] == 0:
1733
+ raise ValueError("setting min_part=0 is not allowed for Compositions")
1734
+
1735
+ if 'outer' in kwargs:
1736
+ kwargs['ceiling'] = list(kwargs['outer'])
1737
+ if 'max_length' in kwargs:
1738
+ kwargs['max_length'] = min(len(kwargs['outer']), kwargs['max_length'])
1739
+ else:
1740
+ kwargs['max_length'] = len(kwargs['outer'])
1741
+ del kwargs['outer']
1742
+
1743
+ if 'inner' in kwargs:
1744
+ inner = list(kwargs['inner'])
1745
+ kwargs['floor'] = inner
1746
+ del kwargs['inner']
1747
+ # Should this be handled by integer lists lex?
1748
+ if 'min_length' in kwargs:
1749
+ kwargs['min_length'] = max(len(inner), kwargs['min_length'])
1750
+ else:
1751
+ kwargs['min_length'] = len(inner)
1752
+ return IntegerListsLex(n, **kwargs)
1753
+
1754
+ def __init__(self, is_infinite=False, category=None):
1755
+ """
1756
+ Initialize ``self``.
1757
+
1758
+ EXAMPLES::
1759
+
1760
+ sage: C = Compositions()
1761
+ sage: TestSuite(C).run()
1762
+ """
1763
+ if category is None:
1764
+ category = EnumeratedSets()
1765
+ if is_infinite:
1766
+ Parent.__init__(self, category=category.Infinite())
1767
+ else:
1768
+ Parent.__init__(self, category=category.Finite())
1769
+
1770
+ Element = Composition
1771
+
1772
+ def _element_constructor_(self, lst) -> Composition:
1773
+ """
1774
+ Construct an element with ``self`` as parent.
1775
+
1776
+ EXAMPLES::
1777
+
1778
+ sage: P = Compositions()
1779
+ sage: P([3,3,1]) # indirect doctest
1780
+ [3, 3, 1]
1781
+ sage: P(Partition([5,2,1])) # needs sage.combinat
1782
+ [5, 2, 1]
1783
+ """
1784
+ # input can be an iterator, and one has to use it twice
1785
+ lst = list(lst)
1786
+ if any(not isinstance(x, (int, Integer)) or x < 0 for x in lst):
1787
+ raise ValueError('not a composition')
1788
+ elt = self.element_class(self, lst)
1789
+ if elt not in self:
1790
+ raise ValueError("%s not in %s" % (elt, self))
1791
+ return elt
1792
+
1793
+ def __contains__(self, x) -> bool:
1794
+ """
1795
+ TESTS::
1796
+
1797
+ sage: [2,1,3] in Compositions()
1798
+ True
1799
+ sage: [] in Compositions()
1800
+ True
1801
+ sage: [-2,-1] in Compositions()
1802
+ False
1803
+ sage: [0,0] in Compositions()
1804
+ True
1805
+ """
1806
+ if isinstance(x, (Composition, Partition)):
1807
+ return True
1808
+ elif isinstance(x, list):
1809
+ for i in x:
1810
+ if (not isinstance(i, (int, Integer))) and i not in ZZ:
1811
+ return False
1812
+ if i < 0:
1813
+ return False
1814
+ return True
1815
+ else:
1816
+ return False
1817
+
1818
+ def from_descents(self, descents, nps=None) -> Composition:
1819
+ """
1820
+ Return a composition from the list of descents.
1821
+
1822
+ INPUT:
1823
+
1824
+ - ``descents`` -- an iterable
1825
+
1826
+ - ``nps`` -- integer or ``None`` (default: ``None``)
1827
+
1828
+ OUTPUT:
1829
+
1830
+ - The composition of ``nps`` whose descents are listed in
1831
+ ``descents``, assuming that ``nps`` is not ``None`` (otherwise,
1832
+ the last element of ``descents`` is removed from ``descents``, and
1833
+ ``nps`` is set to be this last element plus 1).
1834
+
1835
+ EXAMPLES::
1836
+
1837
+ sage: [x-1 for x in Composition([1, 1, 3, 4, 3]).to_subset()]
1838
+ [0, 1, 4, 8]
1839
+ sage: Compositions().from_descents([1,0,4,8],12)
1840
+ [1, 1, 3, 4, 3]
1841
+ sage: Compositions().from_descents([1,0,4,8,11])
1842
+ [1, 1, 3, 4, 3]
1843
+ """
1844
+ d = [x + 1 for x in sorted(descents)]
1845
+ if nps is None:
1846
+ nps = d.pop()
1847
+ return self.from_subset(d, nps)
1848
+
1849
+ def from_subset(self, S, n) -> Composition:
1850
+ r"""
1851
+ The composition of `n` corresponding to the subset ``S`` of
1852
+ `\{1, 2, \ldots, n-1\}` under the bijection that maps the composition
1853
+ `(i_1, i_2, \ldots, i_k)` of `n` to the subset
1854
+ `\{i_1, i_1 + i_2, i_1 + i_2 + i_3, \ldots, i_1 + \cdots + i_{k-1}\}`
1855
+ (see :meth:`Composition.to_subset`).
1856
+
1857
+ INPUT:
1858
+
1859
+ - ``S`` -- an iterable, a subset of `\{1, 2, \ldots, n-1\}`
1860
+
1861
+ - ``n`` -- integer
1862
+
1863
+ EXAMPLES::
1864
+
1865
+ sage: Compositions().from_subset([2,1,5,9], 12)
1866
+ [1, 1, 3, 4, 3]
1867
+ sage: Compositions().from_subset({2,1,5,9}, 12)
1868
+ [1, 1, 3, 4, 3]
1869
+
1870
+ sage: Compositions().from_subset([], 12)
1871
+ [12]
1872
+ sage: Compositions().from_subset([], 0)
1873
+ []
1874
+
1875
+ TESTS::
1876
+
1877
+ sage: Compositions().from_subset([2,1,5,9],9)
1878
+ Traceback (most recent call last):
1879
+ ...
1880
+ ValueError: S (=[1, 2, 5, 9]) is not a subset of {1, ..., 8}
1881
+ """
1882
+ d = sorted(S)
1883
+
1884
+ if not d:
1885
+ if n == 0:
1886
+ return self.element_class(self, [])
1887
+ else:
1888
+ return self.element_class(self, [n])
1889
+
1890
+ if n <= d[-1]:
1891
+ raise ValueError("S (=%s) is not a subset of {1, ..., %s}"
1892
+ % (d, n - 1))
1893
+ else:
1894
+ d.append(n)
1895
+
1896
+ co = [d[0]]
1897
+ co.extend(d[i + 1] - d[i] for i in range(len(d) - 1))
1898
+
1899
+ return self.element_class(self, co)
1900
+
1901
+ def from_code(self, code) -> Composition:
1902
+ r"""
1903
+ Return the composition from its code. The code of a composition
1904
+ `I` is a list of length `\mathrm{size}(I)` consisting of 1s and
1905
+ 0s such that there is a 1 wherever a new part starts.
1906
+ (Exceptional case: When the composition is empty, the code is
1907
+ ``[0]``.)
1908
+
1909
+ EXAMPLES::
1910
+
1911
+ sage: Composition([4,1,2,3,5]).to_code()
1912
+ [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
1913
+ sage: Compositions().from_code(_)
1914
+ [4, 1, 2, 3, 5]
1915
+ sage: Composition([3,1,2,3,5]).to_code()
1916
+ [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
1917
+ sage: Compositions().from_code(_)
1918
+ [3, 1, 2, 3, 5]
1919
+ """
1920
+ if code == [0]:
1921
+ return self.element_class(self, [])
1922
+
1923
+ L = [x for x in range(len(code)) if code[x] == 1] # the positions of the letter 1
1924
+ c = [L[i] - L[i - 1] for i in range(1, len(L))] + [len(code) - L[-1]]
1925
+ return self.element_class(self, c)
1926
+
1927
+
1928
+ # Allows to unpickle old constrained Compositions_constraints objects.
1929
+ class Compositions_constraints(IntegerListsLex):
1930
+ def __setstate__(self, data):
1931
+ """
1932
+ TESTS::
1933
+
1934
+ # This is the unpickling sequence for Compositions(4, max_part=2) in sage <= 4.1.1
1935
+ sage: pg_Compositions_constraints = unpickle_global('sage.combinat.composition', 'Compositions_constraints')
1936
+ sage: si = unpickle_newobj(pg_Compositions_constraints, ())
1937
+ sage: pg_make_integer = unpickle_global('sage.rings.integer', 'make_integer')
1938
+ sage: unpickle_build(si, {'constraints':{'max_part':pg_make_integer('2')}, 'n':pg_make_integer('4')})
1939
+ sage: si
1940
+ Integer lists of sum 4 satisfying certain constraints
1941
+ sage: si.list()
1942
+ [[2, 2], [2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
1943
+ """
1944
+ n = data['n']
1945
+ self.__class__ = IntegerListsLex
1946
+ constraints = {'min_part': 1,
1947
+ 'element_class': Composition}
1948
+ constraints.update(data['constraints'])
1949
+ self.__init__(n, **constraints)
1950
+
1951
+
1952
+ class Compositions_all(Compositions):
1953
+ """
1954
+ Class of all compositions.
1955
+ """
1956
+
1957
+ def __init__(self):
1958
+ """
1959
+ Initialize ``self``.
1960
+
1961
+ TESTS::
1962
+
1963
+ sage: C = Compositions()
1964
+ sage: TestSuite(C).run()
1965
+ """
1966
+ cat = AdditiveMonoids()
1967
+ Compositions.__init__(self, True, category=cat)
1968
+
1969
+ def _repr_(self) -> str:
1970
+ """
1971
+ Return a string representation of ``self``.
1972
+
1973
+ TESTS::
1974
+
1975
+ sage: repr(Compositions())
1976
+ 'Compositions of nonnegative integers'
1977
+ """
1978
+ return "Compositions of nonnegative integers"
1979
+
1980
+ def subset(self, size=None):
1981
+ """
1982
+ Return the set of compositions of the given size.
1983
+
1984
+ EXAMPLES::
1985
+
1986
+ sage: C = Compositions()
1987
+ sage: C.subset(4)
1988
+ Compositions of 4
1989
+ sage: C.subset(size=3)
1990
+ Compositions of 3
1991
+ """
1992
+ if size is None:
1993
+ return self
1994
+ return Compositions(size)
1995
+
1996
+ def zero(self):
1997
+ """
1998
+ Return the zero of the additive monoid.
1999
+
2000
+ This is the empty composition.
2001
+
2002
+ EXAMPLES::
2003
+
2004
+ sage: C = Compositions()
2005
+ sage: C.zero()
2006
+ []
2007
+ """
2008
+ return Composition([])
2009
+
2010
+ def _an_element_(self):
2011
+ """
2012
+ Return an element of ``self``.
2013
+
2014
+ EXAMPLES::
2015
+
2016
+ sage: C = Compositions()
2017
+ sage: C.an_element()
2018
+ []
2019
+ """
2020
+ return self.zero()
2021
+
2022
+ def __iter__(self):
2023
+ """
2024
+ Iterate over all compositions.
2025
+
2026
+ TESTS::
2027
+
2028
+ sage: C = Compositions()
2029
+ sage: it = C.__iter__()
2030
+ sage: [next(it) for i in range(10)]
2031
+ [[], [1], [1, 1], [2], [1, 1, 1], [1, 2], [2, 1], [3], [1, 1, 1, 1], [1, 1, 2]]
2032
+ """
2033
+ n = 0
2034
+ while True:
2035
+ for c in Compositions(n):
2036
+ yield self.element_class(self, list(c))
2037
+ n += 1
2038
+
2039
+
2040
+ class Compositions_n(Compositions):
2041
+ """
2042
+ Class of compositions of a fixed `n`.
2043
+ """
2044
+ @staticmethod
2045
+ def __classcall_private__(cls, n):
2046
+ """
2047
+ Standardize input to ensure a unique representation.
2048
+
2049
+ EXAMPLES::
2050
+
2051
+ sage: C = Compositions(5)
2052
+ sage: C2 = Compositions(int(5))
2053
+ sage: C3 = Compositions(ZZ(5))
2054
+ sage: C is C2
2055
+ True
2056
+ sage: C is C3
2057
+ True
2058
+ """
2059
+ return super().__classcall__(cls, Integer(n))
2060
+
2061
+ def __init__(self, n):
2062
+ """
2063
+ TESTS::
2064
+
2065
+ sage: C = Compositions(3)
2066
+ sage: C == loads(dumps(C))
2067
+ True
2068
+ sage: TestSuite(C).run()
2069
+ """
2070
+ self.n = n
2071
+ Compositions.__init__(self, False)
2072
+
2073
+ def _repr_(self) -> str:
2074
+ """
2075
+ Return a string representation of ``self``.
2076
+
2077
+ TESTS::
2078
+
2079
+ sage: repr(Compositions(3))
2080
+ 'Compositions of 3'
2081
+ """
2082
+ return "Compositions of %s" % self.n
2083
+
2084
+ def __contains__(self, x) -> bool:
2085
+ """
2086
+ TESTS::
2087
+
2088
+ sage: [2,1,3] in Compositions(6)
2089
+ True
2090
+ sage: [2,1,2] in Compositions(6)
2091
+ False
2092
+ sage: [] in Compositions(0)
2093
+ True
2094
+ sage: [0] in Compositions(0)
2095
+ True
2096
+ """
2097
+ return x in Compositions() and sum(x) == self.n
2098
+
2099
+ def cardinality(self) -> Integer:
2100
+ """
2101
+ Return the number of compositions of `n`.
2102
+
2103
+ TESTS::
2104
+
2105
+ sage: Compositions(3).cardinality()
2106
+ 4
2107
+ sage: Compositions(0).cardinality()
2108
+ 1
2109
+ """
2110
+ if self.n >= 1:
2111
+ return ZZ(2)**(self.n - 1)
2112
+ elif self.n == 0:
2113
+ return ZZ.one()
2114
+ else:
2115
+ return ZZ.zero()
2116
+
2117
+ def random_element(self) -> Composition:
2118
+ r"""
2119
+ Return a random ``Composition`` with uniform probability.
2120
+
2121
+ This method generates a random binary word starting with a 1
2122
+ and then uses the bijection between compositions and their code.
2123
+
2124
+ EXAMPLES::
2125
+
2126
+ sage: Compositions(5).random_element() # random
2127
+ [2, 1, 1, 1]
2128
+ sage: Compositions(0).random_element()
2129
+ []
2130
+ sage: Compositions(1).random_element()
2131
+ [1]
2132
+
2133
+ TESTS::
2134
+
2135
+ sage: all(Compositions(10).random_element() in Compositions(10) for i in range(20))
2136
+ True
2137
+ """
2138
+ from sage.misc.prandom import choice
2139
+
2140
+ if self.n == 0:
2141
+ return Compositions()([])
2142
+ return Compositions().from_code([1] + [choice([0, 1]) for _ in range(self.n - 1)])
2143
+
2144
+ def __iter__(self):
2145
+ """
2146
+ Iterate over the compositions of `n`.
2147
+
2148
+ TESTS::
2149
+
2150
+ sage: Compositions(4).list()
2151
+ [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]
2152
+ sage: Compositions(0).list()
2153
+ [[]]
2154
+ """
2155
+ for c in composition_iterator_fast(self.n):
2156
+ yield self.element_class(self, c)
2157
+
2158
+
2159
+ def composition_iterator_fast(n):
2160
+ """
2161
+ Iterator over compositions of `n` yielded as lists.
2162
+
2163
+ TESTS::
2164
+
2165
+ sage: from sage.combinat.composition import composition_iterator_fast
2166
+ sage: L = list(composition_iterator_fast(4)); L
2167
+ [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]
2168
+ sage: type(L[0])
2169
+ <class 'list'>
2170
+ """
2171
+ # Special cases
2172
+ if n < 0:
2173
+ return
2174
+ if n == 0:
2175
+ yield []
2176
+ return
2177
+
2178
+ s = Integer(0) # Current sum
2179
+ cur = [Integer(0)]
2180
+ while cur:
2181
+ cur[-1] += 1
2182
+ s += 1
2183
+ # Note that because we are adding 1 every time,
2184
+ # we will never have s > n
2185
+ if s == n:
2186
+ yield list(cur)
2187
+ s -= cur.pop()
2188
+ else:
2189
+ cur.append(Integer(0))
2190
+
2191
+
2192
+ register_unpickle_override('sage.combinat.composition', 'Composition_class', Composition)