passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.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 (401) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
  3. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  4. passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
  5. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  6. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  7. passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
  8. passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
  9. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  10. sage/algebras/all.py +24 -0
  11. sage/algebras/all__sagemath_combinat.py +35 -0
  12. sage/algebras/askey_wilson.py +935 -0
  13. sage/algebras/associated_graded.py +345 -0
  14. sage/algebras/cellular_basis.py +350 -0
  15. sage/algebras/cluster_algebra.py +2766 -0
  16. sage/algebras/down_up_algebra.py +860 -0
  17. sage/algebras/free_algebra.py +1698 -0
  18. sage/algebras/free_algebra_element.py +345 -0
  19. sage/algebras/free_algebra_quotient.py +405 -0
  20. sage/algebras/free_algebra_quotient_element.py +295 -0
  21. sage/algebras/free_zinbiel_algebra.py +885 -0
  22. sage/algebras/hall_algebra.py +783 -0
  23. sage/algebras/hecke_algebras/all.py +4 -0
  24. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  25. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  28. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  29. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  30. sage/algebras/jordan_algebra.py +1773 -0
  31. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  32. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  33. sage/algebras/lie_conformal_algebras/all.py +18 -0
  34. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  35. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  36. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  37. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  38. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  39. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  40. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  41. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  45. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  46. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  47. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  48. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  49. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  50. sage/algebras/nil_coxeter_algebra.py +191 -0
  51. sage/algebras/q_commuting_polynomials.py +673 -0
  52. sage/algebras/q_system.py +608 -0
  53. sage/algebras/quantum_clifford.py +959 -0
  54. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  55. sage/algebras/quantum_groups/all.py +9 -0
  56. sage/algebras/quantum_groups/fock_space.py +2219 -0
  57. sage/algebras/quantum_groups/q_numbers.py +207 -0
  58. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  59. sage/algebras/quantum_groups/representations.py +591 -0
  60. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  61. sage/algebras/quantum_oscillator.py +623 -0
  62. sage/algebras/quaternion_algebra.py +20 -0
  63. sage/algebras/quaternion_algebra_element.py +55 -0
  64. sage/algebras/rational_cherednik_algebra.py +525 -0
  65. sage/algebras/schur_algebra.py +670 -0
  66. sage/algebras/shuffle_algebra.py +1011 -0
  67. sage/algebras/splitting_algebra.py +779 -0
  68. sage/algebras/tensor_algebra.py +709 -0
  69. sage/algebras/yangian.py +1082 -0
  70. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  71. sage/all__sagemath_combinat.py +44 -0
  72. sage/combinat/SJT.py +255 -0
  73. sage/combinat/affine_permutation.py +2405 -0
  74. sage/combinat/algebraic_combinatorics.py +55 -0
  75. sage/combinat/all.py +53 -0
  76. sage/combinat/all__sagemath_combinat.py +195 -0
  77. sage/combinat/alternating_sign_matrix.py +2063 -0
  78. sage/combinat/baxter_permutations.py +346 -0
  79. sage/combinat/bijectionist.py +3220 -0
  80. sage/combinat/binary_recurrence_sequences.py +1180 -0
  81. sage/combinat/blob_algebra.py +685 -0
  82. sage/combinat/catalog_partitions.py +27 -0
  83. sage/combinat/chas/all.py +23 -0
  84. sage/combinat/chas/fsym.py +1180 -0
  85. sage/combinat/chas/wqsym.py +2601 -0
  86. sage/combinat/cluster_complex.py +326 -0
  87. sage/combinat/colored_permutations.py +2039 -0
  88. sage/combinat/colored_permutations_representations.py +964 -0
  89. sage/combinat/composition_signed.py +142 -0
  90. sage/combinat/composition_tableau.py +855 -0
  91. sage/combinat/constellation.py +1729 -0
  92. sage/combinat/core.py +751 -0
  93. sage/combinat/counting.py +12 -0
  94. sage/combinat/crystals/affine.py +742 -0
  95. sage/combinat/crystals/affine_factorization.py +518 -0
  96. sage/combinat/crystals/affinization.py +331 -0
  97. sage/combinat/crystals/alcove_path.py +2013 -0
  98. sage/combinat/crystals/all.py +22 -0
  99. sage/combinat/crystals/bkk_crystals.py +141 -0
  100. sage/combinat/crystals/catalog.py +115 -0
  101. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  102. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  103. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  104. sage/combinat/crystals/crystals.py +257 -0
  105. sage/combinat/crystals/direct_sum.py +260 -0
  106. sage/combinat/crystals/elementary_crystals.py +1251 -0
  107. sage/combinat/crystals/fast_crystals.py +441 -0
  108. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  109. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  110. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  111. sage/combinat/crystals/induced_structure.py +695 -0
  112. sage/combinat/crystals/infinity_crystals.py +730 -0
  113. sage/combinat/crystals/kac_modules.py +863 -0
  114. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  115. sage/combinat/crystals/kyoto_path_model.py +497 -0
  116. sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
  117. sage/combinat/crystals/letters.pxd +79 -0
  118. sage/combinat/crystals/letters.pyx +3056 -0
  119. sage/combinat/crystals/littelmann_path.py +1518 -0
  120. sage/combinat/crystals/monomial_crystals.py +1262 -0
  121. sage/combinat/crystals/multisegments.py +462 -0
  122. sage/combinat/crystals/mv_polytopes.py +467 -0
  123. sage/combinat/crystals/pbw_crystal.py +511 -0
  124. sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
  125. sage/combinat/crystals/pbw_datum.pxd +4 -0
  126. sage/combinat/crystals/pbw_datum.pyx +487 -0
  127. sage/combinat/crystals/polyhedral_realization.py +372 -0
  128. sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
  129. sage/combinat/crystals/spins.pxd +21 -0
  130. sage/combinat/crystals/spins.pyx +756 -0
  131. sage/combinat/crystals/star_crystal.py +290 -0
  132. sage/combinat/crystals/subcrystal.py +464 -0
  133. sage/combinat/crystals/tensor_product.py +1177 -0
  134. sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
  135. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  136. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  137. sage/combinat/crystals/virtual_crystal.py +420 -0
  138. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  139. sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
  140. sage/combinat/debruijn_sequence.pyx +355 -0
  141. sage/combinat/decorated_permutation.py +270 -0
  142. sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
  143. sage/combinat/degree_sequences.pyx +588 -0
  144. sage/combinat/derangements.py +527 -0
  145. sage/combinat/descent_algebra.py +1008 -0
  146. sage/combinat/diagram.py +1551 -0
  147. sage/combinat/diagram_algebras.py +5886 -0
  148. sage/combinat/dyck_word.py +4349 -0
  149. sage/combinat/e_one_star.py +1623 -0
  150. sage/combinat/enumerated_sets.py +123 -0
  151. sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
  152. sage/combinat/expnums.pyx +148 -0
  153. sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
  154. sage/combinat/fast_vector_partitions.pyx +346 -0
  155. sage/combinat/fqsym.py +1977 -0
  156. sage/combinat/free_dendriform_algebra.py +954 -0
  157. sage/combinat/free_prelie_algebra.py +1141 -0
  158. sage/combinat/fully_commutative_elements.py +1077 -0
  159. sage/combinat/fully_packed_loop.py +1523 -0
  160. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  161. sage/combinat/gray_codes.py +311 -0
  162. sage/combinat/grossman_larson_algebras.py +667 -0
  163. sage/combinat/growth.py +4352 -0
  164. sage/combinat/hall_polynomial.py +188 -0
  165. sage/combinat/hillman_grassl.py +866 -0
  166. sage/combinat/integer_matrices.py +329 -0
  167. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  168. sage/combinat/k_tableau.py +4564 -0
  169. sage/combinat/kazhdan_lusztig.py +215 -0
  170. sage/combinat/key_polynomial.py +885 -0
  171. sage/combinat/knutson_tao_puzzles.py +2286 -0
  172. sage/combinat/lr_tableau.py +311 -0
  173. sage/combinat/matrices/all.py +24 -0
  174. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  175. sage/combinat/matrices/latin.py +2912 -0
  176. sage/combinat/misc.py +401 -0
  177. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  178. sage/combinat/ncsf_qsym/all.py +21 -0
  179. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  180. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  181. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  182. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  183. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  184. sage/combinat/ncsym/all.py +21 -0
  185. sage/combinat/ncsym/bases.py +855 -0
  186. sage/combinat/ncsym/dual.py +593 -0
  187. sage/combinat/ncsym/ncsym.py +2076 -0
  188. sage/combinat/necklace.py +551 -0
  189. sage/combinat/non_decreasing_parking_function.py +634 -0
  190. sage/combinat/nu_dyck_word.py +1474 -0
  191. sage/combinat/output.py +861 -0
  192. sage/combinat/parallelogram_polyomino.py +4326 -0
  193. sage/combinat/parking_functions.py +1602 -0
  194. sage/combinat/partition_algebra.py +1998 -0
  195. sage/combinat/partition_kleshchev.py +1982 -0
  196. sage/combinat/partition_shifting_algebras.py +584 -0
  197. sage/combinat/partition_tuple.py +3114 -0
  198. sage/combinat/path_tableaux/all.py +13 -0
  199. sage/combinat/path_tableaux/catalog.py +29 -0
  200. sage/combinat/path_tableaux/dyck_path.py +380 -0
  201. sage/combinat/path_tableaux/frieze.py +476 -0
  202. sage/combinat/path_tableaux/path_tableau.py +728 -0
  203. sage/combinat/path_tableaux/semistandard.py +510 -0
  204. sage/combinat/perfect_matching.py +779 -0
  205. sage/combinat/plane_partition.py +3300 -0
  206. sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
  207. sage/combinat/q_bernoulli.pyx +128 -0
  208. sage/combinat/quickref.py +81 -0
  209. sage/combinat/recognizable_series.py +2051 -0
  210. sage/combinat/regular_sequence.py +4316 -0
  211. sage/combinat/regular_sequence_bounded.py +543 -0
  212. sage/combinat/restricted_growth.py +81 -0
  213. sage/combinat/ribbon.py +20 -0
  214. sage/combinat/ribbon_shaped_tableau.py +489 -0
  215. sage/combinat/ribbon_tableau.py +1180 -0
  216. sage/combinat/rigged_configurations/all.py +46 -0
  217. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  218. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  219. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  222. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  223. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  224. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  225. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  226. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  227. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  228. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  229. sage/combinat/rigged_configurations/bijection.py +143 -0
  230. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  231. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  232. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  233. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  234. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  235. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  236. sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  238. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  240. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  241. sage/combinat/rsk.py +3438 -0
  242. sage/combinat/schubert_polynomial.py +508 -0
  243. sage/combinat/set_partition.py +3318 -0
  244. sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
  245. sage/combinat/set_partition_iterator.pyx +136 -0
  246. sage/combinat/set_partition_ordered.py +1590 -0
  247. sage/combinat/sf/abreu_nigro.py +346 -0
  248. sage/combinat/sf/all.py +52 -0
  249. sage/combinat/sf/character.py +576 -0
  250. sage/combinat/sf/classical.py +319 -0
  251. sage/combinat/sf/dual.py +996 -0
  252. sage/combinat/sf/elementary.py +549 -0
  253. sage/combinat/sf/hall_littlewood.py +1028 -0
  254. sage/combinat/sf/hecke.py +336 -0
  255. sage/combinat/sf/homogeneous.py +464 -0
  256. sage/combinat/sf/jack.py +1428 -0
  257. sage/combinat/sf/k_dual.py +1458 -0
  258. sage/combinat/sf/kfpoly.py +447 -0
  259. sage/combinat/sf/llt.py +789 -0
  260. sage/combinat/sf/macdonald.py +2019 -0
  261. sage/combinat/sf/monomial.py +525 -0
  262. sage/combinat/sf/multiplicative.py +113 -0
  263. sage/combinat/sf/new_kschur.py +1786 -0
  264. sage/combinat/sf/ns_macdonald.py +964 -0
  265. sage/combinat/sf/orthogonal.py +246 -0
  266. sage/combinat/sf/orthotriang.py +355 -0
  267. sage/combinat/sf/powersum.py +963 -0
  268. sage/combinat/sf/schur.py +880 -0
  269. sage/combinat/sf/sf.py +1653 -0
  270. sage/combinat/sf/sfa.py +7053 -0
  271. sage/combinat/sf/symplectic.py +253 -0
  272. sage/combinat/sf/witt.py +721 -0
  273. sage/combinat/shifted_primed_tableau.py +2735 -0
  274. sage/combinat/shuffle.py +830 -0
  275. sage/combinat/sidon_sets.py +146 -0
  276. sage/combinat/similarity_class_type.py +1721 -0
  277. sage/combinat/sine_gordon.py +618 -0
  278. sage/combinat/six_vertex_model.py +784 -0
  279. sage/combinat/skew_partition.py +2053 -0
  280. sage/combinat/skew_tableau.py +2989 -0
  281. sage/combinat/sloane_functions.py +8935 -0
  282. sage/combinat/specht_module.py +1403 -0
  283. sage/combinat/species/all.py +48 -0
  284. sage/combinat/species/characteristic_species.py +321 -0
  285. sage/combinat/species/composition_species.py +273 -0
  286. sage/combinat/species/cycle_species.py +284 -0
  287. sage/combinat/species/empty_species.py +155 -0
  288. sage/combinat/species/functorial_composition_species.py +148 -0
  289. sage/combinat/species/generating_series.py +673 -0
  290. sage/combinat/species/library.py +148 -0
  291. sage/combinat/species/linear_order_species.py +169 -0
  292. sage/combinat/species/misc.py +83 -0
  293. sage/combinat/species/partition_species.py +290 -0
  294. sage/combinat/species/permutation_species.py +268 -0
  295. sage/combinat/species/product_species.py +423 -0
  296. sage/combinat/species/recursive_species.py +476 -0
  297. sage/combinat/species/set_species.py +192 -0
  298. sage/combinat/species/species.py +820 -0
  299. sage/combinat/species/structure.py +539 -0
  300. sage/combinat/species/subset_species.py +243 -0
  301. sage/combinat/species/sum_species.py +225 -0
  302. sage/combinat/subword.py +564 -0
  303. sage/combinat/subword_complex.py +2122 -0
  304. sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
  305. sage/combinat/subword_complex_c.pyx +119 -0
  306. sage/combinat/super_tableau.py +821 -0
  307. sage/combinat/superpartition.py +1154 -0
  308. sage/combinat/symmetric_group_algebra.py +3774 -0
  309. sage/combinat/symmetric_group_representations.py +1830 -0
  310. sage/combinat/t_sequences.py +877 -0
  311. sage/combinat/tableau.py +9506 -0
  312. sage/combinat/tableau_residues.py +860 -0
  313. sage/combinat/tableau_tuple.py +5353 -0
  314. sage/combinat/tiling.py +2432 -0
  315. sage/combinat/triangles_FHM.py +777 -0
  316. sage/combinat/tutorial.py +1857 -0
  317. sage/combinat/vector_partition.py +337 -0
  318. sage/combinat/words/abstract_word.py +1722 -0
  319. sage/combinat/words/all.py +59 -0
  320. sage/combinat/words/alphabet.py +268 -0
  321. sage/combinat/words/finite_word.py +7201 -0
  322. sage/combinat/words/infinite_word.py +113 -0
  323. sage/combinat/words/lyndon_word.py +652 -0
  324. sage/combinat/words/morphic.py +351 -0
  325. sage/combinat/words/morphism.py +3878 -0
  326. sage/combinat/words/paths.py +2932 -0
  327. sage/combinat/words/shuffle_product.py +278 -0
  328. sage/combinat/words/suffix_trees.py +1873 -0
  329. sage/combinat/words/word.py +769 -0
  330. sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
  331. sage/combinat/words/word_char.pyx +847 -0
  332. sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
  333. sage/combinat/words/word_datatypes.pxd +4 -0
  334. sage/combinat/words/word_datatypes.pyx +1067 -0
  335. sage/combinat/words/word_generators.py +2026 -0
  336. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  337. sage/combinat/words/word_options.py +99 -0
  338. sage/combinat/words/words.py +2396 -0
  339. sage/data_structures/all__sagemath_combinat.py +1 -0
  340. sage/databases/all__sagemath_combinat.py +13 -0
  341. sage/databases/findstat.py +4897 -0
  342. sage/databases/oeis.py +2058 -0
  343. sage/databases/sloane.py +393 -0
  344. sage/dynamics/all__sagemath_combinat.py +14 -0
  345. sage/dynamics/cellular_automata/all.py +7 -0
  346. sage/dynamics/cellular_automata/catalog.py +34 -0
  347. sage/dynamics/cellular_automata/elementary.py +612 -0
  348. sage/dynamics/cellular_automata/glca.py +477 -0
  349. sage/dynamics/cellular_automata/solitons.py +1463 -0
  350. sage/dynamics/finite_dynamical_system.py +1249 -0
  351. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  352. sage/games/all.py +7 -0
  353. sage/games/hexad.py +704 -0
  354. sage/games/quantumino.py +591 -0
  355. sage/games/sudoku.py +889 -0
  356. sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
  357. sage/games/sudoku_backtrack.pyx +189 -0
  358. sage/groups/all__sagemath_combinat.py +1 -0
  359. sage/groups/indexed_free_group.py +489 -0
  360. sage/libs/all__sagemath_combinat.py +6 -0
  361. sage/libs/lrcalc/__init__.py +1 -0
  362. sage/libs/lrcalc/lrcalc.py +525 -0
  363. sage/libs/symmetrica/__init__.py +7 -0
  364. sage/libs/symmetrica/all.py +101 -0
  365. sage/libs/symmetrica/kostka.pxi +168 -0
  366. sage/libs/symmetrica/part.pxi +193 -0
  367. sage/libs/symmetrica/plet.pxi +42 -0
  368. sage/libs/symmetrica/sab.pxi +196 -0
  369. sage/libs/symmetrica/sb.pxi +332 -0
  370. sage/libs/symmetrica/sc.pxi +192 -0
  371. sage/libs/symmetrica/schur.pxi +956 -0
  372. sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
  373. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  374. sage/libs/symmetrica/symmetrica.pyx +39 -0
  375. sage/monoids/all.py +13 -0
  376. sage/monoids/automatic_semigroup.py +1054 -0
  377. sage/monoids/free_abelian_monoid.py +315 -0
  378. sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
  379. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  380. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  381. sage/monoids/free_monoid.py +335 -0
  382. sage/monoids/free_monoid_element.py +431 -0
  383. sage/monoids/hecke_monoid.py +65 -0
  384. sage/monoids/string_monoid.py +817 -0
  385. sage/monoids/string_monoid_element.py +547 -0
  386. sage/monoids/string_ops.py +143 -0
  387. sage/monoids/trace_monoid.py +972 -0
  388. sage/rings/all__sagemath_combinat.py +2 -0
  389. sage/sat/all.py +4 -0
  390. sage/sat/boolean_polynomials.py +405 -0
  391. sage/sat/converters/__init__.py +6 -0
  392. sage/sat/converters/anf2cnf.py +14 -0
  393. sage/sat/converters/polybori.py +611 -0
  394. sage/sat/solvers/__init__.py +5 -0
  395. sage/sat/solvers/cryptominisat.py +287 -0
  396. sage/sat/solvers/dimacs.py +783 -0
  397. sage/sat/solvers/picosat.py +228 -0
  398. sage/sat/solvers/sat_lp.py +156 -0
  399. sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
  400. sage/sat/solvers/satsolver.pxd +3 -0
  401. sage/sat/solvers/satsolver.pyx +405 -0
sage/combinat/fqsym.py ADDED
@@ -0,0 +1,1977 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules
3
+ r"""
4
+ Free quasi-symmetric functions
5
+
6
+ AUTHORS:
7
+
8
+ - Frédéric Chapoton, Darij Grinberg (2017)
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2010-2015 Frédéric Chapoton <chapoton@unistra.fr>,
13
+ # Copyright (C) 2017 Darij Grinberg <dgrinber at umn.edu>
14
+ #
15
+ # Distributed under the terms of the GNU General Public License (GPL)
16
+ # as published by the Free Software Foundation; either version 2 of
17
+ # the License, or (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ # ****************************************************************************
20
+
21
+ from sage.misc.cachefunc import cached_method
22
+ from sage.misc.bindable_class import BindableClass
23
+ from sage.misc.lazy_attribute import lazy_attribute
24
+ from sage.misc.lazy_import import lazy_import
25
+ from sage.structure.parent import Parent
26
+ from sage.structure.unique_representation import UniqueRepresentation
27
+ from sage.categories.hopf_algebras import HopfAlgebras
28
+ from sage.categories.realizations import Category_realization_of_parent
29
+ from sage.combinat.free_module import CombinatorialFreeModule
30
+ from sage.combinat.permutation import Permutations, Permutation
31
+ from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra
32
+ from sage.combinat.words.word import Word
33
+
34
+ lazy_import('sage.groups.perm_gps.permgroup_element', 'PermutationGroupElement')
35
+
36
+
37
+ class FQSymBasis_abstract(CombinatorialFreeModule, BindableClass):
38
+ """
39
+ Abstract base class for bases of FQSym.
40
+
41
+ This must define two attributes:
42
+
43
+ - ``_prefix`` -- the basis prefix
44
+ - ``_basis_name`` -- the name of the basis and must match one
45
+ of the names that the basis can be constructed from FQSym
46
+ """
47
+
48
+ def __init__(self, alg):
49
+ r"""
50
+ Initialize ``self``.
51
+
52
+ EXAMPLES::
53
+
54
+ sage: TestSuite(algebras.FQSym(QQ).F()).run() # long time
55
+ """
56
+ CombinatorialFreeModule.__init__(self, alg.base_ring(),
57
+ Permutations(),
58
+ category=FQSymBases(alg),
59
+ bracket='', prefix=self._prefix)
60
+
61
+ def _coerce_map_from_(self, R):
62
+ r"""
63
+ Return ``True`` if there is a coercion from ``R`` into ``self``
64
+ and ``False`` otherwise.
65
+
66
+ The things that coerce into ``self`` are
67
+
68
+ - free quasi-symmetric functions over a base with
69
+ a coercion map into ``self.base_ring()``
70
+ - free symmetric functions over a base with
71
+ a coercion map into ``self.base_ring()``
72
+
73
+ EXAMPLES::
74
+
75
+ sage: F = algebras.FQSym(GF(7)).F(); F
76
+ Free Quasi-symmetric functions over Finite Field of size 7 in the F basis
77
+
78
+ Elements of the free quasi-symmetric functions canonically coerce in::
79
+
80
+ sage: x, y, z = F([1]), F([2,1]), F([1,3,2])
81
+ sage: F.coerce(x+y) == x+y
82
+ True
83
+
84
+ The free quasi-symmetric functions over `\ZZ` coerces in,
85
+ since `\ZZ` coerces to `\GF{7}`::
86
+
87
+ sage: G = algebras.FQSym(ZZ).F()
88
+ sage: Gx, Gy = G([1]), G([2,1])
89
+ sage: z = F.coerce(Gx+Gy); z
90
+ F[1] + F[2, 1]
91
+ sage: z.parent() is F
92
+ True
93
+
94
+ However, `\GF{7}` does not coerce to `\ZZ`, so free
95
+ quasi-symmetric functions over `\GF{7}` does not coerce
96
+ to the same algebra over `\ZZ`::
97
+
98
+ sage: G.coerce(y)
99
+ Traceback (most recent call last):
100
+ ...
101
+ TypeError: no canonical coercion from Free Quasi-symmetric functions
102
+ over Finite Field of size 7 in the F basis to
103
+ Free Quasi-symmetric functions over Integer Ring in the F basis
104
+
105
+ Check that `FSym` bases coerce in::
106
+
107
+ sage: FSym = algebras.FSym(ZZ)
108
+ sage: TG = FSym.G()
109
+ sage: t = StandardTableau([[1,3],[2,4],[5]])
110
+ sage: F(TG[t])
111
+ F[2, 1, 5, 4, 3] + F[2, 5, 1, 4, 3] + F[2, 5, 4, 1, 3]
112
+ + F[5, 2, 1, 4, 3] + F[5, 2, 4, 1, 3]
113
+ sage: algebras.FQSym(QQ)(TG[t])
114
+ F[2, 1, 5, 4, 3] + F[2, 5, 1, 4, 3] + F[2, 5, 4, 1, 3]
115
+ + F[5, 2, 1, 4, 3] + F[5, 2, 4, 1, 3]
116
+ sage: G7 = algebras.FQSym(GF(7)).G()
117
+ sage: G7(TG[[1,2],[3,4]])
118
+ G[2, 4, 1, 3] + G[3, 4, 1, 2]
119
+
120
+ TESTS::
121
+
122
+ sage: F = algebras.FQSym(ZZ).F()
123
+ sage: G = algebras.FQSym(QQ).F()
124
+ sage: F.has_coerce_map_from(G)
125
+ False
126
+ sage: G.has_coerce_map_from(F)
127
+ True
128
+ sage: F.has_coerce_map_from(QQ)
129
+ False
130
+ sage: G.has_coerce_map_from(QQ)
131
+ True
132
+ sage: F.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z'))
133
+ False
134
+ """
135
+ # free quasi-symmetric functions in the same variables
136
+ # over any base that coerces in:
137
+ if isinstance(R, FQSymBasis_abstract):
138
+ if R.realization_of() == self.realization_of():
139
+ return True
140
+ if not self.base_ring().has_coerce_map_from(R.base_ring()):
141
+ return False
142
+ if self._basis_name == R._basis_name: # The same basis
143
+ def coerce_base_ring(self, x):
144
+ return self._from_dict(x.monomial_coefficients())
145
+ return coerce_base_ring
146
+ # Otherwise lift that basis up and then coerce over
147
+ target = getattr(self.realization_of(), R._basis_name)()
148
+ return self._coerce_map_via([target], R)
149
+
150
+ # FSym coerces in:
151
+ from sage.combinat.chas.fsym import FreeSymmetricFunctions
152
+ if isinstance(R, FreeSymmetricFunctions.Fundamental):
153
+ if not self.base_ring().has_coerce_map_from(R.base_ring()):
154
+ return False
155
+ G = self.realization_of().G()
156
+ P = G._indices
157
+
158
+ def G_to_G_on_basis(t):
159
+ return G.sum_of_monomials(P(sigma) for sigma in Permutations(t.size())
160
+ if sigma.right_tableau() == t)
161
+ phi = R.module_morphism(G_to_G_on_basis, codomain=G)
162
+ if self is G:
163
+ return phi
164
+ else:
165
+ return self.coerce_map_from(G) * phi
166
+
167
+ return super()._coerce_map_from_(R)
168
+
169
+ def _an_element_(self):
170
+ """
171
+ Return an element of ``self``.
172
+
173
+ EXAMPLES::
174
+
175
+ sage: A = algebras.FQSym(QQ)
176
+ sage: F = A.F()
177
+ sage: F.an_element()
178
+ F[1] + 2*F[1, 2] + 2*F[2, 1]
179
+ sage: G = A.G()
180
+ sage: G.an_element()
181
+ G[1] + 2*G[1, 2] + 2*G[2, 1]
182
+ sage: M = A.M()
183
+ sage: M.an_element()
184
+ M[1] + 2*M[1, 2] + 4*M[2, 1]
185
+ """
186
+ o = self.monomial(Permutation([1]))
187
+ return o + 2 * o * o
188
+
189
+
190
+ class FreeQuasisymmetricFunctions(UniqueRepresentation, Parent):
191
+ r"""
192
+ The free quasi-symmetric functions.
193
+
194
+ The Hopf algebra `FQSym` of free quasi-symmetric functions
195
+ over a commutative ring `R` is the free `R`-module with basis
196
+ indexed by all permutations (i.e., the indexing set is
197
+ the disjoint union of all symmetric groups).
198
+ Its product is determined by the shifted shuffles of two
199
+ permutations, whereas its coproduct is given by splitting
200
+ a permutation (regarded as a word) into two (at every
201
+ possible point) and standardizing the two pieces.
202
+ This Hopf algebra was introduced in [MR]_.
203
+ See [GriRei18]_ (Chapter 8) for a treatment using modern
204
+ notations.
205
+
206
+ In more detail:
207
+ For each `n \geq 0`, consider the symmetric group `S_n`.
208
+ Let `S` be the disjoint union of the `S_n` over all
209
+ `n \geq 0`.
210
+ Then, `FQSym` is the free `R`-module with basis
211
+ `(F_w)_{w \in S}`.
212
+ This `R`-module is graded, with the `n`-th graded
213
+ component being spanned by all `F_w` for `w \in S_n`.
214
+ A multiplication is defined on `FQSym` as follows:
215
+ For any two permutations `u \in S_k` and `v \in S_l`,
216
+ we set
217
+
218
+ .. MATH::
219
+
220
+ F_u F_v = \sum F_w ,
221
+
222
+ where the sum is over all shuffles of `u` with `v[k]`.
223
+ Here, the permutations `u` and `v` are regarded as words
224
+ (by writing them in one-line notation), and `v[k]` means
225
+ the word obtained from `v` by increasing each letter by
226
+ `k` (for example, `(1,4,2,3)[5] = (6,9,7,8)`); and the
227
+ shuffles `w` are translated back into permutations.
228
+ This defines an associative multiplication on `FQSym`;
229
+ its unity is `F_e`, where `e` is the identity
230
+ permutation in `S_0`.
231
+
232
+ In Section 1.3 of [AguSot05]_, Aguiar and Sottile construct a
233
+ different basis of `FQSym`. Their basis, called the
234
+ *monomial basis* and denoted by `(\mathcal{M}_u)`,
235
+ is also indexed by permutations. It is connected to the
236
+ above F-basis by the relation
237
+
238
+ .. MATH::
239
+
240
+ F_u = \sum_v \mathcal{M}_v ,
241
+
242
+ where the sum ranges over all permutations `v` such that each
243
+ inversion of `u` is an inversion of `v`. (An *inversion* of a
244
+ permutation `w` means a pair `(i, j)` of positions satisfying
245
+ `i < j` and `w(i) > w(j)`.) The above relation yields a
246
+ unitriangular change-of-basis matrix, and thus can be used to
247
+ compute the `\mathcal{M}_u` by Mobius inversion.
248
+
249
+ Another classical basis of `FQSym` is `(G_w)_{w \in S}`,
250
+ where `G_w = F_{w^{-1}}`.
251
+ This is just a relabeling of the basis `(F_w)_{w \in S}`,
252
+ but is a more natural choice from some viewpoints.
253
+
254
+ The algebra `FQSym` is often identified with ("realized as") a
255
+ subring of the ring of all bounded-degree noncommutative power
256
+ series in countably many indeterminates (i.e., elements in
257
+ `R \langle \langle x_1, x_2, x_3, \ldots \rangle \rangle` of bounded
258
+ degree). Namely, consider words over the alphabet `\{1, 2, 3, \ldots\}`;
259
+ every noncommutative power series is an infinite `R`-linear
260
+ combination of these words.
261
+ Consider the `R`-linear map that sends each `G_u` to the sum of
262
+ all words whose standardization (also known as "standard
263
+ permutation"; see
264
+ :meth:`~sage.combinat.words.finite_word.FiniteWord_class.standard_permutation`)
265
+ is `u`. This map is an injective `R`-algebra homomorphism, and
266
+ thus embeds `FQSym` into the latter ring.
267
+
268
+ As an associative algebra, `FQSym` has the richer structure
269
+ of a dendriform algebra. This means that the associative
270
+ product ``*`` is decomposed as a sum of two binary operations
271
+
272
+ .. MATH::
273
+
274
+ x y = x \succ y + x \prec y
275
+
276
+ that satisfy the axioms:
277
+
278
+ .. MATH::
279
+
280
+ (x \succ y) \prec z = x \succ (y \prec z),
281
+
282
+ .. MATH::
283
+
284
+ (x \prec y) \prec z = x \prec (y z),
285
+
286
+ .. MATH::
287
+
288
+ (x y) \succ z = x \succ (y \succ z).
289
+
290
+ These two binary operations are defined similarly to the
291
+ (associative) product above: We set
292
+
293
+ .. MATH::
294
+
295
+ F_u \prec F_v = \sum F_w ,
296
+
297
+ where the sum is now over all shuffles of `u` with `v[k]`
298
+ whose first letter is taken from `u` (rather than from
299
+ `v[k]`). Similarly,
300
+
301
+ .. MATH::
302
+
303
+ F_u \succ F_v = \sum F_w ,
304
+
305
+ where the sum is over all remaining shuffles of `u` with
306
+ `v[k]`.
307
+
308
+ .. TODO::
309
+
310
+ Decide what `1 \prec 1` and `1 \succ 1` are.
311
+
312
+ .. NOTE::
313
+
314
+ The usual binary operator ``*`` is used for the
315
+ associative product.
316
+
317
+ EXAMPLES::
318
+
319
+ sage: F = algebras.FQSym(ZZ).F()
320
+ sage: x,y,z = F([1]), F([1,2]), F([1,3,2])
321
+ sage: (x * y) * z
322
+ F[1, 2, 3, 4, 6, 5] + ...
323
+
324
+ The product of `FQSym` is associative::
325
+
326
+ sage: x * (y * z) == (x * y) * z
327
+ True
328
+
329
+ The associative product decomposes into two parts::
330
+
331
+ sage: x * y == F.prec(x, y) + F.succ(x, y)
332
+ True
333
+
334
+ The axioms of a dendriform algebra hold::
335
+
336
+ sage: F.prec(F.succ(x, y), z) == F.succ(x, F.prec(y, z))
337
+ True
338
+ sage: F.prec(F.prec(x, y), z) == F.prec(x, y * z)
339
+ True
340
+ sage: F.succ(x * y, z) == F.succ(x, F.succ(y, z))
341
+ True
342
+
343
+ `FQSym` is also known as the Malvenuto-Reutenauer algebra::
344
+
345
+ sage: algebras.MalvenutoReutenauer(ZZ)
346
+ Free Quasi-symmetric functions over Integer Ring
347
+
348
+ REFERENCES:
349
+
350
+ - [MR]_
351
+ - [LR1998]_
352
+ - [GriRei18]_
353
+ """
354
+
355
+ def __init__(self, R):
356
+ """
357
+ Initialize ``self``.
358
+
359
+ TESTS::
360
+
361
+ sage: A = algebras.FQSym(QQ); A
362
+ Free Quasi-symmetric functions over Rational Field
363
+ sage: TestSuite(A).run() # long time (3s)
364
+
365
+ sage: F = algebras.FQSym(QQ)
366
+ sage: TestSuite(F).run() # long time (3s)
367
+ """
368
+ category = HopfAlgebras(R).Graded().Connected()
369
+ Parent.__init__(self, base=R, category=category.WithRealizations())
370
+
371
+ # Bases
372
+ F = self.F()
373
+ G = self.G()
374
+
375
+ F.module_morphism(G._F_to_G_on_basis,
376
+ codomain=G, category=category).register_as_coercion()
377
+ G.module_morphism(G._G_to_F_on_basis,
378
+ codomain=F, category=category).register_as_coercion()
379
+
380
+ def _repr_(self):
381
+ """
382
+ Return the string representation of ``self``.
383
+
384
+ EXAMPLES::
385
+
386
+ sage: algebras.FQSym(QQ) # indirect doctest
387
+ Free Quasi-symmetric functions over Rational Field
388
+ """
389
+ s = "Free Quasi-symmetric functions over {}"
390
+ return s.format(self.base_ring())
391
+
392
+ def a_realization(self):
393
+ r"""
394
+ Return a particular realization of ``self`` (the F-basis).
395
+
396
+ EXAMPLES::
397
+
398
+ sage: FQSym = algebras.FQSym(QQ)
399
+ sage: FQSym.a_realization()
400
+ Free Quasi-symmetric functions over Rational Field in the F basis
401
+ """
402
+ return self.F()
403
+
404
+ _shorthands = tuple(['F', 'G', 'M'])
405
+
406
+ class F(FQSymBasis_abstract):
407
+ r"""
408
+ The F-basis of `FQSym`.
409
+
410
+ This is the basis `(F_w)`, with `w` ranging over all
411
+ permutations. See the documentation of
412
+ :class:`FreeQuasisymmetricFunctions` for details.
413
+
414
+ EXAMPLES::
415
+
416
+ sage: FQSym = algebras.FQSym(QQ)
417
+ sage: FQSym.F()
418
+ Free Quasi-symmetric functions over Rational Field in the F basis
419
+ """
420
+ _prefix = "F"
421
+ _basis_name = "F"
422
+
423
+ def _element_constructor_(self, x):
424
+ r"""
425
+ Convert ``x`` into ``self``.
426
+
427
+ EXAMPLES::
428
+
429
+ sage: R = algebras.FQSym(QQ).F()
430
+ sage: x, y, z = R([1]), R([2,1]), R([3,2,1])
431
+ sage: R(x)
432
+ F[1]
433
+ sage: R(x+4*y)
434
+ F[1] + 4*F[2, 1]
435
+ sage: R(1)
436
+ F[]
437
+
438
+ sage: D = algebras.FQSym(ZZ).F()
439
+ sage: X, Y, Z = D([1]), D([2,1]), D([3,2,1])
440
+ sage: R(X-Y).parent()
441
+ Free Quasi-symmetric functions over Rational Field in the F basis
442
+
443
+ sage: R([1, 3, 2])
444
+ F[1, 3, 2]
445
+ sage: R(Permutation([1, 3, 2]))
446
+ F[1, 3, 2]
447
+ sage: R(SymmetricGroup(4)(Permutation([1,3,4,2])))
448
+ F[1, 3, 4, 2]
449
+ """
450
+ if isinstance(x, (list, tuple, PermutationGroupElement)):
451
+ x = Permutation(x)
452
+ try:
453
+ P = x.parent()
454
+ if isinstance(P, FreeQuasisymmetricFunctions.F):
455
+ if P is self:
456
+ return x
457
+ return self.element_class(self, x.monomial_coefficients())
458
+ except AttributeError:
459
+ pass
460
+ return CombinatorialFreeModule._element_constructor_(self, x)
461
+
462
+ def __getitem__(self, r):
463
+ r"""
464
+ The default implementation of ``__getitem__`` interprets
465
+ the input as a tuple, which in case of permutations
466
+ is interpreted as cycle notation, even though the input
467
+ looks like a one-line notation.
468
+ We override this method to amend this.
469
+
470
+ EXAMPLES::
471
+
472
+ sage: F = algebras.FQSym(QQ).F()
473
+ sage: F[3, 2, 1]
474
+ F[3, 2, 1]
475
+ sage: F[1]
476
+ F[1]
477
+ """
478
+ if isinstance(r, tuple):
479
+ r = list(r)
480
+ elif r == 1:
481
+ r = [1]
482
+ return super().__getitem__(r)
483
+
484
+ def degree_on_basis(self, t):
485
+ """
486
+ Return the degree of a permutation in
487
+ the algebra of free quasi-symmetric functions.
488
+
489
+ This is the size of the permutation (i.e., the `n`
490
+ for which the permutation belongs to `S_n`).
491
+
492
+ EXAMPLES::
493
+
494
+ sage: A = algebras.FQSym(QQ).F()
495
+ sage: u = Permutation([2,1])
496
+ sage: A.degree_on_basis(u)
497
+ 2
498
+ """
499
+ return len(t)
500
+
501
+ def product_on_basis(self, x, y):
502
+ r"""
503
+ Return the `*` associative product of two permutations.
504
+
505
+ This is the shifted shuffle of `x` and `y`.
506
+
507
+ .. SEEALSO::
508
+
509
+ :meth:`succ_product_on_basis`, :meth:`prec_product_on_basis`
510
+
511
+ EXAMPLES::
512
+
513
+ sage: A = algebras.FQSym(QQ).F()
514
+ sage: x = Permutation([1])
515
+ sage: A.product_on_basis(x, x)
516
+ F[1, 2] + F[2, 1]
517
+ """
518
+ return self.sum_of_monomials(u for u in x.shifted_shuffle(y))
519
+
520
+ def succ_product_on_basis(self, x, y):
521
+ r"""
522
+ Return the `\succ` product of two permutations.
523
+
524
+ This is the shifted shuffle of `x` and `y` with the additional
525
+ condition that the first letter of the result comes from `y`.
526
+
527
+ The usual symbol for this operation is `\succ`.
528
+
529
+ .. SEEALSO::
530
+
531
+ - :meth:`product_on_basis`, :meth:`prec_product_on_basis`
532
+
533
+ EXAMPLES::
534
+
535
+ sage: A = algebras.FQSym(QQ).F()
536
+ sage: x = Permutation([1,2])
537
+ sage: A.succ_product_on_basis(x, x)
538
+ F[3, 1, 2, 4] + F[3, 1, 4, 2] + F[3, 4, 1, 2]
539
+ sage: y = Permutation([])
540
+ sage: A.succ_product_on_basis(x, y) == 0
541
+ True
542
+ sage: A.succ_product_on_basis(y, x) == A(x)
543
+ True
544
+
545
+ TESTS::
546
+
547
+ sage: u = A.one().support()[0] # this is F[]
548
+ sage: A.succ_product_on_basis(x, u)
549
+ 0
550
+ sage: A.succ_product_on_basis(u, x)
551
+ F[1, 2]
552
+ sage: A.succ_product_on_basis(u, u)
553
+ Traceback (most recent call last):
554
+ ...
555
+ ValueError: products | < | and | > | are not defined
556
+ """
557
+ if not y:
558
+ if not x:
559
+ raise ValueError("products | < | and | > | are not defined")
560
+ else:
561
+ return self.zero()
562
+ basis = self.basis()
563
+ if not x:
564
+ return basis[y]
565
+ K = basis.keys()
566
+ n = len(x)
567
+ shy = Word([a + n for a in y])
568
+ shy0 = shy[0]
569
+ return self.sum_of_monomials(K([shy0] + list(u))
570
+ for u in Word(x).shuffle(Word(shy[1:])))
571
+
572
+ def prec_product_on_basis(self, x, y):
573
+ r"""
574
+ Return the `\prec` product of two permutations.
575
+
576
+ This is the shifted shuffle of `x` and `y` with the additional
577
+ condition that the first letter of the result comes from `x`.
578
+
579
+ The usual symbol for this operation is `\prec`.
580
+
581
+ .. SEEALSO::
582
+
583
+ :meth:`product_on_basis`, :meth:`succ_product_on_basis`
584
+
585
+ EXAMPLES::
586
+
587
+ sage: A = algebras.FQSym(QQ).F()
588
+ sage: x = Permutation([1,2])
589
+ sage: A.prec_product_on_basis(x, x)
590
+ F[1, 2, 3, 4] + F[1, 3, 2, 4] + F[1, 3, 4, 2]
591
+ sage: y = Permutation([])
592
+ sage: A.prec_product_on_basis(x, y) == A(x)
593
+ True
594
+ sage: A.prec_product_on_basis(y, x) == 0
595
+ True
596
+
597
+ TESTS::
598
+
599
+ sage: u = A.one().support()[0] # this is F[]
600
+ sage: A.prec_product_on_basis(x, u)
601
+ F[1, 2]
602
+ sage: A.prec_product_on_basis(u, x)
603
+ 0
604
+ sage: A.prec_product_on_basis(u, u)
605
+ Traceback (most recent call last):
606
+ ...
607
+ ValueError: products | < | and | > | are not defined
608
+ """
609
+ if not x and not y:
610
+ raise ValueError("products | < | and | > | are not defined")
611
+ if not x:
612
+ return self.zero()
613
+ basis = self.basis()
614
+ if not y:
615
+ return basis[x]
616
+ K = basis.keys()
617
+ n = len(x)
618
+ shy = Word([a + n for a in y])
619
+ x0 = x[0]
620
+ return self.sum_of_monomials(K([x0] + list(u))
621
+ for u in Word(x[1:]).shuffle(shy))
622
+
623
+ def coproduct_on_basis(self, x):
624
+ r"""
625
+ Return the coproduct of `F_{\sigma}` for `\sigma` a permutation
626
+ (here, `\sigma` is ``x``).
627
+
628
+ EXAMPLES::
629
+
630
+ sage: A = algebras.FQSym(QQ).F()
631
+ sage: x = A([1])
632
+ sage: ascii_art(A.coproduct(A.one())) # indirect doctest
633
+ 1 # 1
634
+
635
+ sage: ascii_art(A.coproduct(x)) # indirect doctest
636
+ 1 # F + F # 1
637
+ [1] [1]
638
+
639
+ sage: A = algebras.FQSym(QQ).F()
640
+ sage: x, y, z = A([1]), A([2,1]), A([3,2,1])
641
+ sage: A.coproduct(z)
642
+ F[] # F[3, 2, 1] + F[1] # F[2, 1] + F[2, 1] # F[1]
643
+ + F[3, 2, 1] # F[]
644
+ """
645
+ if not x:
646
+ return self.one().tensor(self.one())
647
+ return sum(self(Word(x[:i]).standard_permutation()).tensor(
648
+ self(Word(x[i:]).standard_permutation()))
649
+ for i in range(len(x) + 1))
650
+
651
+ class Element(FQSymBasis_abstract.Element):
652
+ def to_symmetric_group_algebra(self, n=None):
653
+ """
654
+ Return the element of a symmetric group algebra
655
+ corresponding to the element ``self`` of `FQSym`.
656
+
657
+ INPUT:
658
+
659
+ - ``n`` -- integer (default: the maximal degree of ``self``);
660
+ the rank of the target symmetric group algebra
661
+
662
+ EXAMPLES::
663
+
664
+ sage: A = algebras.FQSym(QQ).F()
665
+ sage: x = A([1,3,2,4]) + 5/2 * A([1,2,4,3])
666
+ sage: x.to_symmetric_group_algebra()
667
+ 5/2*[1, 2, 4, 3] + [1, 3, 2, 4]
668
+ sage: x.to_symmetric_group_algebra(n=7)
669
+ 5/2*[1, 2, 4, 3, 5, 6, 7] + [1, 3, 2, 4, 5, 6, 7]
670
+ sage: a = A.zero().to_symmetric_group_algebra(); a
671
+ 0
672
+ sage: parent(a)
673
+ Symmetric group algebra of order 0 over Rational Field
674
+
675
+ sage: y = A([1,3,2,4]) + 5/2 * A([2,1])
676
+ sage: y.to_symmetric_group_algebra()
677
+ [1, 3, 2, 4] + 5/2*[2, 1, 3, 4]
678
+ sage: y.to_symmetric_group_algebra(6)
679
+ [1, 3, 2, 4, 5, 6] + 5/2*[2, 1, 3, 4, 5, 6]
680
+ """
681
+ if not self:
682
+ if n is None:
683
+ n = 0
684
+ return SymmetricGroupAlgebra(self.base_ring(), n).zero()
685
+ m = self.maximal_degree()
686
+ if n is None:
687
+ n = m
688
+ elif n < m:
689
+ raise ValueError("n must be at least the maximal degree")
690
+
691
+ SGA = SymmetricGroupAlgebra(self.base_ring(), n)
692
+ return SGA._from_dict({Permutations(n)(key): c for (key, c) in self})
693
+
694
+ class G(FQSymBasis_abstract):
695
+ r"""
696
+ The G-basis of `FQSym`.
697
+
698
+ This is the basis `(G_w)`, with `w` ranging over all
699
+ permutations. See the documentation of
700
+ :class:`FreeQuasisymmetricFunctions` for details.
701
+
702
+ EXAMPLES::
703
+
704
+ sage: FQSym = algebras.FQSym(QQ)
705
+ sage: G = FQSym.G(); G
706
+ Free Quasi-symmetric functions over Rational Field in the G basis
707
+
708
+ sage: G([3, 1, 2]).coproduct()
709
+ G[] # G[3, 1, 2] + G[1] # G[2, 1] + G[1, 2] # G[1]
710
+ + G[3, 1, 2] # G[]
711
+
712
+ sage: G([3, 1, 2]) * G([2, 1])
713
+ G[3, 1, 2, 5, 4] + G[4, 1, 2, 5, 3] + G[4, 1, 3, 5, 2]
714
+ + G[4, 2, 3, 5, 1] + G[5, 1, 2, 4, 3] + G[5, 1, 3, 4, 2]
715
+ + G[5, 1, 4, 3, 2] + G[5, 2, 3, 4, 1] + G[5, 2, 4, 3, 1]
716
+ + G[5, 3, 4, 2, 1]
717
+ """
718
+ _prefix = "G"
719
+ _basis_name = "G"
720
+
721
+ def _element_constructor_(self, x):
722
+ r"""
723
+ Convert ``x`` into ``self``.
724
+
725
+ EXAMPLES::
726
+
727
+ sage: R = algebras.FQSym(QQ).G()
728
+ sage: x, y, z = R([1]), R([2,1]), R([3,2,1])
729
+ sage: R(x)
730
+ G[1]
731
+ sage: R(x+4*y)
732
+ G[1] + 4*G[2, 1]
733
+ sage: R(1)
734
+ G[]
735
+
736
+ sage: D = algebras.FQSym(ZZ).G()
737
+ sage: X, Y, Z = D([1]), D([2,1]), D([3,2,1])
738
+ sage: R(X-Y).parent()
739
+ Free Quasi-symmetric functions over Rational Field in the G basis
740
+
741
+ sage: R([1, 3, 2])
742
+ G[1, 3, 2]
743
+ sage: R(Permutation([1, 3, 2]))
744
+ G[1, 3, 2]
745
+ sage: R(SymmetricGroup(4)(Permutation([1,3,4,2])))
746
+ G[1, 3, 4, 2]
747
+
748
+ sage: RF = algebras.FQSym(QQ).F()
749
+ sage: R(RF([2, 3, 4, 1]))
750
+ G[4, 1, 2, 3]
751
+ sage: R(RF([3, 2, 4, 1]))
752
+ G[4, 2, 1, 3]
753
+ sage: DF = algebras.FQSym(ZZ).F()
754
+ sage: D(DF([2, 3, 4, 1]))
755
+ G[4, 1, 2, 3]
756
+ sage: R(DF([2, 3, 4, 1]))
757
+ G[4, 1, 2, 3]
758
+ sage: RF(R[2, 3, 4, 1])
759
+ F[4, 1, 2, 3]
760
+ """
761
+ if isinstance(x, (list, tuple, PermutationGroupElement)):
762
+ x = Permutation(x)
763
+ try:
764
+ P = x.parent()
765
+ if isinstance(P, FreeQuasisymmetricFunctions.G):
766
+ if P is self:
767
+ return x
768
+ return self.element_class(self, x.monomial_coefficients())
769
+ except AttributeError:
770
+ pass
771
+ return CombinatorialFreeModule._element_constructor_(self, x)
772
+
773
+ def __getitem__(self, r):
774
+ r"""
775
+ The default implementation of ``__getitem__`` interprets
776
+ the input as a tuple, which in case of permutations
777
+ is interpreted as cycle notation, even though the input
778
+ looks like a one-line notation.
779
+ We override this method to amend this.
780
+
781
+ EXAMPLES::
782
+
783
+ sage: G = algebras.FQSym(QQ).G()
784
+ sage: G[3, 2, 1]
785
+ G[3, 2, 1]
786
+ sage: G[1]
787
+ G[1]
788
+ """
789
+ if isinstance(r, tuple):
790
+ r = list(r)
791
+ elif r == 1:
792
+ r = [1]
793
+ return super().__getitem__(r)
794
+
795
+ def _G_to_F_on_basis(self, w):
796
+ r"""
797
+ Return `G_w` in terms of the F basis.
798
+
799
+ INPUT:
800
+
801
+ - ``w`` -- a permutation
802
+
803
+ OUTPUT: an element of the F basis
804
+
805
+ TESTS::
806
+
807
+ sage: FQSym = algebras.FQSym(ZZ)
808
+ sage: F = FQSym.F()
809
+ sage: G = FQSym.G()
810
+ sage: F(G[3, 2, 1] - 4 * G[4, 2, 1, 3])
811
+ F[3, 2, 1] - 4*F[3, 2, 4, 1]
812
+ sage: all(F(G._G_to_F_on_basis(w)) == G[w] for i in range(5)
813
+ ....: for w in Permutations(i))
814
+ True
815
+ sage: G[3, 2, 1] == F[3, 2, 1]
816
+ True
817
+ sage: G[4, 2, 1, 3] == F[3, 2, 4, 1]
818
+ True
819
+ sage: G[4, 2, 1, 3] == F[4, 2, 1, 3]
820
+ False
821
+ """
822
+ F = self.realization_of().F()
823
+ return F.basis()[w.inverse()]
824
+
825
+ def _F_to_G_on_basis(self, w):
826
+ r"""
827
+ Return `F_w` in terms of the G basis.
828
+
829
+ INPUT:
830
+
831
+ - ``w`` -- a permutation
832
+
833
+ OUTPUT: an element of the G basis
834
+
835
+ TESTS::
836
+
837
+ sage: FQSym = algebras.FQSym(ZZ)
838
+ sage: F = FQSym.F()
839
+ sage: G = FQSym.G()
840
+ sage: G(F[3, 2, 1] - 4 * F[4, 2, 1, 3])
841
+ G[3, 2, 1] - 4*G[3, 2, 4, 1]
842
+ sage: all(G(G._F_to_G_on_basis(w)) == F[w] for i in range(5)
843
+ ....: for w in Permutations(i))
844
+ True
845
+ sage: F[3, 2, 1] == G[3, 2, 1]
846
+ True
847
+ sage: F[4, 2, 1, 3] == G[3, 2, 4, 1]
848
+ True
849
+ sage: F[4, 2, 1, 3] == G[4, 2, 1, 3]
850
+ False
851
+ """
852
+ return self.basis()[w.inverse()]
853
+
854
+ def degree_on_basis(self, t):
855
+ """
856
+ Return the degree of a permutation in
857
+ the algebra of free quasi-symmetric functions.
858
+
859
+ This is the size of the permutation (i.e., the `n`
860
+ for which the permutation belongs to `S_n`).
861
+
862
+ EXAMPLES::
863
+
864
+ sage: A = algebras.FQSym(QQ).G()
865
+ sage: u = Permutation([2,1])
866
+ sage: A.degree_on_basis(u)
867
+ 2
868
+ """
869
+ return len(t)
870
+
871
+ class M(FQSymBasis_abstract):
872
+ r"""
873
+ The M-basis of `FQSym`.
874
+
875
+ This is the Monomial basis `(\mathcal{M}_w)`, with `w` ranging
876
+ over all permutations. See the documentation of :class:`FQSym`
877
+ for details.
878
+
879
+ EXAMPLES::
880
+
881
+ sage: FQSym = algebras.FQSym(QQ)
882
+ sage: M = FQSym.M(); M
883
+ Free Quasi-symmetric functions over Rational Field in the Monomial basis
884
+
885
+ sage: M([3, 1, 2]).coproduct()
886
+ M[] # M[3, 1, 2] + M[1] # M[1, 2] + M[3, 1, 2] # M[]
887
+ sage: M([3, 2, 1]).coproduct()
888
+ M[] # M[3, 2, 1] + M[1] # M[2, 1] + M[2, 1] # M[1]
889
+ + M[3, 2, 1] # M[]
890
+
891
+ sage: M([1, 2]) * M([1])
892
+ M[1, 2, 3] + 2*M[1, 3, 2] + M[2, 3, 1] + M[3, 1, 2]
893
+ """
894
+ _prefix = "M"
895
+ _basis_name = "Monomial"
896
+
897
+ def __init__(self, alg):
898
+ """
899
+ Initialize ``self``.
900
+
901
+ EXAMPLES::
902
+
903
+ sage: M = algebras.FQSym(QQ).M()
904
+ sage: TestSuite(M).run(elements=M.some_elements()[:-1]) # long time
905
+ """
906
+ FQSymBasis_abstract.__init__(self, alg)
907
+
908
+ F = self.realization_of().F()
909
+ phi = F.module_morphism(self._F_to_M_on_basis, codomain=self,
910
+ unitriangular='lower')
911
+ phi.register_as_coercion()
912
+ phi_i = self.module_morphism(self._M_to_F_on_basis, codomain=F,
913
+ unitriangular='lower')
914
+ phi_i.register_as_coercion()
915
+
916
+ def _element_constructor_(self, x):
917
+ r"""
918
+ Convert ``x`` into ``self``.
919
+
920
+ EXAMPLES::
921
+
922
+ sage: R = algebras.FQSym(QQ).M()
923
+ sage: x, y, z = R([1]), R([2,1]), R([3,2,1])
924
+ sage: R(x)
925
+ M[1]
926
+ sage: R(x+4*y)
927
+ M[1] + 4*M[2, 1]
928
+ sage: R(1)
929
+ M[]
930
+
931
+ sage: D = algebras.FQSym(ZZ).M()
932
+ sage: X, Y, Z = D([1]), D([2,1]), D([3,2,1])
933
+ sage: R(X-Y).parent()
934
+ Free Quasi-symmetric functions over Rational Field in the Monomial basis
935
+
936
+ sage: R([1, 3, 2])
937
+ M[1, 3, 2]
938
+ sage: R(Permutation([1, 3, 2]))
939
+ M[1, 3, 2]
940
+ sage: R(SymmetricGroup(4)(Permutation([1,3,4,2])))
941
+ M[1, 3, 4, 2]
942
+
943
+ sage: RF = algebras.FQSym(QQ).F()
944
+ sage: R(RF([2, 3, 4, 1]))
945
+ M[2, 3, 4, 1] + M[2, 4, 3, 1] + M[3, 2, 4, 1] + M[3, 4, 2, 1]
946
+ + M[4, 2, 3, 1] + M[4, 3, 2, 1]
947
+ sage: R(RF([3, 2, 4, 1]))
948
+ M[3, 2, 4, 1] + M[4, 2, 3, 1] + M[4, 3, 2, 1]
949
+ sage: DF = algebras.FQSym(ZZ).F()
950
+ sage: D(DF([2, 3, 4, 1]))
951
+ M[2, 3, 4, 1] + M[2, 4, 3, 1] + M[3, 2, 4, 1] + M[3, 4, 2, 1]
952
+ + M[4, 2, 3, 1] + M[4, 3, 2, 1]
953
+ sage: R(DF([2, 3, 4, 1]))
954
+ M[2, 3, 4, 1] + M[2, 4, 3, 1] + M[3, 2, 4, 1] + M[3, 4, 2, 1]
955
+ + M[4, 2, 3, 1] + M[4, 3, 2, 1]
956
+ sage: RF(R[2, 3, 4, 1])
957
+ F[2, 3, 4, 1] - F[2, 4, 3, 1] - F[3, 2, 4, 1] + F[4, 3, 2, 1]
958
+
959
+ sage: RG = algebras.FQSym(QQ).G()
960
+ sage: R(RG([4, 1, 2, 3]))
961
+ M[2, 3, 4, 1] + M[2, 4, 3, 1] + M[3, 2, 4, 1] + M[3, 4, 2, 1]
962
+ + M[4, 2, 3, 1] + M[4, 3, 2, 1]
963
+ sage: R(RG([4, 2, 1, 3]))
964
+ M[3, 2, 4, 1] + M[4, 2, 3, 1] + M[4, 3, 2, 1]
965
+ sage: DG = algebras.FQSym(ZZ).G()
966
+ sage: D(DG([4, 1, 2, 3]))
967
+ M[2, 3, 4, 1] + M[2, 4, 3, 1] + M[3, 2, 4, 1] + M[3, 4, 2, 1]
968
+ + M[4, 2, 3, 1] + M[4, 3, 2, 1]
969
+ sage: R(DG([4, 1, 2, 3]))
970
+ M[2, 3, 4, 1] + M[2, 4, 3, 1] + M[3, 2, 4, 1] + M[3, 4, 2, 1]
971
+ + M[4, 2, 3, 1] + M[4, 3, 2, 1]
972
+ sage: RG(R[2, 3, 4, 1])
973
+ G[4, 1, 2, 3] - G[4, 1, 3, 2] - G[4, 2, 1, 3] + G[4, 3, 2, 1]
974
+ """
975
+ if isinstance(x, (list, tuple, PermutationGroupElement)):
976
+ x = Permutation(x)
977
+ try:
978
+ P = x.parent()
979
+ if isinstance(P, FreeQuasisymmetricFunctions.M):
980
+ if P is self:
981
+ return x
982
+ return self.element_class(self, x.monomial_coefficients())
983
+ except AttributeError:
984
+ pass
985
+ return CombinatorialFreeModule._element_constructor_(self, x)
986
+
987
+ def __getitem__(self, r):
988
+ r"""
989
+ The default implementation of ``__getitem__`` interprets
990
+ the input as a tuple, which in case of permutations
991
+ is interpreted as cycle notation, even though the input
992
+ looks like a one-line notation.
993
+ We override this method to amend this.
994
+
995
+ EXAMPLES::
996
+
997
+ sage: M = algebras.FQSym(QQ).M()
998
+ sage: M[3, 2, 1]
999
+ M[3, 2, 1]
1000
+ sage: M[1]
1001
+ M[1]
1002
+ """
1003
+ if isinstance(r, tuple):
1004
+ r = list(r)
1005
+ elif r == 1:
1006
+ r = [1]
1007
+ return super().__getitem__(r)
1008
+
1009
+ def _F_to_M_on_basis(self, w):
1010
+ r"""
1011
+ Return `F_w` in terms of the M basis.
1012
+
1013
+ INPUT:
1014
+
1015
+ - ``w`` -- a permutation
1016
+
1017
+ OUTPUT: an element of the M basis
1018
+
1019
+ TESTS::
1020
+
1021
+ sage: FQSym = algebras.FQSym(ZZ)
1022
+ sage: F = FQSym.F()
1023
+ sage: M = FQSym.M()
1024
+ sage: M(F[3, 2, 1] - 4 * F[4, 2, 1, 3])
1025
+ M[3, 2, 1] - 4*M[4, 2, 1, 3] - 4*M[4, 3, 1, 2] - 4*M[4, 3, 2, 1]
1026
+ sage: all(M(M._F_to_M_on_basis(w)) == F[w] for i in range(5)
1027
+ ....: for w in Permutations(i))
1028
+ True
1029
+ sage: F[3, 2, 1] == M[3, 2, 1]
1030
+ True
1031
+ sage: F[4, 2, 1, 3] == M[3, 2, 4, 1]
1032
+ False
1033
+ """
1034
+ return self.sum_of_monomials(w.permutohedron_greater(side='left'))
1035
+
1036
+ def _M_to_F_on_basis(self, w):
1037
+ r"""
1038
+ Return `\mathcal{M}_w` in terms of the F basis.
1039
+
1040
+ INPUT:
1041
+
1042
+ - ``w`` -- a permutation
1043
+
1044
+ OUTPUT: an element of the F basis
1045
+
1046
+ ALGORITHM:
1047
+
1048
+ If `w` is any permutation in `S_n`, then
1049
+
1050
+ .. MATH::
1051
+
1052
+ \mathcal{M}_w = \sum_u (-1)^{j(w, u)} F_u,
1053
+
1054
+ where the sum ranges over all permutations `u \in S_n`
1055
+ obtained as follows:
1056
+
1057
+ * Let `v = w^{-1}`.
1058
+
1059
+ * Subdivide the list `(v(1), v(2), \ldots, v(n))` into
1060
+ an arbitrary number of nonempty blocks (by putting
1061
+ dividers between adjacent entries) in such a way that
1062
+ each block is strictly increasing (i.e., each descent
1063
+ of `v` is followed by a divider, but not every
1064
+ divider must necessarily follow a descent).
1065
+
1066
+ * Reverse the order of entries in each block.
1067
+
1068
+ * Remove the dividers. The resulting list is the
1069
+ one-line notation `(x(1), x(2), \ldots, x(n))` of
1070
+ some permutation `x \in S_n`.
1071
+
1072
+ * Set `u = x^{-1}`. Also, let `j(w, u)` be `n` minus
1073
+ the number of blocks in our subdivision.
1074
+
1075
+ This formula is equivalent to the formula (1.13) in
1076
+ [AguSot05]_, since Corollary 3.2.8 in [BB2005]_ expresses
1077
+ the Mobius function of the weak order.
1078
+
1079
+ TESTS::
1080
+
1081
+ sage: FQSym = algebras.FQSym(ZZ)
1082
+ sage: F = FQSym.F()
1083
+ sage: M = FQSym.M()
1084
+ sage: F(M[3, 2, 1] - 4 * F[4, 2, 1, 3])
1085
+ F[3, 2, 1] - 4*F[4, 2, 1, 3]
1086
+ sage: all(F(M._M_to_F_on_basis(w)) == M[w] for i in range(5) # indirect doctest
1087
+ ....: for w in Permutations(i))
1088
+ True
1089
+ sage: all(M(F(M[w])) == M[w] for i in range(5)
1090
+ ....: for w in Permutations(i))
1091
+ True
1092
+ sage: M[3, 2, 1] == F[3, 2, 1]
1093
+ True
1094
+ sage: M[3, 2, 4, 1] == F[4, 2, 1, 3]
1095
+ False
1096
+ sage: F(M[[]]) == F[[]]
1097
+ True
1098
+ """
1099
+ F = self.realization_of().F()
1100
+ if len(w) <= 1:
1101
+ return F.monomial(w)
1102
+
1103
+ w_i = w.inverse()
1104
+ w_i = w_i[:]
1105
+ n = len(w_i)
1106
+ des = tuple([0] + [g for g in range(1, n)
1107
+ if w_i[g - 1] > w_i[g]] + [n])
1108
+ non_des = [g for g in range(1, n) if w_i[g - 1] < w_i[g]]
1109
+ # Now, des is a list of all descents of w_i and also 0 and n,
1110
+ # whereas non_des is a list of all non-descents of w_i.
1111
+
1112
+ Perms = self.basis().keys()
1113
+
1114
+ R = self.base_ring()
1115
+ one = R.one()
1116
+ mine = -one
1117
+
1118
+ dc = {w: one}
1119
+ from itertools import combinations
1120
+ for k in range(len(non_des)):
1121
+ kk = k + len(des)
1122
+ for extra_des in combinations(non_des, k):
1123
+ breakpoints = sorted(des + extra_des)
1124
+ # so that kk == len(breakpoints)
1125
+ p = sum([w_i[breakpoints[g]: breakpoints[g + 1]][::-1]
1126
+ for g in range(kk - 1)],
1127
+ [])
1128
+ u = Perms(p).inverse()
1129
+ dc[u] = one if n % 2 != kk % 2 else mine
1130
+
1131
+ return F._from_dict(dc)
1132
+
1133
+ def degree_on_basis(self, t):
1134
+ """
1135
+ Return the degree of a permutation in
1136
+ the algebra of free quasi-symmetric functions.
1137
+
1138
+ This is the size of the permutation (i.e., the `n`
1139
+ for which the permutation belongs to `S_n`).
1140
+
1141
+ EXAMPLES::
1142
+
1143
+ sage: A = algebras.FQSym(QQ).M()
1144
+ sage: u = Permutation([2,1])
1145
+ sage: A.degree_on_basis(u)
1146
+ 2
1147
+ """
1148
+ return len(t)
1149
+
1150
+ def coproduct_on_basis(self, x):
1151
+ r"""
1152
+ Return the coproduct of `\mathcal{M}_{\sigma}` for `\sigma`
1153
+ a permutation (here, `\sigma` is ``x``).
1154
+
1155
+ This uses Theorem 3.1 in [AguSot05]_.
1156
+
1157
+ EXAMPLES::
1158
+
1159
+ sage: M = algebras.FQSym(QQ).M()
1160
+ sage: x = M([1])
1161
+ sage: ascii_art(M.coproduct(M.one())) # indirect doctest
1162
+ 1 # 1
1163
+
1164
+ sage: ascii_art(M.coproduct(x)) # indirect doctest
1165
+ 1 # M + M # 1
1166
+ [1] [1]
1167
+
1168
+ sage: M.coproduct(M([2, 1, 3]))
1169
+ M[] # M[2, 1, 3] + M[2, 1, 3] # M[]
1170
+ sage: M.coproduct(M([2, 3, 1]))
1171
+ M[] # M[2, 3, 1] + M[1, 2] # M[1] + M[2, 3, 1] # M[]
1172
+ sage: M.coproduct(M([3, 2, 1]))
1173
+ M[] # M[3, 2, 1] + M[1] # M[2, 1] + M[2, 1] # M[1]
1174
+ + M[3, 2, 1] # M[]
1175
+ sage: M.coproduct(M([3, 4, 2, 1]))
1176
+ M[] # M[3, 4, 2, 1] + M[1, 2] # M[2, 1] + M[2, 3, 1] # M[1]
1177
+ + M[3, 4, 2, 1] # M[]
1178
+ sage: M.coproduct(M([3, 4, 1, 2]))
1179
+ M[] # M[3, 4, 1, 2] + M[1, 2] # M[1, 2] + M[3, 4, 1, 2] # M[]
1180
+ """
1181
+ n = len(x)
1182
+ if not n:
1183
+ return self.one().tensor(self.one())
1184
+ return sum(self(Word(x[:i]).standard_permutation()).tensor(
1185
+ self(Word(x[i:]).standard_permutation()))
1186
+ for i in range(n + 1)
1187
+ if (i == 0 or i == n or min(x[:i]) > max(x[i:])))
1188
+
1189
+ class Element(FQSymBasis_abstract.Element):
1190
+ def star_involution(self):
1191
+ r"""
1192
+ Return the image of the element ``self`` of `FQSym`
1193
+ under the star involution.
1194
+
1195
+ See
1196
+ :meth:`FQSymBases.ElementMethods.star_involution`
1197
+ for a definition of the involution and for examples.
1198
+
1199
+ .. SEEALSO::
1200
+
1201
+ :meth:`omega_involution`, :meth:`psi_involution`
1202
+
1203
+ EXAMPLES::
1204
+
1205
+ sage: FQSym = algebras.FQSym(ZZ)
1206
+ sage: M = FQSym.M()
1207
+ sage: M[[2,3,1]].star_involution()
1208
+ M[3, 1, 2]
1209
+ sage: M[[]].star_involution()
1210
+ M[]
1211
+
1212
+ TESTS::
1213
+
1214
+ sage: F = FQSym.F()
1215
+ sage: all(M(F[w]).star_involution() == M(F[w].star_involution())
1216
+ ....: for w in Permutations(4))
1217
+ True
1218
+ """
1219
+ # See the FQSymBases.ElementMethods.star_involution doc
1220
+ # for the formula we're using here.
1221
+ M = self.parent()
1222
+ return M._from_dict({w.complement().reverse(): c for (w, c) in self},
1223
+ remove_zeros=False)
1224
+
1225
+
1226
+ class FQSymBases(Category_realization_of_parent):
1227
+ r"""
1228
+ The category of graded bases of `FQSym` indexed by permutations.
1229
+ """
1230
+
1231
+ def __init__(self, base):
1232
+ r"""
1233
+ Initialize the bases of an `FQSym`.
1234
+
1235
+ INPUT:
1236
+
1237
+ - ``base`` -- an instance of `FQSym`
1238
+
1239
+ TESTS::
1240
+
1241
+ sage: from sage.combinat.fqsym import FQSymBases
1242
+ sage: FQSym = algebras.FQSym(ZZ)
1243
+ sage: bases = FQSymBases(FQSym)
1244
+ sage: FQSym.F() in bases
1245
+ True
1246
+ """
1247
+ Category_realization_of_parent.__init__(self, base)
1248
+
1249
+ def _repr_(self):
1250
+ r"""
1251
+ Return the representation of ``self``.
1252
+
1253
+ EXAMPLES::
1254
+
1255
+ sage: from sage.combinat.fqsym import FQSymBases
1256
+ sage: FQSym = algebras.FQSym(ZZ)
1257
+ sage: FQSymBases(FQSym)
1258
+ Category of bases of Free Quasi-symmetric functions over Integer Ring
1259
+ """
1260
+ return "Category of bases of {}".format(self.base())
1261
+
1262
+ def super_categories(self):
1263
+ r"""
1264
+ The super categories of ``self``.
1265
+
1266
+ EXAMPLES::
1267
+
1268
+ sage: from sage.combinat.fqsym import FQSymBases
1269
+ sage: FQSym = algebras.FQSym(ZZ)
1270
+ sage: bases = FQSymBases(FQSym)
1271
+ sage: bases.super_categories()
1272
+ [Category of realizations of Free Quasi-symmetric functions over Integer Ring,
1273
+ Join of Category of realizations of Hopf algebras over Integer Ring
1274
+ and Category of graded algebras over Integer Ring
1275
+ and Category of graded coalgebras over Integer Ring,
1276
+ Category of graded connected Hopf algebras with basis over Integer Ring]
1277
+ """
1278
+ R = self.base().base_ring()
1279
+ return [self.base().Realizations(),
1280
+ HopfAlgebras(R).Graded().Realizations(),
1281
+ HopfAlgebras(R).Graded().WithBasis().Graded().Connected(),
1282
+ ]
1283
+
1284
+ class ParentMethods:
1285
+ def _repr_(self):
1286
+ """
1287
+ Text representation of this basis of `FQSym`.
1288
+
1289
+ EXAMPLES::
1290
+
1291
+ sage: FQSym = algebras.FQSym(ZZ)
1292
+ sage: FQSym.F()
1293
+ Free Quasi-symmetric functions over Integer Ring in the F basis
1294
+ """
1295
+ return "{} in the {} basis".format(self.realization_of(), self._basis_name)
1296
+
1297
+ def __getitem__(self, p):
1298
+ """
1299
+ Return the basis element indexed by ``p``.
1300
+
1301
+ INPUT:
1302
+
1303
+ - ``p`` -- a permutation
1304
+
1305
+ EXAMPLES::
1306
+
1307
+ sage: R = algebras.FQSym(QQ).F()
1308
+ sage: R[[1, 3, 2]]
1309
+ F[1, 3, 2]
1310
+ sage: R[Permutation([1, 3, 2])]
1311
+ F[1, 3, 2]
1312
+ sage: R[SymmetricGroup(4)(Permutation([1,3,4,2]))]
1313
+ F[1, 3, 4, 2]
1314
+ """
1315
+ return self.monomial(Permutation(p))
1316
+
1317
+ def basis(self, degree=None):
1318
+ r"""
1319
+ The basis elements (optionally: of the specified degree).
1320
+
1321
+ OUTPUT: Family
1322
+
1323
+ EXAMPLES::
1324
+
1325
+ sage: FQSym = algebras.FQSym(QQ)
1326
+ sage: G = FQSym.G()
1327
+ sage: G.basis()
1328
+ Lazy family (Term map from Standard permutations to Free Quasi-symmetric functions over Rational Field in the G basis(i))_{i in Standard permutations}
1329
+ sage: G.basis().keys()
1330
+ Standard permutations
1331
+ sage: G.basis(degree=3).keys()
1332
+ Standard permutations of 3
1333
+ sage: G.basis(degree=3).list()
1334
+ [G[1, 2, 3], G[1, 3, 2], G[2, 1, 3], G[2, 3, 1], G[3, 1, 2], G[3, 2, 1]]
1335
+ """
1336
+ from sage.sets.family import Family
1337
+ if degree is None:
1338
+ return Family(self._indices, self.monomial)
1339
+ else:
1340
+ return Family(Permutations(degree), self.monomial)
1341
+
1342
+ def is_field(self, proof=True):
1343
+ """
1344
+ Return whether this `FQSym` is a field.
1345
+
1346
+ EXAMPLES::
1347
+
1348
+ sage: F = algebras.FQSym(QQ).F()
1349
+ sage: F.is_field()
1350
+ False
1351
+ """
1352
+ return False
1353
+
1354
+ def is_commutative(self):
1355
+ """
1356
+ Return whether this `FQSym` is commutative.
1357
+
1358
+ EXAMPLES::
1359
+
1360
+ sage: F = algebras.FQSym(ZZ).F()
1361
+ sage: F.is_commutative()
1362
+ False
1363
+ """
1364
+ return self.base_ring().is_zero()
1365
+
1366
+ def some_elements(self):
1367
+ """
1368
+ Return some elements of the free quasi-symmetric functions.
1369
+
1370
+ EXAMPLES::
1371
+
1372
+ sage: A = algebras.FQSym(QQ)
1373
+ sage: F = A.F()
1374
+ sage: F.some_elements()
1375
+ [F[], F[1], F[1, 2] + F[2, 1], F[] + F[1, 2] + F[2, 1]]
1376
+ sage: G = A.G()
1377
+ sage: G.some_elements()
1378
+ [G[], G[1], G[1, 2] + G[2, 1], G[] + G[1, 2] + G[2, 1]]
1379
+ sage: M = A.M()
1380
+ sage: M.some_elements()
1381
+ [M[], M[1], M[1, 2] + 2*M[2, 1], M[] + M[1, 2] + 2*M[2, 1]]
1382
+ """
1383
+ u = self.one()
1384
+ o = self.monomial(Permutation([1]))
1385
+ x = o * o
1386
+ y = u + x
1387
+ return [u, o, x, y]
1388
+
1389
+ @cached_method
1390
+ def one_basis(self):
1391
+ """
1392
+ Return the index of the unit.
1393
+
1394
+ EXAMPLES::
1395
+
1396
+ sage: A = algebras.FQSym(QQ).F()
1397
+ sage: A.one_basis()
1398
+ []
1399
+ """
1400
+ Perm = self.basis().keys()
1401
+ return Perm([])
1402
+
1403
+ @lazy_attribute
1404
+ def succ(self):
1405
+ r"""
1406
+ Return the `\succ` product.
1407
+
1408
+ On the F-basis of ``FQSym``, this product is determined by
1409
+ `F_x \succ F_y = \sum F_z`, where the sum ranges over all `z`
1410
+ in the shifted shuffle of `x` and `y` with the additional
1411
+ condition that the first letter of the result comes from `y`.
1412
+
1413
+ The usual symbol for this operation is `\succ`.
1414
+
1415
+ .. SEEALSO::
1416
+
1417
+ :meth:`~sage.categories.magmas.Magmas.ParentMethods.product`,
1418
+ :meth:`prec`
1419
+
1420
+ EXAMPLES::
1421
+
1422
+ sage: A = algebras.FQSym(QQ).F()
1423
+ sage: x = A([1])
1424
+ sage: A.succ(x, x)
1425
+ F[2, 1]
1426
+ sage: y = A([3,1,2])
1427
+ sage: A.succ(x, y)
1428
+ F[4, 1, 2, 3] + F[4, 2, 1, 3] + F[4, 2, 3, 1]
1429
+ sage: A.succ(y, x)
1430
+ F[4, 3, 1, 2]
1431
+ """
1432
+ try:
1433
+ suc = self.succ_product_on_basis
1434
+ except AttributeError:
1435
+ return self.succ_by_coercion
1436
+ return self._module_morphism(self._module_morphism(suc, position=0,
1437
+ codomain=self),
1438
+ position=1)
1439
+
1440
+ def succ_by_coercion(self, x, y):
1441
+ r"""
1442
+ Return `x \succ y`, computed using coercion to the F-basis.
1443
+
1444
+ See :meth:`succ` for the definition of the objects involved.
1445
+
1446
+ EXAMPLES::
1447
+
1448
+ sage: G = algebras.FQSym(ZZ).G()
1449
+ sage: G.succ(G([1]), G([2, 3, 1])) # indirect doctest
1450
+ G[2, 3, 4, 1] + G[3, 2, 4, 1] + G[4, 2, 3, 1]
1451
+ """
1452
+ F = self.realization_of().a_realization()
1453
+ return self(F.succ(F(x), F(y)))
1454
+
1455
+ @lazy_attribute
1456
+ def prec(self):
1457
+ r"""
1458
+ Return the `\prec` product.
1459
+
1460
+ On the F-basis of ``FQSym``, this product is determined by
1461
+ `F_x \prec F_y = \sum F_z`, where the sum ranges over all `z`
1462
+ in the shifted shuffle of `x` and `y` with the additional
1463
+ condition that the first letter of the result comes from `x`.
1464
+
1465
+ The usual symbol for this operation is `\prec`.
1466
+
1467
+ .. SEEALSO::
1468
+
1469
+ :meth:`~sage.categories.magmas.Magmas.ParentMethods.product`,
1470
+ :meth:`succ`
1471
+
1472
+ EXAMPLES::
1473
+
1474
+ sage: A = algebras.FQSym(QQ).F()
1475
+ sage: x = A([2,1])
1476
+ sage: A.prec(x, x)
1477
+ F[2, 1, 4, 3] + F[2, 4, 1, 3] + F[2, 4, 3, 1]
1478
+ sage: y = A([2,1,3])
1479
+ sage: A.prec(x, y)
1480
+ F[2, 1, 4, 3, 5] + F[2, 4, 1, 3, 5] + F[2, 4, 3, 1, 5]
1481
+ + F[2, 4, 3, 5, 1]
1482
+ sage: A.prec(y, x)
1483
+ F[2, 1, 3, 5, 4] + F[2, 1, 5, 3, 4] + F[2, 1, 5, 4, 3]
1484
+ + F[2, 5, 1, 3, 4] + F[2, 5, 1, 4, 3] + F[2, 5, 4, 1, 3]
1485
+ """
1486
+ try:
1487
+ pre = self.prec_product_on_basis
1488
+ except AttributeError:
1489
+ return self.prec_by_coercion
1490
+ return self._module_morphism(self._module_morphism(pre, position=0,
1491
+ codomain=self),
1492
+ position=1)
1493
+
1494
+ def prec_by_coercion(self, x, y):
1495
+ r"""
1496
+ Return `x \prec y`, computed using coercion to the F-basis.
1497
+
1498
+ See :meth:`prec` for the definition of the objects involved.
1499
+
1500
+ EXAMPLES::
1501
+
1502
+ sage: G = algebras.FQSym(ZZ).G()
1503
+ sage: a = G([1])
1504
+ sage: b = G([2, 3, 1])
1505
+ sage: G.prec(a, b) + G.succ(a, b) == a * b # indirect doctest
1506
+ True
1507
+ """
1508
+ F = self.realization_of().a_realization()
1509
+ return self(F.prec(F(x), F(y)))
1510
+
1511
+ def from_symmetric_group_algebra(self, x):
1512
+ """
1513
+ Return the element of `FQSym` corresponding to the element
1514
+ `x` of a symmetric group algebra.
1515
+
1516
+ EXAMPLES::
1517
+
1518
+ sage: A = algebras.FQSym(QQ).F()
1519
+ sage: SGA4 = SymmetricGroupAlgebra(QQ, 4)
1520
+ sage: x = SGA4([1,3,2,4]) + 5/2 * SGA4([1,2,4,3])
1521
+ sage: A.from_symmetric_group_algebra(x)
1522
+ 5/2*F[1, 2, 4, 3] + F[1, 3, 2, 4]
1523
+ sage: A.from_symmetric_group_algebra(SGA4.zero())
1524
+ 0
1525
+ """
1526
+ return self._from_dict({Permutation(key): c for (key, c) in x})
1527
+
1528
+ class ElementMethods:
1529
+ def omega_involution(self):
1530
+ r"""
1531
+ Return the image of the element ``self`` of `FQSym`
1532
+ under the omega involution.
1533
+
1534
+ The `\omega` involution is defined as the
1535
+ linear map `FQSym \to FQSym` that sends each basis
1536
+ element `F_u` of the F-basis of `FQSym`
1537
+ to the basis element `F_{u \circ w_0}`, where `w_0` is
1538
+ the longest word (i.e., `w_0(i) = n + 1 - i`) in the
1539
+ symmetric group `S_n` that contains `u`. The `\omega`
1540
+ involution is a graded algebra automorphism and a
1541
+ coalgebra anti-automorphism of `FQSym`. Every
1542
+ permutation `u \in S_n` satisfies
1543
+
1544
+ .. MATH::
1545
+
1546
+ \omega(F_u) = F_{u \circ w_0}, \qquad
1547
+ \omega(G_u) = G_{w_0 \circ u},
1548
+
1549
+ where standard notations for classical bases of `FQSym`
1550
+ are being used (that is, `F` for the F-basis, and
1551
+ `G` for the G-basis).
1552
+ In other words, writing permutations in one-line notation,
1553
+ we have
1554
+
1555
+ .. MATH::
1556
+
1557
+ \omega(F_{(u_1, u_2, \ldots, u_n)})
1558
+ = F_{(u_n, u_{n-1}, \ldots, u_1)}, \qquad
1559
+ \omega(G_{(u_1, u_2, \ldots, u_n)})
1560
+ = G_{(n+1-u_1, n+1-u_2, \ldots, n+1-u_n)}.
1561
+
1562
+ If we also consider the `\omega` involution
1563
+ (:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.omega_involution`)
1564
+ of the quasisymmetric functions (by slight abuse
1565
+ of notation), and if we let `\pi` be the canonical
1566
+ projection `FQSym \to QSym`, then
1567
+ `\pi \circ \omega = \omega \circ \pi`.
1568
+
1569
+ Additionally, consider the `\psi` involution
1570
+ (:meth:`~sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.psi_involution`)
1571
+ of the noncommutative symmetric functions, and if we let
1572
+ `\iota` be the canonical inclusion `NSym \to FQSym`,
1573
+ then `\omega \circ \iota = \iota \circ \psi`.
1574
+
1575
+ .. TODO::
1576
+
1577
+ Duality?
1578
+
1579
+ .. SEEALSO::
1580
+
1581
+ :meth:`psi_involution`, :meth:`star_involution`
1582
+
1583
+ EXAMPLES::
1584
+
1585
+ sage: FQSym = algebras.FQSym(ZZ)
1586
+ sage: F = FQSym.F()
1587
+ sage: F[[2,3,1]].omega_involution()
1588
+ F[1, 3, 2]
1589
+ sage: (3*F[[1]] - 4*F[[]] + 5*F[[1,2]]).omega_involution()
1590
+ -4*F[] + 3*F[1] + 5*F[2, 1]
1591
+ sage: G = FQSym.G()
1592
+ sage: G[[2,3,1]].omega_involution()
1593
+ G[2, 1, 3]
1594
+ sage: M = FQSym.M()
1595
+ sage: M[[2,3,1]].omega_involution()
1596
+ -M[1, 2, 3] - M[2, 1, 3] - M[3, 1, 2]
1597
+
1598
+ The omega involution is an algebra homomorphism::
1599
+
1600
+ sage: (F[1,2] * F[1]).omega_involution()
1601
+ F[2, 1, 3] + F[2, 3, 1] + F[3, 2, 1]
1602
+ sage: F[1,2].omega_involution() * F[1].omega_involution()
1603
+ F[2, 1, 3] + F[2, 3, 1] + F[3, 2, 1]
1604
+
1605
+ The omega involution intertwines the antipode
1606
+ and the inverse of the antipode::
1607
+
1608
+ sage: all( F(I).antipode().omega_involution().antipode()
1609
+ ....: == F(I).omega_involution()
1610
+ ....: for I in Permutations(4) )
1611
+ True
1612
+
1613
+ Testing the `\pi \circ \omega = \omega \circ \pi` relation
1614
+ noticed above::
1615
+
1616
+ sage: all( M[I].omega_involution().to_qsym()
1617
+ ....: == M[I].to_qsym().omega_involution()
1618
+ ....: for I in Permutations(4) )
1619
+ True
1620
+
1621
+ Testing the `\omega \circ \iota = \iota \circ \psi` relation::
1622
+
1623
+ sage: NSym = NonCommutativeSymmetricFunctions(ZZ)
1624
+ sage: S = NSym.S()
1625
+ sage: all( S[I].psi_involution().to_fqsym() == S[I].to_fqsym().omega_involution()
1626
+ ....: for I in Compositions(4) )
1627
+ True
1628
+
1629
+ .. TODO::
1630
+
1631
+ Check further commutative squares.
1632
+ """
1633
+ # Convert to the F-basis, there apply the reversal
1634
+ # componentwise, then convert back.
1635
+ parent = self.parent()
1636
+ F = parent.realization_of().F()
1637
+ dct = {I.reverse(): coeff for (I, coeff) in F(self)}
1638
+ return parent(F._from_dict(dct, remove_zeros=False))
1639
+
1640
+ def psi_involution(self):
1641
+ r"""
1642
+ Return the image of the element ``self`` of `FQSym`
1643
+ under the psi involution.
1644
+
1645
+ The `\psi` involution is defined as the
1646
+ linear map `FQSym \to FQSym` that sends each basis
1647
+ element `F_u` of the F-basis of `FQSym`
1648
+ to the basis element `F_{w_0 \circ u}`, where `w_0` is
1649
+ the longest word (i.e., `w_0(i) = n + 1 - i`) in the
1650
+ symmetric group `S_n` that contains `u`. The `\psi`
1651
+ involution is a graded coalgebra automorphism and
1652
+ an algebra anti-automorphism of `FQSym`. Every
1653
+ permutation `u \in S_n` satisfies
1654
+
1655
+ .. MATH::
1656
+
1657
+ \psi(F_u) = F_{w_0 \circ u}, \qquad
1658
+ \psi(G_u) = G_{u \circ w_0},
1659
+
1660
+ where standard notations for classical bases of `FQSym`
1661
+ are being used (that is, `F` for the F-basis, and
1662
+ `G` for the G-basis). In other words, writing
1663
+ permutations in one-line notation, we have
1664
+
1665
+ .. MATH::
1666
+
1667
+ \psi(F_{(u_1, u_2, \ldots, u_n)})
1668
+ = F_{(n+1-u_1, n+1-u_2, \ldots, n+1-u_n)}, \qquad
1669
+ \psi(G_{(u_1, u_2, \ldots, u_n)})
1670
+ = G_{(u_n, u_{n-1}, \ldots, u_1)}.
1671
+
1672
+ If we also consider the `\psi` involution
1673
+ (:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.psi_involution`)
1674
+ of the quasisymmetric functions (by slight abuse of
1675
+ notation), and if we let `\pi` be the canonical
1676
+ projection `FQSym \to QSym`, then
1677
+ `\pi \circ \psi = \psi \circ \pi`.
1678
+
1679
+ Additionally, consider the `\omega` involution
1680
+ (:meth:`~sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.omega_involution`)
1681
+ of the noncommutative symmetric functions, and if we let
1682
+ `\iota` be the canonical inclusion `NSym \to FQSym`,
1683
+ then `\psi \circ \iota = \iota \circ \omega`.
1684
+
1685
+ .. TODO::
1686
+
1687
+ Duality?
1688
+
1689
+ .. SEEALSO::
1690
+
1691
+ :meth:`omega_involution`, :meth:`star_involution`
1692
+
1693
+ EXAMPLES::
1694
+
1695
+ sage: FQSym = algebras.FQSym(ZZ)
1696
+ sage: F = FQSym.F()
1697
+ sage: F[[2,3,1]].psi_involution()
1698
+ F[2, 1, 3]
1699
+ sage: (3*F[[1]] - 4*F[[]] + 5*F[[1,2]]).psi_involution()
1700
+ -4*F[] + 3*F[1] + 5*F[2, 1]
1701
+ sage: G = FQSym.G()
1702
+ sage: G[[2,3,1]].psi_involution()
1703
+ G[1, 3, 2]
1704
+ sage: M = FQSym.M()
1705
+ sage: M[[2,3,1]].psi_involution()
1706
+ -M[1, 2, 3] - M[1, 3, 2] - M[2, 3, 1]
1707
+
1708
+ The `\psi` involution intertwines the antipode
1709
+ and the inverse of the antipode::
1710
+
1711
+ sage: all( F(I).antipode().psi_involution().antipode()
1712
+ ....: == F(I).psi_involution()
1713
+ ....: for I in Permutations(4) )
1714
+ True
1715
+
1716
+ Testing the `\pi \circ \psi = \psi \circ \pi` relation above::
1717
+
1718
+ sage: all( M[I].psi_involution().to_qsym()
1719
+ ....: == M[I].to_qsym().psi_involution()
1720
+ ....: for I in Permutations(4) )
1721
+ True
1722
+
1723
+ Testing the `\psi \circ \iota = \iota \circ \omega` relation::
1724
+
1725
+ sage: NSym = NonCommutativeSymmetricFunctions(ZZ)
1726
+ sage: S = NSym.S()
1727
+ sage: all( S[I].omega_involution().to_fqsym() == S[I].to_fqsym().psi_involution()
1728
+ ....: for I in Compositions(4) )
1729
+ True
1730
+
1731
+ .. TODO::
1732
+
1733
+ Check further commutative squares.
1734
+ """
1735
+ # Convert to the F-basis, there apply the complement
1736
+ # componentwise, then convert back.
1737
+ parent = self.parent()
1738
+ F = parent.realization_of().F()
1739
+ dct = {I.complement(): coeff for (I, coeff) in F(self)}
1740
+ return parent(F._from_dict(dct, remove_zeros=False))
1741
+
1742
+ def star_involution(self):
1743
+ r"""
1744
+ Return the image of the element ``self`` of `FQSym`
1745
+ under the star involution.
1746
+
1747
+ The star involution is defined as the
1748
+ linear map `FQSym \to FQSym` that sends each basis
1749
+ element `F_u` of the F-basis of `FQSym`
1750
+ to the basis element `F_{w_0 \circ u \circ w_0}`, where
1751
+ `w_0` is the longest word (i.e., `w_0(i) = n + 1 - i`)
1752
+ in the symmetric group `S_n` that contains `u`.
1753
+ The star involution is a graded Hopf algebra
1754
+ anti-automorphism of `FQSym`.
1755
+ It is denoted by `f \mapsto f^*`. Every permutation
1756
+ `u \in S_n` satisfies
1757
+
1758
+ .. MATH::
1759
+
1760
+ (F_u)^* = F_{w_0 \circ u \circ w_0}, \qquad
1761
+ (G_u)^* = G_{w_0 \circ u \circ w_0}, \qquad
1762
+ (\mathcal{M}_u)^* = \mathcal{M}_{w_0 \circ u \circ w_0},
1763
+
1764
+ where standard notations for classical bases of `FQSym`
1765
+ are being used (that is, `F` for the F-basis,
1766
+ `G` for the G-basis, and `\mathcal{M}` for the Monomial
1767
+ basis). In other words, writing permutations in one-line
1768
+ notation, we have
1769
+
1770
+ .. MATH::
1771
+
1772
+ (F_{(u_1, u_2, \ldots, u_n)})^*
1773
+ = F_{(n+1-u_n, n+1-u_{n-1}, \ldots, n+1-u_1)}, \qquad
1774
+ (G_{(u_1, u_2, \ldots, u_n)})^*
1775
+ = G_{(n+1-u_n, n+1-u_{n-1}, \ldots, n+1-u_1)},
1776
+
1777
+ and
1778
+
1779
+ .. MATH::
1780
+
1781
+ (\mathcal{M}_{(u_1, u_2, \ldots, u_n)})^*
1782
+ = \mathcal{M}_{(n+1-u_n, n+1-u_{n-1}, \ldots, n+1-u_1)}.
1783
+
1784
+ Let us denote the star involution by `(\ast)` as well.
1785
+
1786
+ If we also denote by `(\ast)` the star involution of
1787
+ of the quasisymmetric functions
1788
+ (:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution`)
1789
+ and if we let `\pi : FQSym \to QSym` be the canonical
1790
+ projection then `\pi \circ (\ast) = (\ast) \circ \pi`.
1791
+ Similar for the noncommutative symmetric functions
1792
+ (:meth:`~sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.star_involution`)
1793
+ with `\pi : NSym \to FQSym` being the canonical inclusion
1794
+ and the word quasisymmetric functions
1795
+ (:meth:`~sage.combinat.chas.wqsym.WordQuasiSymmetricFunctions.Bases.ElementMethods.star_involution`)
1796
+ with `\pi : FQSym \to WQSym` the canonical inclusion.
1797
+
1798
+ .. TODO::
1799
+
1800
+ Duality?
1801
+
1802
+ .. SEEALSO::
1803
+
1804
+ :meth:`omega_involution`, :meth:`psi_involution`
1805
+
1806
+ EXAMPLES::
1807
+
1808
+ sage: FQSym = algebras.FQSym(ZZ)
1809
+ sage: F = FQSym.F()
1810
+ sage: F[[2,3,1]].star_involution()
1811
+ F[3, 1, 2]
1812
+ sage: (3*F[[1]] - 4*F[[]] + 5*F[[1,2]]).star_involution()
1813
+ -4*F[] + 3*F[1] + 5*F[1, 2]
1814
+ sage: G = FQSym.G()
1815
+ sage: G[[2,3,1]].star_involution()
1816
+ G[3, 1, 2]
1817
+ sage: M = FQSym.M()
1818
+ sage: M[[2,3,1]].star_involution()
1819
+ M[3, 1, 2]
1820
+
1821
+ The star involution commutes with the antipode::
1822
+
1823
+ sage: all( F(I).antipode().star_involution()
1824
+ ....: == F(I).star_involution().antipode()
1825
+ ....: for I in Permutations(4) )
1826
+ True
1827
+
1828
+ Testing the `\pi \circ (\ast) = (\ast) \circ \pi` relation::
1829
+
1830
+ sage: all( M[I].star_involution().to_qsym()
1831
+ ....: == M[I].to_qsym().star_involution()
1832
+ ....: for I in Permutations(4) )
1833
+ True
1834
+
1835
+ Similar for `NSym`::
1836
+
1837
+ sage: NSym = NonCommutativeSymmetricFunctions(ZZ)
1838
+ sage: S = NSym.S()
1839
+ sage: all( S[I].star_involution().to_fqsym() == S[I].to_fqsym().star_involution()
1840
+ ....: for I in Compositions(4) )
1841
+ True
1842
+
1843
+ Similar for `WQSym`::
1844
+
1845
+ sage: WQSym = algebras.WQSym(ZZ)
1846
+ sage: all( F(I).to_wqsym().star_involution()
1847
+ ....: == F(I).star_involution().to_wqsym()
1848
+ ....: for I in Permutations(4) )
1849
+ True
1850
+
1851
+ .. TODO::
1852
+
1853
+ Check further commutative squares.
1854
+ """
1855
+ # Convert to the F-basis, there apply the reversal and
1856
+ # complement componentwise, then convert back.
1857
+ parent = self.parent()
1858
+ F = parent.realization_of().F()
1859
+ dct = {I.complement().reverse(): coeff for (I, coeff) in F(self)}
1860
+ return parent(F._from_dict(dct, remove_zeros=False))
1861
+
1862
+ def to_symmetric_group_algebra(self, n=None):
1863
+ """
1864
+ Return the element of a symmetric group algebra
1865
+ corresponding to the element ``self`` of `FQSym`.
1866
+
1867
+ INPUT:
1868
+
1869
+ - ``n`` -- integer (default: the maximal degree of ``self``);
1870
+ the rank of the target symmetric group algebra
1871
+
1872
+ EXAMPLES::
1873
+
1874
+ sage: A = algebras.FQSym(QQ).G()
1875
+ sage: x = A([1,3,2,4]) + 5/2 * A([2,3,4,1])
1876
+ sage: x.to_symmetric_group_algebra()
1877
+ [1, 3, 2, 4] + 5/2*[4, 1, 2, 3]
1878
+ """
1879
+ F = self.parent().realization_of().F()
1880
+ return F(self).to_symmetric_group_algebra(n=n)
1881
+
1882
+ def to_wqsym(self):
1883
+ r"""
1884
+ Return the image of ``self`` under the canonical
1885
+ inclusion map `FQSym \to WQSym`.
1886
+
1887
+ The canonical inclusion map `FQSym \to WQSym` is
1888
+ an injective homomorphism of Hopf algebras. It sends
1889
+ a basis element `G_w` of `FQSym` to the sum of
1890
+ basis elements `\mathbf{M}_u` of `WQSym`, where `u`
1891
+ ranges over all packed words whose standardization
1892
+ is `w`.
1893
+
1894
+ .. SEEALSO::
1895
+
1896
+ :class:`WordQuasiSymmetricFunctions` for a
1897
+ definition of `WQSym`.
1898
+
1899
+ EXAMPLES::
1900
+
1901
+ sage: G = algebras.FQSym(QQ).G()
1902
+ sage: x = G[1, 3, 2]
1903
+ sage: x.to_wqsym()
1904
+ M[{1}, {3}, {2}] + M[{1, 3}, {2}]
1905
+ sage: G[1, 2].to_wqsym()
1906
+ M[{1}, {2}] + M[{1, 2}]
1907
+ sage: F = algebras.FQSym(QQ).F()
1908
+ sage: F[3, 1, 2].to_wqsym()
1909
+ M[{3}, {1}, {2}] + M[{3}, {1, 2}]
1910
+ sage: G[2, 3, 1].to_wqsym()
1911
+ M[{3}, {1}, {2}] + M[{3}, {1, 2}]
1912
+ """
1913
+ parent = self.parent()
1914
+ FQSym = parent.realization_of()
1915
+ G = FQSym.G()
1916
+ from sage.combinat.chas.wqsym import WordQuasiSymmetricFunctions
1917
+ M = WordQuasiSymmetricFunctions(parent.base_ring()).M()
1918
+ OSP = M.basis().keys()
1919
+ from sage.combinat.words.finite_word import word_to_ordered_set_partition
1920
+
1921
+ def to_wqsym_on_G_basis(w):
1922
+ # Return the image of `G_w` under the inclusion
1923
+ # map `FQSym \to WQSym`.
1924
+ dc = w.inverse().descents_composition()
1925
+ res = M.zero()
1926
+ for comp in dc.finer():
1927
+ v = w.destandardize(comp)
1928
+ res += M[OSP(word_to_ordered_set_partition(v))]
1929
+ return res
1930
+ return M.linear_combination((to_wqsym_on_G_basis(w), coeff)
1931
+ for w, coeff in G(self))
1932
+
1933
+ def to_qsym(self):
1934
+ r"""
1935
+ Return the image of ``self`` under the canonical
1936
+ projection `FQSym \to QSym`.
1937
+
1938
+ The canonical projection `FQSym \to QSym` is a
1939
+ surjective homomorphism of Hopf algebras. It sends a
1940
+ basis element `F_w` of `FQSym` to the basis element
1941
+ `F_{\operatorname{Comp} w}` of the fundamental basis
1942
+ of `QSym`, where `\operatorname{Comp} w` stands for
1943
+ the descent composition
1944
+ (:meth:`sage.combinat.permutation.Permutation.descents_composition`)
1945
+ of the permutation `w`.
1946
+
1947
+ .. SEEALSO::
1948
+
1949
+ :class:`QuasiSymmetricFunctions` for a
1950
+ definition of `QSym`.
1951
+
1952
+ EXAMPLES::
1953
+
1954
+ sage: G = algebras.FQSym(QQ).G()
1955
+ sage: x = G[1, 3, 2]
1956
+ sage: x.to_qsym()
1957
+ F[2, 1]
1958
+ sage: G[2, 3, 1].to_qsym()
1959
+ F[1, 2]
1960
+ sage: F = algebras.FQSym(QQ).F()
1961
+ sage: F[2, 3, 1].to_qsym()
1962
+ F[2, 1]
1963
+ sage: (F[2, 3, 1] + F[1, 3, 2] + F[1, 2, 3]).to_qsym()
1964
+ 2*F[2, 1] + F[3]
1965
+ sage: F2 = algebras.FQSym(GF(2)).F()
1966
+ sage: F2[2, 3, 1].to_qsym()
1967
+ F[2, 1]
1968
+ sage: (F2[2, 3, 1] + F2[1, 3, 2] + F2[1, 2, 3]).to_qsym()
1969
+ F[3]
1970
+ """
1971
+ parent = self.parent()
1972
+ FQSym = parent.realization_of()
1973
+ F = FQSym.F()
1974
+ from sage.combinat.ncsf_qsym.qsym import QuasiSymmetricFunctions
1975
+ QF = QuasiSymmetricFunctions(parent.base_ring()).F()
1976
+ return QF.sum_of_terms((w.descents_composition(), coeff)
1977
+ for w, coeff in F(self))