passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.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 (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,2601 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules
3
+ r"""
4
+ Word quasi-symmetric functions
5
+
6
+ AUTHORS:
7
+
8
+ - Travis Scrimshaw (2018-04-09): initial implementation
9
+ - Darij Grinberg and Amy Pang (2018-04-12): further bases and methods
10
+
11
+ TESTS:
12
+
13
+ We check that the coercion `C \to M` goes through the `X` basis::
14
+
15
+ sage: WQSym = algebras.WQSym(QQ)
16
+ sage: Q = WQSym.Q()
17
+ sage: C = WQSym.C()
18
+ sage: M = WQSym.M()
19
+ sage: M.coerce_map_from(C)
20
+ Composite map:
21
+ From: Word Quasi-symmetric functions over Rational Field in the Cone basis
22
+ To: Word Quasi-symmetric functions over Rational Field in the Monomial basis
23
+ Defn: Generic morphism:
24
+ From: Word Quasi-symmetric functions over Rational Field in the Cone basis
25
+ To: Word Quasi-symmetric functions over Rational Field in the Characteristic basis
26
+ then
27
+ Generic morphism:
28
+ From: Word Quasi-symmetric functions over Rational Field in the Characteristic basis
29
+ To: Word Quasi-symmetric functions over Rational Field in the Monomial basis
30
+ """
31
+
32
+ # ****************************************************************************
33
+ # Copyright (C) 2018 Travis Scrimshaw <tcscrims at gmail.com>
34
+ #
35
+ # Distributed under the terms of the GNU General Public License (GPL)
36
+ # as published by the Free Software Foundation; either version 2 of
37
+ # the License, or (at your option) any later version.
38
+ # https://www.gnu.org/licenses/
39
+ # ****************************************************************************
40
+
41
+ from sage.misc.bindable_class import BindableClass
42
+ from sage.structure.parent import Parent
43
+ from sage.structure.unique_representation import UniqueRepresentation
44
+ from sage.structure.global_options import GlobalOptions
45
+ from sage.categories.hopf_algebras import HopfAlgebras
46
+ from sage.categories.realizations import Category_realization_of_parent
47
+ from sage.combinat.free_module import CombinatorialFreeModule
48
+ from sage.combinat.set_partition_ordered import OrderedSetPartitions
49
+ from sage.combinat.shuffle import ShuffleProduct_overlapping, ShuffleProduct
50
+ from sage.rings.integer_ring import ZZ
51
+
52
+
53
+ class WQSymBasis_abstract(CombinatorialFreeModule, BindableClass):
54
+ """
55
+ Abstract base class for bases of `WQSym`.
56
+
57
+ This must define two attributes:
58
+
59
+ - ``_prefix`` -- the basis prefix
60
+ - ``_basis_name`` -- the name of the basis (must match one
61
+ of the names that the basis can be constructed from `WQSym`)
62
+ """
63
+ def __init__(self, alg, graded=True):
64
+ r"""
65
+ Initialize ``self``.
66
+
67
+ EXAMPLES::
68
+
69
+ sage: M = algebras.WQSym(QQ).M()
70
+ sage: TestSuite(M).run() # long time
71
+ """
72
+ def sorting_key(X):
73
+ return (sum(map(len, X)), X)
74
+ CombinatorialFreeModule.__init__(self, alg.base_ring(),
75
+ OrderedSetPartitions(),
76
+ category=WQSymBases(alg, graded),
77
+ sorting_key=sorting_key,
78
+ bracket='', prefix=self._prefix)
79
+
80
+ def _repr_term(self, osp):
81
+ r"""
82
+ Return a string representation of an element of WordQuasiSymmetricFunctions
83
+ in the basis ``self``.
84
+
85
+ TESTS::
86
+
87
+ sage: M = WordQuasiSymmetricFunctions(QQ).M()
88
+ sage: elt = M[[[1,2]]] * M[[[1]]]; elt
89
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
90
+ sage: M.options.objects = "words"
91
+ sage: elt
92
+ M[1, 1, 2] + M[1, 1, 1] + M[2, 2, 1]
93
+ sage: M.options._reset()
94
+ """
95
+ return self._prefix + self.options._dispatch(self, '_repr_', 'objects', osp)
96
+
97
+ def _repr_compositions(self, osp):
98
+ """
99
+ Return a string representation of ``osp`` indexed by ordered set partitions.
100
+
101
+ This method is called by ``self_repr_term``.
102
+
103
+ EXAMPLES::
104
+
105
+ sage: M = WordQuasiSymmetricFunctions(QQ).M()
106
+ sage: elt = M[[[1,2]]] * M[[[1]]]; elt
107
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
108
+ sage: M.options.display = "tight"
109
+ sage: elt
110
+ M[{1,2},{3}] + M[{1,2,3}] + M[{3},{1,2}]
111
+ sage: M.options.display = "compact"
112
+ sage: elt
113
+ M[12.3] + M[123] + M[3.12]
114
+ sage: osp = OrderedSetPartition([[2,4], [1,3,7],[5,6]])
115
+ sage: M._repr_compositions(osp) == '[24.137.56]'
116
+ True
117
+ sage: M.options._reset(); elt
118
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
119
+ """
120
+ display = self.options.display
121
+ disp = repr(osp)
122
+ if display == 'tight':
123
+ disp = disp.replace(", ", ",")
124
+ return disp
125
+ elif display == 'compact':
126
+ disp = disp.replace("}, ", ".").replace("}", "").replace("{", "")
127
+ return disp.replace(", ", "")
128
+ else:
129
+ # treat display as 'normal'
130
+ return disp
131
+
132
+ def _repr_words(self, osp):
133
+ """
134
+ Return a string representation of ``self`` indexed by packed words.
135
+
136
+ This method is called by ``self_repr_term``.
137
+
138
+ EXAMPLES::
139
+
140
+ sage: M = WordQuasiSymmetricFunctions(QQ).M()
141
+ sage: elt = M[[[1,2]]]*M[[[1]]]; elt
142
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
143
+ sage: M.options.objects = "words"
144
+ sage: elt
145
+ M[1, 1, 2] + M[1, 1, 1] + M[2, 2, 1]
146
+ sage: M.options.display = "tight"
147
+ sage: elt
148
+ M[1,1,2] + M[1,1,1] + M[2,2,1]
149
+ sage: M.options.display = "compact"
150
+ sage: elt
151
+ M[112] + M[111] + M[221]
152
+ sage: osp = OrderedSetPartition([[2,4], [1,3,7],[5,6]])
153
+ sage: M._repr_words(osp) == '[2121332]'
154
+ True
155
+ sage: M.options._reset(); elt
156
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
157
+ """
158
+ display = self.options.display
159
+ disp = repr(list(osp.to_packed_word()))
160
+ if display == 'tight':
161
+ return disp.replace(", ", ",")
162
+ elif display == 'compact':
163
+ return disp.replace(", ", "")
164
+ else:
165
+ # treat display as 'normal'
166
+ return disp
167
+
168
+ def _coerce_map_from_(self, R):
169
+ r"""
170
+ Return ``True`` if there is a coercion from ``R`` into ``self``
171
+ and ``False`` otherwise.
172
+
173
+ The things that coerce into ``self`` are
174
+
175
+ - word quasi-symmetric functions over a base with
176
+ a coercion map into ``self.base_ring()``
177
+
178
+ EXAMPLES::
179
+
180
+ sage: M = algebras.WQSym(GF(7)).M(); M
181
+ Word Quasi-symmetric functions over Finite Field of size 7 in the Monomial basis
182
+
183
+ Elements of the word quasi-symmetric functions canonically coerce in::
184
+
185
+ sage: x, y = M([[1]]), M([[2,1]])
186
+ sage: M.coerce(x+y) == x+y
187
+ True
188
+
189
+ The word quasi-symmetric functions over `\ZZ` coerces in,
190
+ since `\ZZ` coerces to `\GF{7}`::
191
+
192
+ sage: N = algebras.WQSym(ZZ).M()
193
+ sage: Nx, Ny = N([[1]]), N([[2,1]])
194
+ sage: z = M.coerce(Nx+Ny); z
195
+ M[{1}] + M[{1, 2}]
196
+ sage: z.parent() is M
197
+ True
198
+
199
+ However, `\GF{7}` does not coerce to `\ZZ`, so word
200
+ quasi-symmetric functions over `\GF{7}` does not coerce
201
+ to the same algebra over `\ZZ`::
202
+
203
+ sage: N.coerce(y)
204
+ Traceback (most recent call last):
205
+ ...
206
+ TypeError: no canonical coercion from Word Quasi-symmetric functions
207
+ over Finite Field of size 7 in the Monomial basis to
208
+ Word Quasi-symmetric functions over Integer Ring in the Monomial basis
209
+
210
+ TESTS::
211
+
212
+ sage: M = algebras.WQSym(ZZ).M()
213
+ sage: N = algebras.WQSym(QQ).M()
214
+ sage: M.has_coerce_map_from(N)
215
+ False
216
+ sage: N.has_coerce_map_from(M)
217
+ True
218
+ sage: M.has_coerce_map_from(QQ)
219
+ False
220
+ sage: N.has_coerce_map_from(QQ)
221
+ True
222
+ sage: M.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z'))
223
+ False
224
+ """
225
+ # word quasi-symmetric functions in the same variables
226
+ # over any base that coerces in:
227
+ if isinstance(R, WQSymBasis_abstract):
228
+ if R.realization_of() == self.realization_of():
229
+ return True
230
+ if not self.base_ring().has_coerce_map_from(R.base_ring()):
231
+ return False
232
+ if self._basis_name == R._basis_name: # The same basis
233
+ def coerce_base_ring(self, x):
234
+ return self._from_dict(x.monomial_coefficients())
235
+ return coerce_base_ring
236
+ # Otherwise lift that basis up and then coerce over
237
+ target = getattr(self.realization_of(), R._basis_name)()
238
+ return self._coerce_map_via([target], R)
239
+ return super()._coerce_map_from_(R)
240
+
241
+ def _an_element_(self):
242
+ """
243
+ Return an element of ``self``.
244
+
245
+ EXAMPLES::
246
+
247
+ sage: M = algebras.WQSym(QQ).M()
248
+ sage: M.an_element()
249
+ M[{1}] + 2*M[{1}, {2}]
250
+ """
251
+ return self([[1]]) + 2 * self([[1], [2]])
252
+
253
+ def some_elements(self):
254
+ """
255
+ Return some elements of the word quasi-symmetric functions.
256
+
257
+ EXAMPLES::
258
+
259
+ sage: M = algebras.WQSym(QQ).M()
260
+ sage: M.some_elements()
261
+ [M[], M[{1}], M[{1, 2}],
262
+ M[{1}] + M[{1}, {2}],
263
+ M[] + 1/2*M[{1}]]
264
+ """
265
+ u = self.one()
266
+ o = self([[1]])
267
+ s = self.base_ring().an_element()
268
+ return [u, o, self([[1, 2]]), o + self([[1], [2]]), u + s * o]
269
+
270
+
271
+ class WordQuasiSymmetricFunctions(UniqueRepresentation, Parent):
272
+ r"""
273
+ The word quasi-symmetric functions.
274
+
275
+ The ring of word quasi-symmetric functions can be defined as a
276
+ subring of the ring of all bounded-degree noncommutative power
277
+ series in countably many indeterminates (i.e., elements in
278
+ `R \langle \langle x_1, x_2, x_3, \ldots \rangle \rangle` of bounded
279
+ degree). Namely, consider words over the alphabet `\{1, 2, 3, \ldots\}`;
280
+ every noncommutative power series is an infinite `R`-linear
281
+ combination of these words.
282
+ For each such word `w`, we define the *packing* of `w` to be the
283
+ word `\operatorname{pack}(w)` that is obtained from `w` by replacing
284
+ the smallest letter that appears in `w` by `1`, the second-smallest
285
+ letter that appears in `w` by `2`, etc. (for example,
286
+ `\operatorname{pack}(4112774) = 3112443`).
287
+ A word `w` is said to be *packed* if `\operatorname{pack}(w) = w`.
288
+ For each packed word `u`, we define the noncommutative power series
289
+ `\mathbf{M}_u = \sum w`, where the sum ranges over all words `w`
290
+ satisfying `\operatorname{pack}(w) = u`.
291
+ The span of these power series `\mathbf{M}_u` is a subring of the
292
+ ring of all noncommutative power series; it is called the ring of
293
+ word quasi-symmetric functions, and is denoted by `WQSym`.
294
+
295
+ For each nonnegative integer `n`, there is a bijection between
296
+ packed words of length `n` and ordered set partitions of
297
+ `\{1, 2, \ldots, n\}`. Under this bijection, a packed word
298
+ `u = (u_1, u_2, \ldots, u_n)` of length `n` corresponds to the
299
+ ordered set partition `P = (P_1, P_2, \ldots, P_k)` of
300
+ `\{1, 2, \ldots, n\}` whose `i`-th part `P_i` (for each `i`) is the
301
+ set of all `j \in \{1, 2, \ldots, n\}` such that `u_j = i`.
302
+
303
+ The basis element `\mathbf{M}_u` is also denoted as `\mathbf{M}_P`
304
+ in this situation. The basis `(\mathbf{M}_P)_P` is called the
305
+ *Monomial basis* and is implemented as
306
+ :class:`~sage.combinat.chas.wqsym.WordQuasiSymmetricFunctions.Monomial`.
307
+
308
+ Other bases are the cone basis (aka C basis), the characteristic
309
+ basis (aka X basis), the Q basis and the Phi basis.
310
+
311
+ Bases of `WQSym` are implemented (internally) using ordered set
312
+ partitions. However, the user may access specific basis vectors using
313
+ either packed words or ordered set partitions. See the examples below,
314
+ noting especially the section on ambiguities.
315
+
316
+ `WQSym` is endowed with a connected graded Hopf algebra structure (see
317
+ Section 2.2 of [NoThWi08]_, Section 1.1 of [FoiMal14]_ and
318
+ Section 4.3.2 of [MeNoTh11]_) given by
319
+
320
+ .. MATH::
321
+
322
+ \Delta(\mathbf{M}_{(P_1,\ldots,P_{\ell})}) = \sum_{i=0}^{\ell}
323
+ \mathbf{M}_{\operatorname{st}(P_1, \ldots, P_i)} \otimes
324
+ \mathbf{M}_{\operatorname{st}(P_{i+1}, \ldots, P_{\ell})}.
325
+
326
+ Here, for any ordered set partition `(Q_1, \ldots, Q_k)` of a
327
+ finite set `Z` of integers, we let `\operatorname{st}(Q_1, \ldots, Q_k)`
328
+ denote the set partition obtained from `Z` by replacing the smallest
329
+ element appearing in it by `1`, the second-smallest element by `2`,
330
+ and so on.
331
+
332
+ A rule for multiplying elements of the monomial basis relies on the
333
+ *quasi-shuffle product* of two ordered set partitions.
334
+ The quasi-shuffle product `\Box` is given by
335
+ :class:`~sage.combinat.shuffle.ShuffleProduct_overlapping` with the
336
+ ``+`` operation in the overlapping of the shuffles being the
337
+ union of the sets. The product `\mathbf{M}_P \mathbf{M}_Q`
338
+ for two ordered set partitions `P` and `Q` of `[n]` and `[m]`
339
+ is then given by
340
+
341
+ .. MATH::
342
+
343
+ \mathbf{M}_P \mathbf{M}_Q
344
+ = \sum_{R \in P \Box Q^+} \mathbf{M}_R ,
345
+
346
+ where `Q^+` means `Q` with all numbers shifted upwards by `n`.
347
+
348
+ Sometimes, `WQSym` is also denoted as `NCQSym`.
349
+
350
+ REFERENCES:
351
+
352
+ - [FoiMal14]_
353
+ - [MeNoTh11]_
354
+ - [NoThWi08]_
355
+ - [BerZab05]_
356
+
357
+ EXAMPLES:
358
+
359
+ Constructing the algebra and its Monomial basis::
360
+
361
+ sage: WQSym = algebras.WQSym(ZZ)
362
+ sage: WQSym
363
+ Word Quasi-symmetric functions over Integer Ring
364
+ sage: M = WQSym.M()
365
+ sage: M
366
+ Word Quasi-symmetric functions over Integer Ring in the Monomial basis
367
+ sage: M[[]]
368
+ M[]
369
+
370
+ Calling basis elements using packed words::
371
+
372
+ sage: x = M[1,2,1]; x
373
+ M[{1, 3}, {2}]
374
+ sage: x == M[[1,2,1]] == M[Word([1,2,1])]
375
+ True
376
+ sage: y = M[1,1,2] - M[1,2,2]; y
377
+ -M[{1}, {2, 3}] + M[{1, 2}, {3}]
378
+
379
+ Calling basis elements using ordered set partitions::
380
+
381
+ sage: z = M[[1,2,3],]; z
382
+ M[{1, 2, 3}]
383
+ sage: z == M[[[1,2,3]]] == M[OrderedSetPartition([[1,2,3]])]
384
+ True
385
+ sage: M[[1,2],[3]]
386
+ M[{1, 2}, {3}]
387
+
388
+ Note that expressions above are output in terms of ordered set partitions,
389
+ even when input as packed words. Output as packed words can be achieved
390
+ by modifying the global options. (See :meth:`OrderedSetPartitions.options`
391
+ for further details.)::
392
+
393
+ sage: M.options.objects = "words"
394
+ sage: y
395
+ -M[1, 2, 2] + M[1, 1, 2]
396
+ sage: M.options.display = "compact"
397
+ sage: y
398
+ -M[122] + M[112]
399
+ sage: z
400
+ M[111]
401
+
402
+ The options should be reset to display as ordered set partitions::
403
+
404
+ sage: M.options._reset()
405
+ sage: z
406
+ M[{1, 2, 3}]
407
+
408
+ Illustration of the Hopf algebra structure::
409
+
410
+ sage: M[[2, 3], [5], [6], [4], [1]].coproduct()
411
+ M[] # M[{2, 3}, {5}, {6}, {4}, {1}] + M[{1, 2}] # M[{3}, {4}, {2}, {1}]
412
+ + M[{1, 2}, {3}] # M[{3}, {2}, {1}] + M[{1, 2}, {3}, {4}] # M[{2}, {1}]
413
+ + M[{1, 2}, {4}, {5}, {3}] # M[{1}] + M[{2, 3}, {5}, {6}, {4}, {1}] # M[]
414
+ sage: _ == M[5,1,1,4,2,3].coproduct()
415
+ True
416
+ sage: M[[1,1,1]] * M[[1,1,2]] # packed words
417
+ M[{1, 2, 3}, {4, 5}, {6}] + M[{1, 2, 3, 4, 5}, {6}]
418
+ + M[{4, 5}, {1, 2, 3}, {6}] + M[{4, 5}, {1, 2, 3, 6}]
419
+ + M[{4, 5}, {6}, {1, 2, 3}]
420
+ sage: M[[1,2,3],].antipode() # ordered set partition
421
+ -M[{1, 2, 3}]
422
+ sage: M[[1], [2], [3]].antipode()
423
+ -M[{1, 2, 3}] - M[{2, 3}, {1}] - M[{3}, {1, 2}] - M[{3}, {2}, {1}]
424
+ sage: x = M[[1],[2],[3]] + 3*M[[2],[1]]
425
+ sage: x.counit()
426
+ 0
427
+ sage: x.antipode()
428
+ 3*M[{1}, {2}] + 3*M[{1, 2}] - M[{1, 2, 3}] - M[{2, 3}, {1}]
429
+ - M[{3}, {1, 2}] - M[{3}, {2}, {1}]
430
+
431
+ .. rubric:: Ambiguities
432
+
433
+ Some ambiguity arises when accessing basis vectors with the dictionary syntax,
434
+ i.e., ``M[...]``. A common example is when referencing an ordered set partition
435
+ with one part. For example, in the expression ``M[[1,2]]``, does ``[[1,2]]``
436
+ refer to an ordered set partition or does ``[1,2]`` refer to a packed word?
437
+ We choose the latter: if the received arguments do not behave like a tuple of
438
+ iterables, then view them as describing a packed word. (In the running example,
439
+ one argument is received, which behaves as a tuple of integers.) Here are a
440
+ variety of ways to get the same basis vector::
441
+
442
+ sage: x = M[1,1]; x
443
+ M[{1, 2}]
444
+ sage: x == M[[1,1]] # treated as word
445
+ True
446
+ sage: x == M[[1,2],] == M[[[1,2]]] # treated as ordered set partitions
447
+ True
448
+
449
+ sage: M[[1,3],[2]] # treat as ordered set partition
450
+ M[{1, 3}, {2}]
451
+ sage: M[[1,3],[2]] == M[1,2,1] # treat as word
452
+ True
453
+
454
+ TESTS::
455
+
456
+ sage: M = WordQuasiSymmetricFunctions(QQ).M()
457
+ sage: a = M[OrderedSetPartition([[1]])]
458
+ sage: b = M[OrderedSetPartitions(1)([[1]])]
459
+ sage: c = M[[1]]
460
+ sage: a == b == c
461
+ True
462
+
463
+ .. TODO::
464
+
465
+ - Dendriform structure.
466
+ """
467
+ def __init__(self, R):
468
+ """
469
+ Initialize ``self``.
470
+
471
+ TESTS::
472
+
473
+ sage: A = algebras.WQSym(QQ)
474
+ sage: TestSuite(A).run() # long time
475
+ """
476
+ category = HopfAlgebras(R).Graded().Connected()
477
+ Parent.__init__(self, base=R, category=category.WithRealizations())
478
+
479
+ def _repr_(self):
480
+ """
481
+ Return the string representation of ``self``.
482
+
483
+ EXAMPLES::
484
+
485
+ sage: algebras.WQSym(QQ) # indirect doctest
486
+ Word Quasi-symmetric functions over Rational Field
487
+ """
488
+ return "Word Quasi-symmetric functions over {}".format(self.base_ring())
489
+
490
+ def a_realization(self):
491
+ r"""
492
+ Return a particular realization of ``self`` (the `M`-basis).
493
+
494
+ EXAMPLES::
495
+
496
+ sage: WQSym = algebras.WQSym(QQ)
497
+ sage: WQSym.a_realization()
498
+ Word Quasi-symmetric functions over Rational Field in the Monomial basis
499
+ """
500
+ return self.M()
501
+
502
+ _shorthands = tuple(['M', 'X', 'C', 'Q', 'Phi'])
503
+
504
+ # add options to class
505
+ class options(GlobalOptions):
506
+ r"""
507
+ Set and display the global options for bases of WordQuasiSymmetricFunctions.
508
+ If no parameters are set, then the function returns a copy of the options
509
+ dictionary.
510
+
511
+ The ``options`` can be accessed as the method
512
+ :obj:`WordQuasiSymmetricFunctions.options` of
513
+ :class:`WordQuasiSymmetricFunctions` or of any associated basis.
514
+
515
+ @OPTIONS@
516
+
517
+ The ``'words'`` representation of a basis element of
518
+ :class:`WordQuasiSymmetricFunctions`, indexed by an ordered
519
+ set partition `A`, is the packed word associated to `A`.
520
+ See :meth:`OrderedSetPartition.to_packed_word` for details.)
521
+
522
+ EXAMPLES::
523
+
524
+ sage: WQ = WordQuasiSymmetricFunctions(QQ)
525
+ sage: M = WQ.M()
526
+ sage: elt = M[[[1,2]]]*M[[[1]]]; elt
527
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
528
+ sage: M.options.display = "tight"
529
+ sage: elt
530
+ M[{1,2},{3}] + M[{1,2,3}] + M[{3},{1,2}]
531
+ sage: M.options.display = "compact"
532
+ sage: elt
533
+ M[12.3] + M[123] + M[3.12]
534
+ sage: WQ.options._reset()
535
+ sage: M.options.objects = "words"
536
+ sage: elt
537
+ M[1, 1, 2] + M[1, 1, 1] + M[2, 2, 1]
538
+ sage: M.options.display = "tight"
539
+ sage: elt
540
+ M[1,1,2] + M[1,1,1] + M[2,2,1]
541
+ sage: WQ.options.display = "compact"
542
+ sage: elt
543
+ M[112] + M[111] + M[221]
544
+ sage: M.options._reset()
545
+ sage: elt
546
+ M[{1, 2}, {3}] + M[{1, 2, 3}] + M[{3}, {1, 2}]
547
+ """
548
+ NAME = 'WordQuasiSymmetricFunctions element'
549
+ module = 'sage.combinat.chas.wqsym'
550
+ option_class = 'WordQuasiSymmetricFunctions'
551
+ objects = dict(default='compositions',
552
+ description='Specifies how basis elements of WordQuasiSymmetricFunctions should be indexed',
553
+ values=dict(compositions="Indexing the basis by ordered set partitions",
554
+ words="Indexing the basis by packed words"),
555
+ case_sensitive=False)
556
+ display = dict(default='normal',
557
+ description='Specifies how basis elements of WordQuasiSymmetricFunctions should be printed',
558
+ values=dict(normal="Using the normal representation",
559
+ tight="Dropping spaces after commas",
560
+ compact="Using a severely compacted representation"),
561
+ case_sensitive=False)
562
+
563
+ class Monomial(WQSymBasis_abstract):
564
+ r"""
565
+ The Monomial basis of `WQSym`.
566
+
567
+ The family `(\mathbf{M}_u)`, as defined in
568
+ :class:`~sage.combinat.chas.wqsym.WordQuasiSymmetricFunctions`
569
+ with `u` ranging over all packed words, is a basis for the
570
+ free `R`-module `WQSym` and called the *Monomial basis*.
571
+ Here it is labelled using ordered set partitions.
572
+
573
+ EXAMPLES::
574
+
575
+ sage: WQSym = algebras.WQSym(QQ)
576
+ sage: M = WQSym.M(); M
577
+ Word Quasi-symmetric functions over Rational Field in the Monomial basis
578
+ sage: sorted(M.basis(2))
579
+ [M[{1}, {2}], M[{2}, {1}], M[{1, 2}]]
580
+ """
581
+ _prefix = "M"
582
+ _basis_name = "Monomial"
583
+
584
+ def product_on_basis(self, x, y):
585
+ r"""
586
+ Return the (associative) `*` product of the basis elements
587
+ of ``self`` indexed by the ordered set partitions `x` and
588
+ `y`.
589
+
590
+ This is the shifted quasi-shuffle product of `x` and `y`.
591
+
592
+ EXAMPLES::
593
+
594
+ sage: A = algebras.WQSym(QQ).M()
595
+ sage: x = OrderedSetPartition([[1],[2,3]])
596
+ sage: y = OrderedSetPartition([[1,2]])
597
+ sage: z = OrderedSetPartition([[1,2],[3]])
598
+ sage: A.product_on_basis(x, y)
599
+ M[{1}, {2, 3}, {4, 5}] + M[{1}, {2, 3, 4, 5}]
600
+ + M[{1}, {4, 5}, {2, 3}] + M[{1, 4, 5}, {2, 3}]
601
+ + M[{4, 5}, {1}, {2, 3}]
602
+ sage: A.product_on_basis(x, z)
603
+ M[{1}, {2, 3}, {4, 5}, {6}] + M[{1}, {2, 3, 4, 5}, {6}]
604
+ + M[{1}, {4, 5}, {2, 3}, {6}] + M[{1}, {4, 5}, {2, 3, 6}]
605
+ + M[{1}, {4, 5}, {6}, {2, 3}] + M[{1, 4, 5}, {2, 3}, {6}]
606
+ + M[{1, 4, 5}, {2, 3, 6}] + M[{1, 4, 5}, {6}, {2, 3}]
607
+ + M[{4, 5}, {1}, {2, 3}, {6}] + M[{4, 5}, {1}, {2, 3, 6}]
608
+ + M[{4, 5}, {1}, {6}, {2, 3}] + M[{4, 5}, {1, 6}, {2, 3}]
609
+ + M[{4, 5}, {6}, {1}, {2, 3}]
610
+ sage: A.product_on_basis(y, y)
611
+ M[{1, 2}, {3, 4}] + M[{1, 2, 3, 4}] + M[{3, 4}, {1, 2}]
612
+
613
+ TESTS::
614
+
615
+ sage: one = OrderedSetPartition([])
616
+ sage: all(A.product_on_basis(one, z) == A(z) == A.basis()[z] for z in OrderedSetPartitions(3))
617
+ True
618
+ sage: all(A.product_on_basis(z, one) == A(z) == A.basis()[z] for z in OrderedSetPartitions(3))
619
+ True
620
+ """
621
+ K = self.basis().keys()
622
+ if not x:
623
+ return self.monomial(y)
624
+ m = max(max(part) for part in x) # The degree of x
625
+ x = [set(part) for part in x]
626
+ yshift = [[val + m for val in part] for part in y]
627
+
628
+ def union(X, Y):
629
+ return X.union(Y)
630
+
631
+ return self.sum_of_monomials(ShuffleProduct_overlapping(x, yshift,
632
+ K, union))
633
+
634
+ def coproduct_on_basis(self, x):
635
+ r"""
636
+ Return the coproduct of ``self`` on the basis element
637
+ indexed by the ordered set partition ``x``.
638
+
639
+ EXAMPLES::
640
+
641
+ sage: M = algebras.WQSym(QQ).M()
642
+
643
+ sage: M.coproduct(M.one()) # indirect doctest
644
+ M[] # M[]
645
+ sage: M.coproduct( M([[1]]) ) # indirect doctest
646
+ M[] # M[{1}] + M[{1}] # M[]
647
+ sage: M.coproduct( M([[1,2]]) )
648
+ M[] # M[{1, 2}] + M[{1, 2}] # M[]
649
+ sage: M.coproduct( M([[1], [2]]) )
650
+ M[] # M[{1}, {2}] + M[{1}] # M[{1}] + M[{1}, {2}] # M[]
651
+ """
652
+ if not x:
653
+ return self.one().tensor(self.one())
654
+ K = self.indices()
655
+
656
+ def standardize(P): # standardize an ordered set partition
657
+ base = sorted(sum((list(part) for part in P), []))
658
+ # base is the ground set of P, as a sorted list.
659
+ d = {val: i + 1 for i, val in enumerate(base)}
660
+ # d is the unique order isomorphism from base to
661
+ # {1, 2, ..., |base|} (encoded as dict).
662
+ return K([[d[x] for x in part] for part in P])
663
+ T = self.tensor_square()
664
+ return T.sum_of_monomials((standardize(x[:i]), standardize(x[i:]))
665
+ for i in range(len(x) + 1))
666
+
667
+ M = Monomial
668
+
669
+ class Characteristic(WQSymBasis_abstract):
670
+ r"""
671
+ The Characteristic basis of `WQSym`.
672
+
673
+ The *Characteristic basis* is a graded basis `(X_P)` of `WQSym`,
674
+ indexed by ordered set partitions `P`. It is defined by
675
+
676
+ .. MATH::
677
+
678
+ X_P = (-1)^{\ell(P)} \mathbf{M}_P ,
679
+
680
+ where `(\mathbf{M}_P)_P` denotes the Monomial basis,
681
+ and where `\ell(P)` denotes the number of blocks in an ordered
682
+ set partition `P`.
683
+
684
+ EXAMPLES::
685
+
686
+ sage: WQSym = algebras.WQSym(QQ)
687
+ sage: X = WQSym.X(); X
688
+ Word Quasi-symmetric functions over Rational Field in the Characteristic basis
689
+
690
+ sage: X[[[1,2,3]]] * X[[1,2],[3]]
691
+ X[{1, 2, 3}, {4, 5}, {6}] - X[{1, 2, 3, 4, 5}, {6}]
692
+ + X[{4, 5}, {1, 2, 3}, {6}] - X[{4, 5}, {1, 2, 3, 6}]
693
+ + X[{4, 5}, {6}, {1, 2, 3}]
694
+
695
+ sage: X[[1, 4], [3], [2]].coproduct()
696
+ X[] # X[{1, 4}, {3}, {2}] + X[{1, 2}] # X[{2}, {1}]
697
+ + X[{1, 3}, {2}] # X[{1}] + X[{1, 4}, {3}, {2}] # X[]
698
+
699
+ sage: M = WQSym.M()
700
+ sage: M(X[[1, 2, 3],])
701
+ -M[{1, 2, 3}]
702
+ sage: M(X[[1, 3], [2]])
703
+ M[{1, 3}, {2}]
704
+ sage: X(M[[1, 2, 3],])
705
+ -X[{1, 2, 3}]
706
+ sage: X(M[[1, 3], [2]])
707
+ X[{1, 3}, {2}]
708
+ """
709
+ _prefix = "X"
710
+ _basis_name = "Characteristic"
711
+
712
+ def __init__(self, alg):
713
+ """
714
+ Initialize ``self``.
715
+
716
+ EXAMPLES::
717
+
718
+ sage: X = algebras.WQSym(QQ).X()
719
+ sage: TestSuite(X).run() # long time
720
+ """
721
+ WQSymBasis_abstract.__init__(self, alg)
722
+
723
+ M = self.realization_of().M()
724
+ mone = -self.base_ring().one()
725
+
726
+ def sgn(P):
727
+ return mone**len(P)
728
+ self.module_morphism(codomain=M, diagonal=sgn).register_as_coercion()
729
+ M.module_morphism(codomain=self, diagonal=sgn).register_as_coercion()
730
+
731
+ class Element(WQSymBasis_abstract.Element):
732
+ def algebraic_complement(self):
733
+ r"""
734
+ Return the image of the element ``self`` of `WQSym`
735
+ under the algebraic complement involution.
736
+
737
+ See
738
+ :meth:`WQSymBases.ElementMethods.algebraic_complement`
739
+ for a definition of the involution and for examples.
740
+
741
+ .. SEEALSO::
742
+
743
+ :meth:`coalgebraic_complement`, :meth:`star_involution`
744
+
745
+ EXAMPLES::
746
+
747
+ sage: WQSym = algebras.WQSym(ZZ)
748
+ sage: X = WQSym.X()
749
+ sage: X[[1,2],[5,6],[3,4]].algebraic_complement()
750
+ X[{3, 4}, {5, 6}, {1, 2}]
751
+ sage: X[[3], [1, 2], [4]].algebraic_complement()
752
+ X[{4}, {1, 2}, {3}]
753
+
754
+ TESTS::
755
+
756
+ sage: M = WQSym.M()
757
+ sage: all(M(X[A]).algebraic_complement() == M(X[A].algebraic_complement())
758
+ ....: for A in OrderedSetPartitions(4))
759
+ True
760
+ """
761
+ # See the WQSymBases.ElementMethods.algebraic_complement doc
762
+ # for the formula we're using here.
763
+ Q = self.parent()
764
+ OSPs = Q.basis().keys()
765
+ return Q._from_dict({OSPs(A.reversed()): c for (A, c) in self},
766
+ remove_zeros=False)
767
+
768
+ def coalgebraic_complement(self):
769
+ r"""
770
+ Return the image of the element ``self`` of `WQSym`
771
+ under the coalgebraic complement involution.
772
+
773
+ See
774
+ :meth:`WQSymBases.ElementMethods.coalgebraic_complement`
775
+ for a definition of the involution and for examples.
776
+
777
+ .. SEEALSO::
778
+
779
+ :meth:`algebraic_complement`, :meth:`star_involution`
780
+
781
+ EXAMPLES::
782
+
783
+ sage: WQSym = algebras.WQSym(ZZ)
784
+ sage: X = WQSym.X()
785
+ sage: X[[1,2],[5,6],[3,4]].coalgebraic_complement()
786
+ X[{5, 6}, {1, 2}, {3, 4}]
787
+ sage: X[[3], [1, 2], [4]].coalgebraic_complement()
788
+ X[{2}, {3, 4}, {1}]
789
+
790
+ TESTS::
791
+
792
+ sage: M = WQSym.M()
793
+ sage: all(M(X[A]).coalgebraic_complement()
794
+ ....: == M(X[A].coalgebraic_complement())
795
+ ....: for A in OrderedSetPartitions(4))
796
+ True
797
+ """
798
+ # See the WQSymBases.ElementMethods.coalgebraic_complement doc
799
+ # for the formula we're using here.
800
+ Q = self.parent()
801
+ OSPs = Q.basis().keys()
802
+ return Q._from_dict({OSPs(A.complement()): c for (A, c) in self},
803
+ remove_zeros=False)
804
+
805
+ def star_involution(self):
806
+ r"""
807
+ Return the image of the element ``self`` of `WQSym`
808
+ under the star involution.
809
+
810
+ See
811
+ :meth:`WQSymBases.ElementMethods.star_involution`
812
+ for a definition of the involution and for examples.
813
+
814
+ .. SEEALSO::
815
+
816
+ :meth:`algebraic_complement`, :meth:`coalgebraic_complement`
817
+
818
+ EXAMPLES::
819
+
820
+ sage: WQSym = algebras.WQSym(ZZ)
821
+ sage: X = WQSym.X()
822
+ sage: X[[1,2],[5,6],[3,4]].star_involution()
823
+ X[{3, 4}, {1, 2}, {5, 6}]
824
+ sage: X[[3], [1, 2], [4]].star_involution()
825
+ X[{1}, {3, 4}, {2}]
826
+
827
+ TESTS:
828
+
829
+ sage: M = WQSym.M()
830
+ sage: all(M(X[A]).star_involution() == M(X[A].star_involution())
831
+ ....: for A in OrderedSetPartitions(4))
832
+ True
833
+ """
834
+ # See the WQSymBases.ElementMethods.star_involution doc
835
+ # for the formula we're using here.
836
+ Q = self.parent()
837
+ OSPs = Q.basis().keys()
838
+ return Q._from_dict({OSPs(A.complement().reversed()): c for (A, c) in self},
839
+ remove_zeros=False)
840
+
841
+ X = Characteristic
842
+
843
+ class Cone(WQSymBasis_abstract):
844
+ r"""
845
+ The Cone basis of `WQSym`.
846
+
847
+ Let `(X_P)_P` denote the Characteristic basis of `WQSym`.
848
+ Denote the quasi-shuffle of two ordered set partitions `A` and
849
+ `B` by `A \Box B`. For an ordered set partition
850
+ `P = (P_1, \ldots, P_{\ell})`, we form a list of ordered set
851
+ partitions `[P] := (P'_1, \ldots, P'_k)` as follows.
852
+ Define a strictly decreasing sequence of integers
853
+ `\ell + 1 = i_0 > i_1 > \cdots > i_k = 1` recursively by
854
+ requiring that `\min P_{i_j} \leq \min P_a` for all `a < i_{j-1}`.
855
+ Set `P'_j = (P_{i_j}, \ldots, P_{i_{j-1}-1})`.
856
+
857
+ The *Cone basis* `(C_P)_P` is defined by
858
+
859
+ .. MATH::
860
+
861
+ C_P = \sum_Q X_Q,
862
+
863
+ where the sum is over all elements `Q` of the quasi-shuffle
864
+ product `P'_1 \Box P'_2 \Box \cdots \Box P'_k` with
865
+ `[P] = (P'_1, \ldots, P'_k)`.
866
+
867
+ EXAMPLES::
868
+
869
+ sage: WQSym = algebras.WQSym(QQ)
870
+ sage: C = WQSym.C()
871
+ sage: C
872
+ Word Quasi-symmetric functions over Rational Field in the Cone basis
873
+
874
+ sage: X = WQSym.X()
875
+ sage: X(C[[2,3],[1,4]])
876
+ X[{1, 2, 3, 4}] + X[{1, 4}, {2, 3}] + X[{2, 3}, {1, 4}]
877
+ sage: X(C[[1,4],[2,3]])
878
+ X[{1, 4}, {2, 3}]
879
+ sage: X(C[[2,3],[1],[4]])
880
+ X[{1}, {2, 3}, {4}] + X[{1}, {2, 3, 4}] + X[{1}, {4}, {2, 3}]
881
+ + X[{1, 2, 3}, {4}] + X[{2, 3}, {1}, {4}]
882
+ sage: X(C[[3], [2, 5], [1, 4]])
883
+ X[{1, 2, 3, 4, 5}] + X[{1, 2, 4, 5}, {3}] + X[{1, 3, 4}, {2, 5}]
884
+ + X[{1, 4}, {2, 3, 5}] + X[{1, 4}, {2, 5}, {3}]
885
+ + X[{1, 4}, {3}, {2, 5}] + X[{2, 3, 5}, {1, 4}]
886
+ + X[{2, 5}, {1, 3, 4}] + X[{2, 5}, {1, 4}, {3}]
887
+ + X[{2, 5}, {3}, {1, 4}] + X[{3}, {1, 2, 4, 5}]
888
+ + X[{3}, {1, 4}, {2, 5}] + X[{3}, {2, 5}, {1, 4}]
889
+ sage: C(X[[2,3],[1,4]])
890
+ -C[{1, 2, 3, 4}] - C[{1, 4}, {2, 3}] + C[{2, 3}, {1, 4}]
891
+
892
+ REFERENCES:
893
+
894
+ - Section 4 of [Early2017]_
895
+
896
+ .. TODO::
897
+
898
+ Experiments suggest that :meth:`algebraic_complement`,
899
+ :meth:`coalgebraic_complement`, and :meth:`star_involution`
900
+ should have reasonable formulas on the C basis; at least
901
+ the coefficients of the outputs on any element of the C
902
+ basis seem to be always `0, 1, -1`.
903
+ Is this true? What is the formula?
904
+ """
905
+ _prefix = "C"
906
+ _basis_name = "Cone"
907
+
908
+ def __init__(self, alg):
909
+ """
910
+ Initialize ``self``.
911
+
912
+ EXAMPLES::
913
+
914
+ sage: C = algebras.WQSym(QQ).C()
915
+ sage: TestSuite(C).run() # long time
916
+ """
917
+ WQSymBasis_abstract.__init__(self, alg)
918
+
919
+ X = self.realization_of().X()
920
+ phi = self.module_morphism(self._C_to_X, codomain=X, unitriangular='upper')
921
+ phi.register_as_coercion()
922
+ inv_phi = ~phi
923
+ inv_phi.register_as_coercion()
924
+ # We need to explicitly construct the coercion to/from M via X
925
+ # as otherwise, when another basis B is created before X, the
926
+ # coercion is attempted to be built via B, which is cannot do.
927
+ # So the coercion map returned is the default one that calls
928
+ # the _element_constructor_.
929
+ # This is only a problem because X is not the default
930
+ # a_realization(), which is M, and the coercions are always
931
+ # first attempted through M to another basis. -- TS
932
+ M = self.realization_of().M()
933
+ M.register_coercion(M.coerce_map_from(X) * phi)
934
+ self.register_coercion(inv_phi * X.coerce_map_from(M))
935
+
936
+ def some_elements(self):
937
+ """
938
+ Return some elements of the word quasi-symmetric functions
939
+ in the Cone basis.
940
+
941
+ EXAMPLES::
942
+
943
+ sage: C = algebras.WQSym(QQ).C()
944
+ sage: C.some_elements()
945
+ [C[], C[{1}], C[{1, 2}], C[] + 1/2*C[{1}]]
946
+ """
947
+ u = self.one()
948
+ o = self([[1]])
949
+ s = self.base_ring().an_element()
950
+ return [u, o, self([[1, 2]]), u + s * o]
951
+
952
+ def _C_to_X(self, P):
953
+ """
954
+ Return the image of the basis element of ``self`` indexed
955
+ by ``P`` in the Characteristic basis.
956
+
957
+ EXAMPLES::
958
+
959
+ sage: C = algebras.WQSym(QQ).C()
960
+ sage: OSP = C.basis().keys()
961
+ sage: C._C_to_X(OSP([[2,3],[1,4]]))
962
+ X[{1, 2, 3, 4}] + X[{1, 4}, {2, 3}] + X[{2, 3}, {1, 4}]
963
+ """
964
+ X = self.realization_of().X()
965
+ if not P:
966
+ return X.one()
967
+
968
+ OSP = self.basis().keys()
969
+
970
+ # Convert to standard set of ordered set partitions
971
+ temp = list(P)
972
+ data = []
973
+ while temp:
974
+ i = min(min(X) for X in temp)
975
+ for j, A in enumerate(temp):
976
+ if i in A:
977
+ data.append(OSP(temp[j:]))
978
+ temp = temp[:j]
979
+ break
980
+
981
+ def union(X, Y):
982
+ return X.union(Y)
983
+
984
+ # Perform the quasi-shuffle product
985
+ cur = {data[0]: 1}
986
+ for B in data[1:]:
987
+ ret = {}
988
+ for A, curA in cur.items():
989
+ for C in ShuffleProduct_overlapping(A, B, element_constructor=OSP, add=union):
990
+ if C in ret:
991
+ ret[C] += curA
992
+ else:
993
+ ret[C] = curA
994
+ cur = ret
995
+
996
+ # Return the result in the X basis
997
+ return X._from_dict(cur, coerce=True)
998
+
999
+ C = Cone
1000
+
1001
+ class StronglyCoarser(WQSymBasis_abstract):
1002
+ r"""
1003
+ The Q basis of `WQSym`.
1004
+
1005
+ We define a partial order `\leq` on the set of all ordered
1006
+ set partitions as follows: `A \leq B` if and only if
1007
+ `A` is strongly finer than `B` (see
1008
+ :meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.is_strongly_finer`
1009
+ for a definition of this).
1010
+
1011
+ The *Q basis* `(Q_P)_P` is a basis of `WQSym` indexed by ordered
1012
+ set partitions, and is defined by
1013
+
1014
+ .. MATH::
1015
+
1016
+ Q_P = \sum \mathbf{M}_W,
1017
+
1018
+ where the sum is over ordered set partitions `W` satisfying
1019
+ `P \leq W`.
1020
+
1021
+ EXAMPLES::
1022
+
1023
+ sage: WQSym = algebras.WQSym(QQ)
1024
+ sage: M = WQSym.M(); Q = WQSym.Q()
1025
+ sage: Q
1026
+ Word Quasi-symmetric functions over Rational Field in the Q basis
1027
+
1028
+ sage: Q(M[[2,3],[1,4]])
1029
+ Q[{2, 3}, {1, 4}]
1030
+ sage: Q(M[[1,2],[3,4]])
1031
+ Q[{1, 2}, {3, 4}] - Q[{1, 2, 3, 4}]
1032
+ sage: M(Q[[1,2],[3,4]])
1033
+ M[{1, 2}, {3, 4}] + M[{1, 2, 3, 4}]
1034
+ sage: M(Q[[2,3],[1],[4]])
1035
+ M[{2, 3}, {1}, {4}] + M[{2, 3}, {1, 4}]
1036
+ sage: M(Q[[3], [2, 5], [1, 4]])
1037
+ M[{3}, {2, 5}, {1, 4}]
1038
+ sage: M(Q[[1, 4], [2, 3], [5], [6]])
1039
+ M[{1, 4}, {2, 3}, {5}, {6}] + M[{1, 4}, {2, 3}, {5, 6}]
1040
+ + M[{1, 4}, {2, 3, 5}, {6}] + M[{1, 4}, {2, 3, 5, 6}]
1041
+
1042
+ sage: Q[[1, 3], [2]] * Q[[1], [2]]
1043
+ Q[{1, 3}, {2}, {4}, {5}] + Q[{1, 3}, {4}, {2}, {5}]
1044
+ + Q[{1, 3}, {4}, {5}, {2}] + Q[{4}, {1, 3}, {2}, {5}]
1045
+ + Q[{4}, {1, 3}, {5}, {2}] + Q[{4}, {5}, {1, 3}, {2}]
1046
+
1047
+ sage: Q[[1, 3], [2]].coproduct()
1048
+ Q[] # Q[{1, 3}, {2}] + Q[{1, 2}] # Q[{1}] + Q[{1, 3}, {2}] # Q[]
1049
+
1050
+ REFERENCES:
1051
+
1052
+ - Section 6 of [BerZab05]_
1053
+ """
1054
+ _prefix = "Q"
1055
+ _basis_name = "Q"
1056
+
1057
+ def __init__(self, alg):
1058
+ """
1059
+ Initialize ``self``.
1060
+
1061
+ EXAMPLES::
1062
+
1063
+ sage: Q = algebras.WQSym(QQ).Q()
1064
+ sage: TestSuite(Q).run() # long time
1065
+ """
1066
+ WQSymBasis_abstract.__init__(self, alg)
1067
+
1068
+ M = self.realization_of().M()
1069
+ phi = self.module_morphism(self._Q_to_M, codomain=M, unitriangular='lower')
1070
+ phi.register_as_coercion()
1071
+ phi_inv = M.module_morphism(self._M_to_Q, codomain=self, unitriangular='lower')
1072
+ phi_inv.register_as_coercion()
1073
+
1074
+ def some_elements(self):
1075
+ """
1076
+ Return some elements of the word quasi-symmetric functions
1077
+ in the Q basis.
1078
+
1079
+ EXAMPLES::
1080
+
1081
+ sage: Q = algebras.WQSym(QQ).Q()
1082
+ sage: Q.some_elements()
1083
+ [Q[], Q[{1}], Q[{1, 2}], Q[] + 1/2*Q[{1}]]
1084
+ """
1085
+ u = self.one()
1086
+ o = self([[1]])
1087
+ s = self.base_ring().an_element()
1088
+ return [u, o, self([[1, 2]]), u + s * o]
1089
+
1090
+ def _Q_to_M(self, P):
1091
+ """
1092
+ Return the image of the basis element of ``self`` indexed
1093
+ by ``P`` in the Monomial basis.
1094
+
1095
+ EXAMPLES::
1096
+
1097
+ sage: Q = algebras.WQSym(QQ).Q()
1098
+ sage: OSP = Q.basis().keys()
1099
+ sage: Q._Q_to_M(OSP([[2,3],[1,4]]))
1100
+ M[{2, 3}, {1, 4}]
1101
+ sage: Q._Q_to_M(OSP([[1,2],[3,4]]))
1102
+ M[{1, 2}, {3, 4}] + M[{1, 2, 3, 4}]
1103
+ """
1104
+ M = self.realization_of().M()
1105
+ if not P:
1106
+ return M.one()
1107
+
1108
+ OSP = self.basis().keys()
1109
+ R = M.base_ring()
1110
+ one = R.one()
1111
+ return M._from_dict({OSP(G): one for G in P.strongly_fatter()},
1112
+ coerce=False)
1113
+
1114
+ def _M_to_Q(self, P):
1115
+ """
1116
+ Return the image of the basis element of the monomial
1117
+ basis indexed by ``P`` in the Q basis ``self``.
1118
+
1119
+ EXAMPLES::
1120
+
1121
+ sage: Q = algebras.WQSym(QQ).Q()
1122
+ sage: M = algebras.WQSym(QQ).M()
1123
+ sage: OSP = Q.basis().keys()
1124
+ sage: Q._M_to_Q(OSP([[2,3],[1,4]]))
1125
+ Q[{2, 3}, {1, 4}]
1126
+ sage: Q._M_to_Q(OSP([[1,2],[3,4]]))
1127
+ Q[{1, 2}, {3, 4}] - Q[{1, 2, 3, 4}]
1128
+
1129
+ TESTS::
1130
+
1131
+ sage: Q = algebras.WQSym(QQ).Q()
1132
+ sage: M = algebras.WQSym(QQ).M()
1133
+ sage: OSP4 = OrderedSetPartitions(4)
1134
+ sage: all(M(Q(M[P])) == M[P] for P in OSP4) # long time
1135
+ True
1136
+ sage: all(Q(M(Q[P])) == Q[P] for P in OSP4) # long time
1137
+ True
1138
+ """
1139
+ Q = self
1140
+ if not P:
1141
+ return Q.one()
1142
+
1143
+ OSP = self.basis().keys()
1144
+ R = self.base_ring()
1145
+ one = R.one()
1146
+ lenP = len(P)
1147
+
1148
+ def sign(R):
1149
+ # the coefficient with which another
1150
+ # ordered set partition will appear
1151
+ if len(R) % 2 == lenP % 2:
1152
+ return one
1153
+ return -one
1154
+ return Q._from_dict({OSP(G): sign(G) for G in P.strongly_fatter()},
1155
+ coerce=False)
1156
+
1157
+ def product_on_basis(self, x, y):
1158
+ r"""
1159
+ Return the (associative) `*` product of the basis elements
1160
+ of the Q basis ``self`` indexed by the ordered set partitions
1161
+ `x` and `y`.
1162
+
1163
+ This is the shifted shuffle product of `x` and `y`.
1164
+
1165
+ EXAMPLES::
1166
+
1167
+ sage: A = algebras.WQSym(QQ).Q()
1168
+ sage: x = OrderedSetPartition([[1],[2,3]])
1169
+ sage: y = OrderedSetPartition([[1,2]])
1170
+ sage: z = OrderedSetPartition([[1,2],[3]])
1171
+ sage: A.product_on_basis(x, y)
1172
+ Q[{1}, {2, 3}, {4, 5}] + Q[{1}, {4, 5}, {2, 3}]
1173
+ + Q[{4, 5}, {1}, {2, 3}]
1174
+ sage: A.product_on_basis(x, z)
1175
+ Q[{1}, {2, 3}, {4, 5}, {6}] + Q[{1}, {4, 5}, {2, 3}, {6}]
1176
+ + Q[{1}, {4, 5}, {6}, {2, 3}] + Q[{4, 5}, {1}, {2, 3}, {6}]
1177
+ + Q[{4, 5}, {1}, {6}, {2, 3}] + Q[{4, 5}, {6}, {1}, {2, 3}]
1178
+ sage: A.product_on_basis(y, y)
1179
+ Q[{1, 2}, {3, 4}] + Q[{3, 4}, {1, 2}]
1180
+
1181
+ TESTS::
1182
+
1183
+ sage: one = OrderedSetPartition([])
1184
+ sage: all(A.product_on_basis(one, z) == A(z) == A.basis()[z] for z in OrderedSetPartitions(3))
1185
+ True
1186
+ sage: all(A.product_on_basis(z, one) == A(z) == A.basis()[z] for z in OrderedSetPartitions(3))
1187
+ True
1188
+ """
1189
+ K = self.basis().keys()
1190
+ if not x:
1191
+ return self.monomial(y)
1192
+ m = max(max(part) for part in x) # The degree of x
1193
+ x = [set(part) for part in x]
1194
+ yshift = [[val + m for val in part] for part in y]
1195
+ return self.sum_of_monomials(ShuffleProduct(x, yshift, K))
1196
+
1197
+ def coproduct_on_basis(self, x):
1198
+ r"""
1199
+ Return the coproduct of ``self`` on the basis element
1200
+ indexed by the ordered set partition ``x``.
1201
+
1202
+ EXAMPLES::
1203
+
1204
+ sage: Q = algebras.WQSym(QQ).Q()
1205
+
1206
+ sage: Q.coproduct(Q.one()) # indirect doctest
1207
+ Q[] # Q[]
1208
+ sage: Q.coproduct( Q([[1]]) ) # indirect doctest
1209
+ Q[] # Q[{1}] + Q[{1}] # Q[]
1210
+ sage: Q.coproduct( Q([[1,2]]) )
1211
+ Q[] # Q[{1, 2}] + Q[{1, 2}] # Q[]
1212
+ sage: Q.coproduct( Q([[1], [2]]) )
1213
+ Q[] # Q[{1}, {2}] + Q[{1}] # Q[{1}] + Q[{1}, {2}] # Q[]
1214
+ sage: Q[[1,2],[3],[4]].coproduct()
1215
+ Q[] # Q[{1, 2}, {3}, {4}] + Q[{1, 2}] # Q[{1}, {2}]
1216
+ + Q[{1, 2}, {3}] # Q[{1}] + Q[{1, 2}, {3}, {4}] # Q[]
1217
+ """
1218
+ # The coproduct on the Q basis satisfies the same formula
1219
+ # as on the M basis. This is easily derived from the
1220
+ # formula on the M basis.
1221
+ if not x:
1222
+ return self.one().tensor(self.one())
1223
+ K = self.indices()
1224
+
1225
+ def standardize(P): # standardize an ordered set partition
1226
+ base = sorted(sum((list(part) for part in P), []))
1227
+ # base is the ground set of P, as a sorted list.
1228
+ d = {val: i + 1 for i, val in enumerate(base)}
1229
+ # d is the unique order isomorphism from base to
1230
+ # {1, 2, ..., |base|} (encoded as dict).
1231
+ return K([[d[x] for x in part] for part in P])
1232
+ T = self.tensor_square()
1233
+ return T.sum_of_monomials((standardize(x[:i]), standardize(x[i:]))
1234
+ for i in range(len(x) + 1))
1235
+
1236
+ class Element(WQSymBasis_abstract.Element):
1237
+ def algebraic_complement(self):
1238
+ r"""
1239
+ Return the image of the element ``self`` of `WQSym`
1240
+ under the algebraic complement involution.
1241
+
1242
+ See
1243
+ :meth:`WQSymBases.ElementMethods.algebraic_complement`
1244
+ for a definition of the involution and for examples.
1245
+
1246
+ .. SEEALSO::
1247
+
1248
+ :meth:`coalgebraic_complement`, :meth:`star_involution`
1249
+
1250
+ EXAMPLES::
1251
+
1252
+ sage: WQSym = algebras.WQSym(ZZ)
1253
+ sage: Q = WQSym.Q()
1254
+ sage: Q[[1,2],[5,6],[3,4]].algebraic_complement()
1255
+ Q[{3, 4}, {1, 2, 5, 6}] + Q[{3, 4}, {5, 6}, {1, 2}]
1256
+ - Q[{3, 4, 5, 6}, {1, 2}]
1257
+ sage: Q[[3], [1, 2], [4]].algebraic_complement()
1258
+ Q[{1, 2, 4}, {3}] + Q[{4}, {1, 2}, {3}] - Q[{4}, {1, 2, 3}]
1259
+
1260
+ TESTS::
1261
+
1262
+ sage: M = WQSym.M()
1263
+ sage: all(M(Q[A]).algebraic_complement() # long time
1264
+ ....: == M(Q[A].algebraic_complement())
1265
+ ....: for A in OrderedSetPartitions(4))
1266
+ True
1267
+ """
1268
+ # See the WQSymBases.ElementMethods.algebraic_complement doc
1269
+ # for the formula we're using here.
1270
+ BR = self.base_ring()
1271
+ one = BR.one()
1272
+ mine = -one
1273
+ Q = self.parent()
1274
+ OSPs = Q.basis().keys()
1275
+ from sage.data_structures.blas_dict import linear_combination
1276
+
1277
+ def img(A):
1278
+ # The image of the basis element Q[A], written as a
1279
+ # dictionary (of its coordinates in the Q-basis).
1280
+ Rs = [Rr.reversed() for Rr in A.strongly_fatter()]
1281
+ return {OSPs(P): (one if (len(R) % 2 == len(P) % 2)
1282
+ else mine)
1283
+ for R in Rs for P in R.strongly_fatter()}
1284
+ return Q._from_dict(linear_combination((img(A), c) for (A, c) in self))
1285
+
1286
+ def coalgebraic_complement(self):
1287
+ r"""
1288
+ Return the image of the element ``self`` of `WQSym`
1289
+ under the coalgebraic complement involution.
1290
+
1291
+ See
1292
+ :meth:`WQSymBases.ElementMethods.coalgebraic_complement`
1293
+ for a definition of the involution and for examples.
1294
+
1295
+ .. SEEALSO::
1296
+
1297
+ :meth:`algebraic_complement`, :meth:`star_involution`
1298
+
1299
+ EXAMPLES::
1300
+
1301
+ sage: WQSym = algebras.WQSym(ZZ)
1302
+ sage: Q = WQSym.Q()
1303
+ sage: Q[[1,2],[5,6],[3,4]].coalgebraic_complement()
1304
+ Q[{1, 2, 5, 6}, {3, 4}] + Q[{5, 6}, {1, 2}, {3, 4}] - Q[{5, 6}, {1, 2, 3, 4}]
1305
+ sage: Q[[3], [1, 2], [4]].coalgebraic_complement()
1306
+ Q[{2}, {1, 3, 4}] + Q[{2}, {3, 4}, {1}] - Q[{2, 3, 4}, {1}]
1307
+
1308
+ TESTS::
1309
+
1310
+ sage: M = WQSym.M()
1311
+ sage: all(M(Q[A]).coalgebraic_complement() # long time
1312
+ ....: == M(Q[A].coalgebraic_complement())
1313
+ ....: for A in OrderedSetPartitions(4))
1314
+ True
1315
+ """
1316
+ # See the WQSymBases.ElementMethods.coalgebraic_complement doc
1317
+ # for the formula we're using here.
1318
+ BR = self.base_ring()
1319
+ one = BR.one()
1320
+ mine = -one
1321
+ Q = self.parent()
1322
+ OSPs = Q.basis().keys()
1323
+ from sage.data_structures.blas_dict import linear_combination
1324
+
1325
+ def img(A):
1326
+ # The image of the basis element Q[A], written as a
1327
+ # dictionary (of its coordinates in the Q-basis).
1328
+ Rs = [Rr.complement() for Rr in A.strongly_fatter()]
1329
+ return {OSPs(P): (one if (len(R) % 2 == len(P) % 2)
1330
+ else mine)
1331
+ for R in Rs for P in R.strongly_fatter()}
1332
+ return Q._from_dict(linear_combination((img(A), c) for (A, c) in self))
1333
+
1334
+ def star_involution(self):
1335
+ r"""
1336
+ Return the image of the element ``self`` of `WQSym`
1337
+ under the star involution.
1338
+
1339
+ See
1340
+ :meth:`WQSymBases.ElementMethods.star_involution`
1341
+ for a definition of the involution and for examples.
1342
+
1343
+ .. SEEALSO::
1344
+
1345
+ :meth:`algebraic_complement`, :meth:`coalgebraic_complement`
1346
+
1347
+ EXAMPLES::
1348
+
1349
+ sage: WQSym = algebras.WQSym(ZZ)
1350
+ sage: Q = WQSym.Q()
1351
+ sage: Q[[1,2],[5,6],[3,4]].star_involution()
1352
+ Q[{3, 4}, {1, 2}, {5, 6}]
1353
+ sage: Q[[3], [1, 2], [4]].star_involution()
1354
+ Q[{1}, {3, 4}, {2}]
1355
+
1356
+ TESTS::
1357
+
1358
+ sage: M = WQSym.M()
1359
+ sage: all(M(Q[A]).star_involution() == M(Q[A].star_involution())
1360
+ ....: for A in OrderedSetPartitions(4))
1361
+ True
1362
+ """
1363
+ # See the WQSymBases.ElementMethods.star_involution doc
1364
+ # for the formula we're using here.
1365
+ Q = self.parent()
1366
+ OSPs = Q.basis().keys()
1367
+ return Q._from_dict({OSPs(A.complement().reversed()): c for (A, c) in self},
1368
+ remove_zeros=False)
1369
+
1370
+ Q = StronglyCoarser
1371
+
1372
+ class StronglyFiner(WQSymBasis_abstract):
1373
+ r"""
1374
+ The Phi basis of `WQSym`.
1375
+
1376
+ We define a partial order `\leq` on the set of all ordered
1377
+ set partitions as follows: `A \leq B` if and only if
1378
+ `A` is strongly finer than `B` (see
1379
+ :meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.is_strongly_finer`
1380
+ for a definition of this).
1381
+
1382
+ The *Phi basis* `(\Phi_P)_P` is a basis of `WQSym` indexed by ordered
1383
+ set partitions, and is defined by
1384
+
1385
+ .. MATH::
1386
+
1387
+ \Phi_P = \sum \mathbf{M}_W,
1388
+
1389
+ where the sum is over ordered set partitions `W` satisfying
1390
+ `W \leq P`.
1391
+
1392
+ Novelli and Thibon introduced this basis in [NovThi06]_
1393
+ Section 2.7.2, and called it the quasi-ribbon basis.
1394
+ It later reappeared in [MeNoTh11]_ Section 4.3.2.
1395
+
1396
+ EXAMPLES::
1397
+
1398
+ sage: WQSym = algebras.WQSym(QQ)
1399
+ sage: M = WQSym.M(); Phi = WQSym.Phi()
1400
+ sage: Phi
1401
+ Word Quasi-symmetric functions over Rational Field in the Phi basis
1402
+
1403
+ sage: Phi(M[[2,3],[1,4]])
1404
+ Phi[{2}, {3}, {1}, {4}] - Phi[{2}, {3}, {1, 4}]
1405
+ - Phi[{2, 3}, {1}, {4}] + Phi[{2, 3}, {1, 4}]
1406
+ sage: Phi(M[[1,2],[3,4]])
1407
+ Phi[{1}, {2}, {3}, {4}] - Phi[{1}, {2}, {3, 4}]
1408
+ - Phi[{1, 2}, {3}, {4}] + Phi[{1, 2}, {3, 4}]
1409
+ sage: M(Phi[[1,2],[3,4]])
1410
+ M[{1}, {2}, {3}, {4}] + M[{1}, {2}, {3, 4}]
1411
+ + M[{1, 2}, {3}, {4}] + M[{1, 2}, {3, 4}]
1412
+ sage: M(Phi[[2,3],[1],[4]])
1413
+ M[{2}, {3}, {1}, {4}] + M[{2, 3}, {1}, {4}]
1414
+ sage: M(Phi[[3], [2, 5], [1, 4]])
1415
+ M[{3}, {2}, {5}, {1}, {4}] + M[{3}, {2}, {5}, {1, 4}]
1416
+ + M[{3}, {2, 5}, {1}, {4}] + M[{3}, {2, 5}, {1, 4}]
1417
+ sage: M(Phi[[1, 4], [2, 3], [5], [6]])
1418
+ M[{1}, {4}, {2}, {3}, {5}, {6}] + M[{1}, {4}, {2, 3}, {5}, {6}]
1419
+ + M[{1, 4}, {2}, {3}, {5}, {6}] + M[{1, 4}, {2, 3}, {5}, {6}]
1420
+
1421
+ sage: Phi[[1],] * Phi[[1, 3], [2]]
1422
+ Phi[{1, 2, 4}, {3}] + Phi[{2}, {1, 4}, {3}]
1423
+ + Phi[{2, 4}, {1, 3}] + Phi[{2, 4}, {3}, {1}]
1424
+ sage: Phi[[3, 5], [1, 4], [2]].coproduct()
1425
+ Phi[] # Phi[{3, 5}, {1, 4}, {2}]
1426
+ + Phi[{1}] # Phi[{4}, {1, 3}, {2}]
1427
+ + Phi[{1, 2}] # Phi[{1, 3}, {2}]
1428
+ + Phi[{2, 3}, {1}] # Phi[{2}, {1}]
1429
+ + Phi[{2, 4}, {1, 3}] # Phi[{1}]
1430
+ + Phi[{3, 5}, {1, 4}, {2}] # Phi[]
1431
+
1432
+ REFERENCES:
1433
+
1434
+ - Section 2.7.2 of [NovThi06]_
1435
+ """
1436
+ _prefix = "Phi"
1437
+ _basis_name = "Phi"
1438
+
1439
+ def __init__(self, alg):
1440
+ """
1441
+ Initialize ``self``.
1442
+
1443
+ EXAMPLES::
1444
+
1445
+ sage: Phi = algebras.WQSym(QQ).Phi()
1446
+ sage: TestSuite(Phi).run() # long time
1447
+ """
1448
+ WQSymBasis_abstract.__init__(self, alg)
1449
+
1450
+ M = self.realization_of().M()
1451
+ phi = self.module_morphism(self._Phi_to_M, codomain=M, unitriangular='lower')
1452
+ phi.register_as_coercion()
1453
+ phi_inv = M.module_morphism(self._M_to_Phi, codomain=self, unitriangular='lower')
1454
+ phi_inv.register_as_coercion()
1455
+
1456
+ def some_elements(self):
1457
+ """
1458
+ Return some elements of the word quasi-symmetric functions
1459
+ in the Phi basis.
1460
+
1461
+ EXAMPLES::
1462
+
1463
+ sage: Phi = algebras.WQSym(QQ).Phi()
1464
+ sage: Phi.some_elements()
1465
+ [Phi[], Phi[{1}], Phi[{1, 2}], Phi[] + 1/2*Phi[{1}]]
1466
+ """
1467
+ u = self.one()
1468
+ o = self([[1]])
1469
+ s = self.base_ring().an_element()
1470
+ return [u, o, self([[1, 2]]), u + s * o]
1471
+
1472
+ def _Phi_to_M(self, P):
1473
+ """
1474
+ Return the image of the basis element of ``self`` indexed
1475
+ by ``P`` in the Monomial basis.
1476
+
1477
+ EXAMPLES::
1478
+
1479
+ sage: Phi = algebras.WQSym(QQ).Phi()
1480
+ sage: OSP = Phi.basis().keys()
1481
+ sage: Phi._Phi_to_M(OSP([[2,3],[1,4]]))
1482
+ M[{2}, {3}, {1}, {4}] + M[{2}, {3}, {1, 4}]
1483
+ + M[{2, 3}, {1}, {4}] + M[{2, 3}, {1, 4}]
1484
+ sage: Phi._Phi_to_M(OSP([[1,2],[3,4]]))
1485
+ M[{1}, {2}, {3}, {4}] + M[{1}, {2}, {3, 4}]
1486
+ + M[{1, 2}, {3}, {4}] + M[{1, 2}, {3, 4}]
1487
+ """
1488
+ M = self.realization_of().M()
1489
+ if not P:
1490
+ return M.one()
1491
+
1492
+ OSP = self.basis().keys()
1493
+ R = M.base_ring()
1494
+ one = R.one()
1495
+ return M._from_dict({OSP(G): one for G in P.strongly_finer()},
1496
+ coerce=False)
1497
+
1498
+ def _M_to_Phi(self, P):
1499
+ """
1500
+ Return the image of the basis element of the monomial
1501
+ basis indexed by ``P`` in the Phi basis ``self``.
1502
+
1503
+ EXAMPLES::
1504
+
1505
+ sage: Phi = algebras.WQSym(QQ).Phi()
1506
+ sage: M = algebras.WQSym(QQ).M()
1507
+ sage: OSP = Phi.basis().keys()
1508
+ sage: Phi._M_to_Phi(OSP([[2,3],[1,4]]))
1509
+ Phi[{2}, {3}, {1}, {4}] - Phi[{2}, {3}, {1, 4}]
1510
+ - Phi[{2, 3}, {1}, {4}] + Phi[{2, 3}, {1, 4}]
1511
+ sage: Phi._M_to_Phi(OSP([[1,2],[3,4]]))
1512
+ Phi[{1}, {2}, {3}, {4}] - Phi[{1}, {2}, {3, 4}]
1513
+ - Phi[{1, 2}, {3}, {4}] + Phi[{1, 2}, {3, 4}]
1514
+
1515
+ TESTS::
1516
+
1517
+ sage: Phi = algebras.WQSym(QQ).Phi()
1518
+ sage: M = algebras.WQSym(QQ).M()
1519
+ sage: OSP4 = OrderedSetPartitions(4)
1520
+ sage: all(M(Phi(M[P])) == M[P] for P in OSP4) # long time
1521
+ True
1522
+ sage: all(Phi(M(Phi[P])) == Phi[P] for P in OSP4) # long time
1523
+ True
1524
+ """
1525
+ Phi = self
1526
+ if not P:
1527
+ return Phi.one()
1528
+
1529
+ OSP = self.basis().keys()
1530
+ R = self.base_ring()
1531
+ one = R.one()
1532
+ lenP = len(P)
1533
+
1534
+ def sign(R):
1535
+ # the coefficient with which another
1536
+ # ordered set partition will appear
1537
+ if len(R) % 2 == lenP % 2:
1538
+ return one
1539
+ return -one
1540
+ return Phi._from_dict({OSP(G): sign(G) for G in P.strongly_finer()},
1541
+ coerce=False)
1542
+
1543
+ def product_on_basis(self, x, y):
1544
+ r"""
1545
+ Return the (associative) `*` product of the basis elements
1546
+ of the Phi basis ``self`` indexed by the ordered set partitions
1547
+ `x` and `y`.
1548
+
1549
+ This is obtained by the following algorithm (going back to
1550
+ [NovThi06]_):
1551
+
1552
+ Let `x` be an ordered set partition of `[m]`, and `y` an
1553
+ ordered set partition of `[n]`.
1554
+ Transform `x` into a list `u` of all the `m` elements of `[m]`
1555
+ by writing out each block of `x` (in increasing order) and
1556
+ putting bars between each two consecutive blocks; this is
1557
+ called a barred permutation.
1558
+ Do the same for `y`, but also shift each entry of the
1559
+ resulting barred permutation by `m`. Let `v` be the barred
1560
+ permutation of `[m+n] \setminus [m]` thus obtained.
1561
+ Now, shuffle the two barred permutations `u` and `v`
1562
+ (ignoring the bars) in all the `\binom{n+m}{n}` possible ways.
1563
+ For each shuffle obtained, place bars between some entries
1564
+ of the shuffle, according to the following rule:
1565
+
1566
+ * If two consecutive entries of the shuffle both come from
1567
+ `u`, then place a bar between them if the corresponding
1568
+ entries of `u` had a bar between them.
1569
+
1570
+ * If the first of two consecutive entries of the shuffle
1571
+ comes from `v` and the second from `u`, then place a bar
1572
+ between them.
1573
+
1574
+ This results in a barred permutation of `[m+n]`.
1575
+ Transform it into an ordered set partition of `[m+n]`,
1576
+ by treating the bars as dividers separating consecutive
1577
+ blocks.
1578
+
1579
+ The product `\Phi_x \Phi_y` is the sum of `\Phi_p` with
1580
+ `p` ranging over all ordered set partitions obtained this
1581
+ way.
1582
+
1583
+ EXAMPLES::
1584
+
1585
+ sage: A = algebras.WQSym(QQ).Phi()
1586
+ sage: x = OrderedSetPartition([[1],[2,3]])
1587
+ sage: y = OrderedSetPartition([[1,2]])
1588
+ sage: z = OrderedSetPartition([[1,2],[3]])
1589
+ sage: A.product_on_basis(x, y)
1590
+ Phi[{1}, {2, 3, 4, 5}] + Phi[{1}, {2, 4}, {3, 5}]
1591
+ + Phi[{1}, {2, 4, 5}, {3}] + Phi[{1, 4}, {2, 3, 5}]
1592
+ + Phi[{1, 4}, {2, 5}, {3}] + Phi[{1, 4, 5}, {2, 3}]
1593
+ + Phi[{4}, {1}, {2, 3, 5}] + Phi[{4}, {1}, {2, 5}, {3}]
1594
+ + Phi[{4}, {1, 5}, {2, 3}] + Phi[{4, 5}, {1}, {2, 3}]
1595
+ sage: A.product_on_basis(x, z)
1596
+ Phi[{1}, {2, 3, 4, 5}, {6}] + Phi[{1}, {2, 4}, {3, 5}, {6}]
1597
+ + Phi[{1}, {2, 4, 5}, {3, 6}] + Phi[{1}, {2, 4, 5}, {6}, {3}]
1598
+ + Phi[{1, 4}, {2, 3, 5}, {6}] + Phi[{1, 4}, {2, 5}, {3, 6}]
1599
+ + Phi[{1, 4}, {2, 5}, {6}, {3}] + Phi[{1, 4, 5}, {2, 3, 6}]
1600
+ + Phi[{1, 4, 5}, {2, 6}, {3}] + Phi[{1, 4, 5}, {6}, {2, 3}]
1601
+ + Phi[{4}, {1}, {2, 3, 5}, {6}]
1602
+ + Phi[{4}, {1}, {2, 5}, {3, 6}]
1603
+ + Phi[{4}, {1}, {2, 5}, {6}, {3}]
1604
+ + Phi[{4}, {1, 5}, {2, 3, 6}] + Phi[{4}, {1, 5}, {2, 6}, {3}]
1605
+ + Phi[{4}, {1, 5}, {6}, {2, 3}] + Phi[{4, 5}, {1}, {2, 3, 6}]
1606
+ + Phi[{4, 5}, {1}, {2, 6}, {3}] + Phi[{4, 5}, {1, 6}, {2, 3}]
1607
+ + Phi[{4, 5}, {6}, {1}, {2, 3}]
1608
+ sage: A.product_on_basis(y, y)
1609
+ Phi[{1, 2, 3, 4}] + Phi[{1, 3}, {2, 4}] + Phi[{1, 3, 4}, {2}]
1610
+ + Phi[{3}, {1, 2, 4}] + Phi[{3}, {1, 4}, {2}]
1611
+ + Phi[{3, 4}, {1, 2}]
1612
+
1613
+ TESTS::
1614
+
1615
+ sage: one = OrderedSetPartition([])
1616
+ sage: all(A.product_on_basis(one, z) == A(z) == A.basis()[z] for z in OrderedSetPartitions(3))
1617
+ True
1618
+ sage: all(A.product_on_basis(z, one) == A(z) == A.basis()[z] for z in OrderedSetPartitions(3))
1619
+ True
1620
+ sage: M = algebras.WQSym(QQ).M()
1621
+ sage: x = A[[2, 4], [1, 3]]
1622
+ sage: y = A[[1, 3], [2]]
1623
+ sage: A(M(x) * M(y)) == x * y # long time
1624
+ True
1625
+ sage: A(M(x) ** 2) == x**2 # long time
1626
+ True
1627
+ sage: A(M(y) ** 2) == y**2
1628
+ True
1629
+ """
1630
+ K = self.basis().keys()
1631
+ if not x:
1632
+ return self.monomial(y)
1633
+ if not y:
1634
+ return self.monomial(x)
1635
+ xlist = [(j, (k == 0))
1636
+ for part in x
1637
+ for (k, j) in enumerate(sorted(part))]
1638
+ # xlist is a list of the form
1639
+ # [(e_1, s_1), (e_2, s_2), ..., (e_n, s_n)],
1640
+ # where e_1, e_2, ..., e_n are the entries of the parts of
1641
+ # x in the order in which they appear in x (reading each
1642
+ # part from bottom to top), and where s_i = True if e_i is
1643
+ # the smallest element of its part and False otherwise.
1644
+ m = max(max(part) for part in x) # The degree of x
1645
+ ylist = [(m + j, (k == 0))
1646
+ for part in y
1647
+ for (k, j) in enumerate(sorted(part))]
1648
+ # ylist is like xlist, but for y instead of x, and with
1649
+ # a shift by m.
1650
+
1651
+ def digest(s):
1652
+ # Turn a shuffle of xlist with ylist into the appropriate
1653
+ # ordered set partition.
1654
+ s0 = [p[0] for p in s]
1655
+ s1 = [p[1] for p in s]
1656
+ N = len(s)
1657
+ bars = [False] * N
1658
+ for i in range(N - 1):
1659
+ s0i = s0[i]
1660
+ s0i1 = s0[i + 1]
1661
+ if s0i <= m and s0i1 <= m:
1662
+ bars[i + 1] = s1[i + 1]
1663
+ elif s0i > m and s0i1 > m:
1664
+ bars[i + 1] = s1[i + 1]
1665
+ elif s0i > m and s0i1 <= m:
1666
+ bars[i + 1] = True
1667
+ blocks = []
1668
+ block = []
1669
+ for i in range(N):
1670
+ if bars[i]:
1671
+ blocks.append(block)
1672
+ block = [s0[i]]
1673
+ else:
1674
+ block.append(s0[i])
1675
+ blocks.append(block)
1676
+ return K(blocks)
1677
+ return self.sum_of_monomials(digest(s) for s in ShuffleProduct(xlist, ylist))
1678
+
1679
+ def coproduct_on_basis(self, x):
1680
+ r"""
1681
+ Return the coproduct of ``self`` on the basis element
1682
+ indexed by the ordered set partition ``x``.
1683
+
1684
+ The coproduct of the basis element `\Phi_x` indexed by
1685
+ an ordered set partition `x` of `[n]` can be computed by the
1686
+ following formula ([NovThi06]_):
1687
+
1688
+ .. MATH::
1689
+
1690
+ \Delta \Phi_x
1691
+ = \sum \Phi_y \otimes \Phi_z ,
1692
+
1693
+ where the sum ranges over all pairs `(y, z)` of ordered set
1694
+ partitions `y` and `z` such that:
1695
+
1696
+ * `y` and `z` are ordered set partitions of two complementary
1697
+ subsets of `[n]`;
1698
+
1699
+ * `x` is obtained either by concatenating `y` and `z`, or by
1700
+ first concatenating `y` and `z` and then merging the two
1701
+ "middle blocks" (i.e., the last block of `y` and the first
1702
+ block of `z`); in the latter case, the maximum of the last
1703
+ block of `y` has to be smaller than the minimum of the first
1704
+ block of `z` (so that when merging these blocks, their
1705
+ entries don't need to be sorted).
1706
+
1707
+ EXAMPLES::
1708
+
1709
+ sage: Phi = algebras.WQSym(QQ).Phi()
1710
+
1711
+ sage: Phi.coproduct(Phi.one()) # indirect doctest
1712
+ Phi[] # Phi[]
1713
+ sage: Phi.coproduct( Phi([[1]]) ) # indirect doctest
1714
+ Phi[] # Phi[{1}] + Phi[{1}] # Phi[]
1715
+ sage: Phi.coproduct( Phi([[1,2]]) )
1716
+ Phi[] # Phi[{1, 2}] + Phi[{1}] # Phi[{1}] + Phi[{1, 2}] # Phi[]
1717
+ sage: Phi.coproduct( Phi([[1], [2]]) )
1718
+ Phi[] # Phi[{1}, {2}] + Phi[{1}] # Phi[{1}] + Phi[{1}, {2}] # Phi[]
1719
+ sage: Phi[[1,2],[3],[4]].coproduct()
1720
+ Phi[] # Phi[{1, 2}, {3}, {4}] + Phi[{1}] # Phi[{1}, {2}, {3}]
1721
+ + Phi[{1, 2}] # Phi[{1}, {2}] + Phi[{1, 2}, {3}] # Phi[{1}]
1722
+ + Phi[{1, 2}, {3}, {4}] # Phi[]
1723
+
1724
+ TESTS::
1725
+
1726
+ sage: M = algebras.WQSym(QQ).M()
1727
+ sage: x = Phi[[2, 4], [6], [1, 3], [5, 7]]
1728
+ sage: MM = M.tensor(M); AA = Phi.tensor(Phi)
1729
+ sage: AA(M(x).coproduct()) == x.coproduct()
1730
+ True
1731
+ """
1732
+ if not x:
1733
+ return self.one().tensor(self.one())
1734
+ K = self.indices()
1735
+
1736
+ def standardize(P): # standardize an ordered set partition
1737
+ base = sorted(sum((list(part) for part in P), []))
1738
+ # base is the ground set of P, as a sorted list.
1739
+ d = {val: i + 1 for i, val in enumerate(base)}
1740
+ # d is the unique order isomorphism from base to
1741
+ # {1, 2, ..., |base|} (encoded as dict).
1742
+ return K([[d[x] for x in part] for part in P])
1743
+ deconcatenates = [(x[:i], x[i:]) for i in range(len(x) + 1)]
1744
+ for i in range(len(x)):
1745
+ xi = sorted(x[i])
1746
+ for j in range(1, len(xi)):
1747
+ left = K(list(x[:i]) + [xi[:j]])
1748
+ right = K([xi[j:]] + list(x[i + 1:]))
1749
+ deconcatenates.append((left, right))
1750
+ T = self.tensor_square()
1751
+ return T.sum_of_monomials((standardize(left), standardize(right))
1752
+ for (left, right) in deconcatenates)
1753
+
1754
+ class Element(WQSymBasis_abstract.Element):
1755
+ def algebraic_complement(self):
1756
+ r"""
1757
+ Return the image of the element ``self`` of `WQSym`
1758
+ under the algebraic complement involution.
1759
+
1760
+ See
1761
+ :meth:`WQSymBases.ElementMethods.algebraic_complement`
1762
+ for a definition of the involution and for examples.
1763
+
1764
+ .. SEEALSO::
1765
+
1766
+ :meth:`coalgebraic_complement`, :meth:`star_involution`
1767
+
1768
+ EXAMPLES::
1769
+
1770
+ sage: WQSym = algebras.WQSym(ZZ)
1771
+ sage: Phi = WQSym.Phi()
1772
+ sage: Phi[[1],[2,4],[3]].algebraic_complement()
1773
+ -Phi[{3}, {2}, {4}, {1}] + Phi[{3}, {2, 4}, {1}] + Phi[{3}, {4}, {2}, {1}]
1774
+ sage: Phi[[1],[2,3],[4]].algebraic_complement()
1775
+ -Phi[{4}, {2}, {3}, {1}] + Phi[{4}, {2, 3}, {1}] + Phi[{4}, {3}, {2}, {1}]
1776
+
1777
+ TESTS::
1778
+
1779
+ sage: M = WQSym.M()
1780
+ sage: all(M(Phi[A]).algebraic_complement()
1781
+ ....: == M(Phi[A].algebraic_complement())
1782
+ ....: for A in OrderedSetPartitions(4))
1783
+ True
1784
+ """
1785
+ # See the WQSymBases.ElementMethods.algebraic_complement doc
1786
+ # for the formula we're using here.
1787
+ BR = self.base_ring()
1788
+ one = BR.one()
1789
+ mine = -one
1790
+ Phi = self.parent()
1791
+ OSPs = Phi.basis().keys()
1792
+ from sage.data_structures.blas_dict import linear_combination
1793
+
1794
+ def img(A):
1795
+ # The image of the basis element Phi[A], written as a
1796
+ # dictionary (of its coordinates in the Phi-basis).
1797
+ Rs = [Rr.reversed() for Rr in A.strongly_finer()]
1798
+ return {OSPs(P): (one if (len(R) % 2 == len(P) % 2)
1799
+ else mine)
1800
+ for R in Rs for P in R.strongly_finer()}
1801
+ return Phi._from_dict(linear_combination((img(A), c) for (A, c) in self))
1802
+
1803
+ def coalgebraic_complement(self):
1804
+ r"""
1805
+ Return the image of the element ``self`` of `WQSym`
1806
+ under the coalgebraic complement involution.
1807
+
1808
+ See
1809
+ :meth:`WQSymBases.ElementMethods.coalgebraic_complement`
1810
+ for a definition of the involution and for examples.
1811
+
1812
+ .. SEEALSO::
1813
+
1814
+ :meth:`algebraic_complement`, :meth:`star_involution`
1815
+
1816
+ EXAMPLES::
1817
+
1818
+ sage: WQSym = algebras.WQSym(ZZ)
1819
+ sage: Phi = WQSym.Phi()
1820
+ sage: Phi[[1],[2],[3,4]].coalgebraic_complement()
1821
+ -Phi[{4}, {3}, {1}, {2}] + Phi[{4}, {3}, {1, 2}] + Phi[{4}, {3}, {2}, {1}]
1822
+ sage: Phi[[2],[1,4],[3]].coalgebraic_complement()
1823
+ -Phi[{3}, {1}, {4}, {2}] + Phi[{3}, {1, 4}, {2}] + Phi[{3}, {4}, {1}, {2}]
1824
+
1825
+ TESTS::
1826
+
1827
+ sage: M = WQSym.M()
1828
+ sage: all(M(Phi[A]).coalgebraic_complement()
1829
+ ....: == M(Phi[A].coalgebraic_complement())
1830
+ ....: for A in OrderedSetPartitions(4))
1831
+ True
1832
+ """
1833
+ # See the WQSymBases.ElementMethods.coalgebraic_complement doc
1834
+ # for the formula we're using here.
1835
+ BR = self.base_ring()
1836
+ one = BR.one()
1837
+ mine = -one
1838
+ Phi = self.parent()
1839
+ OSPs = Phi.basis().keys()
1840
+ from sage.data_structures.blas_dict import linear_combination
1841
+
1842
+ def img(A):
1843
+ # The image of the basis element Phi[A], written as a
1844
+ # dictionary (of its coordinates in the Phi-basis).
1845
+ Rs = [Rr.complement() for Rr in A.strongly_finer()]
1846
+ return {OSPs(P): (one if (len(R) % 2 == len(P) % 2)
1847
+ else mine)
1848
+ for R in Rs for P in R.strongly_finer()}
1849
+ return Phi._from_dict(linear_combination((img(A), c) for (A, c) in self))
1850
+
1851
+ def star_involution(self):
1852
+ r"""
1853
+ Return the image of the element ``self`` of `WQSym`
1854
+ under the star involution.
1855
+
1856
+ See
1857
+ :meth:`WQSymBases.ElementMethods.star_involution`
1858
+ for a definition of the involution and for examples.
1859
+
1860
+ .. SEEALSO::
1861
+
1862
+ :meth:`algebraic_complement`, :meth:`coalgebraic_complement`
1863
+
1864
+ EXAMPLES::
1865
+
1866
+ sage: WQSym = algebras.WQSym(ZZ)
1867
+ sage: Phi = WQSym.Phi()
1868
+ sage: Phi[[1,2],[5,6],[3,4]].star_involution()
1869
+ Phi[{3, 4}, {1, 2}, {5, 6}]
1870
+ sage: Phi[[3], [1, 2], [4]].star_involution()
1871
+ Phi[{1}, {3, 4}, {2}]
1872
+
1873
+ TESTS::
1874
+
1875
+ sage: M = WQSym.M()
1876
+ sage: all(M(Phi[A]).star_involution() == M(Phi[A].star_involution())
1877
+ ....: for A in OrderedSetPartitions(4))
1878
+ True
1879
+ """
1880
+ # See the WQSymBases.ElementMethods.star_involution doc
1881
+ # for the formula we're using here.
1882
+ Phi = self.parent()
1883
+ OSPs = Phi.basis().keys()
1884
+ return Phi._from_dict({OSPs(A.complement().reversed()): c for (A, c) in self},
1885
+ remove_zeros=False)
1886
+
1887
+ Phi = StronglyFiner
1888
+
1889
+
1890
+ WQSymBasis_abstract.options = WordQuasiSymmetricFunctions.options
1891
+
1892
+
1893
+ class WQSymBases(Category_realization_of_parent):
1894
+ r"""
1895
+ The category of bases of `WQSym`.
1896
+ """
1897
+ def __init__(self, base, graded):
1898
+ r"""
1899
+ Initialize ``self``.
1900
+
1901
+ INPUT:
1902
+
1903
+ - ``base`` -- an instance of `WQSym`
1904
+ - ``graded`` -- boolean; if the basis is graded or filtered
1905
+
1906
+ TESTS::
1907
+
1908
+ sage: from sage.combinat.chas.wqsym import WQSymBases
1909
+ sage: WQSym = algebras.WQSym(ZZ)
1910
+ sage: bases = WQSymBases(WQSym, True)
1911
+ sage: WQSym.M() in bases
1912
+ True
1913
+ """
1914
+ self._graded = graded
1915
+ Category_realization_of_parent.__init__(self, base)
1916
+
1917
+ def _repr_(self):
1918
+ r"""
1919
+ Return the representation of ``self``.
1920
+
1921
+ EXAMPLES::
1922
+
1923
+ sage: from sage.combinat.chas.wqsym import WQSymBases
1924
+ sage: WQSym = algebras.WQSym(ZZ)
1925
+ sage: WQSymBases(WQSym, True)
1926
+ Category of graded bases of Word Quasi-symmetric functions over Integer Ring
1927
+ sage: WQSymBases(WQSym, False)
1928
+ Category of filtered bases of Word Quasi-symmetric functions over Integer Ring
1929
+ """
1930
+ if self._graded:
1931
+ type_str = "graded"
1932
+ else:
1933
+ type_str = "filtered"
1934
+ return "Category of {} bases of {}".format(type_str, self.base())
1935
+
1936
+ def super_categories(self):
1937
+ r"""
1938
+ The super categories of ``self``.
1939
+
1940
+ EXAMPLES::
1941
+
1942
+ sage: from sage.combinat.chas.wqsym import WQSymBases
1943
+ sage: WQSym = algebras.WQSym(ZZ)
1944
+ sage: bases = WQSymBases(WQSym, True)
1945
+ sage: bases.super_categories()
1946
+ [Category of realizations of Word Quasi-symmetric functions over Integer Ring,
1947
+ Join of Category of realizations of Hopf algebras over Integer Ring
1948
+ and Category of graded algebras over Integer Ring
1949
+ and Category of graded coalgebras over Integer Ring,
1950
+ Category of graded connected Hopf algebras with basis over Integer Ring]
1951
+
1952
+ sage: bases = WQSymBases(WQSym, False)
1953
+ sage: bases.super_categories()
1954
+ [Category of realizations of Word Quasi-symmetric functions over Integer Ring,
1955
+ Join of Category of realizations of Hopf algebras over Integer Ring
1956
+ and Category of graded algebras over Integer Ring
1957
+ and Category of graded coalgebras over Integer Ring,
1958
+ Join of Category of filtered connected Hopf algebras with basis over Integer Ring
1959
+ and Category of graded algebras over Integer Ring
1960
+ and Category of graded coalgebras over Integer Ring]
1961
+ """
1962
+ R = self.base().base_ring()
1963
+ cat = HopfAlgebras(R).Graded().WithBasis()
1964
+ if self._graded:
1965
+ cat = cat.Graded()
1966
+ else:
1967
+ cat = cat.Filtered()
1968
+ return [self.base().Realizations(),
1969
+ HopfAlgebras(R).Graded().Realizations(),
1970
+ cat.Connected()]
1971
+
1972
+ class ParentMethods:
1973
+ def _repr_(self):
1974
+ """
1975
+ Text representation of this basis of `WQSym`.
1976
+
1977
+ EXAMPLES::
1978
+
1979
+ sage: WQSym = algebras.WQSym(ZZ)
1980
+ sage: WQSym.M()
1981
+ Word Quasi-symmetric functions over Integer Ring in the Monomial basis
1982
+ """
1983
+ return "{} in the {} basis".format(self.realization_of(), self._basis_name)
1984
+
1985
+ def __getitem__(self, p):
1986
+ """
1987
+ Return the basis element indexed by ``p``.
1988
+
1989
+ INPUT:
1990
+
1991
+ - ``p`` -- an ordered set partition
1992
+
1993
+ EXAMPLES::
1994
+
1995
+ sage: M = algebras.WQSym(QQ).M()
1996
+ sage: M[1, 2, 1] # pass a word
1997
+ M[{1, 3}, {2}]
1998
+ sage: _ == M[[1, 2, 1]] == M[Word([1,2,1])]
1999
+ True
2000
+ sage: M[[1, 2, 3]]
2001
+ M[{1}, {2}, {3}]
2002
+
2003
+ sage: M[[[1, 2, 3]]] # pass an ordered set partition
2004
+ M[{1, 2, 3}]
2005
+ sage: _ == M[[1,2,3],] == M[OrderedSetPartition([[1,2,3]])]
2006
+ True
2007
+ sage: M[[1,3],[2]]
2008
+ M[{1, 3}, {2}]
2009
+
2010
+ TESTS::
2011
+
2012
+ sage: M[[]]
2013
+ M[]
2014
+ sage: M[1, 2, 1] == M[Word([2,3,2])] == M[Word('aca')]
2015
+ True
2016
+ sage: M[[[1,2]]] == M[1,1] == M[1/1,2/2] == M[2/1,2/1] == M['aa']
2017
+ True
2018
+ sage: M[1] == M[1,] == M[Word([1])] == M[OrderedSetPartition([[1]])] == M[[1],]
2019
+ True
2020
+ """
2021
+ if p in ZZ:
2022
+ p = [ZZ(p)]
2023
+ if all(s in ZZ for s in p):
2024
+ return self.monomial(self._indices.from_finite_word([ZZ(s) for s in p]))
2025
+
2026
+ if all(isinstance(s, str) for s in p):
2027
+ return self.monomial(self._indices.from_finite_word(p))
2028
+ try:
2029
+ return self.monomial(self._indices(p))
2030
+ except TypeError:
2031
+ raise ValueError("cannot convert %s into an element of %s" % (p, self._indices))
2032
+
2033
+ def is_field(self, proof=True):
2034
+ """
2035
+ Return whether ``self`` is a field.
2036
+
2037
+ EXAMPLES::
2038
+
2039
+ sage: M = algebras.WQSym(QQ).M()
2040
+ sage: M.is_field()
2041
+ False
2042
+ """
2043
+ return False
2044
+
2045
+ def is_commutative(self):
2046
+ """
2047
+ Return whether ``self`` is commutative.
2048
+
2049
+ EXAMPLES::
2050
+
2051
+ sage: M = algebras.WQSym(ZZ).M()
2052
+ sage: M.is_commutative()
2053
+ False
2054
+ """
2055
+ return self.base_ring().is_zero()
2056
+
2057
+ def one_basis(self):
2058
+ """
2059
+ Return the index of the unit.
2060
+
2061
+ EXAMPLES::
2062
+
2063
+ sage: A = algebras.WQSym(QQ).M()
2064
+ sage: A.one_basis()
2065
+ []
2066
+ """
2067
+ OSP = self.basis().keys()
2068
+ return OSP([])
2069
+
2070
+ def degree_on_basis(self, t):
2071
+ """
2072
+ Return the degree of an ordered set partition in
2073
+ the algebra of word quasi-symmetric functions.
2074
+
2075
+ This is the sum of the sizes of the blocks of the
2076
+ ordered set partition.
2077
+
2078
+ EXAMPLES::
2079
+
2080
+ sage: A = algebras.WQSym(QQ).M()
2081
+ sage: u = OrderedSetPartition([[2,1],])
2082
+ sage: A.degree_on_basis(u)
2083
+ 2
2084
+ sage: u = OrderedSetPartition([[2], [1]])
2085
+ sage: A.degree_on_basis(u)
2086
+ 2
2087
+ """
2088
+ return sum(len(part) for part in t)
2089
+
2090
+ class ElementMethods:
2091
+ def algebraic_complement(self):
2092
+ r"""
2093
+ Return the image of the element ``self`` of `WQSym`
2094
+ under the algebraic complement involution.
2095
+
2096
+ If `u = (u_1, u_2, \ldots, u_n)` is a packed word
2097
+ that contains the letters `1, 2, \ldots, k` and no
2098
+ others, then the *complement* of `u` is defined to
2099
+ be the packed word
2100
+ `\overline{u} := (k+1 - u_1, k+1 - u_2, \ldots, k+1 - u_n)`.
2101
+
2102
+ The algebraic complement involution is defined as the
2103
+ linear map `WQSym \to WQSym` that sends each basis
2104
+ element `\mathbf{M}_u` of the monomial basis of `WQSym`
2105
+ to the basis element `\mathbf{M}_{\overline{u}}`.
2106
+ This is a graded algebra automorphism and a coalgebra
2107
+ anti-automorphism of `WQSym`.
2108
+ Denoting by `\overline{f}` the image of an element
2109
+ `f \in WQSym` under the algebraic complement involution,
2110
+ it can be shown that every packed word `u` satisfies
2111
+
2112
+ .. MATH::
2113
+
2114
+ \overline{\mathbf{M}_u} = \mathbf{M}_{\overline{u}},
2115
+ \qquad \overline{X_u} = X_{\overline{u}},
2116
+
2117
+ where standard notations for classical bases of `WQSym`
2118
+ are being used (that is, `\mathbf{M}` for the monomial
2119
+ basis, and `X` for the characteristic basis).
2120
+
2121
+ This can be restated in terms of ordered set partitions:
2122
+ For any ordered set partition `R = (R_1, R_2, \ldots, R_k)`,
2123
+ let `R^r` denote the ordered set partition
2124
+ `(R_k, R_{k-1}, \ldots, R_1)`; this is known as
2125
+ the *reversal* of `R`. Then,
2126
+
2127
+ .. MATH::
2128
+
2129
+ \overline{\mathbf{M}_A} = \mathbf{M}_{A^r}, \qquad
2130
+ \overline{X_A} = X_{A^r}
2131
+
2132
+ for any ordered set partition `A`.
2133
+
2134
+ The formula describing algebraic complements on the Q basis
2135
+ (:class:`WordQuasiSymmetricFunctions.StronglyCoarser`)
2136
+ is more complicated, and requires some definitions.
2137
+ We define a partial order `\leq` on the set of all ordered
2138
+ set partitions as follows: `A \leq B` if and only if
2139
+ `A` is strongly finer than `B` (see
2140
+ :meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.is_strongly_finer`
2141
+ for a definition of this).
2142
+ The *length* `\ell(R)` of an ordered set partition `R` shall
2143
+ be defined as the number of parts of `R`.
2144
+ Use the notation `Q` for the Q basis.
2145
+ For any ordered set partition `A` of `[n]`, we have
2146
+
2147
+ .. MATH::
2148
+
2149
+ \overline{Q_A} = \sum_P c_{A, P} Q_P,
2150
+
2151
+ where the sum is over all ordered set partitions `P` of
2152
+ `[n]`, and where the coefficient `c_{A, P}` is defined
2153
+ as follows:
2154
+
2155
+ * If there exists an ordered set partition `R` satisfying
2156
+ `R \leq P` and `A \leq R^r`, then this `R` is unique,
2157
+ and `c_{A, P} = \left(-1\right)^{\ell(R) - \ell(P)}`.
2158
+
2159
+ * If there exists no such `R`, then `c_{A, P} = 0`.
2160
+
2161
+ The formula describing algebraic complements on the `\Phi`
2162
+ basis (:class:`WordQuasiSymmetricFunctions.StronglyFiner`)
2163
+ is identical to the above formula for the Q basis, except
2164
+ that the `\leq` sign has to be replaced by `\geq` in the
2165
+ definition of the coefficients `c_{A, P}`. In fact, both
2166
+ formulas are particular cases of a general formula for
2167
+ involutions:
2168
+ Assume that `V` is an (additive) abelian group, and that
2169
+ `I` is a poset. For each `i \in I`, let `M_i` be an element
2170
+ of `V`. Also, let `\omega` be an involution of the set `I`
2171
+ (not necessarily order-preserving or order-reversing),
2172
+ and let `\omega'` be an involutive group endomorphism of
2173
+ `V` such that each `i \in I` satisfies
2174
+ `\omega'(M_i) = M_{\omega(i)}`.
2175
+ For each `i \in I`, let `F_i = \sum_{j \geq i} M_j`,
2176
+ where we assume that the sum is finite.
2177
+ Then, each `i \in I` satisfies
2178
+
2179
+ .. MATH::
2180
+
2181
+ \omega'(F_i)
2182
+ = \sum_j \sum_{\substack{k \leq j; \\ \omega(k) \geq i}}
2183
+ \mu(k, j) F_j,
2184
+
2185
+ where `\mu` denotes the Möbius function. This formula becomes
2186
+ particularly useful when the `k` satisfying `k \leq j`
2187
+ and `\omega(k) \geq i` is unique (if it exists).
2188
+ In our situation, `V` is `WQSym`, and `I` is the set of
2189
+ ordered set partitions equipped either with the `\leq` partial
2190
+ order defined above or with its opposite order.
2191
+ The `M_i` is the `\mathbf{M}_A`, whereas the `F_i` is either
2192
+ `Q_i` or `\Phi_i`.
2193
+
2194
+ If we denote the star involution
2195
+ (:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution`)
2196
+ of the quasisymmetric functions by `f \mapsto f^{\ast}`,
2197
+ and if we let `\pi` be the canonical projection
2198
+ `WQSym \to QSym`, then each `f \in WQSym` satisfies
2199
+ `\pi(\overline{f}) = (\pi(f))^{\ast}`.
2200
+
2201
+ .. SEEALSO::
2202
+
2203
+ :meth:`coalgebraic_complement`, :meth:`star_involution`
2204
+
2205
+ EXAMPLES:
2206
+
2207
+ Recall that the index set for the bases of `WQSym` is
2208
+ given by ordered set partitions, not packed words.
2209
+ Translated into the language of ordered set partitions,
2210
+ the algebraic complement involution acts on the
2211
+ Monomial basis by reversing the ordered set partition.
2212
+ In other words, we have
2213
+
2214
+ .. MATH::
2215
+
2216
+ \overline{\mathbf{M}_{(P_1, P_2, \ldots, P_k)}}
2217
+ = \mathbf{M}_{(P_k, P_{k-1}, \ldots, P_1)}
2218
+
2219
+ for any standard ordered set partition
2220
+ `(P_1, P_2, \ldots, P_k)`. Let us check this in practice::
2221
+
2222
+ sage: WQSym = algebras.WQSym(ZZ)
2223
+ sage: M = WQSym.M()
2224
+ sage: M[[1,3],[2]].algebraic_complement()
2225
+ M[{2}, {1, 3}]
2226
+ sage: M[[1,4],[2,5],[3,6]].algebraic_complement()
2227
+ M[{3, 6}, {2, 5}, {1, 4}]
2228
+ sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).algebraic_complement()
2229
+ -4*M[] + 3*M[{1}] + 5*M[{2}, {1}]
2230
+ sage: X = WQSym.X()
2231
+ sage: X[[1,3],[2]].algebraic_complement()
2232
+ X[{2}, {1, 3}]
2233
+ sage: C = WQSym.C()
2234
+ sage: C[[1,3],[2]].algebraic_complement()
2235
+ -C[{1, 2, 3}] - C[{1, 3}, {2}] + C[{2}, {1, 3}]
2236
+ sage: Q = WQSym.Q()
2237
+ sage: Q[[1,2],[5,6],[3,4]].algebraic_complement()
2238
+ Q[{3, 4}, {1, 2, 5, 6}] + Q[{3, 4}, {5, 6}, {1, 2}] - Q[{3, 4, 5, 6}, {1, 2}]
2239
+ sage: Phi = WQSym.Phi()
2240
+ sage: Phi[[2], [1,3]].algebraic_complement()
2241
+ -Phi[{1}, {3}, {2}] + Phi[{1, 3}, {2}] + Phi[{3}, {1}, {2}]
2242
+
2243
+ The algebraic complement involution intertwines the antipode
2244
+ and the inverse of the antipode::
2245
+
2246
+ sage: all( M(I).antipode().algebraic_complement().antipode() # long time
2247
+ ....: == M(I).algebraic_complement()
2248
+ ....: for I in OrderedSetPartitions(4) )
2249
+ True
2250
+
2251
+ Testing the `\pi(\overline{f}) = (\pi(f))^{\ast}` relation::
2252
+
2253
+ sage: all( M[I].algebraic_complement().to_quasisymmetric_function()
2254
+ ....: == M[I].to_quasisymmetric_function().star_involution()
2255
+ ....: for I in OrderedSetPartitions(4) )
2256
+ True
2257
+
2258
+ .. TODO::
2259
+
2260
+ Check further commutative squares.
2261
+ """
2262
+ # Convert to the Monomial basis, there apply the algebraic
2263
+ # complement componentwise, then convert back.
2264
+ parent = self.parent()
2265
+ M = parent.realization_of().M()
2266
+ dct = {I.reversed(): coeff for (I, coeff) in M(self)}
2267
+ return parent(M._from_dict(dct, remove_zeros=False))
2268
+
2269
+ def coalgebraic_complement(self):
2270
+ r"""
2271
+ Return the image of the element ``self`` of `WQSym`
2272
+ under the coalgebraic complement involution.
2273
+
2274
+ If `u = (u_1, u_2, \ldots, u_n)` is a packed word,
2275
+ then the *reversal* of `u` is defined to be the
2276
+ packed word `(u_n, u_{n-1}, \ldots, u_1)`.
2277
+ This reversal is denoted by `u^r`.
2278
+
2279
+ The coalgebraic complement involution is defined as the
2280
+ linear map `WQSym \to WQSym` that sends each basis
2281
+ element `\mathbf{M}_u` of the monomial basis of `WQSym`
2282
+ to the basis element `\mathbf{M}_{u^r}`.
2283
+ This is a graded coalgebra automorphism and an algebra
2284
+ anti-automorphism of `WQSym`.
2285
+ Denoting by `f^r` the image of an element `f \in WQSym`
2286
+ under the coalgebraic complement involution,
2287
+ it can be shown that every packed word `u` satisfies
2288
+
2289
+ .. MATH::
2290
+
2291
+ (\mathbf{M}_u)^r = \mathbf{M}_{u^r}, \qquad
2292
+ (X_u)^r = X_{u^r},
2293
+
2294
+ where standard notations for classical bases of `WQSym`
2295
+ are being used (that is, `\mathbf{M}` for the monomial
2296
+ basis, and `X` for the characteristic basis).
2297
+
2298
+ This can be restated in terms of ordered set partitions:
2299
+ For any ordered set partition `R` of `[n]`, let
2300
+ `\overline{R}` denote the complement of `R` (defined in
2301
+ :meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.complement`).
2302
+ Then,
2303
+
2304
+ .. MATH::
2305
+
2306
+ (\mathbf{M}_A)^r = \mathbf{M}_{\overline{A}}, \qquad
2307
+ (X_A)^r = X_{\overline{A}}
2308
+
2309
+ for any ordered set partition `A`.
2310
+
2311
+ Recall that `WQSym` is a subring of the ring of all
2312
+ bounded-degree noncommutative power series in countably many
2313
+ indeterminates. The latter ring has an obvious continuous
2314
+ algebra anti-endomorphism which sends each letter `x_i` to
2315
+ `x_i` (and thus sends each monomial
2316
+ `x_{i_1} x_{i_2} \cdots x_{i_n}` to
2317
+ `x_{i_n} x_{i_{n-1}} \cdots x_{i_1}`).
2318
+ This anti-endomorphism is actually an involution.
2319
+ The coalgebraic complement involution is simply the
2320
+ restriction of this involution to the subring `WQSym`.
2321
+
2322
+ The formula describing coalgebraic complements on the Q basis
2323
+ (:class:`WordQuasiSymmetricFunctions.StronglyCoarser`)
2324
+ is more complicated, and requires some definitions.
2325
+ We define a partial order `\leq` on the set of all ordered
2326
+ set partitions as follows: `A \leq B` if and only if
2327
+ `A` is strongly finer than `B` (see
2328
+ :meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.is_strongly_finer`
2329
+ for a definition of this).
2330
+ The *length* `\ell(R)` of an ordered set partition `R` shall
2331
+ be defined as the number of parts of `R`.
2332
+ Use the notation `Q` for the Q basis.
2333
+ For any ordered set partition `A` of `[n]`, we have
2334
+
2335
+ .. MATH::
2336
+
2337
+ (Q_A)^r = \sum_P c_{A, P} Q_P ,
2338
+
2339
+ where the sum is over all ordered set partitions `P` of
2340
+ `[n]`, and where the coefficient `c_{A, P}` is defined
2341
+ as follows:
2342
+
2343
+ * If there exists an ordered set partition `R` satisfying
2344
+ `R \leq P` and `A \leq \overline{R}`, then this `R` is
2345
+ unique,
2346
+ and `c_{A, P} = \left(-1\right)^{\ell(R) - \ell(P)}`.
2347
+
2348
+ * If there exists no such `R`, then `c_{A, P} = 0`.
2349
+
2350
+ The formula describing coalgebraic complements on the `\Phi`
2351
+ basis (:class:`WordQuasiSymmetricFunctions.StronglyFiner`)
2352
+ is identical to the above formula for the Q basis, except
2353
+ that the `\leq` sign has to be replaced by `\geq` in the
2354
+ definition of the coefficients `c_{A, P}`. In fact, both
2355
+ formulas are particular cases of the general formula for
2356
+ involutions described in the documentation of
2357
+ :meth:`algebraic_complement`.
2358
+
2359
+ If we let `\pi` be the canonical projection
2360
+ `WQSym \to QSym`, then each `f \in WQSym` satisfies
2361
+ `\pi(f^r) = \pi(f)`.
2362
+
2363
+ .. SEEALSO::
2364
+
2365
+ :meth:`algebraic_complement`, :meth:`star_involution`
2366
+
2367
+ EXAMPLES:
2368
+
2369
+ Recall that the index set for the bases of `WQSym` is
2370
+ given by ordered set partitions, not packed words.
2371
+ Translated into the language of ordered set partitions,
2372
+ the coalgebraic complement involution acts on the
2373
+ Monomial basis by complementing the ordered set partition.
2374
+ In other words, we have
2375
+
2376
+ .. MATH::
2377
+
2378
+ (\mathbf{M}_A)^r = \mathbf{M}_{\overline{A}}
2379
+
2380
+ for any standard ordered set partition `P`.
2381
+ Let us check this in practice::
2382
+
2383
+ sage: WQSym = algebras.WQSym(ZZ)
2384
+ sage: M = WQSym.M()
2385
+ sage: M[[1,3],[2]].coalgebraic_complement()
2386
+ M[{1, 3}, {2}]
2387
+ sage: M[[1,2],[3]].coalgebraic_complement()
2388
+ M[{2, 3}, {1}]
2389
+ sage: M[[1], [4], [2,3]].coalgebraic_complement()
2390
+ M[{4}, {1}, {2, 3}]
2391
+ sage: M[[1,4],[2,5],[3,6]].coalgebraic_complement()
2392
+ M[{3, 6}, {2, 5}, {1, 4}]
2393
+ sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).coalgebraic_complement()
2394
+ -4*M[] + 3*M[{1}] + 5*M[{2}, {1}]
2395
+ sage: X = WQSym.X()
2396
+ sage: X[[1,3],[2]].coalgebraic_complement()
2397
+ X[{1, 3}, {2}]
2398
+ sage: C = WQSym.C()
2399
+ sage: C[[1,3],[2]].coalgebraic_complement()
2400
+ C[{1, 3}, {2}]
2401
+ sage: Q = WQSym.Q()
2402
+ sage: Q[[1,2],[5,6],[3,4]].coalgebraic_complement()
2403
+ Q[{1, 2, 5, 6}, {3, 4}] + Q[{5, 6}, {1, 2}, {3, 4}] - Q[{5, 6}, {1, 2, 3, 4}]
2404
+ sage: Phi = WQSym.Phi()
2405
+ sage: Phi[[2], [1,3]].coalgebraic_complement()
2406
+ -Phi[{2}, {1}, {3}] + Phi[{2}, {1, 3}] + Phi[{2}, {3}, {1}]
2407
+
2408
+ The coalgebraic complement involution intertwines the antipode
2409
+ and the inverse of the antipode::
2410
+
2411
+ sage: all( M(I).antipode().coalgebraic_complement().antipode() # long time
2412
+ ....: == M(I).coalgebraic_complement()
2413
+ ....: for I in OrderedSetPartitions(4) )
2414
+ True
2415
+
2416
+ Testing the `\pi(f^r) = \pi(f)` relation above::
2417
+
2418
+ sage: all( M[I].coalgebraic_complement().to_quasisymmetric_function()
2419
+ ....: == M[I].to_quasisymmetric_function()
2420
+ ....: for I in OrderedSetPartitions(4) )
2421
+ True
2422
+
2423
+ .. TODO::
2424
+
2425
+ Check further commutative squares.
2426
+ """
2427
+ # Convert to the Monomial basis, there apply the coalgebraic
2428
+ # complement componentwise, then convert back.
2429
+ parent = self.parent()
2430
+ M = parent.realization_of().M()
2431
+ dct = {I.complement(): coeff for (I, coeff) in M(self)}
2432
+ return parent(M._from_dict(dct, remove_zeros=False))
2433
+
2434
+ def star_involution(self):
2435
+ r"""
2436
+ Return the image of the element ``self`` of `WQSym`
2437
+ under the star involution.
2438
+
2439
+ The star involution is the composition of the
2440
+ algebraic complement involution
2441
+ (:meth:`algebraic_complement`) with the coalgebraic
2442
+ complement involution (:meth:`coalgebraic_complement`).
2443
+ The composition can be performed in either order, as the
2444
+ involutions commute.
2445
+
2446
+ The star involution is a graded Hopf algebra
2447
+ anti-automorphism of `WQSym`.
2448
+ Let `f^{\ast}` denote the image of an element
2449
+ `f \in WQSym` under the star involution.
2450
+ Let `\mathbf{M}`, `X`, `Q` and `\Phi` stand for the
2451
+ monomial, characteristic, Q and Phi bases of `WQSym`.
2452
+ For any ordered set partition `A` of `[n]`, we let
2453
+ `A^{\ast}` denote the complement
2454
+ (:meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.complement`)
2455
+ of the reversal
2456
+ (:meth:`~sage.combinat.set_partition_ordered.OrderedSetPartition.reversed`)
2457
+ of `A`. Then, for any ordered set partition `A` of `[n]`,
2458
+ we have
2459
+
2460
+ .. MATH::
2461
+
2462
+ (\mathbf{M}_A)^{\ast} = \mathbf{M}_{A^{\ast}}, \qquad
2463
+ (X_A)^{\ast} = X_{A^{\ast}}, \qquad
2464
+ (Q_A)^{\ast} = Q_{A^{\ast}}, \qquad
2465
+ (\Phi_A)^{\ast} = \Phi_{A^{\ast}} .
2466
+
2467
+ The star involution
2468
+ (:meth:`~sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.star_involution`)
2469
+ on the ring of noncommutative symmetric functions is a
2470
+ restriction of the star involution on `WQSym`.
2471
+
2472
+ If we denote the star involution
2473
+ (:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution`)
2474
+ of the quasisymmetric functions by `f \mapsto f^{\ast}`,
2475
+ and if we let `\pi` be the canonical projection
2476
+ `WQSym \to QSym`, then each `f \in WQSym` satisfies
2477
+ `\pi(f^{\ast}) = (\pi(f))^{\ast}`.
2478
+
2479
+ .. TODO::
2480
+
2481
+ More commutative diagrams?
2482
+ FQSym and FSym need their own star_involution
2483
+ methods defined first.
2484
+
2485
+ .. SEEALSO::
2486
+
2487
+ :meth:`algebraic_complement`, :meth:`coalgebraic_complement`
2488
+
2489
+ EXAMPLES:
2490
+
2491
+ Keep in mind that the default input method for basis keys
2492
+ of `WQSym` is by entering an ordered set partition, not a
2493
+ packed word. Let us check the basis formulas for the
2494
+ star involution::
2495
+
2496
+ sage: WQSym = algebras.WQSym(ZZ)
2497
+ sage: M = WQSym.M()
2498
+ sage: M[[1,3], [2,4,5]].star_involution()
2499
+ M[{1, 2, 4}, {3, 5}]
2500
+ sage: M[[1,3],[2]].star_involution()
2501
+ M[{2}, {1, 3}]
2502
+ sage: M[[1,4],[2,5],[3,6]].star_involution()
2503
+ M[{1, 4}, {2, 5}, {3, 6}]
2504
+ sage: (3*M[[1]] - 4*M[[]] + 5*M[[1],[2]]).star_involution()
2505
+ -4*M[] + 3*M[{1}] + 5*M[{1}, {2}]
2506
+ sage: X = WQSym.X()
2507
+ sage: X[[1,3],[2]].star_involution()
2508
+ X[{2}, {1, 3}]
2509
+ sage: C = WQSym.C()
2510
+ sage: C[[1,3],[2]].star_involution()
2511
+ -C[{1, 2, 3}] - C[{1, 3}, {2}] + C[{2}, {1, 3}]
2512
+ sage: Q = WQSym.Q()
2513
+ sage: Q[[1,3], [2,4,5]].star_involution()
2514
+ Q[{1, 2, 4}, {3, 5}]
2515
+ sage: Phi = WQSym.Phi()
2516
+ sage: Phi[[1,3], [2,4,5]].star_involution()
2517
+ Phi[{1, 2, 4}, {3, 5}]
2518
+
2519
+ Testing the formulas for `(Q_A)^{\ast}` and `(\Phi_A)^{\ast}`::
2520
+
2521
+ sage: all(Q[A].star_involution() == Q[A.complement().reversed()] for A in OrderedSetPartitions(4))
2522
+ True
2523
+ sage: all(Phi[A].star_involution() == Phi[A.complement().reversed()] for A in OrderedSetPartitions(4))
2524
+ True
2525
+
2526
+ The star involution commutes with the antipode::
2527
+
2528
+ sage: all( M(I).antipode().star_involution() # long time
2529
+ ....: == M(I).star_involution().antipode()
2530
+ ....: for I in OrderedSetPartitions(4) )
2531
+ True
2532
+
2533
+ Testing the `\pi(f^{\ast}) = (\pi(f))^{\ast}` relation::
2534
+
2535
+ sage: all( M[I].star_involution().to_quasisymmetric_function()
2536
+ ....: == M[I].to_quasisymmetric_function().star_involution()
2537
+ ....: for I in OrderedSetPartitions(4) )
2538
+ True
2539
+
2540
+ Testing the fact that the star involution on the
2541
+ noncommutative symmetric functions is a restriction of
2542
+ the star involution on `WQSym`::
2543
+
2544
+ sage: NCSF = NonCommutativeSymmetricFunctions(QQ)
2545
+ sage: R = NCSF.R()
2546
+ sage: all(R[I].star_involution().to_fqsym().to_wqsym()
2547
+ ....: == R[I].to_fqsym().to_wqsym().star_involution()
2548
+ ....: for I in Compositions(4))
2549
+ True
2550
+
2551
+ .. TODO::
2552
+
2553
+ Check further commutative squares.
2554
+ """
2555
+ # Convert to the Monomial basis, there apply the algebraic
2556
+ # complement componentwise, then convert back.
2557
+ parent = self.parent()
2558
+ M = parent.realization_of().M()
2559
+ dct = {I.reversed().complement(): coeff for (I, coeff) in M(self)}
2560
+ return parent(M._from_dict(dct, remove_zeros=False))
2561
+
2562
+ def to_quasisymmetric_function(self):
2563
+ r"""
2564
+ The projection of ``self`` to the ring `QSym` of
2565
+ quasisymmetric functions.
2566
+
2567
+ There is a canonical projection `\pi : WQSym \to QSym`
2568
+ that sends every element `\mathbf{M}_P` of the monomial
2569
+ basis of `WQSym` to the monomial quasisymmetric function
2570
+ `M_c`, where `c` is the composition whose parts are the
2571
+ sizes of the blocks of `P`.
2572
+ This `\pi` is a ring homomorphism.
2573
+
2574
+ OUTPUT: an element of the quasisymmetric functions in the monomial basis
2575
+
2576
+ EXAMPLES::
2577
+
2578
+ sage: M = algebras.WQSym(QQ).M()
2579
+ sage: M[[1,3],[2]].to_quasisymmetric_function()
2580
+ M[2, 1]
2581
+ sage: (M[[1,3],[2]] + 3*M[[2,3],[1]] - M[[1,2,3],]).to_quasisymmetric_function()
2582
+ 4*M[2, 1] - M[3]
2583
+ sage: X, Y = M[[1,3],[2]], M[[1,2,3],]
2584
+ sage: X.to_quasisymmetric_function() * Y.to_quasisymmetric_function() == (X*Y).to_quasisymmetric_function()
2585
+ True
2586
+
2587
+ sage: C = algebras.WQSym(QQ).C()
2588
+ sage: C[[2,3],[1,4]].to_quasisymmetric_function() == M(C[[2,3],[1,4]]).to_quasisymmetric_function()
2589
+ True
2590
+
2591
+ sage: C2 = algebras.WQSym(GF(2)).C()
2592
+ sage: C2[[1,2],[3,4]].to_quasisymmetric_function()
2593
+ M[2, 2]
2594
+ sage: C2[[2,3],[1,4]].to_quasisymmetric_function()
2595
+ M[4]
2596
+ """
2597
+ from sage.combinat.ncsf_qsym.qsym import QuasiSymmetricFunctions
2598
+ M = QuasiSymmetricFunctions(self.parent().base_ring()).Monomial()
2599
+ MW = self.parent().realization_of().M()
2600
+ return M.sum_of_terms((i.to_composition(), coeff)
2601
+ for (i, coeff) in MW(self))