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.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
- passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
- passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
- passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
- passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
- sage/algebras/affine_nil_temperley_lieb.py +263 -0
- sage/algebras/all.py +24 -0
- sage/algebras/all__sagemath_combinat.py +35 -0
- sage/algebras/askey_wilson.py +935 -0
- sage/algebras/associated_graded.py +345 -0
- sage/algebras/cellular_basis.py +350 -0
- sage/algebras/cluster_algebra.py +2766 -0
- sage/algebras/down_up_algebra.py +860 -0
- sage/algebras/free_algebra.py +1698 -0
- sage/algebras/free_algebra_element.py +345 -0
- sage/algebras/free_algebra_quotient.py +405 -0
- sage/algebras/free_algebra_quotient_element.py +295 -0
- sage/algebras/free_zinbiel_algebra.py +885 -0
- sage/algebras/hall_algebra.py +783 -0
- sage/algebras/hecke_algebras/all.py +4 -0
- sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
- sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
- sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
- sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
- sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
- sage/algebras/iwahori_hecke_algebra.py +3095 -0
- sage/algebras/jordan_algebra.py +1773 -0
- sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
- sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
- sage/algebras/lie_conformal_algebras/all.py +18 -0
- sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
- sage/algebras/lie_conformal_algebras/examples.py +43 -0
- sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
- sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
- sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
- sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
- sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
- sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
- sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
- sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
- sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
- sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
- sage/algebras/nil_coxeter_algebra.py +191 -0
- sage/algebras/q_commuting_polynomials.py +673 -0
- sage/algebras/q_system.py +608 -0
- sage/algebras/quantum_clifford.py +959 -0
- sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
- sage/algebras/quantum_groups/all.py +9 -0
- sage/algebras/quantum_groups/fock_space.py +2219 -0
- sage/algebras/quantum_groups/q_numbers.py +207 -0
- sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
- sage/algebras/quantum_groups/representations.py +591 -0
- sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
- sage/algebras/quantum_oscillator.py +623 -0
- sage/algebras/quaternion_algebra.py +20 -0
- sage/algebras/quaternion_algebra_element.py +55 -0
- sage/algebras/rational_cherednik_algebra.py +525 -0
- sage/algebras/schur_algebra.py +670 -0
- sage/algebras/shuffle_algebra.py +1011 -0
- sage/algebras/splitting_algebra.py +779 -0
- sage/algebras/tensor_algebra.py +709 -0
- sage/algebras/yangian.py +1082 -0
- sage/algebras/yokonuma_hecke_algebra.py +1018 -0
- sage/all__sagemath_combinat.py +44 -0
- sage/combinat/SJT.py +255 -0
- sage/combinat/affine_permutation.py +2405 -0
- sage/combinat/algebraic_combinatorics.py +55 -0
- sage/combinat/all.py +53 -0
- sage/combinat/all__sagemath_combinat.py +195 -0
- sage/combinat/alternating_sign_matrix.py +2063 -0
- sage/combinat/baxter_permutations.py +346 -0
- sage/combinat/bijectionist.py +3220 -0
- sage/combinat/binary_recurrence_sequences.py +1180 -0
- sage/combinat/blob_algebra.py +685 -0
- sage/combinat/catalog_partitions.py +27 -0
- sage/combinat/chas/all.py +23 -0
- sage/combinat/chas/fsym.py +1180 -0
- sage/combinat/chas/wqsym.py +2601 -0
- sage/combinat/cluster_complex.py +326 -0
- sage/combinat/colored_permutations.py +2039 -0
- sage/combinat/colored_permutations_representations.py +964 -0
- sage/combinat/composition_signed.py +142 -0
- sage/combinat/composition_tableau.py +855 -0
- sage/combinat/constellation.py +1729 -0
- sage/combinat/core.py +751 -0
- sage/combinat/counting.py +12 -0
- sage/combinat/crystals/affine.py +742 -0
- sage/combinat/crystals/affine_factorization.py +518 -0
- sage/combinat/crystals/affinization.py +331 -0
- sage/combinat/crystals/alcove_path.py +2013 -0
- sage/combinat/crystals/all.py +22 -0
- sage/combinat/crystals/bkk_crystals.py +141 -0
- sage/combinat/crystals/catalog.py +115 -0
- sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
- sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
- sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
- sage/combinat/crystals/crystals.py +257 -0
- sage/combinat/crystals/direct_sum.py +260 -0
- sage/combinat/crystals/elementary_crystals.py +1251 -0
- sage/combinat/crystals/fast_crystals.py +441 -0
- sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
- sage/combinat/crystals/generalized_young_walls.py +1076 -0
- sage/combinat/crystals/highest_weight_crystals.py +436 -0
- sage/combinat/crystals/induced_structure.py +695 -0
- sage/combinat/crystals/infinity_crystals.py +730 -0
- sage/combinat/crystals/kac_modules.py +863 -0
- sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
- sage/combinat/crystals/kyoto_path_model.py +497 -0
- sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/letters.pxd +79 -0
- sage/combinat/crystals/letters.pyx +3056 -0
- sage/combinat/crystals/littelmann_path.py +1518 -0
- sage/combinat/crystals/monomial_crystals.py +1262 -0
- sage/combinat/crystals/multisegments.py +462 -0
- sage/combinat/crystals/mv_polytopes.py +467 -0
- sage/combinat/crystals/pbw_crystal.py +511 -0
- sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/pbw_datum.pxd +4 -0
- sage/combinat/crystals/pbw_datum.pyx +487 -0
- sage/combinat/crystals/polyhedral_realization.py +372 -0
- sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/spins.pxd +21 -0
- sage/combinat/crystals/spins.pyx +756 -0
- sage/combinat/crystals/star_crystal.py +290 -0
- sage/combinat/crystals/subcrystal.py +464 -0
- sage/combinat/crystals/tensor_product.py +1177 -0
- sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
- sage/combinat/crystals/tensor_product_element.pxd +35 -0
- sage/combinat/crystals/tensor_product_element.pyx +1870 -0
- sage/combinat/crystals/virtual_crystal.py +420 -0
- sage/combinat/cyclic_sieving_phenomenon.py +204 -0
- sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
- sage/combinat/degree_sequences.pyx +588 -0
- sage/combinat/derangements.py +527 -0
- sage/combinat/descent_algebra.py +1008 -0
- sage/combinat/diagram.py +1551 -0
- sage/combinat/diagram_algebras.py +5886 -0
- sage/combinat/dyck_word.py +4349 -0
- sage/combinat/e_one_star.py +1623 -0
- sage/combinat/enumerated_sets.py +123 -0
- sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
- sage/combinat/fast_vector_partitions.pyx +346 -0
- sage/combinat/fqsym.py +1977 -0
- sage/combinat/free_dendriform_algebra.py +954 -0
- sage/combinat/free_prelie_algebra.py +1141 -0
- sage/combinat/fully_commutative_elements.py +1077 -0
- sage/combinat/fully_packed_loop.py +1523 -0
- sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
- sage/combinat/gray_codes.py +311 -0
- sage/combinat/grossman_larson_algebras.py +667 -0
- sage/combinat/growth.py +4352 -0
- sage/combinat/hall_polynomial.py +188 -0
- sage/combinat/hillman_grassl.py +866 -0
- sage/combinat/integer_matrices.py +329 -0
- sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
- sage/combinat/k_tableau.py +4564 -0
- sage/combinat/kazhdan_lusztig.py +215 -0
- sage/combinat/key_polynomial.py +885 -0
- sage/combinat/knutson_tao_puzzles.py +2286 -0
- sage/combinat/lr_tableau.py +311 -0
- sage/combinat/matrices/all.py +24 -0
- sage/combinat/matrices/hadamard_matrix.py +3790 -0
- sage/combinat/matrices/latin.py +2912 -0
- sage/combinat/misc.py +401 -0
- sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
- sage/combinat/ncsf_qsym/all.py +21 -0
- sage/combinat/ncsf_qsym/combinatorics.py +317 -0
- sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
- sage/combinat/ncsf_qsym/ncsf.py +5637 -0
- sage/combinat/ncsf_qsym/qsym.py +4053 -0
- sage/combinat/ncsf_qsym/tutorial.py +447 -0
- sage/combinat/ncsym/all.py +21 -0
- sage/combinat/ncsym/bases.py +855 -0
- sage/combinat/ncsym/dual.py +593 -0
- sage/combinat/ncsym/ncsym.py +2076 -0
- sage/combinat/necklace.py +551 -0
- sage/combinat/non_decreasing_parking_function.py +634 -0
- sage/combinat/nu_dyck_word.py +1474 -0
- sage/combinat/output.py +861 -0
- sage/combinat/parallelogram_polyomino.py +4326 -0
- sage/combinat/parking_functions.py +1602 -0
- sage/combinat/partition_algebra.py +1998 -0
- sage/combinat/partition_kleshchev.py +1982 -0
- sage/combinat/partition_shifting_algebras.py +584 -0
- sage/combinat/partition_tuple.py +3114 -0
- sage/combinat/path_tableaux/all.py +13 -0
- sage/combinat/path_tableaux/catalog.py +29 -0
- sage/combinat/path_tableaux/dyck_path.py +380 -0
- sage/combinat/path_tableaux/frieze.py +476 -0
- sage/combinat/path_tableaux/path_tableau.py +728 -0
- sage/combinat/path_tableaux/semistandard.py +510 -0
- sage/combinat/perfect_matching.py +779 -0
- sage/combinat/plane_partition.py +3300 -0
- sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
- sage/combinat/q_bernoulli.pyx +128 -0
- sage/combinat/quickref.py +81 -0
- sage/combinat/recognizable_series.py +2051 -0
- sage/combinat/regular_sequence.py +4316 -0
- sage/combinat/regular_sequence_bounded.py +543 -0
- sage/combinat/restricted_growth.py +81 -0
- sage/combinat/ribbon.py +20 -0
- sage/combinat/ribbon_shaped_tableau.py +489 -0
- sage/combinat/ribbon_tableau.py +1180 -0
- sage/combinat/rigged_configurations/all.py +46 -0
- sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
- sage/combinat/rigged_configurations/bij_infinity.py +370 -0
- sage/combinat/rigged_configurations/bij_type_A.py +163 -0
- sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
- sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
- sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
- sage/combinat/rigged_configurations/bij_type_B.py +900 -0
- sage/combinat/rigged_configurations/bij_type_C.py +267 -0
- sage/combinat/rigged_configurations/bij_type_D.py +771 -0
- sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
- sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
- sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
- sage/combinat/rigged_configurations/bijection.py +143 -0
- sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
- sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
- sage/combinat/rigged_configurations/rc_crystal.py +461 -0
- sage/combinat/rigged_configurations/rc_infinity.py +540 -0
- sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
- sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
- sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
- sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
- sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
- sage/combinat/rsk.py +3438 -0
- sage/combinat/schubert_polynomial.py +508 -0
- sage/combinat/set_partition.py +3318 -0
- sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
- sage/combinat/set_partition_iterator.pyx +136 -0
- sage/combinat/set_partition_ordered.py +1590 -0
- sage/combinat/sf/abreu_nigro.py +346 -0
- sage/combinat/sf/all.py +52 -0
- sage/combinat/sf/character.py +576 -0
- sage/combinat/sf/classical.py +319 -0
- sage/combinat/sf/dual.py +996 -0
- sage/combinat/sf/elementary.py +549 -0
- sage/combinat/sf/hall_littlewood.py +1028 -0
- sage/combinat/sf/hecke.py +336 -0
- sage/combinat/sf/homogeneous.py +464 -0
- sage/combinat/sf/jack.py +1428 -0
- sage/combinat/sf/k_dual.py +1458 -0
- sage/combinat/sf/kfpoly.py +447 -0
- sage/combinat/sf/llt.py +789 -0
- sage/combinat/sf/macdonald.py +2019 -0
- sage/combinat/sf/monomial.py +525 -0
- sage/combinat/sf/multiplicative.py +113 -0
- sage/combinat/sf/new_kschur.py +1786 -0
- sage/combinat/sf/ns_macdonald.py +964 -0
- sage/combinat/sf/orthogonal.py +246 -0
- sage/combinat/sf/orthotriang.py +355 -0
- sage/combinat/sf/powersum.py +963 -0
- sage/combinat/sf/schur.py +880 -0
- sage/combinat/sf/sf.py +1653 -0
- sage/combinat/sf/sfa.py +7053 -0
- sage/combinat/sf/symplectic.py +253 -0
- sage/combinat/sf/witt.py +721 -0
- sage/combinat/shifted_primed_tableau.py +2735 -0
- sage/combinat/shuffle.py +830 -0
- sage/combinat/sidon_sets.py +146 -0
- sage/combinat/similarity_class_type.py +1721 -0
- sage/combinat/sine_gordon.py +618 -0
- sage/combinat/six_vertex_model.py +784 -0
- sage/combinat/skew_partition.py +2053 -0
- sage/combinat/skew_tableau.py +2989 -0
- sage/combinat/sloane_functions.py +8935 -0
- sage/combinat/specht_module.py +1403 -0
- sage/combinat/species/all.py +48 -0
- sage/combinat/species/characteristic_species.py +321 -0
- sage/combinat/species/composition_species.py +273 -0
- sage/combinat/species/cycle_species.py +284 -0
- sage/combinat/species/empty_species.py +155 -0
- sage/combinat/species/functorial_composition_species.py +148 -0
- sage/combinat/species/generating_series.py +673 -0
- sage/combinat/species/library.py +148 -0
- sage/combinat/species/linear_order_species.py +169 -0
- sage/combinat/species/misc.py +83 -0
- sage/combinat/species/partition_species.py +290 -0
- sage/combinat/species/permutation_species.py +268 -0
- sage/combinat/species/product_species.py +423 -0
- sage/combinat/species/recursive_species.py +476 -0
- sage/combinat/species/set_species.py +192 -0
- sage/combinat/species/species.py +820 -0
- sage/combinat/species/structure.py +539 -0
- sage/combinat/species/subset_species.py +243 -0
- sage/combinat/species/sum_species.py +225 -0
- sage/combinat/subword.py +564 -0
- sage/combinat/subword_complex.py +2122 -0
- sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
- sage/combinat/subword_complex_c.pyx +119 -0
- sage/combinat/super_tableau.py +821 -0
- sage/combinat/superpartition.py +1154 -0
- sage/combinat/symmetric_group_algebra.py +3774 -0
- sage/combinat/symmetric_group_representations.py +1830 -0
- sage/combinat/t_sequences.py +877 -0
- sage/combinat/tableau.py +9506 -0
- sage/combinat/tableau_residues.py +860 -0
- sage/combinat/tableau_tuple.py +5353 -0
- sage/combinat/tiling.py +2432 -0
- sage/combinat/triangles_FHM.py +777 -0
- sage/combinat/tutorial.py +1857 -0
- sage/combinat/vector_partition.py +337 -0
- sage/combinat/words/abstract_word.py +1722 -0
- sage/combinat/words/all.py +59 -0
- sage/combinat/words/alphabet.py +268 -0
- sage/combinat/words/finite_word.py +7201 -0
- sage/combinat/words/infinite_word.py +113 -0
- sage/combinat/words/lyndon_word.py +652 -0
- sage/combinat/words/morphic.py +351 -0
- sage/combinat/words/morphism.py +3878 -0
- sage/combinat/words/paths.py +2932 -0
- sage/combinat/words/shuffle_product.py +278 -0
- sage/combinat/words/suffix_trees.py +1873 -0
- sage/combinat/words/word.py +769 -0
- sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_datatypes.pxd +4 -0
- sage/combinat/words/word_datatypes.pyx +1067 -0
- sage/combinat/words/word_generators.py +2026 -0
- sage/combinat/words/word_infinite_datatypes.py +1218 -0
- sage/combinat/words/word_options.py +99 -0
- sage/combinat/words/words.py +2396 -0
- sage/data_structures/all__sagemath_combinat.py +1 -0
- sage/databases/all__sagemath_combinat.py +13 -0
- sage/databases/findstat.py +4897 -0
- sage/databases/oeis.py +2058 -0
- sage/databases/sloane.py +393 -0
- sage/dynamics/all__sagemath_combinat.py +14 -0
- sage/dynamics/cellular_automata/all.py +7 -0
- sage/dynamics/cellular_automata/catalog.py +34 -0
- sage/dynamics/cellular_automata/elementary.py +612 -0
- sage/dynamics/cellular_automata/glca.py +477 -0
- sage/dynamics/cellular_automata/solitons.py +1463 -0
- sage/dynamics/finite_dynamical_system.py +1249 -0
- sage/dynamics/finite_dynamical_system_catalog.py +382 -0
- sage/games/all.py +7 -0
- sage/games/hexad.py +704 -0
- sage/games/quantumino.py +591 -0
- sage/games/sudoku.py +889 -0
- sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
- sage/games/sudoku_backtrack.pyx +189 -0
- sage/groups/all__sagemath_combinat.py +1 -0
- sage/groups/indexed_free_group.py +489 -0
- sage/libs/all__sagemath_combinat.py +6 -0
- sage/libs/lrcalc/__init__.py +1 -0
- sage/libs/lrcalc/lrcalc.py +525 -0
- sage/libs/symmetrica/__init__.py +7 -0
- sage/libs/symmetrica/all.py +101 -0
- sage/libs/symmetrica/kostka.pxi +168 -0
- sage/libs/symmetrica/part.pxi +193 -0
- sage/libs/symmetrica/plet.pxi +42 -0
- sage/libs/symmetrica/sab.pxi +196 -0
- sage/libs/symmetrica/sb.pxi +332 -0
- sage/libs/symmetrica/sc.pxi +192 -0
- sage/libs/symmetrica/schur.pxi +956 -0
- sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
- sage/libs/symmetrica/symmetrica.pxi +1172 -0
- sage/libs/symmetrica/symmetrica.pyx +39 -0
- sage/monoids/all.py +13 -0
- sage/monoids/automatic_semigroup.py +1054 -0
- sage/monoids/free_abelian_monoid.py +315 -0
- sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
- sage/monoids/free_abelian_monoid_element.pxd +16 -0
- sage/monoids/free_abelian_monoid_element.pyx +397 -0
- sage/monoids/free_monoid.py +335 -0
- sage/monoids/free_monoid_element.py +431 -0
- sage/monoids/hecke_monoid.py +65 -0
- sage/monoids/string_monoid.py +817 -0
- sage/monoids/string_monoid_element.py +547 -0
- sage/monoids/string_ops.py +143 -0
- sage/monoids/trace_monoid.py +972 -0
- sage/rings/all__sagemath_combinat.py +2 -0
- sage/sat/all.py +4 -0
- sage/sat/boolean_polynomials.py +405 -0
- sage/sat/converters/__init__.py +6 -0
- sage/sat/converters/anf2cnf.py +14 -0
- sage/sat/converters/polybori.py +611 -0
- sage/sat/solvers/__init__.py +5 -0
- sage/sat/solvers/cryptominisat.py +287 -0
- sage/sat/solvers/dimacs.py +783 -0
- sage/sat/solvers/picosat.py +228 -0
- sage/sat/solvers/sat_lp.py +156 -0
- sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- 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))
|