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
|
@@ -0,0 +1,4053 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Quasisymmetric functions
|
|
5
|
+
|
|
6
|
+
REFERENCES:
|
|
7
|
+
|
|
8
|
+
.. [Ges] \I. Gessel, *Multipartite P-partitions and inner products of skew Schur
|
|
9
|
+
functions*, Contemp. Math. **34** (1984), 289-301.
|
|
10
|
+
http://people.brandeis.edu/~gessel/homepage/papers/multipartite.pdf
|
|
11
|
+
|
|
12
|
+
.. [MR] \C. Malvenuto and C. Reutenauer, *Duality between quasi-symmetric
|
|
13
|
+
functions and the Solomon descent algebra*, J. Algebra **177** (1995),
|
|
14
|
+
no. 3, 967-982. http://www.mat.uniroma1.it/people/malvenuto/Duality.pdf
|
|
15
|
+
|
|
16
|
+
.. [GriRei18]_
|
|
17
|
+
|
|
18
|
+
.. [Mal1993] Claudia Malvenuto, *Produits et coproduits des fonctions
|
|
19
|
+
quasi-symétriques et de l'algèbre des descentes*,
|
|
20
|
+
thesis, November 1993.
|
|
21
|
+
http://www1.mat.uniroma1.it/people/malvenuto/Thesis.pdf
|
|
22
|
+
|
|
23
|
+
.. [Haz2004] Michiel Hazewinkel, *Explicit polynomial generators for the
|
|
24
|
+
ring of quasisymmetric functions over the integers*.
|
|
25
|
+
:arxiv:`math/0410366v1`
|
|
26
|
+
|
|
27
|
+
.. [Rad1979] David E. Radford, *A natural ring basis for the shuffle algebra
|
|
28
|
+
and an application to group schemes*, J. Algebra **58** (1979), 432-454.
|
|
29
|
+
|
|
30
|
+
.. [NCSF1] Israel Gelfand, D. Krob, Alain Lascoux, B. Leclerc,
|
|
31
|
+
V. S. Retakh, J.-Y. Thibon,
|
|
32
|
+
*Noncommutative symmetric functions*.
|
|
33
|
+
:arxiv:`hep-th/9407124v1`
|
|
34
|
+
|
|
35
|
+
.. [NCSF2] \D. Krob, B. Leclerc, J.-Y. Thibon,
|
|
36
|
+
*Noncommutative symmetric functions II: Transformations of alphabets*.
|
|
37
|
+
http://www-igm.univ-mlv.fr/~jyt/ARTICLES/NCSF2.ps
|
|
38
|
+
|
|
39
|
+
.. [HLNT09] \F. Hivert, J.-G. Luque, J.-C. Novelli, J.-Y. Thibon,
|
|
40
|
+
*The (1-E)-transform in combinatorial Hopf algebras*.
|
|
41
|
+
:arxiv:`math/0912.0184v2`
|
|
42
|
+
|
|
43
|
+
.. [LMvW13] Kurt Luoto, Stefan Mykytiuk and Stephanie van Willigenburg,
|
|
44
|
+
*An introduction to quasisymmetric Schur functions -- Hopf algebras,
|
|
45
|
+
quasisymmetric functions, and Young composition tableaux*,
|
|
46
|
+
May 23, 2013, Springer.
|
|
47
|
+
http://www.math.ubc.ca/%7Esteph/papers/QuasiSchurBook.pdf
|
|
48
|
+
|
|
49
|
+
.. [BBSSZ2012] Chris Berg, Nantel Bergeron, Franco Saliola,
|
|
50
|
+
Luis Serrano, Mike Zabrocki,
|
|
51
|
+
*A lift of the Schur and Hall-Littlewood bases to
|
|
52
|
+
non-commutative symmetric functions*,
|
|
53
|
+
:arxiv:`1208.5191v3`.
|
|
54
|
+
|
|
55
|
+
.. [Hoff2015] Michael Hoffman.
|
|
56
|
+
*Quasi-symmetric functions and mod* `p` *multiple harmonic sums*.
|
|
57
|
+
Kyushu J. Math. **69** (2015), pp. 345-366.
|
|
58
|
+
:doi:`10.2206/kyushujm.69.345`, :arxiv:`math/0401319v3`.
|
|
59
|
+
|
|
60
|
+
.. [BDHMN2017] Cristina Ballantine, Zajj Daugherty, Angela Hicks, Sarah Mason,
|
|
61
|
+
Elizabeth Niese. *Quasisymmetric power sums*. :arxiv:`1710.11613`.
|
|
62
|
+
|
|
63
|
+
.. [AHM2018] Edward Allen, Joshua Hallam, Sarah Mason, *Dual Immaculate
|
|
64
|
+
Quasisymmetric Functions Expand Positively into Young Quasisymmetric
|
|
65
|
+
Schur Functions*. :arxiv:`1606.03519`
|
|
66
|
+
|
|
67
|
+
.. [SW2010] John Shareshian and Michelle Wachs.
|
|
68
|
+
*Eulerian quasisymmetric functions*. (2010).
|
|
69
|
+
:arxiv:`0812.0764v2`
|
|
70
|
+
|
|
71
|
+
AUTHOR:
|
|
72
|
+
|
|
73
|
+
- Jason Bandlow
|
|
74
|
+
- Franco Saliola
|
|
75
|
+
- Chris Berg
|
|
76
|
+
- Darij Grinberg
|
|
77
|
+
"""
|
|
78
|
+
# ****************************************************************************
|
|
79
|
+
# Copyright (C) 2010 Jason Bandlow <jbandlow@gmail.com>,
|
|
80
|
+
# 2012 Franco Saliola <saliola@gmail.com>,
|
|
81
|
+
# 2012 Chris Berg <chrisjamesberg@gmail.com>
|
|
82
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
83
|
+
# https://www.gnu.org/licenses/
|
|
84
|
+
# ****************************************************************************
|
|
85
|
+
from sage.categories.graded_hopf_algebras import GradedHopfAlgebras
|
|
86
|
+
from sage.categories.rings import Rings
|
|
87
|
+
from sage.categories.fields import Fields
|
|
88
|
+
from sage.categories.realizations import Category_realization_of_parent
|
|
89
|
+
from sage.combinat.permutation import Permutations
|
|
90
|
+
from sage.combinat.composition import Composition, Compositions
|
|
91
|
+
from sage.combinat.partition import Partitions, _Partitions
|
|
92
|
+
from sage.combinat.free_module import CombinatorialFreeModule
|
|
93
|
+
from sage.combinat.sf.sf import SymmetricFunctions
|
|
94
|
+
from sage.combinat.ncsf_qsym.generic_basis_code import BasesOfQSymOrNCSF
|
|
95
|
+
from sage.combinat.ncsf_qsym.combinatorics import (number_of_fCT, number_of_SSRCT,
|
|
96
|
+
compositions_order, coeff_pi, coeff_lp, coeff_sp, coeff_ell)
|
|
97
|
+
from sage.combinat.ncsf_qsym.ncsf import NonCommutativeSymmetricFunctions
|
|
98
|
+
from sage.combinat.words.word import Word
|
|
99
|
+
from sage.combinat.tableau import StandardTableaux
|
|
100
|
+
from sage.misc.bindable_class import BindableClass
|
|
101
|
+
from sage.misc.cachefunc import cached_method
|
|
102
|
+
from sage.misc.lazy_import import lazy_import
|
|
103
|
+
from sage.misc.superseded import deprecated_function_alias
|
|
104
|
+
from sage.structure.parent import Parent
|
|
105
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
106
|
+
|
|
107
|
+
lazy_import('sage.matrix.constructor', 'matrix')
|
|
108
|
+
lazy_import('sage.matrix.matrix_space', 'MatrixSpace')
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class QuasiSymmetricFunctions(UniqueRepresentation, Parent):
|
|
112
|
+
r"""
|
|
113
|
+
.. rubric:: The Hopf algebra of quasisymmetric functions.
|
|
114
|
+
|
|
115
|
+
Let `R` be a commutative ring with unity.
|
|
116
|
+
The `R`-algebra of quasi-symmetric functions may be realized as an
|
|
117
|
+
`R`-subalgebra of the ring of power series in countably many
|
|
118
|
+
variables `R[[x_1, x_2, x_3, \ldots]]`. It consists of those
|
|
119
|
+
formal power series `p` which are degree-bounded (i. e., the degrees
|
|
120
|
+
of all monomials occurring with nonzero coefficient in `p` are bounded
|
|
121
|
+
from above, although the bound can depend on `p`) and satisfy the
|
|
122
|
+
following condition: For every tuple `(a_1, a_2, \ldots, a_m)` of
|
|
123
|
+
positive integers, the coefficient of the monomial
|
|
124
|
+
`x_{i_1}^{a_1} x_{i_2}^{a_2} \cdots x_{i_m}^{a_m}` in `p` is the same
|
|
125
|
+
for all strictly increasing sequences `(i_1 < i_2 < \cdots < i_m)` of
|
|
126
|
+
positive integers. (In other words, the coefficient of a monomial in `p`
|
|
127
|
+
depends only on the sequence of nonzero exponents in the monomial. If
|
|
128
|
+
"sequence" were to be replaced by "multiset" here, we would obtain
|
|
129
|
+
the definition of a symmetric function.)
|
|
130
|
+
|
|
131
|
+
The `R`-algebra of quasi-symmetric functions is commonly called
|
|
132
|
+
`\mathrm{QSym}_R` or occasionally just `\mathrm{QSym}` (when
|
|
133
|
+
`R` is clear from the context or `\ZZ` or `\QQ`). It is graded by
|
|
134
|
+
the total degree of the power series. Its homogeneous elements of degree
|
|
135
|
+
`k` form a free `R`-submodule of rank equal to the number of
|
|
136
|
+
compositions of `k` (that is, `2^{k-1}` if `k \geq 1`, else `1`).
|
|
137
|
+
|
|
138
|
+
The two classical bases of `\mathrm{QSym}`, the monomial basis
|
|
139
|
+
`(M_I)_I` and the fundamental basis `(F_I)_I`, are indexed by
|
|
140
|
+
compositions `I = (I_1, I_2, \cdots, I_\ell )` and defined by the
|
|
141
|
+
formulas:
|
|
142
|
+
|
|
143
|
+
.. MATH::
|
|
144
|
+
|
|
145
|
+
M_I = \sum_{1 \leq i_1 < i_2 < \cdots < i_\ell} x_{i_1}^{I_1}
|
|
146
|
+
x_{i_2}^{I_2} \cdots x_{i_\ell}^{I_\ell}
|
|
147
|
+
|
|
148
|
+
and
|
|
149
|
+
|
|
150
|
+
.. MATH::
|
|
151
|
+
|
|
152
|
+
F_I = \sum_{(j_1, j_2, \ldots, j_n)} x_{j_1} x_{j_2} \cdots
|
|
153
|
+
x_{j_n}
|
|
154
|
+
|
|
155
|
+
where in the second equation the sum runs over all weakly increasing
|
|
156
|
+
`n`-tuples `(j_1, j_2, \ldots, j_n)` of positive integers
|
|
157
|
+
(where `n` is the size of `I`) which increase strictly from `j_r`
|
|
158
|
+
to `j_{r+1}` if `r` is a descent of the composition `I`.
|
|
159
|
+
|
|
160
|
+
These bases are related by the formula
|
|
161
|
+
|
|
162
|
+
`F_I = \sum_{J \leq I} M_J`
|
|
163
|
+
|
|
164
|
+
where the inequality `J \leq I` indicates that `J` is finer than `I`.
|
|
165
|
+
|
|
166
|
+
The `R`-algebra of quasi-symmetric functions is a Hopf algebra,
|
|
167
|
+
with the coproduct satisfying
|
|
168
|
+
|
|
169
|
+
.. MATH::
|
|
170
|
+
|
|
171
|
+
\Delta M_I = \sum_{k=0}^{\ell} M_{(I_1, I_2, \cdots, I_k)} \otimes
|
|
172
|
+
M_{(I_{k+1}, I_{k+2}, \cdots , I_{\ell})}
|
|
173
|
+
|
|
174
|
+
for every composition `I = (I_1, I_2, \cdots , I_\ell )`.
|
|
175
|
+
|
|
176
|
+
It is possible to define an `R`-algebra of quasi-symmetric
|
|
177
|
+
functions in a finite number of variables as well (but it is not
|
|
178
|
+
a bialgebra). These quasi-symmetric functions are actual polynomials
|
|
179
|
+
then, not just power series.
|
|
180
|
+
|
|
181
|
+
Chapter 5 of [GriRei18]_ and Section 11 of [HazWitt1]_ are devoted
|
|
182
|
+
to quasi-symmetric functions, as are Malvenuto's thesis [Mal1993]_
|
|
183
|
+
and part of Chapter 7 of [Sta-EC2]_.
|
|
184
|
+
|
|
185
|
+
.. rubric:: The implementation of the quasi-symmetric function Hopf algebra
|
|
186
|
+
|
|
187
|
+
We realize the `R`-algebra of quasi-symmetric functions in Sage as
|
|
188
|
+
a graded Hopf algebra with basis elements indexed by compositions::
|
|
189
|
+
|
|
190
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
191
|
+
sage: QSym.category()
|
|
192
|
+
Join of Category of Hopf algebras over Rational Field
|
|
193
|
+
and Category of graded algebras over Rational Field
|
|
194
|
+
and Category of commutative algebras over Rational Field
|
|
195
|
+
and Category of monoids with realizations
|
|
196
|
+
and Category of graded coalgebras over Rational Field
|
|
197
|
+
and Category of coalgebras over Rational Field with realizations
|
|
198
|
+
|
|
199
|
+
The most standard two bases for this `R`-algebra are the monomial and
|
|
200
|
+
fundamental bases, and are accessible by the ``M()`` and ``F()`` methods::
|
|
201
|
+
|
|
202
|
+
sage: M = QSym.M()
|
|
203
|
+
sage: F = QSym.F()
|
|
204
|
+
sage: M(F[2,1,2])
|
|
205
|
+
M[1, 1, 1, 1, 1] + M[1, 1, 1, 2] + M[2, 1, 1, 1] + M[2, 1, 2]
|
|
206
|
+
sage: F(M[2,1,2])
|
|
207
|
+
F[1, 1, 1, 1, 1] - F[1, 1, 1, 2] - F[2, 1, 1, 1] + F[2, 1, 2]
|
|
208
|
+
|
|
209
|
+
The product on this space is commutative and is inherited from the product
|
|
210
|
+
on the realization within the ring of power series::
|
|
211
|
+
|
|
212
|
+
sage: M[3]*M[1,1] == M[1,1]*M[3]
|
|
213
|
+
True
|
|
214
|
+
sage: M[3]*M[1,1]
|
|
215
|
+
M[1, 1, 3] + M[1, 3, 1] + M[1, 4] + M[3, 1, 1] + M[4, 1]
|
|
216
|
+
sage: F[3]*F[1,1]
|
|
217
|
+
F[1, 1, 3] + F[1, 2, 2] + F[1, 3, 1] + F[1, 4] + F[2, 1, 2]
|
|
218
|
+
+ F[2, 2, 1] + F[2, 3] + F[3, 1, 1] + F[3, 2] + F[4, 1]
|
|
219
|
+
sage: M[3]*F[2]
|
|
220
|
+
M[1, 1, 3] + M[1, 3, 1] + M[1, 4] + M[2, 3] + M[3, 1, 1] + M[3, 2]
|
|
221
|
+
+ M[4, 1] + M[5]
|
|
222
|
+
sage: F[2]*M[3]
|
|
223
|
+
F[1, 1, 1, 2] - F[1, 2, 2] + F[2, 1, 1, 1] - F[2, 1, 2] - F[2, 2, 1]
|
|
224
|
+
+ F[5]
|
|
225
|
+
|
|
226
|
+
There is a coproduct on `\mathrm{QSym}` as well, which in the Monomial
|
|
227
|
+
basis acts by cutting the composition into a left half and a right
|
|
228
|
+
half. The coproduct is not co-commutative::
|
|
229
|
+
|
|
230
|
+
sage: M[1,3,1].coproduct()
|
|
231
|
+
M[] # M[1, 3, 1] + M[1] # M[3, 1] + M[1, 3] # M[1] + M[1, 3, 1] # M[]
|
|
232
|
+
sage: F[1,3,1].coproduct()
|
|
233
|
+
F[] # F[1, 3, 1] + F[1] # F[3, 1] + F[1, 1] # F[2, 1]
|
|
234
|
+
+ F[1, 2] # F[1, 1] + F[1, 3] # F[1] + F[1, 3, 1] # F[]
|
|
235
|
+
|
|
236
|
+
.. rubric:: The duality pairing with non-commutative symmetric functions
|
|
237
|
+
|
|
238
|
+
These two operations endow the quasi-symmetric functions
|
|
239
|
+
`\mathrm{QSym}` with the structure of a Hopf algebra. It is the graded
|
|
240
|
+
dual Hopf algebra of the non-commutative symmetric functions `NCSF`.
|
|
241
|
+
Under this duality, the Monomial basis of `\mathrm{QSym}` is dual to
|
|
242
|
+
the Complete basis of `NCSF`, and the Fundamental basis of
|
|
243
|
+
`\mathrm{QSym}` is dual to the Ribbon basis of `NCSF` (see [MR]_).
|
|
244
|
+
|
|
245
|
+
::
|
|
246
|
+
|
|
247
|
+
sage: S = M.dual(); S
|
|
248
|
+
Non-Commutative Symmetric Functions over the Rational Field in the Complete basis
|
|
249
|
+
sage: M[1,3,1].duality_pairing( S[1,3,1] )
|
|
250
|
+
1
|
|
251
|
+
sage: M.duality_pairing_matrix( S, degree=4 )
|
|
252
|
+
[1 0 0 0 0 0 0 0]
|
|
253
|
+
[0 1 0 0 0 0 0 0]
|
|
254
|
+
[0 0 1 0 0 0 0 0]
|
|
255
|
+
[0 0 0 1 0 0 0 0]
|
|
256
|
+
[0 0 0 0 1 0 0 0]
|
|
257
|
+
[0 0 0 0 0 1 0 0]
|
|
258
|
+
[0 0 0 0 0 0 1 0]
|
|
259
|
+
[0 0 0 0 0 0 0 1]
|
|
260
|
+
sage: F.duality_pairing_matrix( S, degree=4 )
|
|
261
|
+
[1 0 0 0 0 0 0 0]
|
|
262
|
+
[1 1 0 0 0 0 0 0]
|
|
263
|
+
[1 0 1 0 0 0 0 0]
|
|
264
|
+
[1 1 1 1 0 0 0 0]
|
|
265
|
+
[1 0 0 0 1 0 0 0]
|
|
266
|
+
[1 1 0 0 1 1 0 0]
|
|
267
|
+
[1 0 1 0 1 0 1 0]
|
|
268
|
+
[1 1 1 1 1 1 1 1]
|
|
269
|
+
sage: NCSF = M.realization_of().dual()
|
|
270
|
+
sage: R = NCSF.Ribbon()
|
|
271
|
+
sage: F.duality_pairing_matrix( R, degree=4 )
|
|
272
|
+
[1 0 0 0 0 0 0 0]
|
|
273
|
+
[0 1 0 0 0 0 0 0]
|
|
274
|
+
[0 0 1 0 0 0 0 0]
|
|
275
|
+
[0 0 0 1 0 0 0 0]
|
|
276
|
+
[0 0 0 0 1 0 0 0]
|
|
277
|
+
[0 0 0 0 0 1 0 0]
|
|
278
|
+
[0 0 0 0 0 0 1 0]
|
|
279
|
+
[0 0 0 0 0 0 0 1]
|
|
280
|
+
sage: M.duality_pairing_matrix( R, degree=4 )
|
|
281
|
+
[ 1 0 0 0 0 0 0 0]
|
|
282
|
+
[-1 1 0 0 0 0 0 0]
|
|
283
|
+
[-1 0 1 0 0 0 0 0]
|
|
284
|
+
[ 1 -1 -1 1 0 0 0 0]
|
|
285
|
+
[-1 0 0 0 1 0 0 0]
|
|
286
|
+
[ 1 -1 0 0 -1 1 0 0]
|
|
287
|
+
[ 1 0 -1 0 -1 0 1 0]
|
|
288
|
+
[-1 1 1 -1 1 -1 -1 1]
|
|
289
|
+
|
|
290
|
+
Let `H` and `G` be elements of `\mathrm{QSym}`, and `h` an element of
|
|
291
|
+
`NCSF`. Then, if we represent the duality pairing with the
|
|
292
|
+
mathematical notation `[ \cdot, \cdot ]`,
|
|
293
|
+
|
|
294
|
+
`[H G, h] = [H \otimes G, \Delta(h)]~.`
|
|
295
|
+
|
|
296
|
+
For example, the coefficient of ``M[2,1,4,1]`` in ``M[1,3]*M[2,1,1]`` may be
|
|
297
|
+
computed with the duality pairing::
|
|
298
|
+
|
|
299
|
+
sage: I, J = Composition([1,3]), Composition([2,1,1])
|
|
300
|
+
sage: (M[I]*M[J]).duality_pairing(S[2,1,4,1])
|
|
301
|
+
1
|
|
302
|
+
|
|
303
|
+
And the coefficient of ``S[1,3] # S[2,1,1]`` in ``S[2,1,4,1].coproduct()`` is
|
|
304
|
+
equal to this result::
|
|
305
|
+
|
|
306
|
+
sage: S[2,1,4,1].coproduct()
|
|
307
|
+
S[] # S[2, 1, 4, 1] + ... + S[1, 3] # S[2, 1, 1] + ... + S[4, 1] # S[2, 1]
|
|
308
|
+
|
|
309
|
+
The duality pairing on the tensor space is another way of getting this
|
|
310
|
+
coefficient, but currently the method ``duality_pairing`` is not defined on
|
|
311
|
+
the tensor squared space. However, we can extend this functionality by
|
|
312
|
+
applying a linear morphism to the terms in the coproduct, as follows::
|
|
313
|
+
|
|
314
|
+
sage: X = S[2,1,4,1].coproduct()
|
|
315
|
+
sage: def linear_morphism(x, y):
|
|
316
|
+
....: return x.duality_pairing(M[1,3]) * y.duality_pairing(M[2,1,1])
|
|
317
|
+
sage: X.apply_multilinear_morphism(linear_morphism, codomain=ZZ)
|
|
318
|
+
1
|
|
319
|
+
|
|
320
|
+
Similarly, if `H` is an element of `\mathrm{QSym}` and `g` and `h` are
|
|
321
|
+
elements of `NCSF`, then
|
|
322
|
+
|
|
323
|
+
.. MATH::
|
|
324
|
+
|
|
325
|
+
[ H, g h ] = [ \Delta(H), g \otimes h ].
|
|
326
|
+
|
|
327
|
+
For example, the coefficient of ``R[2,3,1]`` in ``R[2,1]*R[2,1]`` is
|
|
328
|
+
computed with the duality pairing by the following command::
|
|
329
|
+
|
|
330
|
+
sage: (R[2,1]*R[2,1]).duality_pairing(F[2,3,1])
|
|
331
|
+
1
|
|
332
|
+
sage: R[2,1]*R[2,1]
|
|
333
|
+
R[2, 1, 2, 1] + R[2, 3, 1]
|
|
334
|
+
|
|
335
|
+
This coefficient should then be equal to the coefficient of
|
|
336
|
+
``F[2,1] # F[2,1]`` in ``F[2,3,1].coproduct()``::
|
|
337
|
+
|
|
338
|
+
sage: F[2,3,1].coproduct()
|
|
339
|
+
F[] # F[2, 3, 1] + ... + F[2, 1] # F[2, 1] + ... + F[2, 3, 1] # F[]
|
|
340
|
+
|
|
341
|
+
This can also be computed by the duality pairing on the tensor space,
|
|
342
|
+
as above::
|
|
343
|
+
|
|
344
|
+
sage: X = F[2,3,1].coproduct()
|
|
345
|
+
sage: def linear_morphism(x, y):
|
|
346
|
+
....: return x.duality_pairing(R[2,1]) * y.duality_pairing(R[2,1])
|
|
347
|
+
sage: X.apply_multilinear_morphism(linear_morphism, codomain=ZZ)
|
|
348
|
+
1
|
|
349
|
+
|
|
350
|
+
.. rubric:: The operation dual to multiplication by a non-commutative symmetric function
|
|
351
|
+
|
|
352
|
+
Let `g \in NCSF` and consider the linear endomorphism of `NCSF` defined by
|
|
353
|
+
left (respectively, right) multiplication by `g`. Since there is a duality
|
|
354
|
+
between `\mathrm{QSym}` and `NCSF`, this linear transformation induces an
|
|
355
|
+
operator `g^{\perp}` on `\mathrm{QSym}` satisfying
|
|
356
|
+
|
|
357
|
+
.. MATH::
|
|
358
|
+
|
|
359
|
+
[ g^{\perp}(H), h ] = [ H, gh ].
|
|
360
|
+
|
|
361
|
+
for any non-commutative symmetric function `h`.
|
|
362
|
+
|
|
363
|
+
This is implemented by the method
|
|
364
|
+
:meth:`~sage.combinat.ncsf_qsym.generic_basis_code.BasesOfQSymOrNCSF.ElementMethods.skew_by`.
|
|
365
|
+
Explicitly, if ``H`` is a quasi-symmetric function and ``g``
|
|
366
|
+
a non-commutative symmetric function, then ``H.skew_by(g)`` and
|
|
367
|
+
``H.skew_by(g, side='right')`` are expressions that satisfy,
|
|
368
|
+
for any non-commutative symmetric function ``h``, the following
|
|
369
|
+
equalities::
|
|
370
|
+
|
|
371
|
+
H.skew_by(g).duality_pairing(h) == H.duality_pairing(g*h)
|
|
372
|
+
H.skew_by(g, side='right').duality_pairing(h) == H.duality_pairing(h*g)
|
|
373
|
+
|
|
374
|
+
For example, ``M[J].skew_by(S[I])`` is `0` unless the composition ``J``
|
|
375
|
+
begins with ``I`` and ``M(J).skew_by(S(I), side='right')`` is `0` unless
|
|
376
|
+
the composition ``J`` ends with ``I``. For example::
|
|
377
|
+
|
|
378
|
+
sage: M[3,2,2].skew_by(S[3])
|
|
379
|
+
M[2, 2]
|
|
380
|
+
sage: M[3,2,2].skew_by(S[2])
|
|
381
|
+
0
|
|
382
|
+
sage: M[3,2,2].coproduct().apply_multilinear_morphism( lambda x,y: x.duality_pairing(S[3])*y )
|
|
383
|
+
M[2, 2]
|
|
384
|
+
sage: M[3,2,2].skew_by(S[3], side='right')
|
|
385
|
+
0
|
|
386
|
+
sage: M[3,2,2].skew_by(S[2], side='right')
|
|
387
|
+
M[3, 2]
|
|
388
|
+
|
|
389
|
+
.. rubric:: The counit
|
|
390
|
+
|
|
391
|
+
The counit is defined by sending all elements of positive degree to zero::
|
|
392
|
+
|
|
393
|
+
sage: M[3].degree(), M[3,1,2].degree(), M.one().degree()
|
|
394
|
+
(3, 6, 0)
|
|
395
|
+
sage: M[3].counit()
|
|
396
|
+
0
|
|
397
|
+
sage: M[3,1,2].counit()
|
|
398
|
+
0
|
|
399
|
+
sage: M.one().counit()
|
|
400
|
+
1
|
|
401
|
+
sage: (M[3] - 2*M[3,1,2] + 7).counit()
|
|
402
|
+
7
|
|
403
|
+
sage: (F[3] - 2*F[3,1,2] + 7).counit()
|
|
404
|
+
7
|
|
405
|
+
|
|
406
|
+
.. rubric:: The antipode
|
|
407
|
+
|
|
408
|
+
The antipode sends the Fundamental basis element indexed by the
|
|
409
|
+
composition `I` to `(-1)^{|I|}` times the Fundamental
|
|
410
|
+
basis element indexed by the conjugate composition to `I`
|
|
411
|
+
(where `|I|` stands for the size of `I`, that is, the sum of all
|
|
412
|
+
entries of `I`).
|
|
413
|
+
::
|
|
414
|
+
|
|
415
|
+
sage: F[3,2,2].antipode()
|
|
416
|
+
-F[1, 2, 2, 1, 1]
|
|
417
|
+
sage: Composition([3,2,2]).conjugate()
|
|
418
|
+
[1, 2, 2, 1, 1]
|
|
419
|
+
|
|
420
|
+
The antipodes of the Monomial quasisymmetric functions can also be
|
|
421
|
+
computed easily: Every composition `I` satisfies
|
|
422
|
+
|
|
423
|
+
.. MATH::
|
|
424
|
+
|
|
425
|
+
\omega(M_I) = (-1)^{\ell(I)} \sum M_J,
|
|
426
|
+
|
|
427
|
+
where the sum ranges over all compositions `J` of `|I|`
|
|
428
|
+
which are coarser than the reversed composition `I^r` of
|
|
429
|
+
`I`. Here, `\ell(I)` denotes the length of the composition `I`
|
|
430
|
+
(that is, the number of its parts). ::
|
|
431
|
+
|
|
432
|
+
sage: M[3,2,1].antipode()
|
|
433
|
+
-M[1, 2, 3] - M[1, 5] - M[3, 3] - M[6]
|
|
434
|
+
sage: M[3,2,2].antipode()
|
|
435
|
+
-M[2, 2, 3] - M[2, 5] - M[4, 3] - M[7]
|
|
436
|
+
|
|
437
|
+
We demonstrate here the defining relation of the antipode::
|
|
438
|
+
|
|
439
|
+
sage: X = F[3,2,2].coproduct()
|
|
440
|
+
sage: X.apply_multilinear_morphism(lambda x,y: x*y.antipode())
|
|
441
|
+
0
|
|
442
|
+
sage: X.apply_multilinear_morphism(lambda x,y: x.antipode()*y)
|
|
443
|
+
0
|
|
444
|
+
|
|
445
|
+
.. rubric:: The relation with symmetric functions
|
|
446
|
+
|
|
447
|
+
The quasi-symmetric functions are a ring which contain the
|
|
448
|
+
symmetric functions as a subring. The Monomial quasi-symmetric
|
|
449
|
+
functions are related to the monomial symmetric functions by
|
|
450
|
+
|
|
451
|
+
.. MATH::
|
|
452
|
+
|
|
453
|
+
m_\lambda = \sum_{\operatorname{sort}(I) = \lambda} M_I
|
|
454
|
+
|
|
455
|
+
(where `\operatorname{sort}(I)` denotes the result of sorting
|
|
456
|
+
the entries of `I` in decreasing order).
|
|
457
|
+
|
|
458
|
+
There are methods to test if an expression in the quasi-symmetric
|
|
459
|
+
functions is a symmetric function and, if it is, send it to an
|
|
460
|
+
expression in the symmetric functions::
|
|
461
|
+
|
|
462
|
+
sage: f = M[1,1,2] + M[1,2,1]
|
|
463
|
+
sage: f.is_symmetric()
|
|
464
|
+
False
|
|
465
|
+
sage: g = M[3,1] + M[1,3]
|
|
466
|
+
sage: g.is_symmetric()
|
|
467
|
+
True
|
|
468
|
+
sage: g.to_symmetric_function()
|
|
469
|
+
m[3, 1]
|
|
470
|
+
|
|
471
|
+
The expansion of the Schur function in terms of the Fundamental quasi-symmetric
|
|
472
|
+
functions is due to [Ges]_. There is one term in the expansion for each standard
|
|
473
|
+
tableau of shape equal to the partition indexing the Schur function.
|
|
474
|
+
::
|
|
475
|
+
|
|
476
|
+
sage: f = F[3,2] + F[2,2,1] + F[2,3] + F[1,3,1] + F[1,2,2]
|
|
477
|
+
sage: f.is_symmetric()
|
|
478
|
+
True
|
|
479
|
+
sage: f.to_symmetric_function()
|
|
480
|
+
5*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + 2*m[2, 2, 1] + m[3, 1, 1] + m[3, 2]
|
|
481
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
482
|
+
sage: s(f.to_symmetric_function())
|
|
483
|
+
s[3, 2]
|
|
484
|
+
|
|
485
|
+
It is also possible to convert a symmetric function to a
|
|
486
|
+
quasi-symmetric function::
|
|
487
|
+
|
|
488
|
+
sage: m = SymmetricFunctions(QQ).m()
|
|
489
|
+
sage: M( m[3,1,1] )
|
|
490
|
+
M[1, 1, 3] + M[1, 3, 1] + M[3, 1, 1]
|
|
491
|
+
sage: F( s[2,2,1] )
|
|
492
|
+
F[1, 1, 2, 1] + F[1, 2, 1, 1] + F[1, 2, 2] + F[2, 1, 2] + F[2, 2, 1]
|
|
493
|
+
|
|
494
|
+
It is possible to experiment with the quasi-symmetric function expansion of other
|
|
495
|
+
bases, but it is important that the base ring be the same for both algebras.
|
|
496
|
+
::
|
|
497
|
+
|
|
498
|
+
sage: R = QQ['t']
|
|
499
|
+
sage: Qp = SymmetricFunctions(R).hall_littlewood().Qp()
|
|
500
|
+
sage: QSymt = QuasiSymmetricFunctions(R)
|
|
501
|
+
sage: Ft = QSymt.F()
|
|
502
|
+
sage: Ft( Qp[2,2] )
|
|
503
|
+
F[1, 2, 1] + t*F[1, 3] + (t+1)*F[2, 2] + t*F[3, 1] + t^2*F[4]
|
|
504
|
+
|
|
505
|
+
::
|
|
506
|
+
|
|
507
|
+
sage: K = QQ['q','t'].fraction_field()
|
|
508
|
+
sage: Ht = SymmetricFunctions(K).macdonald().Ht()
|
|
509
|
+
sage: Fqt = QuasiSymmetricFunctions(Ht.base_ring()).F()
|
|
510
|
+
sage: Fqt(Ht[2,1])
|
|
511
|
+
q*t*F[1, 1, 1] + (q+t)*F[1, 2] + (q+t)*F[2, 1] + F[3]
|
|
512
|
+
|
|
513
|
+
The following will raise an error because the base ring of ``F`` is not
|
|
514
|
+
equal to the base ring of ``Ht``::
|
|
515
|
+
|
|
516
|
+
sage: F(Ht[2,1])
|
|
517
|
+
Traceback (most recent call last):
|
|
518
|
+
...
|
|
519
|
+
TypeError: do not know how to make x (= McdHt[2, 1]) an element of self (=Quasisymmetric functions over the Rational Field in the Fundamental basis)
|
|
520
|
+
|
|
521
|
+
.. rubric:: The map to the ring of polynomials
|
|
522
|
+
|
|
523
|
+
The quasi-symmetric functions can be seen as an inverse limit
|
|
524
|
+
of a subring of a polynomial ring as the number of variables
|
|
525
|
+
increases. Indeed, there exists a projection from the
|
|
526
|
+
quasi-symmetric functions onto the polynomial ring
|
|
527
|
+
`R[x_1, x_2, \ldots, x_n]`. This projection is defined by
|
|
528
|
+
sending the variables `x_{n+1}, x_{n+2}, \cdots` to `0`, while
|
|
529
|
+
the remaining `n` variables remain fixed. Note that this
|
|
530
|
+
projection sends `M_I` to `0` if the length of the composition
|
|
531
|
+
`I` is higher than `n`. ::
|
|
532
|
+
|
|
533
|
+
sage: M[1,3,1].expand(4)
|
|
534
|
+
x0*x1^3*x2 + x0*x1^3*x3 + x0*x2^3*x3 + x1*x2^3*x3
|
|
535
|
+
sage: F[1,3,1].expand(4)
|
|
536
|
+
x0*x1^3*x2 + x0*x1^3*x3 + x0*x1^2*x2*x3 + x0*x1*x2^2*x3 + x0*x2^3*x3 + x1*x2^3*x3
|
|
537
|
+
sage: M[1,3,1].expand(2)
|
|
538
|
+
0
|
|
539
|
+
|
|
540
|
+
TESTS::
|
|
541
|
+
|
|
542
|
+
sage: QSym = QuasiSymmetricFunctions(QQ); QSym
|
|
543
|
+
Quasisymmetric functions over the Rational Field
|
|
544
|
+
sage: QSym.base_ring()
|
|
545
|
+
Rational Field
|
|
546
|
+
sage: algebras.QSym(QQ) is QSym
|
|
547
|
+
True
|
|
548
|
+
"""
|
|
549
|
+
|
|
550
|
+
def __init__(self, R):
|
|
551
|
+
"""
|
|
552
|
+
The Hopf algebra of quasi-symmetric functions.
|
|
553
|
+
See ``QuasiSymmetricFunctions`` for full documentation.
|
|
554
|
+
|
|
555
|
+
EXAMPLES::
|
|
556
|
+
|
|
557
|
+
sage: QuasiSymmetricFunctions(QQ)
|
|
558
|
+
Quasisymmetric functions over the Rational Field
|
|
559
|
+
sage: QSym1 = QuasiSymmetricFunctions(FiniteField(23))
|
|
560
|
+
sage: QSym2 = QuasiSymmetricFunctions(Integers(23))
|
|
561
|
+
sage: TestSuite(QuasiSymmetricFunctions(QQ)).run()
|
|
562
|
+
"""
|
|
563
|
+
# change the line below to assert R in Rings() once MRO issues from #15536, #15475 are resolved
|
|
564
|
+
assert R in Fields() or R in Rings() # side effect of this statement assures MRO exists for R
|
|
565
|
+
self._base = R # Won't be needed once CategoryObject won't override base_ring
|
|
566
|
+
category = GradedHopfAlgebras(R).Commutative()
|
|
567
|
+
self._category = category
|
|
568
|
+
Parent.__init__(self, category=category.WithRealizations())
|
|
569
|
+
|
|
570
|
+
# Bases
|
|
571
|
+
Monomial = self.Monomial()
|
|
572
|
+
Fundamental = self.Fundamental()
|
|
573
|
+
dualImmaculate = self.dualImmaculate()
|
|
574
|
+
QS = self.Quasisymmetric_Schur()
|
|
575
|
+
|
|
576
|
+
# Change of bases
|
|
577
|
+
Fundamental.module_morphism(Monomial.sum_of_finer_compositions,
|
|
578
|
+
codomain=Monomial, category=category
|
|
579
|
+
).register_as_coercion()
|
|
580
|
+
Monomial .module_morphism(Fundamental.alternating_sum_of_finer_compositions,
|
|
581
|
+
codomain=Fundamental, category=category
|
|
582
|
+
).register_as_coercion()
|
|
583
|
+
#This changes dualImmaculate into Monomial
|
|
584
|
+
dualImmaculate.module_morphism(dualImmaculate._to_Monomial_on_basis,
|
|
585
|
+
codomain=Monomial, category=category
|
|
586
|
+
).register_as_coercion()
|
|
587
|
+
#This changes Monomial into dualImmaculate
|
|
588
|
+
Monomial.module_morphism(dualImmaculate._from_Monomial_on_basis,
|
|
589
|
+
codomain=dualImmaculate, category=category
|
|
590
|
+
).register_as_coercion()
|
|
591
|
+
#This changes Quasisymmetric Schur into Monomial
|
|
592
|
+
QS .module_morphism(QS._to_monomial_on_basis,
|
|
593
|
+
codomain=Monomial, category=category
|
|
594
|
+
).register_as_coercion()
|
|
595
|
+
#This changes Monomial into Quasisymmetric Schur
|
|
596
|
+
Monomial.module_morphism(QS._from_monomial_on_basis,
|
|
597
|
+
codomain=QS, category=category
|
|
598
|
+
).register_as_coercion()
|
|
599
|
+
|
|
600
|
+
# Embedding of Sym into QSym in the monomial bases
|
|
601
|
+
Sym = SymmetricFunctions(self.base_ring())
|
|
602
|
+
Sym_m_to_M = Sym.m().module_morphism(Monomial.sum_of_partition_rearrangements,
|
|
603
|
+
triangular='upper', inverse_on_support=Monomial._comp_to_par,
|
|
604
|
+
codomain=Monomial, category=category)
|
|
605
|
+
Sym_m_to_M.register_as_coercion()
|
|
606
|
+
self.to_symmetric_function = Sym_m_to_M.section()
|
|
607
|
+
|
|
608
|
+
Sym_s_to_F = Sym.s().module_morphism(Fundamental._from_schur_on_basis,
|
|
609
|
+
unitriangular='upper',
|
|
610
|
+
codomain=Fundamental, category=category)
|
|
611
|
+
Sym_s_to_F.register_as_coercion()
|
|
612
|
+
|
|
613
|
+
def _repr_(self):
|
|
614
|
+
r"""
|
|
615
|
+
EXAMPLES::
|
|
616
|
+
|
|
617
|
+
sage: M = QuasiSymmetricFunctions(ZZ).M()
|
|
618
|
+
sage: M._repr_()
|
|
619
|
+
'Quasisymmetric functions over the Integer Ring in the Monomial basis'
|
|
620
|
+
"""
|
|
621
|
+
return "Quasisymmetric functions over the %s" % self.base_ring()
|
|
622
|
+
|
|
623
|
+
def a_realization(self):
|
|
624
|
+
r"""
|
|
625
|
+
Return the realization of the Monomial basis of the ring of quasi-symmetric functions.
|
|
626
|
+
|
|
627
|
+
OUTPUT: the Monomial basis of quasi-symmetric functions
|
|
628
|
+
|
|
629
|
+
EXAMPLES::
|
|
630
|
+
|
|
631
|
+
sage: QuasiSymmetricFunctions(QQ).a_realization()
|
|
632
|
+
Quasisymmetric functions over the Rational Field in the Monomial basis
|
|
633
|
+
"""
|
|
634
|
+
return self.Monomial()
|
|
635
|
+
|
|
636
|
+
_shorthands = tuple(['M', 'F', 'E', 'dI', 'QS', 'YQS', 'phi', 'psi'])
|
|
637
|
+
|
|
638
|
+
def dual(self):
|
|
639
|
+
r"""
|
|
640
|
+
Return the dual Hopf algebra of the quasi-symmetric functions, which is the
|
|
641
|
+
non-commutative symmetric functions.
|
|
642
|
+
|
|
643
|
+
OUTPUT: the non-commutative symmetric functions
|
|
644
|
+
|
|
645
|
+
EXAMPLES::
|
|
646
|
+
|
|
647
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
648
|
+
sage: QSym.dual()
|
|
649
|
+
Non-Commutative Symmetric Functions over the Rational Field
|
|
650
|
+
"""
|
|
651
|
+
return NonCommutativeSymmetricFunctions(self.base_ring())
|
|
652
|
+
|
|
653
|
+
def from_polynomial(self, f, check=True):
|
|
654
|
+
"""
|
|
655
|
+
Return the quasi-symmetric function in the Monomial basis
|
|
656
|
+
corresponding to the quasi-symmetric polynomial ``f``.
|
|
657
|
+
|
|
658
|
+
INPUT:
|
|
659
|
+
|
|
660
|
+
- ``f`` -- a polynomial in finitely many variables over the same base
|
|
661
|
+
ring as ``self``. It is assumed that this polynomial is
|
|
662
|
+
quasi-symmetric.
|
|
663
|
+
- ``check`` -- boolean (default: ``True``); checks whether the
|
|
664
|
+
polynomial is indeed quasi-symmetric
|
|
665
|
+
|
|
666
|
+
OUTPUT: quasi-symmetric function in the Monomial basis
|
|
667
|
+
|
|
668
|
+
EXAMPLES::
|
|
669
|
+
|
|
670
|
+
sage: P = PolynomialRing(QQ, 'x', 3)
|
|
671
|
+
sage: x = P.gens()
|
|
672
|
+
sage: f = x[0] + x[1] + x[2]
|
|
673
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
674
|
+
sage: QSym.from_polynomial(f)
|
|
675
|
+
M[1]
|
|
676
|
+
|
|
677
|
+
Beware of setting ``check=False``::
|
|
678
|
+
|
|
679
|
+
sage: f = x[0] + 2*x[1] + x[2]
|
|
680
|
+
sage: QSym.from_polynomial(f, check=True)
|
|
681
|
+
Traceback (most recent call last):
|
|
682
|
+
...
|
|
683
|
+
ValueError: x0 + 2*x1 + x2 is not a quasi-symmetric polynomial
|
|
684
|
+
sage: QSym.from_polynomial(f, check=False)
|
|
685
|
+
M[1]
|
|
686
|
+
|
|
687
|
+
To expand the quasi-symmetric function in a basis other than the
|
|
688
|
+
Monomial basis, the following shorthands are provided::
|
|
689
|
+
|
|
690
|
+
sage: M = QSym.Monomial()
|
|
691
|
+
sage: f = x[0]**2+x[1]**2+x[2]**2
|
|
692
|
+
sage: g = M.from_polynomial(f); g
|
|
693
|
+
M[2]
|
|
694
|
+
sage: F = QSym.Fundamental()
|
|
695
|
+
sage: F(g)
|
|
696
|
+
-F[1, 1] + F[2]
|
|
697
|
+
sage: F.from_polynomial(f)
|
|
698
|
+
-F[1, 1] + F[2]
|
|
699
|
+
"""
|
|
700
|
+
assert self.base_ring() == f.base_ring()
|
|
701
|
+
exponent_coefficient = f.monomial_coefficients()
|
|
702
|
+
z = {}
|
|
703
|
+
for e, c in exponent_coefficient.items():
|
|
704
|
+
I = Compositions()([ei for ei in e if ei])
|
|
705
|
+
if I not in z:
|
|
706
|
+
z[I] = c
|
|
707
|
+
out = self.Monomial()._from_dict(z)
|
|
708
|
+
if check and out.expand(f.parent().ngens(), f.parent().variable_names()) != f:
|
|
709
|
+
raise ValueError("%s is not a quasi-symmetric polynomial" % f)
|
|
710
|
+
return out
|
|
711
|
+
|
|
712
|
+
class Bases(Category_realization_of_parent):
|
|
713
|
+
r"""
|
|
714
|
+
Category of bases of quasi-symmetric functions.
|
|
715
|
+
|
|
716
|
+
EXAMPLES::
|
|
717
|
+
|
|
718
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
719
|
+
sage: QSym.Bases()
|
|
720
|
+
Category of bases of Quasisymmetric functions over the Rational Field
|
|
721
|
+
"""
|
|
722
|
+
|
|
723
|
+
def super_categories(self):
|
|
724
|
+
r"""
|
|
725
|
+
Return the super categories of bases of the Quasi-symmetric functions.
|
|
726
|
+
|
|
727
|
+
OUTPUT: list of categories
|
|
728
|
+
|
|
729
|
+
TESTS::
|
|
730
|
+
|
|
731
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
732
|
+
sage: QSym.Bases().super_categories()
|
|
733
|
+
[Category of commutative bases of Non-Commutative Symmetric Functions or Quasisymmetric functions over the Rational Field]
|
|
734
|
+
"""
|
|
735
|
+
return [BasesOfQSymOrNCSF(self.base()).Commutative()]
|
|
736
|
+
|
|
737
|
+
class ParentMethods:
|
|
738
|
+
r"""
|
|
739
|
+
Methods common to all bases of ``QuasiSymmetricFunctions``.
|
|
740
|
+
"""
|
|
741
|
+
|
|
742
|
+
def from_polynomial(self, f, check=True):
|
|
743
|
+
"""
|
|
744
|
+
The quasi-symmetric function expanded in this basis
|
|
745
|
+
corresponding to the quasi-symmetric polynomial ``f``.
|
|
746
|
+
|
|
747
|
+
This is a default implementation that computes
|
|
748
|
+
the expansion in the Monomial basis and converts
|
|
749
|
+
to this basis.
|
|
750
|
+
|
|
751
|
+
INPUT:
|
|
752
|
+
|
|
753
|
+
- ``f`` -- a polynomial in finitely many variables over the same base
|
|
754
|
+
ring as ``self``. It is assumed that this polynomial is
|
|
755
|
+
quasi-symmetric.
|
|
756
|
+
- ``check`` -- boolean (default: ``True``); checks whether the
|
|
757
|
+
polynomial is indeed quasi-symmetric
|
|
758
|
+
|
|
759
|
+
OUTPUT: quasi-symmetric function
|
|
760
|
+
|
|
761
|
+
EXAMPLES::
|
|
762
|
+
|
|
763
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
764
|
+
sage: F = QuasiSymmetricFunctions(QQ).Fundamental()
|
|
765
|
+
sage: P = PolynomialRing(QQ, 'x', 3)
|
|
766
|
+
sage: x = P.gens()
|
|
767
|
+
sage: f = x[0] + x[1] + x[2]
|
|
768
|
+
sage: M.from_polynomial(f)
|
|
769
|
+
M[1]
|
|
770
|
+
sage: F.from_polynomial(f)
|
|
771
|
+
F[1]
|
|
772
|
+
sage: f = x[0]**2+x[1]**2+x[2]**2
|
|
773
|
+
sage: M.from_polynomial(f)
|
|
774
|
+
M[2]
|
|
775
|
+
sage: F.from_polynomial(f)
|
|
776
|
+
-F[1, 1] + F[2]
|
|
777
|
+
|
|
778
|
+
If the polynomial is not quasi-symmetric, an error
|
|
779
|
+
is raised::
|
|
780
|
+
|
|
781
|
+
sage: f = x[0]^2+x[1]
|
|
782
|
+
sage: M.from_polynomial(f)
|
|
783
|
+
Traceback (most recent call last):
|
|
784
|
+
...
|
|
785
|
+
ValueError: x0^2 + x1 is not a quasi-symmetric polynomial
|
|
786
|
+
sage: F.from_polynomial(f)
|
|
787
|
+
Traceback (most recent call last):
|
|
788
|
+
...
|
|
789
|
+
ValueError: x0^2 + x1 is not a quasi-symmetric polynomial
|
|
790
|
+
|
|
791
|
+
TESTS:
|
|
792
|
+
|
|
793
|
+
We convert some quasi-symmetric functions to quasi-symmetric
|
|
794
|
+
polynomials and back::
|
|
795
|
+
|
|
796
|
+
sage: f = (M[1,2] + M[1,1]).expand(3); f
|
|
797
|
+
x0*x1^2 + x0*x2^2 + x1*x2^2 + x0*x1 + x0*x2 + x1*x2
|
|
798
|
+
sage: M.from_polynomial(f)
|
|
799
|
+
M[1, 1] + M[1, 2]
|
|
800
|
+
sage: f = (2*M[2,1]+M[1,1]+3*M[3]).expand(3)
|
|
801
|
+
sage: M.from_polynomial(f)
|
|
802
|
+
M[1, 1] + 2*M[2, 1] + 3*M[3]
|
|
803
|
+
sage: f = (F[1,2] + F[1,1]).expand(3); f
|
|
804
|
+
x0*x1^2 + x0*x1*x2 + x0*x2^2 + x1*x2^2 + x0*x1 + x0*x2 + x1*x2
|
|
805
|
+
sage: F.from_polynomial(f)
|
|
806
|
+
F[1, 1] + F[1, 2]
|
|
807
|
+
sage: f = (2*F[2,1]+F[1,1]+3*F[3]).expand(3)
|
|
808
|
+
sage: F.from_polynomial(f)
|
|
809
|
+
F[1, 1] + 2*F[2, 1] + 3*F[3]
|
|
810
|
+
"""
|
|
811
|
+
g = self.realization_of().from_polynomial(f, check=check)
|
|
812
|
+
return self(g)
|
|
813
|
+
|
|
814
|
+
def Eulerian(self, n, j, k=None):
|
|
815
|
+
"""
|
|
816
|
+
Return the Eulerian (quasi)symmetric function `Q_{n,j}` in
|
|
817
|
+
terms of ``self``.
|
|
818
|
+
|
|
819
|
+
INPUT:
|
|
820
|
+
|
|
821
|
+
- ``n`` -- the value `n` or a partition
|
|
822
|
+
- ``j`` -- the number of excedances
|
|
823
|
+
- ``k`` -- (optional) if specified, determines the number of
|
|
824
|
+
fixed points of the permutation
|
|
825
|
+
|
|
826
|
+
EXAMPLES::
|
|
827
|
+
|
|
828
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
829
|
+
sage: M = QSym.M()
|
|
830
|
+
sage: M.Eulerian(3, 1)
|
|
831
|
+
4*M[1, 1, 1] + 3*M[1, 2] + 3*M[2, 1] + 2*M[3]
|
|
832
|
+
sage: M.Eulerian(4, 1, 2)
|
|
833
|
+
6*M[1, 1, 1, 1] + 4*M[1, 1, 2] + 4*M[1, 2, 1]
|
|
834
|
+
+ 2*M[1, 3] + 4*M[2, 1, 1] + 3*M[2, 2] + 2*M[3, 1] + M[4]
|
|
835
|
+
sage: QS = QSym.QS()
|
|
836
|
+
sage: QS.Eulerian(4, 2)
|
|
837
|
+
2*QS[1, 3] + QS[2, 2] + 2*QS[3, 1] + 3*QS[4]
|
|
838
|
+
sage: QS.Eulerian([2, 2, 1], 2)
|
|
839
|
+
QS[1, 2, 2] + QS[1, 4] + QS[2, 1, 2] + QS[2, 2, 1]
|
|
840
|
+
+ QS[2, 3] + QS[3, 2] + QS[4, 1] + QS[5]
|
|
841
|
+
sage: dI = QSym.dI()
|
|
842
|
+
sage: dI.Eulerian(5, 2)
|
|
843
|
+
-dI[1, 3, 1] - 5*dI[1, 4] + dI[2, 2, 1] + dI[3, 1, 1]
|
|
844
|
+
+ 5*dI[3, 2] + 6*dI[4, 1] + 6*dI[5]
|
|
845
|
+
"""
|
|
846
|
+
F = self.realization_of().F()
|
|
847
|
+
if n in _Partitions:
|
|
848
|
+
n = _Partitions(n)
|
|
849
|
+
return self(F.Eulerian(n, j, k))
|
|
850
|
+
|
|
851
|
+
class ElementMethods:
|
|
852
|
+
r"""
|
|
853
|
+
Methods common to all elements of ``QuasiSymmetricFunctions``.
|
|
854
|
+
"""
|
|
855
|
+
|
|
856
|
+
def internal_coproduct(self):
|
|
857
|
+
r"""
|
|
858
|
+
Return the inner coproduct of ``self`` in the basis of ``self``.
|
|
859
|
+
|
|
860
|
+
The inner coproduct (also known as the Kronecker coproduct,
|
|
861
|
+
or as the second comultiplication on the `R`-algebra of
|
|
862
|
+
quasi-symmetric functions) is an `R`-algebra homomorphism
|
|
863
|
+
`\Delta^{\times}` from the `R`-algebra of quasi-symmetric
|
|
864
|
+
functions to the tensor square (over `R`) of quasi-symmetric
|
|
865
|
+
functions. It can be defined in the following two ways:
|
|
866
|
+
|
|
867
|
+
#. If `I` is a composition, then a `(0, I)`-matrix will mean a
|
|
868
|
+
matrix whose entries are nonnegative integers such that no
|
|
869
|
+
row and no column of this matrix is zero, and such that if
|
|
870
|
+
all the nonzero entries of the matrix are read (row by row,
|
|
871
|
+
starting at the topmost row, reading every row from left to
|
|
872
|
+
right), then the reading word obtained is `I`. If `A` is
|
|
873
|
+
a `(0, I)`-matrix, then `\mathrm{row}(A)` will denote the
|
|
874
|
+
vector of row sums of `A` (regarded as a composition), and
|
|
875
|
+
`\mathrm{column}(A)` will denote the vector of column sums
|
|
876
|
+
of `A` (regarded as a composition).
|
|
877
|
+
|
|
878
|
+
For every composition `I`, the internal coproduct
|
|
879
|
+
`\Delta^{\times}(M_I)` of the `I`-th monomial quasisymmetric
|
|
880
|
+
function `M_I` is the sum
|
|
881
|
+
|
|
882
|
+
.. MATH::
|
|
883
|
+
|
|
884
|
+
\sum_{A \hbox{ is a } (0, I) \text{-matrix}}
|
|
885
|
+
M_{\mathrm{row}(A)} \otimes M_{\mathrm{column}(A)}.
|
|
886
|
+
|
|
887
|
+
See Section 11.39 of [HazWitt1]_.
|
|
888
|
+
|
|
889
|
+
#. For every permutation `w`, let `C(w)` denote the descent
|
|
890
|
+
composition of `w`. Then, for any composition `I` of size
|
|
891
|
+
`n`, the internal coproduct `\Delta^{\times}(F_I)` of the
|
|
892
|
+
`I`-th fundamental quasisymmetric function `F_I` is the sum
|
|
893
|
+
|
|
894
|
+
.. MATH::
|
|
895
|
+
|
|
896
|
+
\sum_{\substack{\sigma \in S_n,\\ \tau \in S_n,\\
|
|
897
|
+
\tau \sigma = \pi}} F_{C(\sigma)} \otimes F_{C(\tau)},
|
|
898
|
+
|
|
899
|
+
where `\pi` is any permutation in `S_n` having descent
|
|
900
|
+
composition `I` and where permutations act from the left and
|
|
901
|
+
multiply accordingly, so `\tau \sigma` means first applying
|
|
902
|
+
`\sigma` and then `\tau`. See Theorem 4.23 in [Mal1993]_,
|
|
903
|
+
but beware of the notations which are apparently different
|
|
904
|
+
from those in [HazWitt1]_.
|
|
905
|
+
|
|
906
|
+
The restriction of the internal coproduct to the
|
|
907
|
+
`R`-algebra of symmetric functions is the well-known
|
|
908
|
+
internal coproduct on the symmetric functions.
|
|
909
|
+
|
|
910
|
+
The method :meth:`kronecker_coproduct` is a synonym of this one.
|
|
911
|
+
|
|
912
|
+
EXAMPLES:
|
|
913
|
+
|
|
914
|
+
Let us compute the internal coproduct of `M_{21}` (which is
|
|
915
|
+
short for `M_{[2, 1]}`). The `(0, [2,1])`-matrices are
|
|
916
|
+
|
|
917
|
+
.. MATH::
|
|
918
|
+
|
|
919
|
+
\begin{bmatrix} 2 & 1 \end{bmatrix},
|
|
920
|
+
\begin{bmatrix} 2 \\ 1 \end{bmatrix},
|
|
921
|
+
\begin{bmatrix} 2 & 0 \\ 0 & 1 \end{bmatrix}, \hbox{ and }
|
|
922
|
+
\begin{bmatrix} 0 & 2 \\ 1 & 0 \end{bmatrix}
|
|
923
|
+
|
|
924
|
+
so
|
|
925
|
+
|
|
926
|
+
.. MATH::
|
|
927
|
+
|
|
928
|
+
\Delta^\times(M_{21}) = M_{3} \otimes M_{21} +
|
|
929
|
+
M_{21} \otimes M_3 + M_{21} \otimes M_{21} +
|
|
930
|
+
M_{21} \otimes M_{12}.
|
|
931
|
+
|
|
932
|
+
This is confirmed by the following Sage computation
|
|
933
|
+
(incidentally demonstrating the non-cocommutativity of
|
|
934
|
+
the internal coproduct)::
|
|
935
|
+
|
|
936
|
+
sage: M = QuasiSymmetricFunctions(ZZ).M()
|
|
937
|
+
sage: a = M([2,1])
|
|
938
|
+
sage: a.internal_coproduct()
|
|
939
|
+
M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
|
|
940
|
+
|
|
941
|
+
Further examples::
|
|
942
|
+
|
|
943
|
+
sage: all( M([i]).internal_coproduct() == tensor([M([i]), M([i])])
|
|
944
|
+
....: for i in range(1, 4) )
|
|
945
|
+
True
|
|
946
|
+
|
|
947
|
+
sage: M([1, 2]).internal_coproduct()
|
|
948
|
+
M[1, 2] # M[1, 2] + M[1, 2] # M[2, 1] + M[1, 2] # M[3] + M[3] # M[1, 2]
|
|
949
|
+
|
|
950
|
+
The definition of `\Delta^{\times}(M_I)` in terms of
|
|
951
|
+
`(0, I)`-matrices is not suitable for computation in
|
|
952
|
+
cases where the length of `I` is large, but we can use
|
|
953
|
+
it as a doctest. Here is a naive implementation::
|
|
954
|
+
|
|
955
|
+
sage: def naive_internal_coproduct_on_M(I):
|
|
956
|
+
....: # INPUT: composition I
|
|
957
|
+
....: # (not quasi-symmetric function)
|
|
958
|
+
....: # OUTPUT: interior coproduct of M_I
|
|
959
|
+
....: M = QuasiSymmetricFunctions(ZZ).M()
|
|
960
|
+
....: M2 = M.tensor(M)
|
|
961
|
+
....: res = M2.zero()
|
|
962
|
+
....: l = len(I)
|
|
963
|
+
....: n = I.size()
|
|
964
|
+
....: for S in Subsets(range(l**2), l):
|
|
965
|
+
....: M_list = sorted(S)
|
|
966
|
+
....: row_M = [sum([I[M_list.index(l * i + j)]
|
|
967
|
+
....: for j in range(l) if
|
|
968
|
+
....: l * i + j in S])
|
|
969
|
+
....: for i in range(l)]
|
|
970
|
+
....: col_M = [sum([I[M_list.index(l * i + j)]
|
|
971
|
+
....: for i in range(l) if
|
|
972
|
+
....: l * i + j in S])
|
|
973
|
+
....: for j in range(l)]
|
|
974
|
+
....: if 0 in row_M:
|
|
975
|
+
....: first_zero = row_M.index(0)
|
|
976
|
+
....: row_M = row_M[:first_zero]
|
|
977
|
+
....: if sum(row_M) != n:
|
|
978
|
+
....: continue
|
|
979
|
+
....: if 0 in col_M:
|
|
980
|
+
....: first_zero = col_M.index(0)
|
|
981
|
+
....: col_M = col_M[:first_zero]
|
|
982
|
+
....: if sum(col_M) != n:
|
|
983
|
+
....: continue
|
|
984
|
+
....: res += tensor([M(Compositions(n)(row_M)),
|
|
985
|
+
....: M(Compositions(n)(col_M))])
|
|
986
|
+
....: return res
|
|
987
|
+
sage: all( naive_internal_coproduct_on_M(I)
|
|
988
|
+
....: == M(I).internal_coproduct()
|
|
989
|
+
....: for I in Compositions(3) )
|
|
990
|
+
True
|
|
991
|
+
|
|
992
|
+
TESTS:
|
|
993
|
+
|
|
994
|
+
Border cases::
|
|
995
|
+
|
|
996
|
+
sage: M = QuasiSymmetricFunctions(ZZ).M()
|
|
997
|
+
sage: F = QuasiSymmetricFunctions(ZZ).F()
|
|
998
|
+
sage: M([]).internal_coproduct()
|
|
999
|
+
M[] # M[]
|
|
1000
|
+
sage: F([]).internal_coproduct()
|
|
1001
|
+
F[] # F[]
|
|
1002
|
+
|
|
1003
|
+
The implementations on the ``F`` and ``M`` bases agree
|
|
1004
|
+
with each other::
|
|
1005
|
+
|
|
1006
|
+
sage: M = QuasiSymmetricFunctions(ZZ).M()
|
|
1007
|
+
sage: F = QuasiSymmetricFunctions(ZZ).F()
|
|
1008
|
+
sage: def int_copr_on_F_via_M(I):
|
|
1009
|
+
....: result = tensor([F.zero(), F.zero()])
|
|
1010
|
+
....: w = M(F(I)).internal_coproduct()
|
|
1011
|
+
....: for lam, a in w:
|
|
1012
|
+
....: (U, V) = lam
|
|
1013
|
+
....: result += a * tensor([F(M(U)), F(M(V))])
|
|
1014
|
+
....: return result
|
|
1015
|
+
sage: all( int_copr_on_F_via_M(I) == F(I).internal_coproduct()
|
|
1016
|
+
....: for I in Compositions(3) )
|
|
1017
|
+
True
|
|
1018
|
+
sage: all( int_copr_on_F_via_M(I) == F(I).internal_coproduct()
|
|
1019
|
+
....: for I in Compositions(4) )
|
|
1020
|
+
True
|
|
1021
|
+
|
|
1022
|
+
Restricting to the subring of symmetric functions gives the
|
|
1023
|
+
standard internal coproduct on the latter::
|
|
1024
|
+
|
|
1025
|
+
sage: M = QuasiSymmetricFunctions(ZZ).M()
|
|
1026
|
+
sage: e = SymmetricFunctions(ZZ).e()
|
|
1027
|
+
sage: def int_copr_of_e_in_M(mu):
|
|
1028
|
+
....: result = tensor([M.zero(), M.zero()])
|
|
1029
|
+
....: w = e(mu).internal_coproduct()
|
|
1030
|
+
....: for lam, a in w:
|
|
1031
|
+
....: (nu, kappa) = lam
|
|
1032
|
+
....: result += a * tensor([M(e(nu)), M(e(kappa))])
|
|
1033
|
+
....: return result
|
|
1034
|
+
sage: all( int_copr_of_e_in_M(mu) == M(e(mu)).internal_coproduct()
|
|
1035
|
+
....: for mu in Partitions(3) )
|
|
1036
|
+
True
|
|
1037
|
+
sage: all( int_copr_of_e_in_M(mu) == M(e(mu)).internal_coproduct()
|
|
1038
|
+
....: for mu in Partitions(4) )
|
|
1039
|
+
True
|
|
1040
|
+
|
|
1041
|
+
.. TODO::
|
|
1042
|
+
|
|
1043
|
+
Implement this directly on the monomial basis maybe?
|
|
1044
|
+
The `(0, I)`-matrices are a pain to generate from their
|
|
1045
|
+
definition, but maybe there is a good algorithm.
|
|
1046
|
+
If so, the above "further examples" should be moved
|
|
1047
|
+
to the M-method.
|
|
1048
|
+
"""
|
|
1049
|
+
# Coerce to F basis and back, doing the actual computation in that basis.
|
|
1050
|
+
parent = self.parent()
|
|
1051
|
+
F = parent.realization_of().F()
|
|
1052
|
+
from sage.categories.tensor import tensor
|
|
1053
|
+
result = tensor([parent.zero(), parent.zero()])
|
|
1054
|
+
for lam, a in F(self).internal_coproduct():
|
|
1055
|
+
(I, J) = lam
|
|
1056
|
+
result += a * tensor([parent(F(I)), parent(F(J))])
|
|
1057
|
+
return result
|
|
1058
|
+
|
|
1059
|
+
kronecker_coproduct = internal_coproduct
|
|
1060
|
+
|
|
1061
|
+
def adams_operator(self, n):
|
|
1062
|
+
r"""
|
|
1063
|
+
Return the image of the quasi-symmetric function ``self``
|
|
1064
|
+
under the `n`-th Adams operator.
|
|
1065
|
+
|
|
1066
|
+
The `n`-th Adams operator `\mathbf{f}_n` is defined to be
|
|
1067
|
+
the map from the `R`-algebra of quasi-symmetric functions
|
|
1068
|
+
to itself that sends every symmetric function
|
|
1069
|
+
`P(x_1, x_2, x_3, \ldots)` to
|
|
1070
|
+
`P(x_1^n, x_2^n, x_3^n, \ldots)`. This operator `\mathbf{f}_n`
|
|
1071
|
+
is a Hopf algebra endomorphism, and satisfies
|
|
1072
|
+
|
|
1073
|
+
.. MATH::
|
|
1074
|
+
|
|
1075
|
+
f_n M_{(i_1, i_2, i_3, \ldots)} =
|
|
1076
|
+
M_{(ni_1, ni_2, ni_3, \ldots)}
|
|
1077
|
+
|
|
1078
|
+
for every composition `(i_1, i_2, i_3, \ldots)`
|
|
1079
|
+
(where `M` means the monomial basis).
|
|
1080
|
+
|
|
1081
|
+
The `n`-th Adams operator is also called the `n`-th
|
|
1082
|
+
Frobenius endomorphism. It is not related to the Frobenius map
|
|
1083
|
+
which connects the ring of symmetric functions with the
|
|
1084
|
+
representation theory of the symmetric group.
|
|
1085
|
+
|
|
1086
|
+
The `n`-th Adams operator is the `n`-th Adams operator
|
|
1087
|
+
of the `\Lambda`-ring of quasi-symmetric functions over the
|
|
1088
|
+
integers.
|
|
1089
|
+
|
|
1090
|
+
The restriction of the `n`-th Adams operator to the
|
|
1091
|
+
subring formed by all symmetric functions is, not
|
|
1092
|
+
unexpectedly, the `n`-th Adams operator of the ring of
|
|
1093
|
+
symmetric functions.
|
|
1094
|
+
|
|
1095
|
+
.. SEEALSO::
|
|
1096
|
+
|
|
1097
|
+
:meth:`Symmetric functions plethysm
|
|
1098
|
+
<sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.plethysm>`
|
|
1099
|
+
|
|
1100
|
+
INPUT:
|
|
1101
|
+
|
|
1102
|
+
- ``n`` -- positive integer
|
|
1103
|
+
|
|
1104
|
+
OUTPUT:
|
|
1105
|
+
|
|
1106
|
+
The result of applying the `n`-th Adams operator (on the
|
|
1107
|
+
ring of quasi-symmetric functions) to ``self``.
|
|
1108
|
+
|
|
1109
|
+
EXAMPLES::
|
|
1110
|
+
|
|
1111
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
1112
|
+
sage: M = QSym.M()
|
|
1113
|
+
sage: F = QSym.F()
|
|
1114
|
+
sage: M[3,2].adams_operator(2)
|
|
1115
|
+
M[6, 4]
|
|
1116
|
+
sage: (M[2,1] - 2*M[3]).adams_operator(4)
|
|
1117
|
+
M[8, 4] - 2*M[12]
|
|
1118
|
+
sage: M([]).adams_operator(3)
|
|
1119
|
+
M[]
|
|
1120
|
+
sage: F[1,1].adams_operator(2)
|
|
1121
|
+
F[1, 1, 1, 1] - F[1, 1, 2] - F[2, 1, 1] + F[2, 2]
|
|
1122
|
+
|
|
1123
|
+
The Adams endomorphisms are multiplicative::
|
|
1124
|
+
|
|
1125
|
+
sage: all( all( M(I).adams_operator(3) * M(J).adams_operator(3)
|
|
1126
|
+
....: == (M(I) * M(J)).adams_operator(3)
|
|
1127
|
+
....: for I in Compositions(3) )
|
|
1128
|
+
....: for J in Compositions(2) )
|
|
1129
|
+
True
|
|
1130
|
+
|
|
1131
|
+
Being Hopf algebra endomorphisms, the Adams operators
|
|
1132
|
+
commute with the antipode::
|
|
1133
|
+
|
|
1134
|
+
sage: all( M(I).adams_operator(4).antipode()
|
|
1135
|
+
....: == M(I).antipode().adams_operator(4)
|
|
1136
|
+
....: for I in Compositions(3) )
|
|
1137
|
+
True
|
|
1138
|
+
|
|
1139
|
+
The restriction of the Adams operators to the subring
|
|
1140
|
+
of symmetric functions are the Adams operators of
|
|
1141
|
+
the latter::
|
|
1142
|
+
|
|
1143
|
+
sage: e = SymmetricFunctions(ZZ).e()
|
|
1144
|
+
sage: all( M(e(lam)).adams_operator(3)
|
|
1145
|
+
....: == M(e(lam).adams_operator(3))
|
|
1146
|
+
....: for lam in Partitions(3) )
|
|
1147
|
+
True
|
|
1148
|
+
"""
|
|
1149
|
+
# Convert to the monomial basis, there apply componentwise,
|
|
1150
|
+
# then convert back.
|
|
1151
|
+
parent = self.parent()
|
|
1152
|
+
M = parent.realization_of().M()
|
|
1153
|
+
C = parent._indices
|
|
1154
|
+
dct = {C([n * i for i in I]): coeff
|
|
1155
|
+
for (I, coeff) in M(self)}
|
|
1156
|
+
result_in_M_basis = M._from_dict(dct)
|
|
1157
|
+
return parent(result_in_M_basis)
|
|
1158
|
+
|
|
1159
|
+
frobenius = deprecated_function_alias(36396, adams_operator)
|
|
1160
|
+
|
|
1161
|
+
def star_involution(self):
|
|
1162
|
+
r"""
|
|
1163
|
+
Return the image of the quasisymmetric function ``self`` under
|
|
1164
|
+
the star involution.
|
|
1165
|
+
|
|
1166
|
+
The star involution is defined as the linear map
|
|
1167
|
+
`QSym \to QSym` which, for every composition `I`, sends the
|
|
1168
|
+
monomial quasisymmetric function `M_I` to `M_{I^r}`. Here, if
|
|
1169
|
+
`I` is a composition, we denote by `I^r` the reversed
|
|
1170
|
+
composition of `I`. Denoting by `f^{\ast}` the image of an
|
|
1171
|
+
element `f \in QSym` under the star involution, it can be shown
|
|
1172
|
+
that every composition `I` satisfies
|
|
1173
|
+
|
|
1174
|
+
.. MATH::
|
|
1175
|
+
|
|
1176
|
+
(M_I)^{\ast} = M_{I^r}, \quad (F_I)^{\ast} = F_{I^r},
|
|
1177
|
+
|
|
1178
|
+
where `F_I` denotes the fundamental quasisymmetric function
|
|
1179
|
+
corresponding to the composition `I`. The star involution is an
|
|
1180
|
+
involution, an algebra automorphism and a coalgebra
|
|
1181
|
+
anti-automorphism of `QSym`. It also is an automorphism of the
|
|
1182
|
+
graded vector space `QSym`, and is the identity on the subspace
|
|
1183
|
+
`Sym` of `QSym`. It is adjoint to the star involution on `NCSF`
|
|
1184
|
+
by the standard adjunction between `NCSF` and `QSym`.
|
|
1185
|
+
|
|
1186
|
+
The star involution has been denoted by `\rho` in [LMvW13]_,
|
|
1187
|
+
section 3.6.
|
|
1188
|
+
|
|
1189
|
+
.. SEEALSO::
|
|
1190
|
+
|
|
1191
|
+
:meth:`star involution on NCSF
|
|
1192
|
+
<sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.star_involution>`.
|
|
1193
|
+
|
|
1194
|
+
EXAMPLES::
|
|
1195
|
+
|
|
1196
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
1197
|
+
sage: M = QSym.M()
|
|
1198
|
+
sage: M[3,2].star_involution()
|
|
1199
|
+
M[2, 3]
|
|
1200
|
+
sage: M[6,3].star_involution()
|
|
1201
|
+
M[3, 6]
|
|
1202
|
+
sage: (M[9,1] - M[6,2] + 2*M[6,4] - 3*M[3] + 4*M[[]]).star_involution()
|
|
1203
|
+
4*M[] + M[1, 9] - M[2, 6] - 3*M[3] + 2*M[4, 6]
|
|
1204
|
+
sage: (M[3,3] - 2*M[2]).star_involution()
|
|
1205
|
+
-2*M[2] + M[3, 3]
|
|
1206
|
+
sage: M([4,2]).star_involution()
|
|
1207
|
+
M[2, 4]
|
|
1208
|
+
sage: dI = QSym.dI()
|
|
1209
|
+
sage: dI([1,2]).star_involution()
|
|
1210
|
+
-dI[1, 2] + dI[2, 1]
|
|
1211
|
+
sage: dI.zero().star_involution()
|
|
1212
|
+
0
|
|
1213
|
+
|
|
1214
|
+
The star involution commutes with the antipode::
|
|
1215
|
+
|
|
1216
|
+
sage: all( M(I).star_involution().antipode()
|
|
1217
|
+
....: == M(I).antipode().star_involution()
|
|
1218
|
+
....: for I in Compositions(4) )
|
|
1219
|
+
True
|
|
1220
|
+
|
|
1221
|
+
The star involution is the identity on `Sym`::
|
|
1222
|
+
|
|
1223
|
+
sage: Sym = SymmetricFunctions(ZZ)
|
|
1224
|
+
sage: e = Sym.e()
|
|
1225
|
+
sage: all( M(e(lam)).star_involution() == M(e(lam))
|
|
1226
|
+
....: for lam in Partitions(4) )
|
|
1227
|
+
True
|
|
1228
|
+
"""
|
|
1229
|
+
# Convert to the homogeneous basis, there apply the star
|
|
1230
|
+
# involution componentwise, then convert back.
|
|
1231
|
+
parent = self.parent()
|
|
1232
|
+
M = parent.realization_of().M()
|
|
1233
|
+
dct = {I.reversed(): coeff for (I, coeff) in M(self)}
|
|
1234
|
+
return parent(M._from_dict(dct))
|
|
1235
|
+
|
|
1236
|
+
def omega_involution(self):
|
|
1237
|
+
r"""
|
|
1238
|
+
Return the image of the quasisymmetric function
|
|
1239
|
+
``self`` under the omega involution.
|
|
1240
|
+
|
|
1241
|
+
The omega involution is defined as the linear map
|
|
1242
|
+
`QSym \to QSym` which, for every composition `I`, sends
|
|
1243
|
+
the fundamental quasisymmetric function `F_I` to
|
|
1244
|
+
`F_{I^t}`, where `I^t` denotes the conjugate
|
|
1245
|
+
(:meth:`~sage.combinat.composition.Composition.conjugate`)
|
|
1246
|
+
of the composition `I`. This map is commonly denoted by
|
|
1247
|
+
`\omega`. It is an algebra homomorphism and a coalgebra
|
|
1248
|
+
antihomomorphism; it also is an involution and an
|
|
1249
|
+
automorphism of the graded vector space `QSym`. Also,
|
|
1250
|
+
every composition `I` satisfies
|
|
1251
|
+
|
|
1252
|
+
.. MATH::
|
|
1253
|
+
|
|
1254
|
+
\omega(M_I) = (-1)^{|I|-\ell(I)} \sum M_J,
|
|
1255
|
+
|
|
1256
|
+
where the sum ranges over all compositions `J` of `|I|`
|
|
1257
|
+
which are coarser than the reversed composition `I^r` of
|
|
1258
|
+
`I`. Here, `\ell(I)` denotes the length of the composition
|
|
1259
|
+
`I` (that is, the number of parts of `I`).
|
|
1260
|
+
|
|
1261
|
+
If `f` is a homogeneous element of `NCSF` of degree `n`,
|
|
1262
|
+
then
|
|
1263
|
+
|
|
1264
|
+
.. MATH::
|
|
1265
|
+
|
|
1266
|
+
\omega(f) = (-1)^n S(f),
|
|
1267
|
+
|
|
1268
|
+
where `S` denotes the antipode of `QSym`.
|
|
1269
|
+
|
|
1270
|
+
The restriction of `\omega` to the ring of symmetric
|
|
1271
|
+
functions (which is a subring of `QSym`) is precisely the
|
|
1272
|
+
omega involution
|
|
1273
|
+
(:meth:`~sage.combinat.sf.sfa.SymmetricFunctionAlgebra_generic_Element.omega`)
|
|
1274
|
+
of said ring.
|
|
1275
|
+
|
|
1276
|
+
The omega involution on `QSym` is adjoint to the omega
|
|
1277
|
+
involution on `NCSF` by the standard adjunction between `NCSF`
|
|
1278
|
+
and `QSym`.
|
|
1279
|
+
|
|
1280
|
+
The omega involution has been denoted by `\omega` in [LMvW13]_,
|
|
1281
|
+
section 3.6.
|
|
1282
|
+
|
|
1283
|
+
.. SEEALSO::
|
|
1284
|
+
|
|
1285
|
+
:meth:`omega involution on NCSF
|
|
1286
|
+
<sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.omega_involution>`,
|
|
1287
|
+
:meth:`psi involution on QSym
|
|
1288
|
+
<sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.psi_involution>`,
|
|
1289
|
+
:meth:`star involution on QSym
|
|
1290
|
+
<sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution>`.
|
|
1291
|
+
|
|
1292
|
+
EXAMPLES::
|
|
1293
|
+
|
|
1294
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
1295
|
+
sage: F = QSym.F()
|
|
1296
|
+
sage: F[3,2].omega_involution()
|
|
1297
|
+
F[1, 2, 1, 1]
|
|
1298
|
+
sage: F[6,3].omega_involution()
|
|
1299
|
+
F[1, 1, 2, 1, 1, 1, 1, 1]
|
|
1300
|
+
sage: (F[9,1] - F[8,2] + 2*F[2,4] - 3*F[3] + 4*F[[]]).omega_involution()
|
|
1301
|
+
4*F[] - 3*F[1, 1, 1] + 2*F[1, 1, 1, 2, 1] - F[1, 2, 1, 1, 1, 1, 1, 1, 1] + F[2, 1, 1, 1, 1, 1, 1, 1, 1]
|
|
1302
|
+
sage: (F[3,3] - 2*F[2]).omega_involution()
|
|
1303
|
+
-2*F[1, 1] + F[1, 1, 2, 1, 1]
|
|
1304
|
+
sage: F([2,1,1]).omega_involution()
|
|
1305
|
+
F[3, 1]
|
|
1306
|
+
sage: M = QSym.M()
|
|
1307
|
+
sage: M([2,1]).omega_involution()
|
|
1308
|
+
-M[1, 2] - M[3]
|
|
1309
|
+
sage: M.zero().omega_involution()
|
|
1310
|
+
0
|
|
1311
|
+
|
|
1312
|
+
Testing the fact that the restriction of `\omega` to `Sym`
|
|
1313
|
+
is the omega automorphism of `Sym`::
|
|
1314
|
+
|
|
1315
|
+
sage: Sym = SymmetricFunctions(ZZ)
|
|
1316
|
+
sage: e = Sym.e()
|
|
1317
|
+
sage: all( F(e[lam]).omega_involution() == F(e[lam].omega())
|
|
1318
|
+
....: for lam in Partitions(4) )
|
|
1319
|
+
True
|
|
1320
|
+
"""
|
|
1321
|
+
# Use the `\omega(f) = (-1)^n S(f)` formula.
|
|
1322
|
+
return self.antipode().degree_negation()
|
|
1323
|
+
|
|
1324
|
+
def psi_involution(self):
|
|
1325
|
+
r"""
|
|
1326
|
+
Return the image of the quasisymmetric function ``self``
|
|
1327
|
+
under the involution `\psi`.
|
|
1328
|
+
|
|
1329
|
+
The involution `\psi` is defined as the linear map
|
|
1330
|
+
`QSym \to QSym` which, for every composition `I`, sends the
|
|
1331
|
+
fundamental quasisymmetric function `F_I` to `F_{I^c}`, where
|
|
1332
|
+
`I^c` denotes the complement of the composition `I`.
|
|
1333
|
+
The map `\psi` is an involution and a graded Hopf algebra
|
|
1334
|
+
automorphism of `QSym`. Its restriction to the ring of
|
|
1335
|
+
symmetric functions coincides with the omega automorphism of
|
|
1336
|
+
the latter ring.
|
|
1337
|
+
|
|
1338
|
+
The involution `\psi` of `QSym` is adjoint to the involution
|
|
1339
|
+
`\psi` of `NCSF` by the standard adjunction between `NCSF` and
|
|
1340
|
+
`QSym`.
|
|
1341
|
+
|
|
1342
|
+
The involution `\psi` has been denoted by `\psi` in [LMvW13]_,
|
|
1343
|
+
section 3.6.
|
|
1344
|
+
|
|
1345
|
+
.. SEEALSO::
|
|
1346
|
+
|
|
1347
|
+
:meth:`psi involution on NCSF
|
|
1348
|
+
<sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.psi_involution>`,
|
|
1349
|
+
:meth:`star involution on QSym
|
|
1350
|
+
<sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution>`.
|
|
1351
|
+
|
|
1352
|
+
EXAMPLES::
|
|
1353
|
+
|
|
1354
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
1355
|
+
sage: F = QSym.F()
|
|
1356
|
+
sage: F[3,2].psi_involution()
|
|
1357
|
+
F[1, 1, 2, 1]
|
|
1358
|
+
sage: F[6,3].psi_involution()
|
|
1359
|
+
F[1, 1, 1, 1, 1, 2, 1, 1]
|
|
1360
|
+
sage: (F[9,1] - F[8,2] + 2*F[2,4] - 3*F[3] + 4*F[[]]).psi_involution()
|
|
1361
|
+
4*F[] - 3*F[1, 1, 1] + F[1, 1, 1, 1, 1, 1, 1, 1, 2] - F[1, 1, 1, 1, 1, 1, 1, 2, 1] + 2*F[1, 2, 1, 1, 1]
|
|
1362
|
+
sage: (F[3,3] - 2*F[2]).psi_involution()
|
|
1363
|
+
-2*F[1, 1] + F[1, 1, 2, 1, 1]
|
|
1364
|
+
sage: F([2,1,1]).psi_involution()
|
|
1365
|
+
F[1, 3]
|
|
1366
|
+
sage: M = QSym.M()
|
|
1367
|
+
sage: M([2,1]).psi_involution()
|
|
1368
|
+
-M[2, 1] - M[3]
|
|
1369
|
+
sage: M.zero().psi_involution()
|
|
1370
|
+
0
|
|
1371
|
+
|
|
1372
|
+
The involution `\psi` commutes with the antipode::
|
|
1373
|
+
|
|
1374
|
+
sage: all( F(I).psi_involution().antipode()
|
|
1375
|
+
....: == F(I).antipode().psi_involution()
|
|
1376
|
+
....: for I in Compositions(4) )
|
|
1377
|
+
True
|
|
1378
|
+
|
|
1379
|
+
Testing the fact that the restriction of `\psi` to `Sym`
|
|
1380
|
+
is the omega automorphism of `Sym`::
|
|
1381
|
+
|
|
1382
|
+
sage: Sym = SymmetricFunctions(ZZ)
|
|
1383
|
+
sage: e = Sym.e()
|
|
1384
|
+
sage: all( F(e[lam]).psi_involution() == F(e[lam].omega())
|
|
1385
|
+
....: for lam in Partitions(4) )
|
|
1386
|
+
True
|
|
1387
|
+
"""
|
|
1388
|
+
# Convert to the fundamental basis, there apply the psi
|
|
1389
|
+
# involution componentwise, then convert back.
|
|
1390
|
+
parent = self.parent()
|
|
1391
|
+
F = parent.realization_of().F()
|
|
1392
|
+
dct = {I.complement(): coeff for (I, coeff) in F(self)}
|
|
1393
|
+
return parent(F._from_dict(dct))
|
|
1394
|
+
|
|
1395
|
+
def dendriform_less(self, other):
|
|
1396
|
+
r"""
|
|
1397
|
+
Return the result of applying the dendriform smaller
|
|
1398
|
+
operation to the two quasi-symmetric functions ``self``
|
|
1399
|
+
and ``other``.
|
|
1400
|
+
|
|
1401
|
+
The dendriform smaller operation is a binary operation,
|
|
1402
|
+
denoted by `\prec` and written infix, on the ring of
|
|
1403
|
+
quasi-symmetric functions. It can be defined as a
|
|
1404
|
+
restriction of a binary operation (denoted by `\prec`
|
|
1405
|
+
and written infix as well) on the ring of formal power
|
|
1406
|
+
series `R[[x_1, x_2, x_3, \ldots]]`, which is defined
|
|
1407
|
+
as follows: If `m` and `n` are two monomials in
|
|
1408
|
+
`x_1, x_2, x_3, \ldots`, then we let `m \prec n` be
|
|
1409
|
+
the product `mn` if the smallest positive integer `i`
|
|
1410
|
+
for which `x_i` occurs in `m` is smaller than the
|
|
1411
|
+
smallest positive integer `j` for which `x_j` occurs
|
|
1412
|
+
in `n` (this is understood to be false when `m = 1`,
|
|
1413
|
+
and true when `m \neq 1` and `n = 1`), and we let
|
|
1414
|
+
`m \prec n` be `0` otherwise. Having thus defined
|
|
1415
|
+
`\prec` on monomials, we extend `\prec` to a binary
|
|
1416
|
+
operation on `R[[x_1, x_2, x_3, \ldots]]` by requiring
|
|
1417
|
+
it to be continuous (in both inputs) and `R`-bilinear.
|
|
1418
|
+
It is easily seen that `QSym \prec QSym \subseteq
|
|
1419
|
+
QSym`, so that `\prec` restricts to a binary operation
|
|
1420
|
+
on `QSym`.
|
|
1421
|
+
|
|
1422
|
+
.. SEEALSO::
|
|
1423
|
+
|
|
1424
|
+
:meth:`dendriform_leq`
|
|
1425
|
+
|
|
1426
|
+
INPUT:
|
|
1427
|
+
|
|
1428
|
+
- ``other`` -- a quasi-symmetric function over the
|
|
1429
|
+
same base ring as ``self``
|
|
1430
|
+
|
|
1431
|
+
OUTPUT:
|
|
1432
|
+
|
|
1433
|
+
The quasi-symmetric function ``self`` `\prec`
|
|
1434
|
+
``other``, written in the basis of ``self``.
|
|
1435
|
+
|
|
1436
|
+
EXAMPLES::
|
|
1437
|
+
|
|
1438
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
1439
|
+
sage: M = QSym.M()
|
|
1440
|
+
sage: M[2, 1].dendriform_less(M[1, 2])
|
|
1441
|
+
2*M[2, 1, 1, 2] + M[2, 1, 2, 1] + M[2, 1, 3] + M[2, 2, 2]
|
|
1442
|
+
sage: F = QSym.F()
|
|
1443
|
+
sage: F[2, 1].dendriform_less(F[1, 2])
|
|
1444
|
+
F[1, 1, 2, 1, 1] + F[1, 1, 2, 2] + F[1, 1, 3, 1]
|
|
1445
|
+
+ F[1, 2, 1, 2] + F[1, 2, 2, 1] + F[1, 2, 3]
|
|
1446
|
+
+ F[2, 1, 1, 2] + F[2, 1, 2, 1] + F[2, 1, 3] + F[2, 2, 2]
|
|
1447
|
+
|
|
1448
|
+
The operation `\prec` can be used to recursively
|
|
1449
|
+
construct the dual immaculate basis: For every positive
|
|
1450
|
+
integer `m` and every composition `I`, the dual
|
|
1451
|
+
immaculate function `\operatorname{dI}_{[m, I]}` of the
|
|
1452
|
+
composition `[m, I]` (this composition is `I` with `m`
|
|
1453
|
+
prepended to it) is `F_{[m]} \prec \operatorname{dI}_I`. ::
|
|
1454
|
+
|
|
1455
|
+
sage: dI = QSym.dI()
|
|
1456
|
+
sage: dI(F[2]).dendriform_less(dI[1, 2])
|
|
1457
|
+
dI[2, 1, 2]
|
|
1458
|
+
|
|
1459
|
+
We check with the identity element::
|
|
1460
|
+
|
|
1461
|
+
sage: M.one().dendriform_less(M[1,2])
|
|
1462
|
+
0
|
|
1463
|
+
sage: M[1,2].dendriform_less(M.one())
|
|
1464
|
+
M[1, 2]
|
|
1465
|
+
|
|
1466
|
+
The operation `\prec` is not symmetric, nor if
|
|
1467
|
+
`a \prec b \neq 0`, then `b \prec a = 0` (as it would be
|
|
1468
|
+
for a single monomial)::
|
|
1469
|
+
|
|
1470
|
+
sage: M[1,2,1].dendriform_less(M[1,2])
|
|
1471
|
+
M[1, 1, 2, 1, 2] + 2*M[1, 1, 2, 2, 1] + M[1, 1, 2, 3]
|
|
1472
|
+
+ M[1, 1, 4, 1] + 2*M[1, 2, 1, 1, 2] + M[1, 2, 1, 2, 1]
|
|
1473
|
+
+ M[1, 2, 1, 3] + M[1, 2, 2, 2] + M[1, 3, 1, 2]
|
|
1474
|
+
+ M[1, 3, 2, 1] + M[1, 3, 3]
|
|
1475
|
+
sage: M[1,2].dendriform_less(M[1,2,1])
|
|
1476
|
+
M[1, 1, 2, 1, 2] + 2*M[1, 1, 2, 2, 1] + M[1, 1, 2, 3]
|
|
1477
|
+
+ M[1, 1, 4, 1] + M[1, 2, 1, 2, 1] + M[1, 3, 2, 1]
|
|
1478
|
+
"""
|
|
1479
|
+
# Convert to the monomial basis, there do restricted
|
|
1480
|
+
# shuffle product, then convert back to self.parent().
|
|
1481
|
+
P = self.parent()
|
|
1482
|
+
M = P.realization_of().M()
|
|
1483
|
+
a = M(self)
|
|
1484
|
+
b = M(other)
|
|
1485
|
+
res = M.zero()
|
|
1486
|
+
for I, I_coeff in a:
|
|
1487
|
+
if not I:
|
|
1488
|
+
continue
|
|
1489
|
+
i_head = I[0]
|
|
1490
|
+
I_tail = Composition(I[1:])
|
|
1491
|
+
for J, J_coeff in b:
|
|
1492
|
+
shufpro = I_tail.shuffle_product(J, overlap=True)
|
|
1493
|
+
res += J_coeff * M.sum_of_monomials(Composition([i_head] + list(K))
|
|
1494
|
+
for K in shufpro)
|
|
1495
|
+
return P(res)
|
|
1496
|
+
|
|
1497
|
+
def dendriform_leq(self, other):
|
|
1498
|
+
r"""
|
|
1499
|
+
Return the result of applying the dendriform
|
|
1500
|
+
smaller-or-equal operation to the two quasi-symmetric
|
|
1501
|
+
functions ``self`` and ``other``.
|
|
1502
|
+
|
|
1503
|
+
The dendriform smaller-or-equal operation is a binary
|
|
1504
|
+
operation, denoted by `\preceq` and written infix, on
|
|
1505
|
+
the ring of quasi-symmetric functions. It can be
|
|
1506
|
+
defined as a restriction of a binary operation
|
|
1507
|
+
(denoted by `\preceq` and written infix as well) on
|
|
1508
|
+
the ring of formal power series
|
|
1509
|
+
`R[[x_1, x_2, x_3, \ldots]]`, which is defined as
|
|
1510
|
+
follows: If `m` and `n` are two monomials in
|
|
1511
|
+
`x_1, x_2, x_3, \ldots`, then we let `m \preceq n` be
|
|
1512
|
+
the product `mn` if the smallest positive integer `i`
|
|
1513
|
+
for which `x_i` occurs in `m` is smaller or equal to
|
|
1514
|
+
the smallest positive integer `j` for which `x_j`
|
|
1515
|
+
occurs in `n` (this is understood to be false when
|
|
1516
|
+
`m = 1` and `n \neq 1`, and true when `n = 1`), and we
|
|
1517
|
+
let `m \preceq n` be `0` otherwise. Having thus
|
|
1518
|
+
defined `\preceq` on monomials, we extend `\preceq` to
|
|
1519
|
+
a binary operation on `R[[x_1, x_2, x_3, \ldots]]` by
|
|
1520
|
+
requiring it to be continuous (in both inputs) and
|
|
1521
|
+
`R`-bilinear. It is easily seen that
|
|
1522
|
+
`QSym \preceq QSym \subseteq QSym`, so that `\preceq`
|
|
1523
|
+
restricts to a binary operation on `QSym`.
|
|
1524
|
+
|
|
1525
|
+
This operation `\preceq` is related to the dendriform
|
|
1526
|
+
smaller relation `\prec` (:meth:`dendriform_less`).
|
|
1527
|
+
Namely, if we define a binary operation `\succ` on
|
|
1528
|
+
`QSym` by `a \succ b = b \prec a`, then
|
|
1529
|
+
`(QSym, \preceq, \succ)` is a dendriform `R`-algebra.
|
|
1530
|
+
Thus, any `a, b \in QSym` satisfy
|
|
1531
|
+
`a \preceq b = ab - b \prec a`.
|
|
1532
|
+
|
|
1533
|
+
.. SEEALSO::
|
|
1534
|
+
|
|
1535
|
+
:meth:`dendriform_less`
|
|
1536
|
+
|
|
1537
|
+
INPUT:
|
|
1538
|
+
|
|
1539
|
+
- ``other`` -- a quasi-symmetric function over the
|
|
1540
|
+
same base ring as ``self``
|
|
1541
|
+
|
|
1542
|
+
OUTPUT:
|
|
1543
|
+
|
|
1544
|
+
The quasi-symmetric function ``self`` `\preceq`
|
|
1545
|
+
``other``, written in the basis of ``self``.
|
|
1546
|
+
|
|
1547
|
+
EXAMPLES::
|
|
1548
|
+
|
|
1549
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
1550
|
+
sage: M = QSym.M()
|
|
1551
|
+
sage: M[2, 1].dendriform_leq(M[1, 2])
|
|
1552
|
+
2*M[2, 1, 1, 2] + M[2, 1, 2, 1] + M[2, 1, 3] + M[2, 2, 2]
|
|
1553
|
+
+ M[3, 1, 2] + M[3, 2, 1] + M[3, 3]
|
|
1554
|
+
sage: F = QSym.F()
|
|
1555
|
+
sage: F[2, 1].dendriform_leq(F[1, 2])
|
|
1556
|
+
F[2, 1, 1, 2] + F[2, 1, 2, 1] + F[2, 1, 3] + F[2, 2, 1, 1]
|
|
1557
|
+
+ 2*F[2, 2, 2] + F[2, 3, 1] + F[3, 1, 2] + F[3, 2, 1] + F[3, 3]
|
|
1558
|
+
"""
|
|
1559
|
+
# This might be somewhat slow...
|
|
1560
|
+
P = self.parent()
|
|
1561
|
+
return self * P(other) - P(other.dendriform_less(self))
|
|
1562
|
+
|
|
1563
|
+
def expand(self, n, alphabet='x'):
|
|
1564
|
+
r"""
|
|
1565
|
+
Expand the quasi-symmetric function into ``n`` variables in
|
|
1566
|
+
an alphabet, which by default is ``'x'``.
|
|
1567
|
+
|
|
1568
|
+
INPUT:
|
|
1569
|
+
|
|
1570
|
+
- ``n`` -- nonnegative integer; the number of variables
|
|
1571
|
+
in the expansion
|
|
1572
|
+
- ``alphabet`` -- (default: ``'x'``) the alphabet in
|
|
1573
|
+
which ``self`` is to be expanded
|
|
1574
|
+
|
|
1575
|
+
OUTPUT: an expansion of ``self`` into the ``n`` variables
|
|
1576
|
+
specified by ``alphabet``
|
|
1577
|
+
|
|
1578
|
+
EXAMPLES::
|
|
1579
|
+
|
|
1580
|
+
sage: F = QuasiSymmetricFunctions(QQ).Fundamental()
|
|
1581
|
+
sage: F[3].expand(3)
|
|
1582
|
+
x0^3 + x0^2*x1 + x0*x1^2 + x1^3 + x0^2*x2 + x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x2^3
|
|
1583
|
+
sage: F[2,1].expand(3)
|
|
1584
|
+
x0^2*x1 + x0^2*x2 + x0*x1*x2 + x1^2*x2
|
|
1585
|
+
|
|
1586
|
+
One can use a different set of variable by adding an optional
|
|
1587
|
+
argument ``alphabet=...`` ::
|
|
1588
|
+
|
|
1589
|
+
sage: F = QuasiSymmetricFunctions(QQ).Fundamental()
|
|
1590
|
+
sage: F[3].expand(2,alphabet='y')
|
|
1591
|
+
y0^3 + y0^2*y1 + y0*y1^2 + y1^3
|
|
1592
|
+
|
|
1593
|
+
TESTS::
|
|
1594
|
+
|
|
1595
|
+
sage: (3*F([])).expand(2)
|
|
1596
|
+
3
|
|
1597
|
+
sage: F[4,2].expand(0)
|
|
1598
|
+
0
|
|
1599
|
+
sage: F([]).expand(0)
|
|
1600
|
+
1
|
|
1601
|
+
"""
|
|
1602
|
+
M = self.parent().realization_of().Monomial()
|
|
1603
|
+
return M(self).expand(n,alphabet)
|
|
1604
|
+
|
|
1605
|
+
def is_symmetric(self):
|
|
1606
|
+
r"""
|
|
1607
|
+
Return ``True`` if ``self`` is an element of the symmetric
|
|
1608
|
+
functions.
|
|
1609
|
+
|
|
1610
|
+
This is being tested by looking at the expansion in
|
|
1611
|
+
the Monomial basis and checking if the coefficients are
|
|
1612
|
+
the same if the indexing compositions are permutations
|
|
1613
|
+
of each other.
|
|
1614
|
+
|
|
1615
|
+
OUTPUT:
|
|
1616
|
+
|
|
1617
|
+
- ``True`` if ``self`` is symmetric.
|
|
1618
|
+
``False`` if ``self`` is not symmetric.
|
|
1619
|
+
|
|
1620
|
+
EXAMPLES::
|
|
1621
|
+
|
|
1622
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
1623
|
+
sage: F = QSym.Fundamental()
|
|
1624
|
+
sage: (F[3,2] + F[2,3]).is_symmetric()
|
|
1625
|
+
False
|
|
1626
|
+
sage: (F[1, 1, 1, 2] + F[1, 1, 3] + F[1, 3, 1] + F[2, 1, 1, 1] + F[3, 1, 1]).is_symmetric()
|
|
1627
|
+
True
|
|
1628
|
+
sage: F([]).is_symmetric()
|
|
1629
|
+
True
|
|
1630
|
+
"""
|
|
1631
|
+
M = self.parent().realization_of().Monomial()
|
|
1632
|
+
return M(self).is_symmetric()
|
|
1633
|
+
|
|
1634
|
+
def to_symmetric_function(self):
|
|
1635
|
+
r"""
|
|
1636
|
+
Convert a quasi-symmetric function to a symmetric function.
|
|
1637
|
+
|
|
1638
|
+
OUTPUT:
|
|
1639
|
+
|
|
1640
|
+
- If ``self`` is a symmetric function, then return the expansion
|
|
1641
|
+
in the monomial basis. Otherwise raise an error.
|
|
1642
|
+
|
|
1643
|
+
EXAMPLES::
|
|
1644
|
+
|
|
1645
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
1646
|
+
sage: F = QSym.Fundamental()
|
|
1647
|
+
sage: (F[3,2] + F[2,3]).to_symmetric_function()
|
|
1648
|
+
Traceback (most recent call last):
|
|
1649
|
+
...
|
|
1650
|
+
ValueError: F[2, 3] + F[3, 2] is not a symmetric function
|
|
1651
|
+
sage: m = SymmetricFunctions(QQ).m()
|
|
1652
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
1653
|
+
sage: F(s[3,1,1]).to_symmetric_function()
|
|
1654
|
+
6*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + m[2, 2, 1] + m[3, 1, 1]
|
|
1655
|
+
sage: m(s[3,1,1])
|
|
1656
|
+
6*m[1, 1, 1, 1, 1] + 3*m[2, 1, 1, 1] + m[2, 2, 1] + m[3, 1, 1]
|
|
1657
|
+
"""
|
|
1658
|
+
if self.is_symmetric():
|
|
1659
|
+
M = self.parent().realization_of().Monomial()
|
|
1660
|
+
return M( self ).to_symmetric_function()
|
|
1661
|
+
else:
|
|
1662
|
+
raise ValueError("%s is not a symmetric function" % self)
|
|
1663
|
+
|
|
1664
|
+
class Monomial(CombinatorialFreeModule, BindableClass):
|
|
1665
|
+
r"""
|
|
1666
|
+
The Hopf algebra of quasi-symmetric function in the Monomial basis.
|
|
1667
|
+
|
|
1668
|
+
EXAMPLES::
|
|
1669
|
+
|
|
1670
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
1671
|
+
sage: M = QSym.M()
|
|
1672
|
+
sage: F = QSym.F()
|
|
1673
|
+
sage: M(F[2,2])
|
|
1674
|
+
M[1, 1, 1, 1] + M[1, 1, 2] + M[2, 1, 1] + M[2, 2]
|
|
1675
|
+
sage: m = SymmetricFunctions(QQ).m()
|
|
1676
|
+
sage: M(m[3,1,1])
|
|
1677
|
+
M[1, 1, 3] + M[1, 3, 1] + M[3, 1, 1]
|
|
1678
|
+
sage: (1+M[1])^3
|
|
1679
|
+
M[] + 3*M[1] + 6*M[1, 1] + 6*M[1, 1, 1] + 3*M[1, 2] + 3*M[2] + 3*M[2, 1] + M[3]
|
|
1680
|
+
sage: M[1,2,1].coproduct()
|
|
1681
|
+
M[] # M[1, 2, 1] + M[1] # M[2, 1] + M[1, 2] # M[1] + M[1, 2, 1] # M[]
|
|
1682
|
+
|
|
1683
|
+
The following is an alias for this basis::
|
|
1684
|
+
|
|
1685
|
+
sage: QSym.Monomial()
|
|
1686
|
+
Quasisymmetric functions over the Rational Field in the Monomial basis
|
|
1687
|
+
|
|
1688
|
+
TESTS::
|
|
1689
|
+
|
|
1690
|
+
sage: M(F([]))
|
|
1691
|
+
M[]
|
|
1692
|
+
sage: M(F(0))
|
|
1693
|
+
0
|
|
1694
|
+
sage: M(m([]))
|
|
1695
|
+
M[]
|
|
1696
|
+
"""
|
|
1697
|
+
|
|
1698
|
+
def __init__(self, QSym):
|
|
1699
|
+
"""
|
|
1700
|
+
EXAMPLES::
|
|
1701
|
+
|
|
1702
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial(); M
|
|
1703
|
+
Quasisymmetric functions over the Rational Field in the Monomial basis
|
|
1704
|
+
sage: TestSuite(M).run()
|
|
1705
|
+
"""
|
|
1706
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
1707
|
+
prefix='M', bracket=False,
|
|
1708
|
+
category=QSym.Bases())
|
|
1709
|
+
|
|
1710
|
+
def dual(self):
|
|
1711
|
+
r"""
|
|
1712
|
+
Return the dual basis to the Monomial basis. This is the complete basis of the
|
|
1713
|
+
non-commutative symmetric functions.
|
|
1714
|
+
|
|
1715
|
+
OUTPUT: the complete basis of the non-commutative symmetric functions
|
|
1716
|
+
|
|
1717
|
+
EXAMPLES::
|
|
1718
|
+
|
|
1719
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
1720
|
+
sage: M.dual()
|
|
1721
|
+
Non-Commutative Symmetric Functions over the Rational Field in the Complete basis
|
|
1722
|
+
"""
|
|
1723
|
+
return self.realization_of().dual().Complete()
|
|
1724
|
+
|
|
1725
|
+
def product_on_basis(self, I, J):
|
|
1726
|
+
"""
|
|
1727
|
+
The product on Monomial basis elements.
|
|
1728
|
+
|
|
1729
|
+
The product of the basis elements indexed by two compositions
|
|
1730
|
+
`I` and `J` is the sum of the basis elements indexed by
|
|
1731
|
+
compositions in the stuffle product (also called the
|
|
1732
|
+
overlapping shuffle product) of `I` and `J`.
|
|
1733
|
+
|
|
1734
|
+
INPUT:
|
|
1735
|
+
|
|
1736
|
+
- ``I``, ``J`` -- compositions
|
|
1737
|
+
|
|
1738
|
+
OUTPUT:
|
|
1739
|
+
|
|
1740
|
+
- The product of the Monomial quasi-symmetric functions indexed by ``I`` and
|
|
1741
|
+
``J``, expressed in the Monomial basis.
|
|
1742
|
+
|
|
1743
|
+
EXAMPLES::
|
|
1744
|
+
|
|
1745
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
1746
|
+
sage: c1 = Composition([2])
|
|
1747
|
+
sage: c2 = Composition([1,3])
|
|
1748
|
+
sage: M.product_on_basis(c1, c2)
|
|
1749
|
+
M[1, 2, 3] + M[1, 3, 2] + M[1, 5] + M[2, 1, 3] + M[3, 3]
|
|
1750
|
+
sage: M.product_on_basis(c1, Composition([]))
|
|
1751
|
+
M[2]
|
|
1752
|
+
"""
|
|
1753
|
+
return self.sum_of_monomials(I.shuffle_product(J, overlap=True))
|
|
1754
|
+
|
|
1755
|
+
def antipode_on_basis(self, compo):
|
|
1756
|
+
r"""
|
|
1757
|
+
Return the result of the antipode applied to a quasi-symmetric Monomial basis
|
|
1758
|
+
element.
|
|
1759
|
+
|
|
1760
|
+
INPUT:
|
|
1761
|
+
|
|
1762
|
+
- ``compo`` -- composition
|
|
1763
|
+
|
|
1764
|
+
OUTPUT:
|
|
1765
|
+
|
|
1766
|
+
- The result of the antipode applied to the composition ``compo``, expressed
|
|
1767
|
+
in the Monomial basis.
|
|
1768
|
+
|
|
1769
|
+
EXAMPLES::
|
|
1770
|
+
|
|
1771
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
1772
|
+
sage: M.antipode_on_basis(Composition([2,1]))
|
|
1773
|
+
M[1, 2] + M[3]
|
|
1774
|
+
sage: M.antipode_on_basis(Composition([]))
|
|
1775
|
+
M[]
|
|
1776
|
+
"""
|
|
1777
|
+
return (-1)**(len(compo)) * self.sum_of_fatter_compositions(compo.reversed())
|
|
1778
|
+
|
|
1779
|
+
def coproduct_on_basis(self, compo):
|
|
1780
|
+
r"""
|
|
1781
|
+
Return the coproduct of a Monomial basis element.
|
|
1782
|
+
|
|
1783
|
+
Combinatorial rule: deconcatenation.
|
|
1784
|
+
|
|
1785
|
+
INPUT:
|
|
1786
|
+
|
|
1787
|
+
- ``compo`` -- composition
|
|
1788
|
+
|
|
1789
|
+
OUTPUT:
|
|
1790
|
+
|
|
1791
|
+
- The coproduct applied to the Monomial quasi-symmetric function indexed by
|
|
1792
|
+
``compo``, expressed in the Monomial basis.
|
|
1793
|
+
|
|
1794
|
+
EXAMPLES::
|
|
1795
|
+
|
|
1796
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
1797
|
+
sage: M[4,2,3].coproduct()
|
|
1798
|
+
M[] # M[4, 2, 3] + M[4] # M[2, 3] + M[4, 2] # M[3] + M[4, 2, 3] # M[]
|
|
1799
|
+
sage: M.coproduct_on_basis(Composition([]))
|
|
1800
|
+
M[] # M[]
|
|
1801
|
+
"""
|
|
1802
|
+
return self.tensor_square().sum_of_monomials((self._indices(compo[:i]),
|
|
1803
|
+
self._indices(compo[i:]))
|
|
1804
|
+
for i in range(len(compo)+1))
|
|
1805
|
+
|
|
1806
|
+
def lambda_of_monomial(self, I, n):
|
|
1807
|
+
r"""
|
|
1808
|
+
Return the image of the monomial quasi-symmetric function
|
|
1809
|
+
`M_I` under the lambda-map `\lambda^n`, expanded in the
|
|
1810
|
+
monomial basis.
|
|
1811
|
+
|
|
1812
|
+
The ring of quasi-symmetric functions over the integers,
|
|
1813
|
+
`\mathrm{QSym}_{\ZZ}` (and more generally, the ring of
|
|
1814
|
+
quasi-symmetric functions over any binomial ring) becomes
|
|
1815
|
+
a `\lambda`-ring (with the `\lambda`-structure inherited
|
|
1816
|
+
from the ring of formal power series, so that
|
|
1817
|
+
`\lambda^i(x_j)` is `x_j` if `i = 1` and `0` if `i > 1`).
|
|
1818
|
+
|
|
1819
|
+
The Adams operations of this `\lambda`-ring are the
|
|
1820
|
+
Adams endomorphisms `\mathbf{f}_n` (see
|
|
1821
|
+
:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.adams_operator`
|
|
1822
|
+
for their definition). Using these endomorphisms, the
|
|
1823
|
+
`\lambda`-operations can be explicitly computed via the formula
|
|
1824
|
+
|
|
1825
|
+
.. MATH::
|
|
1826
|
+
|
|
1827
|
+
\exp \left(- \sum_{n=1}^{\infty}
|
|
1828
|
+
\frac{1}{n} \mathbf{f}_n(x) t^n \right)
|
|
1829
|
+
= \sum_{j=0}^{\infty} (-1)^j \lambda^j(x) t^j
|
|
1830
|
+
|
|
1831
|
+
in the ring of formal power series in a variable `t` over
|
|
1832
|
+
the ring of quasi-symmetric functions. In particular,
|
|
1833
|
+
every composition `I = (I_1, I_2, \cdots, I_\ell )` satisfies
|
|
1834
|
+
|
|
1835
|
+
.. MATH::
|
|
1836
|
+
|
|
1837
|
+
\exp \left(- \sum_{n=1}^{\infty}
|
|
1838
|
+
\frac{1}{n} M_{(nI_1, nI_2, \cdots, nI_\ell )} t^n \right)
|
|
1839
|
+
= \sum_{j=0}^{\infty} (-1)^j \lambda^j(M_I) t^j
|
|
1840
|
+
|
|
1841
|
+
(corrected version of Remark 2.4 in [Haz2004]_).
|
|
1842
|
+
|
|
1843
|
+
The quasi-symmetric functions `\lambda^i(M_I)` with `n`
|
|
1844
|
+
ranging over the positive integers and `I` ranging over
|
|
1845
|
+
the reduced Lyndon compositions (i. e., compositions
|
|
1846
|
+
which are Lyndon words and have the gcd of their entries
|
|
1847
|
+
equal to `1`) form a set of free polynomial generators
|
|
1848
|
+
for `\mathrm{QSym}`. See [GriRei18]_, Chapter 6, for
|
|
1849
|
+
the proof, and [Haz2004]_ for a major part of it.
|
|
1850
|
+
|
|
1851
|
+
INPUT:
|
|
1852
|
+
|
|
1853
|
+
- ``I`` -- composition
|
|
1854
|
+
- ``n`` -- nonnegative integer
|
|
1855
|
+
|
|
1856
|
+
OUTPUT:
|
|
1857
|
+
|
|
1858
|
+
The quasi-symmetric function `\lambda^n(M_I)`, expanded in
|
|
1859
|
+
the monomial basis over the ground ring of ``self``.
|
|
1860
|
+
|
|
1861
|
+
EXAMPLES::
|
|
1862
|
+
|
|
1863
|
+
sage: # needs sage.rings.number_field
|
|
1864
|
+
sage: M = QuasiSymmetricFunctions(CyclotomicField()).Monomial()
|
|
1865
|
+
sage: M.lambda_of_monomial([1, 2], 2)
|
|
1866
|
+
2*M[1, 1, 2, 2] + M[1, 1, 4] + M[1, 2, 1, 2] + M[1, 3, 2] + M[2, 2, 2]
|
|
1867
|
+
sage: M.lambda_of_monomial([1, 1], 2)
|
|
1868
|
+
3*M[1, 1, 1, 1] + M[1, 1, 2] + M[1, 2, 1] + M[2, 1, 1]
|
|
1869
|
+
sage: M = QuasiSymmetricFunctions(Integers(19)).Monomial()
|
|
1870
|
+
sage: M.lambda_of_monomial([1, 2], 3)
|
|
1871
|
+
6*M[1, 1, 1, 2, 2, 2] + 3*M[1, 1, 1, 2, 4] + 3*M[1, 1, 1, 4, 2]
|
|
1872
|
+
+ M[1, 1, 1, 6] + 4*M[1, 1, 2, 1, 2, 2] + 2*M[1, 1, 2, 1, 4]
|
|
1873
|
+
+ 2*M[1, 1, 2, 2, 1, 2] + 2*M[1, 1, 2, 3, 2] + 4*M[1, 1, 3, 2, 2]
|
|
1874
|
+
+ 2*M[1, 1, 3, 4] + M[1, 1, 4, 1, 2] + M[1, 1, 5, 2]
|
|
1875
|
+
+ 2*M[1, 2, 1, 1, 2, 2] + M[1, 2, 1, 1, 4] + M[1, 2, 1, 2, 1, 2]
|
|
1876
|
+
+ M[1, 2, 1, 3, 2] + 4*M[1, 2, 2, 2, 2] + M[1, 2, 2, 4] + M[1, 2, 4, 2]
|
|
1877
|
+
+ 2*M[1, 3, 1, 2, 2] + M[1, 3, 1, 4] + M[1, 3, 2, 1, 2] + M[1, 3, 3, 2]
|
|
1878
|
+
+ M[1, 4, 2, 2] + 3*M[2, 1, 2, 2, 2] + M[2, 1, 2, 4] + M[2, 1, 4, 2]
|
|
1879
|
+
+ 2*M[2, 2, 1, 2, 2] + M[2, 2, 1, 4] + M[2, 2, 2, 1, 2] + M[2, 2, 3, 2]
|
|
1880
|
+
+ 2*M[2, 3, 2, 2] + M[2, 3, 4] + M[3, 2, 2, 2]
|
|
1881
|
+
|
|
1882
|
+
The map `\lambda^0` sends everything to `1`::
|
|
1883
|
+
|
|
1884
|
+
sage: M = QuasiSymmetricFunctions(ZZ).Monomial()
|
|
1885
|
+
sage: all( M.lambda_of_monomial(I, 0) == M.one()
|
|
1886
|
+
....: for I in Compositions(3) )
|
|
1887
|
+
True
|
|
1888
|
+
|
|
1889
|
+
The map `\lambda^1` is the identity map::
|
|
1890
|
+
|
|
1891
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
1892
|
+
sage: all( M.lambda_of_monomial(I, 1) == M(I)
|
|
1893
|
+
....: for I in Compositions(3) )
|
|
1894
|
+
True
|
|
1895
|
+
sage: M = QuasiSymmetricFunctions(Integers(5)).Monomial()
|
|
1896
|
+
sage: all( M.lambda_of_monomial(I, 1) == M(I)
|
|
1897
|
+
....: for I in Compositions(3) )
|
|
1898
|
+
True
|
|
1899
|
+
sage: M = QuasiSymmetricFunctions(ZZ).Monomial()
|
|
1900
|
+
sage: all( M.lambda_of_monomial(I, 1) == M(I)
|
|
1901
|
+
....: for I in Compositions(3) )
|
|
1902
|
+
True
|
|
1903
|
+
"""
|
|
1904
|
+
# The following algorithm is a rewriting of the formula in the docstring.
|
|
1905
|
+
# We are working over QQ because there are denominators which don't
|
|
1906
|
+
# immediately cancel.
|
|
1907
|
+
from sage.rings.integer_ring import ZZ
|
|
1908
|
+
from sage.rings.rational_field import QQ
|
|
1909
|
+
QQM = QuasiSymmetricFunctions(QQ).M()
|
|
1910
|
+
QQ_result = QQM.zero()
|
|
1911
|
+
for lam in Partitions(n):
|
|
1912
|
+
coeff = QQ((-1) ** len(lam)) / lam.centralizer_size()
|
|
1913
|
+
QQ_result += coeff * QQM.prod([QQM(self._indices([k * i for i in I]))
|
|
1914
|
+
for k in lam])
|
|
1915
|
+
QQ_result *= (-1) ** n
|
|
1916
|
+
# QQ_result is now \lambda^n(M_I) over QQ.
|
|
1917
|
+
result = self.sum_of_terms([(J, ZZ(coeff)) for (J, coeff) in QQ_result],
|
|
1918
|
+
distinct=True)
|
|
1919
|
+
return result
|
|
1920
|
+
|
|
1921
|
+
class Element(CombinatorialFreeModule.Element):
|
|
1922
|
+
r"""
|
|
1923
|
+
Element methods of the ``Monomial`` basis of ``QuasiSymmetricFunctions``.
|
|
1924
|
+
"""
|
|
1925
|
+
|
|
1926
|
+
def psi_involution(self):
|
|
1927
|
+
r"""
|
|
1928
|
+
Return the image of the quasisymmetric function ``self``
|
|
1929
|
+
under the involution `\psi`.
|
|
1930
|
+
|
|
1931
|
+
The involution `\psi` is defined as the linear map
|
|
1932
|
+
`QSym \to QSym` which, for every composition `I`, sends the
|
|
1933
|
+
fundamental quasisymmetric function `F_I` to `F_{I^c}`, where
|
|
1934
|
+
`I^c` denotes the complement of the composition `I`.
|
|
1935
|
+
The map `\psi` is an involution and a graded Hopf algebra
|
|
1936
|
+
automorphism of `QSym`. Its restriction to the ring of
|
|
1937
|
+
symmetric functions coincides with the omega automorphism of
|
|
1938
|
+
the latter ring.
|
|
1939
|
+
|
|
1940
|
+
The involution `\psi` of `QSym` is adjoint to the involution
|
|
1941
|
+
`\psi` of `NCSF` by the standard adjunction between `NCSF` and
|
|
1942
|
+
`QSym`.
|
|
1943
|
+
|
|
1944
|
+
The involution `\psi` has been denoted by `\psi` in [LMvW13]_,
|
|
1945
|
+
section 3.6.
|
|
1946
|
+
|
|
1947
|
+
.. SEEALSO::
|
|
1948
|
+
|
|
1949
|
+
:meth:`psi involution on QSym
|
|
1950
|
+
<sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.psi_involution>`,
|
|
1951
|
+
:meth:`psi involution on NCSF
|
|
1952
|
+
<sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.psi_involution>`,
|
|
1953
|
+
:meth:`star involution on QSym
|
|
1954
|
+
<sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution>`.
|
|
1955
|
+
|
|
1956
|
+
EXAMPLES::
|
|
1957
|
+
|
|
1958
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
1959
|
+
sage: M = QSym.M()
|
|
1960
|
+
sage: M[3,2].psi_involution()
|
|
1961
|
+
-M[3, 2] - M[5]
|
|
1962
|
+
sage: M[3,1].psi_involution()
|
|
1963
|
+
M[3, 1] + M[4]
|
|
1964
|
+
sage: M[3,1,1].psi_involution()
|
|
1965
|
+
M[3, 1, 1] + M[3, 2] + M[4, 1] + M[5]
|
|
1966
|
+
sage: M[1,1,1].psi_involution()
|
|
1967
|
+
M[1, 1, 1] + M[1, 2] + M[2, 1] + M[3]
|
|
1968
|
+
sage: M[[]].psi_involution()
|
|
1969
|
+
M[]
|
|
1970
|
+
sage: M(0).psi_involution()
|
|
1971
|
+
0
|
|
1972
|
+
sage: (2*M[[]] - M[3,1] + 4*M[2]).psi_involution()
|
|
1973
|
+
2*M[] - 4*M[2] - M[3, 1] - M[4]
|
|
1974
|
+
|
|
1975
|
+
This particular implementation is tailored to the monomial
|
|
1976
|
+
basis. It is semantically equivalent to the generic
|
|
1977
|
+
implementation it overshadows::
|
|
1978
|
+
|
|
1979
|
+
sage: F = QSym.F()
|
|
1980
|
+
sage: all( F(M[I].psi_involution()) == F(M[I]).psi_involution()
|
|
1981
|
+
....: for I in Compositions(3) )
|
|
1982
|
+
True
|
|
1983
|
+
|
|
1984
|
+
sage: F = QSym.F()
|
|
1985
|
+
sage: all( F(M[I].psi_involution()) == F(M[I]).psi_involution()
|
|
1986
|
+
....: for I in Compositions(4) )
|
|
1987
|
+
True
|
|
1988
|
+
"""
|
|
1989
|
+
parent = self.parent()
|
|
1990
|
+
return parent.sum( (-1) ** (I.size() - len(I)) * coeff
|
|
1991
|
+
* parent.sum_of_fatter_compositions(I)
|
|
1992
|
+
for I, coeff in
|
|
1993
|
+
self._monomial_coefficients.items() )
|
|
1994
|
+
|
|
1995
|
+
def expand(self, n, alphabet='x'):
|
|
1996
|
+
r"""
|
|
1997
|
+
Expand the quasi-symmetric function written in the monomial basis in
|
|
1998
|
+
`n` variables.
|
|
1999
|
+
|
|
2000
|
+
INPUT:
|
|
2001
|
+
|
|
2002
|
+
- ``n`` -- integer
|
|
2003
|
+
- ``alphabet`` -- string (default: ``'x'``)
|
|
2004
|
+
|
|
2005
|
+
OUTPUT: the quasi-symmetric function ``self`` expressed in the
|
|
2006
|
+
`n` variables described by ``alphabet``
|
|
2007
|
+
|
|
2008
|
+
.. TODO:: accept an *alphabet* as input
|
|
2009
|
+
|
|
2010
|
+
EXAMPLES::
|
|
2011
|
+
|
|
2012
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
2013
|
+
sage: M[4,2].expand(3)
|
|
2014
|
+
x0^4*x1^2 + x0^4*x2^2 + x1^4*x2^2
|
|
2015
|
+
|
|
2016
|
+
One can use a different set of variables by using the
|
|
2017
|
+
optional argument ``alphabet``::
|
|
2018
|
+
|
|
2019
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
2020
|
+
sage: M[2,1,1].expand(4,alphabet='y')
|
|
2021
|
+
y0^2*y1*y2 + y0^2*y1*y3 + y0^2*y2*y3 + y1^2*y2*y3
|
|
2022
|
+
|
|
2023
|
+
TESTS::
|
|
2024
|
+
|
|
2025
|
+
sage: (3*M([])).expand(2)
|
|
2026
|
+
3
|
|
2027
|
+
sage: M[4,2].expand(0)
|
|
2028
|
+
0
|
|
2029
|
+
sage: M([]).expand(0)
|
|
2030
|
+
1
|
|
2031
|
+
"""
|
|
2032
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
2033
|
+
M = self.parent()
|
|
2034
|
+
P = PolynomialRing(M.base_ring(), n, alphabet)
|
|
2035
|
+
x = P.gens()
|
|
2036
|
+
|
|
2037
|
+
def on_basis(comp, i):
|
|
2038
|
+
if not comp:
|
|
2039
|
+
return P.one()
|
|
2040
|
+
elif len(comp) > i:
|
|
2041
|
+
return P.zero()
|
|
2042
|
+
else:
|
|
2043
|
+
return x[i-1]**comp[-1] * on_basis(comp[:-1], i-1) + \
|
|
2044
|
+
on_basis(comp, i-1)
|
|
2045
|
+
return M._apply_module_morphism(self, lambda comp: on_basis(comp,n),
|
|
2046
|
+
codomain=P)
|
|
2047
|
+
|
|
2048
|
+
def is_symmetric( self ):
|
|
2049
|
+
r"""
|
|
2050
|
+
Determine if a quasi-symmetric function, written in the Monomial basis,
|
|
2051
|
+
is symmetric.
|
|
2052
|
+
|
|
2053
|
+
This is being tested by looking at the expansion in the Monomial
|
|
2054
|
+
basis and checking if the coefficients are the same if the indexing
|
|
2055
|
+
compositions are permutations of each other.
|
|
2056
|
+
|
|
2057
|
+
OUTPUT:
|
|
2058
|
+
|
|
2059
|
+
- ``True`` if ``self`` is an element of the symmetric
|
|
2060
|
+
functions and ``False`` otherwise.
|
|
2061
|
+
|
|
2062
|
+
EXAMPLES::
|
|
2063
|
+
|
|
2064
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2065
|
+
sage: M = QSym.Monomial()
|
|
2066
|
+
sage: (M[3,2] + M[2,3] + M[4,1]).is_symmetric()
|
|
2067
|
+
False
|
|
2068
|
+
sage: (M[3,2] + M[2,3]).is_symmetric()
|
|
2069
|
+
True
|
|
2070
|
+
sage: (M[1,2,1] + M[1,1,2]).is_symmetric()
|
|
2071
|
+
False
|
|
2072
|
+
sage: (M[1,2,1] + M[1,1,2] + M[2,1,1]).is_symmetric()
|
|
2073
|
+
True
|
|
2074
|
+
"""
|
|
2075
|
+
# We must check that every rearrangement of a composition
|
|
2076
|
+
# that appears in self appears with the same coefficient.
|
|
2077
|
+
# We use a dictionary to keep track of the coefficient
|
|
2078
|
+
# and how many rearrangements of the composition we've seen.
|
|
2079
|
+
from sage.combinat.permutation import Permutations_mset
|
|
2080
|
+
d = {}
|
|
2081
|
+
for (I, coeff) in self:
|
|
2082
|
+
partition = I.to_partition()
|
|
2083
|
+
if partition not in d:
|
|
2084
|
+
d[partition] = [coeff, 1]
|
|
2085
|
+
else:
|
|
2086
|
+
if d[partition][0] != coeff:
|
|
2087
|
+
return False
|
|
2088
|
+
else:
|
|
2089
|
+
d[partition][1] += 1
|
|
2090
|
+
# make sure we've seen each rearrangement of the composition
|
|
2091
|
+
return all(d[partition][1] == Permutations_mset(partition).cardinality()
|
|
2092
|
+
for partition in d)
|
|
2093
|
+
|
|
2094
|
+
def to_symmetric_function(self):
|
|
2095
|
+
r"""
|
|
2096
|
+
Take a quasi-symmetric function, expressed in the monomial basis, and
|
|
2097
|
+
return its symmetric realization, when possible, expressed in the
|
|
2098
|
+
monomial basis of symmetric functions.
|
|
2099
|
+
|
|
2100
|
+
OUTPUT:
|
|
2101
|
+
|
|
2102
|
+
- If ``self`` is a symmetric function, then the expansion
|
|
2103
|
+
in the monomial basis of the symmetric functions is returned.
|
|
2104
|
+
Otherwise an error is raised.
|
|
2105
|
+
|
|
2106
|
+
EXAMPLES::
|
|
2107
|
+
|
|
2108
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2109
|
+
sage: M = QSym.Monomial()
|
|
2110
|
+
sage: (M[3,2] + M[2,3] + M[4,1]).to_symmetric_function()
|
|
2111
|
+
Traceback (most recent call last):
|
|
2112
|
+
...
|
|
2113
|
+
ValueError: M[2, 3] + M[3, 2] + M[4, 1] is not a symmetric function
|
|
2114
|
+
sage: (M[3,2] + M[2,3] + 2*M[4,1] + 2*M[1,4]).to_symmetric_function()
|
|
2115
|
+
m[3, 2] + 2*m[4, 1]
|
|
2116
|
+
sage: m = SymmetricFunctions(QQ).m()
|
|
2117
|
+
sage: M(m[3,1,1]).to_symmetric_function()
|
|
2118
|
+
m[3, 1, 1]
|
|
2119
|
+
sage: (M(m[2,1])*M(m[2,1])).to_symmetric_function()-m[2,1]*m[2,1]
|
|
2120
|
+
0
|
|
2121
|
+
|
|
2122
|
+
TESTS::
|
|
2123
|
+
|
|
2124
|
+
sage: (M(0)).to_symmetric_function()
|
|
2125
|
+
0
|
|
2126
|
+
sage: (M([])).to_symmetric_function()
|
|
2127
|
+
m[]
|
|
2128
|
+
sage: (2*M([])).to_symmetric_function()
|
|
2129
|
+
2*m[]
|
|
2130
|
+
|
|
2131
|
+
We check that the result is indexed by partitions::
|
|
2132
|
+
|
|
2133
|
+
sage: M([]).to_symmetric_function().leading_support().parent()
|
|
2134
|
+
Partitions
|
|
2135
|
+
"""
|
|
2136
|
+
m = SymmetricFunctions(self.parent().base_ring()).monomial()
|
|
2137
|
+
if self.is_symmetric():
|
|
2138
|
+
return m._from_dict({_Partitions(list(I)): coeff
|
|
2139
|
+
for I, coeff in self
|
|
2140
|
+
if list(I) in _Partitions}, remove_zeros=False)
|
|
2141
|
+
else:
|
|
2142
|
+
raise ValueError("%s is not a symmetric function" % self)
|
|
2143
|
+
|
|
2144
|
+
M = Monomial
|
|
2145
|
+
|
|
2146
|
+
class Fundamental(CombinatorialFreeModule, BindableClass):
|
|
2147
|
+
r"""
|
|
2148
|
+
The Hopf algebra of quasi-symmetric functions in the Fundamental basis.
|
|
2149
|
+
|
|
2150
|
+
EXAMPLES::
|
|
2151
|
+
|
|
2152
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2153
|
+
sage: F = QSym.F()
|
|
2154
|
+
sage: M = QSym.M()
|
|
2155
|
+
sage: F(M[2,2])
|
|
2156
|
+
F[1, 1, 1, 1] - F[1, 1, 2] - F[2, 1, 1] + F[2, 2]
|
|
2157
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
2158
|
+
sage: F(s[3,2])
|
|
2159
|
+
F[1, 2, 2] + F[1, 3, 1] + F[2, 2, 1] + F[2, 3] + F[3, 2]
|
|
2160
|
+
sage: (1+F[1])^3
|
|
2161
|
+
F[] + 3*F[1] + 3*F[1, 1] + F[1, 1, 1] + 2*F[1, 2] + 3*F[2] + 2*F[2, 1] + F[3]
|
|
2162
|
+
sage: F[1,2,1].coproduct()
|
|
2163
|
+
F[] # F[1, 2, 1] + F[1] # F[2, 1] + F[1, 1] # F[1, 1] + F[1, 2] # F[1] + F[1, 2, 1] # F[]
|
|
2164
|
+
|
|
2165
|
+
The following is an alias for this basis::
|
|
2166
|
+
|
|
2167
|
+
sage: QSym.Fundamental()
|
|
2168
|
+
Quasisymmetric functions over the Rational Field in the Fundamental basis
|
|
2169
|
+
|
|
2170
|
+
TESTS::
|
|
2171
|
+
|
|
2172
|
+
sage: F(M([]))
|
|
2173
|
+
F[]
|
|
2174
|
+
sage: F(M(0))
|
|
2175
|
+
0
|
|
2176
|
+
sage: F(s([]))
|
|
2177
|
+
F[]
|
|
2178
|
+
sage: F(s(0))
|
|
2179
|
+
0
|
|
2180
|
+
"""
|
|
2181
|
+
|
|
2182
|
+
def __init__(self, QSym):
|
|
2183
|
+
"""
|
|
2184
|
+
EXAMPLES::
|
|
2185
|
+
|
|
2186
|
+
sage: F = QuasiSymmetricFunctions(QQ).Fundamental(); F
|
|
2187
|
+
Quasisymmetric functions over the Rational Field in the Fundamental basis
|
|
2188
|
+
sage: TestSuite(F).run()
|
|
2189
|
+
"""
|
|
2190
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
2191
|
+
prefix='F', bracket=False,
|
|
2192
|
+
category=QSym.Bases())
|
|
2193
|
+
|
|
2194
|
+
def _from_schur_on_basis(self, la):
|
|
2195
|
+
r"""
|
|
2196
|
+
Map the Schur symmetric function indexed by ``la`` to the
|
|
2197
|
+
Fundamental basis.
|
|
2198
|
+
|
|
2199
|
+
EXAMPLES::
|
|
2200
|
+
|
|
2201
|
+
sage: s = SymmetricFunctions(QQ).schur()
|
|
2202
|
+
sage: F = QuasiSymmetricFunctions(QQ).Fundamental()
|
|
2203
|
+
sage: F(s[2,2]-s[3,1]) # indirect doctest
|
|
2204
|
+
F[1, 2, 1] - F[1, 3] - F[3, 1]
|
|
2205
|
+
|
|
2206
|
+
sage: F._from_schur_on_basis(Partition([]))
|
|
2207
|
+
F[]
|
|
2208
|
+
|
|
2209
|
+
sage: F._from_schur_on_basis(Partition([2,2,2]))
|
|
2210
|
+
F[1, 1, 2, 1, 1] + F[1, 2, 1, 2] + F[1, 2, 2, 1] + F[2, 1, 2, 1] + F[2, 2, 2]
|
|
2211
|
+
"""
|
|
2212
|
+
C = self._indices
|
|
2213
|
+
res = 0
|
|
2214
|
+
n = la.size()
|
|
2215
|
+
for T in StandardTableaux(la):
|
|
2216
|
+
des = T.standard_descents()
|
|
2217
|
+
comp = C.from_descents([d-1 for d in des], n)
|
|
2218
|
+
res += self.monomial(comp)
|
|
2219
|
+
return res
|
|
2220
|
+
|
|
2221
|
+
def dual(self):
|
|
2222
|
+
r"""
|
|
2223
|
+
Return the dual basis to the Fundamental basis. This is the ribbon
|
|
2224
|
+
basis of the non-commutative symmetric functions.
|
|
2225
|
+
|
|
2226
|
+
OUTPUT: the ribbon basis of the non-commutative symmetric functions
|
|
2227
|
+
|
|
2228
|
+
EXAMPLES::
|
|
2229
|
+
|
|
2230
|
+
sage: F = QuasiSymmetricFunctions(QQ).F()
|
|
2231
|
+
sage: F.dual()
|
|
2232
|
+
Non-Commutative Symmetric Functions over the Rational Field in the Ribbon basis
|
|
2233
|
+
"""
|
|
2234
|
+
return self.realization_of().dual().Ribbon()
|
|
2235
|
+
|
|
2236
|
+
def antipode_on_basis(self, compo):
|
|
2237
|
+
r"""
|
|
2238
|
+
Return the antipode to a Fundamental quasi-symmetric basis element.
|
|
2239
|
+
|
|
2240
|
+
INPUT:
|
|
2241
|
+
|
|
2242
|
+
- ``compo`` -- composition
|
|
2243
|
+
|
|
2244
|
+
OUTPUT:
|
|
2245
|
+
|
|
2246
|
+
- The result of the antipode applied to the quasi-symmetric
|
|
2247
|
+
Fundamental basis element indexed by ``compo``.
|
|
2248
|
+
|
|
2249
|
+
EXAMPLES::
|
|
2250
|
+
|
|
2251
|
+
sage: F = QuasiSymmetricFunctions(QQ).F()
|
|
2252
|
+
sage: F.antipode_on_basis(Composition([2,1]))
|
|
2253
|
+
-F[2, 1]
|
|
2254
|
+
"""
|
|
2255
|
+
return (-1)**(compo.size()) * self.monomial(compo.conjugate())
|
|
2256
|
+
|
|
2257
|
+
def coproduct_on_basis(self, compo):
|
|
2258
|
+
r"""
|
|
2259
|
+
Return the coproduct to a Fundamental quasi-symmetric basis element.
|
|
2260
|
+
|
|
2261
|
+
Combinatorial rule: quasi-deconcatenation.
|
|
2262
|
+
|
|
2263
|
+
INPUT:
|
|
2264
|
+
|
|
2265
|
+
- ``compo`` -- composition
|
|
2266
|
+
|
|
2267
|
+
OUTPUT:
|
|
2268
|
+
|
|
2269
|
+
- The application of the coproduct to the Fundamental quasi-symmetric
|
|
2270
|
+
function indexed by the composition ``compo``.
|
|
2271
|
+
|
|
2272
|
+
EXAMPLES::
|
|
2273
|
+
|
|
2274
|
+
sage: F = QuasiSymmetricFunctions(QQ).Fundamental()
|
|
2275
|
+
sage: F[4].coproduct()
|
|
2276
|
+
F[] # F[4] + F[1] # F[3] + F[2] # F[2] + F[3] # F[1] + F[4] # F[]
|
|
2277
|
+
sage: F[2,1,3].coproduct()
|
|
2278
|
+
F[] # F[2, 1, 3] + F[1] # F[1, 1, 3] + F[2] # F[1, 3] + F[2, 1] # F[3] + F[2, 1, 1] # F[2] + F[2, 1, 2] # F[1] + F[2, 1, 3] # F[]
|
|
2279
|
+
|
|
2280
|
+
TESTS::
|
|
2281
|
+
|
|
2282
|
+
sage: F.coproduct_on_basis(Composition([2,1,3]))
|
|
2283
|
+
F[] # F[2, 1, 3] + F[1] # F[1, 1, 3] + F[2] # F[1, 3] + F[2, 1] # F[3] + F[2, 1, 1] # F[2] + F[2, 1, 2] # F[1] + F[2, 1, 3] # F[]
|
|
2284
|
+
sage: F.one().coproduct() # generic for graded / graded connected
|
|
2285
|
+
F[] # F[]
|
|
2286
|
+
"""
|
|
2287
|
+
T = self.tensor_square()
|
|
2288
|
+
C = Composition
|
|
2289
|
+
return T.sum_of_monomials( ( C(compo[:i]), C(compo[i:]) ) for i in range(len(compo)+1) ) + \
|
|
2290
|
+
T.sum_of_monomials( ( C(compo[:i]+[j]), C([compo[i]-j]+compo[i+1:]) )
|
|
2291
|
+
for i in range(len(compo))
|
|
2292
|
+
for j in range(1, compo[i]) )
|
|
2293
|
+
|
|
2294
|
+
@cached_method
|
|
2295
|
+
def Eulerian(self, n, j, k=None):
|
|
2296
|
+
r"""
|
|
2297
|
+
Return the Eulerian (quasi)symmetric function `Q_{n,j}` (with
|
|
2298
|
+
`n` either an integer or a partition) defined in [SW2010]_ in
|
|
2299
|
+
terms of the fundamental quasisymmetric functions.
|
|
2300
|
+
Or, if the optional argument ``k`` is specified, return the
|
|
2301
|
+
function `Q_{n,j,k}` defined ibidem.
|
|
2302
|
+
|
|
2303
|
+
If `n` and `j` are nonnegative integers, then the Eulerian
|
|
2304
|
+
quasisymmetric function `Q_{n,j}` is defined as
|
|
2305
|
+
|
|
2306
|
+
.. MATH::
|
|
2307
|
+
|
|
2308
|
+
Q_{n,j} := \sum_{\sigma} F_{\mathrm{Dex}(\sigma)},
|
|
2309
|
+
|
|
2310
|
+
where we sum over all permutations `\sigma \in S_n` such that
|
|
2311
|
+
the number of excedances of `\sigma` is `j`, and where
|
|
2312
|
+
`\mathrm{Dex}(\sigma)` is a composition of `n` defined as follows:
|
|
2313
|
+
Let `S` be the set of all `i \in \{ 1, 2, \ldots, n-1 \}` such
|
|
2314
|
+
that either `\sigma_i > \sigma_{i+1} > i+1` or
|
|
2315
|
+
`i \geq \sigma_i > \sigma_{i+1}` or
|
|
2316
|
+
`\sigma_{i+1} > i + 1 > \sigma_i`. Then,
|
|
2317
|
+
`\mathrm{Dex}(\sigma)` is set to be the composition of `n` whose
|
|
2318
|
+
descent set is `S`.
|
|
2319
|
+
|
|
2320
|
+
Here, an excedance of a permutation `\sigma \in S_n` means an
|
|
2321
|
+
element `i \in \{ 1, 2, \ldots, n-1 \}` satisfying `\sigma_i > i`.
|
|
2322
|
+
|
|
2323
|
+
Similarly we can define a quasisymmetric function `Q_{\lambda, j}`
|
|
2324
|
+
for every partition `\lambda` and every nonnegative integer `j`.
|
|
2325
|
+
This differs from `Q_{n,j}` only in that the sum is restricted to
|
|
2326
|
+
all permutations `\sigma \in S_n` whose cycle type is `\lambda`
|
|
2327
|
+
(where `n = |\lambda|`, and where we still require the number of
|
|
2328
|
+
excedances to be `j`). The method at hand allows computing these
|
|
2329
|
+
functions by passing `\lambda` as the ``n`` parameter.
|
|
2330
|
+
|
|
2331
|
+
Analogously we can define a quasisymmetric function `Q_{n,j,k}` for
|
|
2332
|
+
any nonnegative integers `n`, `j` and `k` by restricting the sum to
|
|
2333
|
+
all permutations `\sigma \in S_n` that have exactly `k` fixed
|
|
2334
|
+
points (and `j` excedances). This can be obtained by specifying the
|
|
2335
|
+
optional ``k`` argument in this method.
|
|
2336
|
+
|
|
2337
|
+
All three versions of Eulerian quasisymmetric functions
|
|
2338
|
+
(`Q_{n,j}`, `Q_{\lambda,j}` and `Q_{n,j,k}`) are actually
|
|
2339
|
+
symmetric functions. See
|
|
2340
|
+
:meth:`~sage.combinat.sf.SymmetricFunctionsBases.ParentMethods.Eulerian`.
|
|
2341
|
+
|
|
2342
|
+
INPUT:
|
|
2343
|
+
|
|
2344
|
+
- ``n`` -- the nonnegative integer `n` or a partition
|
|
2345
|
+
- ``j`` -- the number of excedances
|
|
2346
|
+
- ``k`` -- (optional) if specified, determines the number of fixed
|
|
2347
|
+
points of the permutations which are being summed over
|
|
2348
|
+
|
|
2349
|
+
EXAMPLES::
|
|
2350
|
+
|
|
2351
|
+
sage: F = QuasiSymmetricFunctions(QQ).F()
|
|
2352
|
+
sage: F.Eulerian(3, 1)
|
|
2353
|
+
F[1, 2] + F[2, 1] + 2*F[3]
|
|
2354
|
+
sage: F.Eulerian(4, 2)
|
|
2355
|
+
F[1, 2, 1] + 2*F[1, 3] + 3*F[2, 2] + 2*F[3, 1] + 3*F[4]
|
|
2356
|
+
sage: F.Eulerian(5, 2)
|
|
2357
|
+
F[1, 1, 2, 1] + F[1, 1, 3] + F[1, 2, 1, 1] + 7*F[1, 2, 2] + 6*F[1, 3, 1] + 6*F[1, 4] + 2*F[2, 1, 2] + 7*F[2, 2, 1] + 11*F[2, 3] + F[3, 1, 1] + 11*F[3, 2] + 6*F[4, 1] + 6*F[5]
|
|
2358
|
+
sage: F.Eulerian(4, 0)
|
|
2359
|
+
F[4]
|
|
2360
|
+
sage: F.Eulerian(4, 3)
|
|
2361
|
+
F[4]
|
|
2362
|
+
sage: F.Eulerian(4, 1, 2)
|
|
2363
|
+
F[1, 2, 1] + F[1, 3] + 2*F[2, 2] + F[3, 1] + F[4]
|
|
2364
|
+
sage: F.Eulerian(Partition([2, 2, 1]), 2)
|
|
2365
|
+
F[1, 1, 2, 1] + F[1, 2, 1, 1] + 2*F[1, 2, 2] + F[1, 3, 1]
|
|
2366
|
+
+ F[1, 4] + F[2, 1, 2] + 2*F[2, 2, 1] + 2*F[2, 3]
|
|
2367
|
+
+ 2*F[3, 2] + F[4, 1] + F[5]
|
|
2368
|
+
sage: F.Eulerian(0, 0)
|
|
2369
|
+
F[]
|
|
2370
|
+
sage: F.Eulerian(0, 1)
|
|
2371
|
+
0
|
|
2372
|
+
sage: F.Eulerian(1, 0)
|
|
2373
|
+
F[1]
|
|
2374
|
+
sage: F.Eulerian(1, 1)
|
|
2375
|
+
0
|
|
2376
|
+
|
|
2377
|
+
TESTS::
|
|
2378
|
+
|
|
2379
|
+
sage: F = QuasiSymmetricFunctions(QQ).F()
|
|
2380
|
+
sage: F.Eulerian(Partition([3, 1]), 1, 1)
|
|
2381
|
+
Traceback (most recent call last):
|
|
2382
|
+
...
|
|
2383
|
+
ValueError: invalid input, k cannot be specified
|
|
2384
|
+
"""
|
|
2385
|
+
from sage.combinat.partition import _Partitions
|
|
2386
|
+
if n in _Partitions:
|
|
2387
|
+
if k is not None:
|
|
2388
|
+
raise ValueError("invalid input, k cannot be specified")
|
|
2389
|
+
la = _Partitions(n)
|
|
2390
|
+
n = sum(la)
|
|
2391
|
+
else:
|
|
2392
|
+
la = None
|
|
2393
|
+
|
|
2394
|
+
if n == 0:
|
|
2395
|
+
if k is not None and k != 0:
|
|
2396
|
+
return self.zero()
|
|
2397
|
+
if j != 0:
|
|
2398
|
+
return self.zero()
|
|
2399
|
+
return self.one()
|
|
2400
|
+
|
|
2401
|
+
monomials = []
|
|
2402
|
+
for p in Permutations(n):
|
|
2403
|
+
dex = []
|
|
2404
|
+
exc = 0
|
|
2405
|
+
for i in range(n-1):
|
|
2406
|
+
if p[i] > i + 1:
|
|
2407
|
+
exc += 1
|
|
2408
|
+
if (p[i] > p[i+1] or (p[i] <= i+1 and p[i+1] > i+2)) \
|
|
2409
|
+
and not (p[i] > i+1 and p[i+1] <= i+2):
|
|
2410
|
+
dex.append(i)
|
|
2411
|
+
|
|
2412
|
+
if exc != j:
|
|
2413
|
+
continue
|
|
2414
|
+
if k is not None and p.number_of_fixed_points() != k:
|
|
2415
|
+
continue
|
|
2416
|
+
if la is not None and p.cycle_type() != la:
|
|
2417
|
+
continue
|
|
2418
|
+
|
|
2419
|
+
# Converting to a composition
|
|
2420
|
+
d = [-1] + dex + [n-1]
|
|
2421
|
+
monomials.append(Compositions()( [d[i+1]-d[i] for i in range(len(d)-1)] ))
|
|
2422
|
+
|
|
2423
|
+
return self.sum_of_monomials(monomials)
|
|
2424
|
+
|
|
2425
|
+
class Element(CombinatorialFreeModule.Element):
|
|
2426
|
+
|
|
2427
|
+
def internal_coproduct(self):
|
|
2428
|
+
r"""
|
|
2429
|
+
Return the inner coproduct of ``self`` in the Fundamental basis.
|
|
2430
|
+
|
|
2431
|
+
The inner coproduct (also known as the Kronecker coproduct,
|
|
2432
|
+
or as the second comultiplication on the `R`-algebra of
|
|
2433
|
+
quasi-symmetric functions) is an `R`-algebra homomorphism
|
|
2434
|
+
`\Delta^{\times}` from the `R`-algebra of quasi-symmetric
|
|
2435
|
+
functions to the tensor square (over `R`) of quasi-symmetric
|
|
2436
|
+
functions. It can be defined in the following two ways:
|
|
2437
|
+
|
|
2438
|
+
#. If `I` is a composition, then a `(0, I)`-matrix will mean a
|
|
2439
|
+
matrix whose entries are nonnegative integers such that no
|
|
2440
|
+
row and no column of this matrix is zero, and such that if
|
|
2441
|
+
all the nonzero entries of the matrix are read (row by row,
|
|
2442
|
+
starting at the topmost row, reading every row from left to
|
|
2443
|
+
right), then the reading word obtained is `I`. If `A` is
|
|
2444
|
+
a `(0, I)`-matrix, then `\mathrm{row}(A)` will denote the
|
|
2445
|
+
vector of row sums of `A` (regarded as a composition), and
|
|
2446
|
+
`\mathrm{column}(A)` will denote the vector of column sums
|
|
2447
|
+
of `A` (regarded as a composition).
|
|
2448
|
+
|
|
2449
|
+
For every composition `I`, the internal coproduct
|
|
2450
|
+
`\Delta^{\times}(M_I)` of the `I`-th monomial quasisymmetric
|
|
2451
|
+
function `M_I` is the sum
|
|
2452
|
+
|
|
2453
|
+
.. MATH::
|
|
2454
|
+
|
|
2455
|
+
\sum_{A \hbox{ is a } (0, I) \text{-matrix}}
|
|
2456
|
+
M_{\mathrm{row}(A)} \otimes M_{\mathrm{column}(A)}.
|
|
2457
|
+
|
|
2458
|
+
See Section 11.39 of [HazWitt1]_.
|
|
2459
|
+
|
|
2460
|
+
#. For every permutation `w`, let `C(w)` denote the descent
|
|
2461
|
+
composition of `w`. Then, for any composition `I` of size
|
|
2462
|
+
`n`, the internal coproduct `\Delta^{\times}(F_I)` of the
|
|
2463
|
+
`I`-th fundamental quasisymmetric function `F_I` is the sum
|
|
2464
|
+
|
|
2465
|
+
.. MATH::
|
|
2466
|
+
|
|
2467
|
+
\sum_{\substack{\sigma \in S_n,\\ \tau \in S_n,\\
|
|
2468
|
+
\tau \sigma = \pi}} F_{C(\sigma)} \otimes F_{C(\tau)},
|
|
2469
|
+
|
|
2470
|
+
where `\pi` is any permutation in `S_n` having descent
|
|
2471
|
+
composition `I` and where permutations act from the left and
|
|
2472
|
+
multiply accordingly, so `\tau \sigma` means first applying
|
|
2473
|
+
`\sigma` and then `\tau`. See Theorem 4.23 in [Mal1993]_,
|
|
2474
|
+
but beware of the notations which are apparently different
|
|
2475
|
+
from those in [HazWitt1]_.
|
|
2476
|
+
|
|
2477
|
+
The restriction of the internal coproduct to the
|
|
2478
|
+
`R`-algebra of symmetric functions is the well-known
|
|
2479
|
+
internal coproduct on the symmetric functions.
|
|
2480
|
+
|
|
2481
|
+
The method :meth:`kronecker_coproduct` is a synonym of this one.
|
|
2482
|
+
|
|
2483
|
+
EXAMPLES:
|
|
2484
|
+
|
|
2485
|
+
Let us compute the internal coproduct of `M_{21}` (which is
|
|
2486
|
+
short for `M_{[2, 1]}`). The `(0, [2,1])`-matrices are
|
|
2487
|
+
|
|
2488
|
+
.. MATH::
|
|
2489
|
+
|
|
2490
|
+
\begin{bmatrix}2& 1\end{bmatrix},
|
|
2491
|
+
\begin{bmatrix}2\\1\end{bmatrix},
|
|
2492
|
+
\begin{bmatrix}2& 0\\0& 1\end{bmatrix}, \hbox{ and }
|
|
2493
|
+
\begin{bmatrix}0&2\\1&0\end{bmatrix}
|
|
2494
|
+
|
|
2495
|
+
so
|
|
2496
|
+
|
|
2497
|
+
.. MATH::
|
|
2498
|
+
|
|
2499
|
+
\Delta^\times(M_{21}) = M_{3} \otimes M_{21} +
|
|
2500
|
+
M_{21} \otimes M_3 + M_{21} \otimes M_{21} +
|
|
2501
|
+
M_{21} \otimes M_{12}.
|
|
2502
|
+
|
|
2503
|
+
This is confirmed by the following Sage computation (incidentally
|
|
2504
|
+
demonstrating the non-cocommutativity of the internal
|
|
2505
|
+
coproduct)::
|
|
2506
|
+
|
|
2507
|
+
sage: M = QuasiSymmetricFunctions(ZZ).M()
|
|
2508
|
+
sage: a = M([2,1])
|
|
2509
|
+
sage: a.internal_coproduct()
|
|
2510
|
+
M[2, 1] # M[1, 2] + M[2, 1] # M[2, 1] + M[2, 1] # M[3] + M[3] # M[2, 1]
|
|
2511
|
+
|
|
2512
|
+
Some examples on the Fundamental basis::
|
|
2513
|
+
|
|
2514
|
+
sage: F = QuasiSymmetricFunctions(ZZ).F()
|
|
2515
|
+
sage: F([1,1]).internal_coproduct()
|
|
2516
|
+
F[1, 1] # F[2] + F[2] # F[1, 1]
|
|
2517
|
+
sage: F([2]).internal_coproduct()
|
|
2518
|
+
F[1, 1] # F[1, 1] + F[2] # F[2]
|
|
2519
|
+
sage: F([3]).internal_coproduct()
|
|
2520
|
+
F[1, 1, 1] # F[1, 1, 1] + F[1, 2] # F[1, 2] + F[1, 2] # F[2, 1]
|
|
2521
|
+
+ F[2, 1] # F[1, 2] + F[2, 1] # F[2, 1] + F[3] # F[3]
|
|
2522
|
+
sage: F([1,2]).internal_coproduct()
|
|
2523
|
+
F[1, 1, 1] # F[1, 2] + F[1, 2] # F[2, 1] + F[1, 2] # F[3]
|
|
2524
|
+
+ F[2, 1] # F[1, 1, 1] + F[2, 1] # F[2, 1] + F[3] # F[1, 2]
|
|
2525
|
+
"""
|
|
2526
|
+
F = self.parent()
|
|
2527
|
+
F2 = F.tensor(F)
|
|
2528
|
+
result = F2.zero()
|
|
2529
|
+
from sage.categories.tensor import tensor
|
|
2530
|
+
from sage.combinat.permutation import Permutation
|
|
2531
|
+
for I, a in self:
|
|
2532
|
+
# We must add a * \Delta^\times(F_I) to result.
|
|
2533
|
+
from sage.combinat.permutation import descents_composition_last
|
|
2534
|
+
pi = descents_composition_last(I)
|
|
2535
|
+
n = I.size()
|
|
2536
|
+
for sigma in Permutations(n):
|
|
2537
|
+
sigma_inverse = sigma.inverse()
|
|
2538
|
+
# If the __mul__ of permutations wasn't such a mess,
|
|
2539
|
+
# the next line could be as simple as
|
|
2540
|
+
# tau = pi * sigma_inverse.
|
|
2541
|
+
tau = Permutation([pi(i) for i in sigma_inverse])
|
|
2542
|
+
result += a * tensor([F(sigma.descents_composition()),
|
|
2543
|
+
F(tau.descents_composition())])
|
|
2544
|
+
return result
|
|
2545
|
+
|
|
2546
|
+
kronecker_coproduct = internal_coproduct
|
|
2547
|
+
|
|
2548
|
+
def star_involution(self):
|
|
2549
|
+
r"""
|
|
2550
|
+
Return the image of the quasisymmetric function ``self`` under
|
|
2551
|
+
the star involution.
|
|
2552
|
+
|
|
2553
|
+
The star involution is defined as the linear map
|
|
2554
|
+
`QSym \to QSym` which, for every composition `I`, sends the
|
|
2555
|
+
monomial quasisymmetric function `M_I` to `M_{I^r}`. Here, if
|
|
2556
|
+
`I` is a composition, we denote by `I^r` the reversed
|
|
2557
|
+
composition of `I`. Denoting by `f^{\ast}` the image of an
|
|
2558
|
+
element `f \in QSym` under the star involution, it can be shown
|
|
2559
|
+
that every composition `I` satisfies
|
|
2560
|
+
|
|
2561
|
+
.. MATH::
|
|
2562
|
+
|
|
2563
|
+
(M_I)^{\ast} = M_{I^r}, \quad (F_I)^{\ast} = F_{I^r},
|
|
2564
|
+
|
|
2565
|
+
where `F_I` denotes the fundamental quasisymmetric function
|
|
2566
|
+
corresponding to the composition `I`. The star involution is an
|
|
2567
|
+
involution, an algebra automorphism and a coalgebra
|
|
2568
|
+
anti-automorphism of `QSym`. It also is an automorphism of the
|
|
2569
|
+
graded vector space `QSym`, and is the identity on the subspace
|
|
2570
|
+
`Sym` of `QSym`. It is adjoint to the star involution on `NCSF`
|
|
2571
|
+
by the standard adjunction between `NCSF` and `QSym`.
|
|
2572
|
+
|
|
2573
|
+
The star involution has been denoted by `\rho` in [LMvW13]_,
|
|
2574
|
+
section 3.6.
|
|
2575
|
+
|
|
2576
|
+
.. SEEALSO::
|
|
2577
|
+
|
|
2578
|
+
:meth:`star involution on QSym
|
|
2579
|
+
<sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Bases.ElementMethods.star_involution>`,
|
|
2580
|
+
:meth:`star involution on NCSF
|
|
2581
|
+
<sage.combinat.ncsf_qsym.ncsf.NonCommutativeSymmetricFunctions.Bases.ElementMethods.star_involution>`.
|
|
2582
|
+
|
|
2583
|
+
EXAMPLES::
|
|
2584
|
+
|
|
2585
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
2586
|
+
sage: F = QSym.F()
|
|
2587
|
+
sage: F[3,1].star_involution()
|
|
2588
|
+
F[1, 3]
|
|
2589
|
+
sage: F[5,3].star_involution()
|
|
2590
|
+
F[3, 5]
|
|
2591
|
+
sage: (F[9,1] - F[6,2] + 2*F[6,4] - 3*F[3] + 4*F[[]]).star_involution()
|
|
2592
|
+
4*F[] + F[1, 9] - F[2, 6] - 3*F[3] + 2*F[4, 6]
|
|
2593
|
+
sage: (F[3,3] - 2*F[2]).star_involution()
|
|
2594
|
+
-2*F[2] + F[3, 3]
|
|
2595
|
+
sage: F([4,2]).star_involution()
|
|
2596
|
+
F[2, 4]
|
|
2597
|
+
sage: dI = QSym.dI()
|
|
2598
|
+
sage: dI([1,2]).star_involution()
|
|
2599
|
+
-dI[1, 2] + dI[2, 1]
|
|
2600
|
+
sage: dI.zero().star_involution()
|
|
2601
|
+
0
|
|
2602
|
+
"""
|
|
2603
|
+
parent = self.parent()
|
|
2604
|
+
dct = {I.reversed(): coeff for (I, coeff) in self}
|
|
2605
|
+
return parent._from_dict(dct)
|
|
2606
|
+
|
|
2607
|
+
F = Fundamental
|
|
2608
|
+
|
|
2609
|
+
class Essential(CombinatorialFreeModule, BindableClass):
|
|
2610
|
+
r"""
|
|
2611
|
+
The Hopf algebra of quasi-symmetric functions in the Essential basis.
|
|
2612
|
+
|
|
2613
|
+
The Essential quasi-symmetric functions are defined by
|
|
2614
|
+
|
|
2615
|
+
.. MATH::
|
|
2616
|
+
|
|
2617
|
+
E_I = \sum_{J \geq I} M_J = \sum_{i_1 \leq \cdots \leq i_k}
|
|
2618
|
+
x_{i_1}^{I_1} \cdots x_{i_k}^{I_k},
|
|
2619
|
+
|
|
2620
|
+
where `I = (I_1, \ldots, I_k)`.
|
|
2621
|
+
|
|
2622
|
+
.. NOTE::
|
|
2623
|
+
|
|
2624
|
+
Our convention of `\leq` and `\geq` of compositions is
|
|
2625
|
+
opposite that of [Hoff2015]_.
|
|
2626
|
+
|
|
2627
|
+
EXAMPLES::
|
|
2628
|
+
|
|
2629
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2630
|
+
sage: E = QSym.E()
|
|
2631
|
+
sage: M = QSym.M()
|
|
2632
|
+
sage: E(M[2,2])
|
|
2633
|
+
E[2, 2] - E[4]
|
|
2634
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
2635
|
+
sage: E(s[3,2])
|
|
2636
|
+
5*E[1, 1, 1, 1, 1] - 2*E[1, 1, 1, 2] - 2*E[1, 1, 2, 1]
|
|
2637
|
+
- 2*E[1, 2, 1, 1] + E[1, 2, 2] - 2*E[2, 1, 1, 1]
|
|
2638
|
+
+ E[2, 1, 2] + E[2, 2, 1]
|
|
2639
|
+
sage: (1 + E[1])^3
|
|
2640
|
+
E[] + 3*E[1] + 6*E[1, 1] + 6*E[1, 1, 1] - 3*E[1, 2]
|
|
2641
|
+
- 3*E[2] - 3*E[2, 1] + E[3]
|
|
2642
|
+
sage: E[1,2,1].coproduct()
|
|
2643
|
+
E[] # E[1, 2, 1] + E[1] # E[2, 1] + E[1, 2] # E[1] + E[1, 2, 1] # E[]
|
|
2644
|
+
|
|
2645
|
+
The following is an alias for this basis::
|
|
2646
|
+
|
|
2647
|
+
sage: QSym.Essential()
|
|
2648
|
+
Quasisymmetric functions over the Rational Field in the Essential basis
|
|
2649
|
+
|
|
2650
|
+
TESTS::
|
|
2651
|
+
|
|
2652
|
+
sage: E(M([]))
|
|
2653
|
+
E[]
|
|
2654
|
+
sage: E(M(0))
|
|
2655
|
+
0
|
|
2656
|
+
sage: E(s([]))
|
|
2657
|
+
E[]
|
|
2658
|
+
sage: E(s(0))
|
|
2659
|
+
0
|
|
2660
|
+
"""
|
|
2661
|
+
|
|
2662
|
+
def __init__(self, QSym):
|
|
2663
|
+
"""
|
|
2664
|
+
EXAMPLES::
|
|
2665
|
+
|
|
2666
|
+
sage: E = QuasiSymmetricFunctions(QQ).Essential()
|
|
2667
|
+
sage: TestSuite(E).run()
|
|
2668
|
+
|
|
2669
|
+
TESTS::
|
|
2670
|
+
|
|
2671
|
+
sage: E = QuasiSymmetricFunctions(QQ).E()
|
|
2672
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
2673
|
+
sage: all(E(M(E[c])) == E[c] for n in range(5)
|
|
2674
|
+
....: for c in Compositions(n))
|
|
2675
|
+
True
|
|
2676
|
+
sage: all(M(E(M[c])) == M[c] for n in range(5)
|
|
2677
|
+
....: for c in Compositions(n))
|
|
2678
|
+
True
|
|
2679
|
+
"""
|
|
2680
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
2681
|
+
prefix='E', bracket=False,
|
|
2682
|
+
category=QSym.Bases())
|
|
2683
|
+
|
|
2684
|
+
M = QSym.M()
|
|
2685
|
+
category = self.realization_of()._category
|
|
2686
|
+
# This changes Monomial into Essential
|
|
2687
|
+
M.module_morphism(self.alternating_sum_of_fatter_compositions,
|
|
2688
|
+
codomain=self, category=category
|
|
2689
|
+
).register_as_coercion()
|
|
2690
|
+
# This changes Essential into Monomial
|
|
2691
|
+
self.module_morphism(M.sum_of_fatter_compositions,
|
|
2692
|
+
codomain=M, category=category
|
|
2693
|
+
).register_as_coercion()
|
|
2694
|
+
|
|
2695
|
+
def antipode_on_basis(self, compo):
|
|
2696
|
+
r"""
|
|
2697
|
+
Return the result of the antipode applied to a quasi-symmetric
|
|
2698
|
+
Essential basis element.
|
|
2699
|
+
|
|
2700
|
+
INPUT:
|
|
2701
|
+
|
|
2702
|
+
- ``compo`` -- composition
|
|
2703
|
+
|
|
2704
|
+
OUTPUT:
|
|
2705
|
+
|
|
2706
|
+
- The result of the antipode applied to the composition ``compo``,
|
|
2707
|
+
expressed in the Essential basis.
|
|
2708
|
+
|
|
2709
|
+
EXAMPLES::
|
|
2710
|
+
|
|
2711
|
+
sage: E = QuasiSymmetricFunctions(QQ).E()
|
|
2712
|
+
sage: E.antipode_on_basis(Composition([2,1]))
|
|
2713
|
+
E[1, 2] - E[3]
|
|
2714
|
+
sage: E.antipode_on_basis(Composition([]))
|
|
2715
|
+
E[]
|
|
2716
|
+
|
|
2717
|
+
TESTS::
|
|
2718
|
+
|
|
2719
|
+
sage: E = QuasiSymmetricFunctions(QQ).E()
|
|
2720
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
2721
|
+
sage: all(E(M(E[c]).antipode()) == E[c].antipode()
|
|
2722
|
+
....: for n in range(5) for c in Compositions(n))
|
|
2723
|
+
True
|
|
2724
|
+
|
|
2725
|
+
sage: all((-1)**len(I) * E[I] == M[I].star_involution().antipode()
|
|
2726
|
+
....: for k in [3,4] for I in Compositions(k))
|
|
2727
|
+
True
|
|
2728
|
+
"""
|
|
2729
|
+
return (-1)**len(compo) * self.alternating_sum_of_fatter_compositions(compo.reversed())
|
|
2730
|
+
|
|
2731
|
+
def coproduct_on_basis(self, compo):
|
|
2732
|
+
r"""
|
|
2733
|
+
Return the coproduct of a Essential basis element.
|
|
2734
|
+
|
|
2735
|
+
Combinatorial rule: deconcatenation.
|
|
2736
|
+
|
|
2737
|
+
INPUT:
|
|
2738
|
+
|
|
2739
|
+
- ``compo`` -- composition
|
|
2740
|
+
|
|
2741
|
+
OUTPUT:
|
|
2742
|
+
|
|
2743
|
+
- The coproduct applied to the Essential quasi-symmetric function
|
|
2744
|
+
indexed by ``compo``, expressed in the Essential basis.
|
|
2745
|
+
|
|
2746
|
+
EXAMPLES::
|
|
2747
|
+
|
|
2748
|
+
sage: E = QuasiSymmetricFunctions(QQ).Essential()
|
|
2749
|
+
sage: E[4,2,3].coproduct()
|
|
2750
|
+
E[] # E[4, 2, 3] + E[4] # E[2, 3] + E[4, 2] # E[3] + E[4, 2, 3] # E[]
|
|
2751
|
+
sage: E.coproduct_on_basis(Composition([]))
|
|
2752
|
+
E[] # E[]
|
|
2753
|
+
"""
|
|
2754
|
+
return self.tensor_square().sum_of_monomials((self._indices(compo[:i]),
|
|
2755
|
+
self._indices(compo[i:]))
|
|
2756
|
+
for i in range(len(compo)+1))
|
|
2757
|
+
|
|
2758
|
+
def product_on_basis(self, I, J):
|
|
2759
|
+
r"""
|
|
2760
|
+
The product on Essential basis elements.
|
|
2761
|
+
|
|
2762
|
+
The product of the basis elements indexed by two compositions
|
|
2763
|
+
`I` and `J` is the sum of the basis elements indexed by
|
|
2764
|
+
compositions `K` in the stuffle product (also called the
|
|
2765
|
+
overlapping shuffle product) of `I` and `J` with a
|
|
2766
|
+
coefficient of `(-1)^{\ell(I) + \ell(J) - \ell(K)}`,
|
|
2767
|
+
where `\ell(C)` is the length of the composition `C`.
|
|
2768
|
+
|
|
2769
|
+
INPUT:
|
|
2770
|
+
|
|
2771
|
+
- ``I``, ``J`` -- compositions
|
|
2772
|
+
|
|
2773
|
+
OUTPUT:
|
|
2774
|
+
|
|
2775
|
+
- The product of the Essential quasi-symmetric functions indexed
|
|
2776
|
+
by ``I`` and ``J``, expressed in the Essential basis.
|
|
2777
|
+
|
|
2778
|
+
EXAMPLES::
|
|
2779
|
+
|
|
2780
|
+
sage: E = QuasiSymmetricFunctions(QQ).E()
|
|
2781
|
+
sage: c1 = Composition([2])
|
|
2782
|
+
sage: c2 = Composition([1,3])
|
|
2783
|
+
sage: E.product_on_basis(c1, c2)
|
|
2784
|
+
E[1, 2, 3] + E[1, 3, 2] - E[1, 5] + E[2, 1, 3] - E[3, 3]
|
|
2785
|
+
sage: E.product_on_basis(c1, Composition([]))
|
|
2786
|
+
E[2]
|
|
2787
|
+
sage: E.product_on_basis(c1, Composition([3]))
|
|
2788
|
+
E[2, 3] + E[3, 2] - E[5]
|
|
2789
|
+
|
|
2790
|
+
TESTS::
|
|
2791
|
+
|
|
2792
|
+
sage: E = QuasiSymmetricFunctions(QQ).E()
|
|
2793
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
2794
|
+
sage: all(E(M(E[cp])*M(E[c])) == E[cp]*E[c] # long time
|
|
2795
|
+
....: for c in Compositions(3) for cp in Compositions(5))
|
|
2796
|
+
True
|
|
2797
|
+
"""
|
|
2798
|
+
n = len(I) + len(J)
|
|
2799
|
+
return self.sum_of_terms((K, (-1)**(n - len(K)))
|
|
2800
|
+
for K in I.shuffle_product(J, overlap=True))
|
|
2801
|
+
|
|
2802
|
+
E = Essential
|
|
2803
|
+
|
|
2804
|
+
class Quasisymmetric_Schur(CombinatorialFreeModule, BindableClass):
|
|
2805
|
+
r"""
|
|
2806
|
+
The Hopf algebra of quasi-symmetric function in the Quasisymmetric
|
|
2807
|
+
Schur basis.
|
|
2808
|
+
|
|
2809
|
+
The basis of Quasisymmetric Schur functions is defined in [QSCHUR]_
|
|
2810
|
+
and in Definition 5.1.1 of [LMvW13]_.
|
|
2811
|
+
Don't mistake them for the completely unrelated quasi-Schur
|
|
2812
|
+
functions of [NCSF1]_!
|
|
2813
|
+
|
|
2814
|
+
EXAMPLES::
|
|
2815
|
+
|
|
2816
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2817
|
+
sage: QS = QSym.QS()
|
|
2818
|
+
sage: F = QSym.F()
|
|
2819
|
+
sage: M = QSym.M()
|
|
2820
|
+
sage: F(QS[1,2])
|
|
2821
|
+
F[1, 2]
|
|
2822
|
+
sage: M(QS[1,2])
|
|
2823
|
+
M[1, 1, 1] + M[1, 2]
|
|
2824
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
2825
|
+
sage: QS(s[2,1,1])
|
|
2826
|
+
QS[1, 1, 2] + QS[1, 2, 1] + QS[2, 1, 1]
|
|
2827
|
+
"""
|
|
2828
|
+
|
|
2829
|
+
def __init__(self, QSym):
|
|
2830
|
+
r"""
|
|
2831
|
+
EXAMPLES::
|
|
2832
|
+
|
|
2833
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2834
|
+
sage: F = QSym.Fundamental()
|
|
2835
|
+
sage: QS = QSym.Quasisymmetric_Schur()
|
|
2836
|
+
sage: QS(F(QS.an_element())) == QS.an_element()
|
|
2837
|
+
True
|
|
2838
|
+
sage: F(QS(F.an_element())) == F.an_element()
|
|
2839
|
+
True
|
|
2840
|
+
sage: M = QSym.Monomial()
|
|
2841
|
+
sage: QS(M(QS.an_element())) == QS.an_element()
|
|
2842
|
+
True
|
|
2843
|
+
sage: M(QS(M.an_element())) == M.an_element()
|
|
2844
|
+
True
|
|
2845
|
+
sage: TestSuite(QS).run() # long time
|
|
2846
|
+
"""
|
|
2847
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
2848
|
+
prefix='QS', bracket=False,
|
|
2849
|
+
category=QSym.Bases())
|
|
2850
|
+
|
|
2851
|
+
def _realization_name(self):
|
|
2852
|
+
r"""
|
|
2853
|
+
Return a nicer name for ``self`` than what is inherited
|
|
2854
|
+
from :mod:`sage.categories.sets_cat`.
|
|
2855
|
+
|
|
2856
|
+
EXAMPLES::
|
|
2857
|
+
|
|
2858
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2859
|
+
sage: QS = QSym.QS()
|
|
2860
|
+
sage: QS._realization_name()
|
|
2861
|
+
'Quasisymmetric Schur'
|
|
2862
|
+
"""
|
|
2863
|
+
return "Quasisymmetric Schur"
|
|
2864
|
+
|
|
2865
|
+
@cached_method
|
|
2866
|
+
def _from_monomial_transition_matrix(self, n):
|
|
2867
|
+
r"""
|
|
2868
|
+
A matrix representing the transition coefficients to
|
|
2869
|
+
the complete basis and the ordering of compositions.
|
|
2870
|
+
|
|
2871
|
+
INPUT:
|
|
2872
|
+
|
|
2873
|
+
- ``n`` -- integer
|
|
2874
|
+
|
|
2875
|
+
OUTPUT: a pair of a square matrix and the ordered list of compositions
|
|
2876
|
+
|
|
2877
|
+
EXAMPLES::
|
|
2878
|
+
|
|
2879
|
+
sage: QS = QuasiSymmetricFunctions(QQ).QS()
|
|
2880
|
+
sage: QS._from_monomial_transition_matrix(4)[0]
|
|
2881
|
+
[ 1 -1 -1 0 1 1 1 -1]
|
|
2882
|
+
[ 0 1 0 0 -1 -1 0 1]
|
|
2883
|
+
[ 0 0 1 -1 0 0 -1 1]
|
|
2884
|
+
[ 0 0 0 1 -1 -1 -1 1]
|
|
2885
|
+
[ 0 0 0 0 1 0 0 -1]
|
|
2886
|
+
[ 0 0 0 0 0 1 0 -1]
|
|
2887
|
+
[ 0 0 0 0 0 0 1 -1]
|
|
2888
|
+
[ 0 0 0 0 0 0 0 1]
|
|
2889
|
+
"""
|
|
2890
|
+
if n == 0:
|
|
2891
|
+
return (matrix([[]]), [])
|
|
2892
|
+
CO = compositions_order(n)
|
|
2893
|
+
# ZZ is faster than over QQ for inverting a matrix
|
|
2894
|
+
from sage.rings.integer_ring import ZZ
|
|
2895
|
+
MS = MatrixSpace(ZZ, len(CO))
|
|
2896
|
+
M = MS([[number_of_SSRCT(al, be) for al in CO] for be in CO])
|
|
2897
|
+
return (M.inverse_of_unit(), CO)
|
|
2898
|
+
|
|
2899
|
+
@cached_method
|
|
2900
|
+
def _from_monomial_on_basis(self, comp):
|
|
2901
|
+
r"""
|
|
2902
|
+
Map the Monomial quasi-symmetric function indexed by
|
|
2903
|
+
``comp`` to the Quasisymmetric Schur basis.
|
|
2904
|
+
|
|
2905
|
+
INPUT:
|
|
2906
|
+
|
|
2907
|
+
- ``comp`` -- a composition
|
|
2908
|
+
|
|
2909
|
+
OUTPUT: a quasi-symmetric function in the Quasisymmetric Schur basis
|
|
2910
|
+
|
|
2911
|
+
EXAMPLES::
|
|
2912
|
+
|
|
2913
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2914
|
+
sage: QS = QSym.QS()
|
|
2915
|
+
sage: M = QSym.M()
|
|
2916
|
+
sage: QS._from_monomial_on_basis(Composition([1,3,1]))
|
|
2917
|
+
QS[1, 1, 1, 1, 1] - QS[1, 1, 2, 1] + QS[1, 3, 1] - QS[2, 2, 1]
|
|
2918
|
+
sage: QS._from_monomial_on_basis(Composition([2]))
|
|
2919
|
+
-QS[1, 1] + QS[2]
|
|
2920
|
+
"""
|
|
2921
|
+
comp = Composition(comp)
|
|
2922
|
+
if not comp._list:
|
|
2923
|
+
return self.one()
|
|
2924
|
+
T, comps = self._from_monomial_transition_matrix(comp.size())
|
|
2925
|
+
i = comps.index(comp)
|
|
2926
|
+
return self._from_dict({c: T[i,j] for j,c in enumerate(comps)
|
|
2927
|
+
if T[i,j] != 0},
|
|
2928
|
+
remove_zeros=False)
|
|
2929
|
+
|
|
2930
|
+
@cached_method
|
|
2931
|
+
def _to_monomial_on_basis(self, comp_shape):
|
|
2932
|
+
r"""
|
|
2933
|
+
Expand the quasi-symmetric Schur function in the Monomial basis.
|
|
2934
|
+
|
|
2935
|
+
The expansion of the quasi-symmetric Schur function indexed
|
|
2936
|
+
by ``comp_shape`` has coefficients which are given by the method
|
|
2937
|
+
:meth:`~sage.combinat.ncsf_qsym.combinatorics.number_of_SSRCT`.
|
|
2938
|
+
|
|
2939
|
+
INPUT:
|
|
2940
|
+
|
|
2941
|
+
- ``comp_shape`` -- a composition
|
|
2942
|
+
|
|
2943
|
+
OUTPUT: a quasi-symmetric function in the Monomial basis
|
|
2944
|
+
|
|
2945
|
+
EXAMPLES::
|
|
2946
|
+
|
|
2947
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2948
|
+
sage: QS = QSym.QS()
|
|
2949
|
+
sage: QS._to_monomial_on_basis(Composition([1,3,1]))
|
|
2950
|
+
2*M[1, 1, 1, 1, 1] + 2*M[1, 1, 2, 1] + M[1, 2, 1, 1] + M[1, 3, 1] + M[2, 1, 1, 1] + M[2, 2, 1]
|
|
2951
|
+
"""
|
|
2952
|
+
M = self.realization_of().Monomial()
|
|
2953
|
+
if not comp_shape:
|
|
2954
|
+
return M([])
|
|
2955
|
+
return M.sum_of_terms(((comp_content,
|
|
2956
|
+
number_of_SSRCT(comp_content, comp_shape))
|
|
2957
|
+
for comp_content in Compositions(sum(comp_shape))),
|
|
2958
|
+
distinct=True )
|
|
2959
|
+
|
|
2960
|
+
def dual(self):
|
|
2961
|
+
r"""
|
|
2962
|
+
The dual basis to the Quasisymmetric Schur basis.
|
|
2963
|
+
|
|
2964
|
+
The dual basis to the Quasisymmetric Schur basis is
|
|
2965
|
+
implemented as dual.
|
|
2966
|
+
|
|
2967
|
+
OUTPUT:
|
|
2968
|
+
|
|
2969
|
+
- the dual Quasisymmetric Schur basis of the
|
|
2970
|
+
non-commutative symmetric functions
|
|
2971
|
+
|
|
2972
|
+
EXAMPLES::
|
|
2973
|
+
|
|
2974
|
+
sage: QS = QuasiSymmetricFunctions(QQ).Quasisymmetric_Schur()
|
|
2975
|
+
sage: QS.dual()
|
|
2976
|
+
Non-Commutative Symmetric Functions over the Rational Field
|
|
2977
|
+
in the dual Quasisymmetric-Schur basis
|
|
2978
|
+
"""
|
|
2979
|
+
return self.realization_of().dual().dualQuasisymmetric_Schur()
|
|
2980
|
+
|
|
2981
|
+
QS = Quasisymmetric_Schur
|
|
2982
|
+
|
|
2983
|
+
class Young_Quasisymmetric_Schur(CombinatorialFreeModule, BindableClass):
|
|
2984
|
+
r"""
|
|
2985
|
+
The Hopf algebra of quasi-symmetric functions in the Young
|
|
2986
|
+
Quasisymmetric Schur basis.
|
|
2987
|
+
|
|
2988
|
+
The basis of Young Quasisymmetric Schur functions is from
|
|
2989
|
+
Definition 5.2.1 of [LMvW13]_.
|
|
2990
|
+
|
|
2991
|
+
This basis is related to the Quasisymmetric Schur basis ``QS`` by
|
|
2992
|
+
``QS(alpha.reversed()) == YQS(alpha).star_involution()`` .
|
|
2993
|
+
|
|
2994
|
+
EXAMPLES::
|
|
2995
|
+
|
|
2996
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
2997
|
+
sage: YQS = QSym.YQS()
|
|
2998
|
+
sage: F = QSym.F()
|
|
2999
|
+
sage: QS = QSym.QS()
|
|
3000
|
+
sage: F(YQS[1,2])
|
|
3001
|
+
F[1, 2]
|
|
3002
|
+
sage: all(QS(al.reversed())==YQS(al).star_involution() for al in Compositions(5))
|
|
3003
|
+
True
|
|
3004
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
3005
|
+
sage: YQS(s[2,1,1])
|
|
3006
|
+
YQS[1, 1, 2] + YQS[1, 2, 1] + YQS[2, 1, 1]
|
|
3007
|
+
"""
|
|
3008
|
+
|
|
3009
|
+
def __init__(self, QSym):
|
|
3010
|
+
r"""
|
|
3011
|
+
Initialize ``self``.
|
|
3012
|
+
|
|
3013
|
+
EXAMPLES::
|
|
3014
|
+
|
|
3015
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3016
|
+
sage: F = QSym.Fundamental()
|
|
3017
|
+
sage: YQS = QSym.Young_Quasisymmetric_Schur()
|
|
3018
|
+
sage: YQS(F(YQS.an_element())) == YQS.an_element()
|
|
3019
|
+
True
|
|
3020
|
+
sage: F(YQS(F.an_element())) == F.an_element()
|
|
3021
|
+
True
|
|
3022
|
+
sage: M = QSym.Monomial()
|
|
3023
|
+
sage: YQS(M(YQS.an_element())) == YQS.an_element()
|
|
3024
|
+
True
|
|
3025
|
+
sage: M(YQS(M.an_element())) == M.an_element()
|
|
3026
|
+
True
|
|
3027
|
+
sage: TestSuite(YQS).run() # long time
|
|
3028
|
+
"""
|
|
3029
|
+
self._QS = QSym.QS()
|
|
3030
|
+
self._M = QSym.M()
|
|
3031
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(),
|
|
3032
|
+
Compositions(), prefix='YQS',
|
|
3033
|
+
bracket=False, category=QSym.Bases())
|
|
3034
|
+
self.module_morphism(self._to_monomial_on_basis,
|
|
3035
|
+
codomain=self._M, category=QSym.Bases()).register_as_coercion()
|
|
3036
|
+
self._M.module_morphism(self._from_monomial_on_basis,
|
|
3037
|
+
codomain=self, category=QSym.Bases()).register_as_coercion()
|
|
3038
|
+
|
|
3039
|
+
def _realization_name(self):
|
|
3040
|
+
r"""
|
|
3041
|
+
Return a nicer name for ``self`` than what is inherited
|
|
3042
|
+
from :mod:`sage.categories.sets_cat`.
|
|
3043
|
+
|
|
3044
|
+
EXAMPLES::
|
|
3045
|
+
|
|
3046
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3047
|
+
sage: QS = QSym.QS()
|
|
3048
|
+
sage: QS._realization_name()
|
|
3049
|
+
'Quasisymmetric Schur'
|
|
3050
|
+
"""
|
|
3051
|
+
return "Young Quasisymmetric Schur"
|
|
3052
|
+
|
|
3053
|
+
@cached_method
|
|
3054
|
+
def _to_monomial_on_basis(self, comp):
|
|
3055
|
+
r"""
|
|
3056
|
+
Expand the Young quasi-symmetric Schur function in the
|
|
3057
|
+
Monomial basis.
|
|
3058
|
+
|
|
3059
|
+
INPUT:
|
|
3060
|
+
|
|
3061
|
+
- ``comp`` -- a composition
|
|
3062
|
+
|
|
3063
|
+
OUTPUT: a quasi-symmetric function in the Monomial basis
|
|
3064
|
+
|
|
3065
|
+
EXAMPLES::
|
|
3066
|
+
|
|
3067
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3068
|
+
sage: YQS = QSym.QS()
|
|
3069
|
+
sage: YQS._to_monomial_on_basis(Composition([2]))
|
|
3070
|
+
M[1, 1] + M[2]
|
|
3071
|
+
sage: YQS._to_monomial_on_basis(Composition([1,3,1]))
|
|
3072
|
+
2*M[1, 1, 1, 1, 1] + 2*M[1, 1, 2, 1] + M[1, 2, 1, 1] + M[1, 3, 1] + M[2, 1, 1, 1] + M[2, 2, 1]
|
|
3073
|
+
"""
|
|
3074
|
+
return self._M(self._QS.monomial(comp.reversed())).star_involution()
|
|
3075
|
+
|
|
3076
|
+
@cached_method
|
|
3077
|
+
def _from_monomial_on_basis(self, comp):
|
|
3078
|
+
r"""
|
|
3079
|
+
The expansion of the quasi-symmetric Schur function indexed
|
|
3080
|
+
by ``comp_shape`` has coefficients which are given by the method
|
|
3081
|
+
:meth:`~sage.combinat.ncsf_qsym.combinatorics.number_of_SSRCT`.
|
|
3082
|
+
|
|
3083
|
+
INPUT:
|
|
3084
|
+
|
|
3085
|
+
- ``comp`` -- a composition
|
|
3086
|
+
|
|
3087
|
+
OUTPUT: a quasi-symmetric function in the Young Quasisymmetric Schur basis
|
|
3088
|
+
|
|
3089
|
+
EXAMPLES::
|
|
3090
|
+
|
|
3091
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3092
|
+
sage: YQS = QSym.YQS()
|
|
3093
|
+
sage: YQS._from_monomial_on_basis(Composition([2]))
|
|
3094
|
+
-YQS[1, 1] + YQS[2]
|
|
3095
|
+
sage: YQS._from_monomial_on_basis(Composition([1,3,1]))
|
|
3096
|
+
YQS[1, 1, 1, 1, 1] - YQS[1, 2, 1, 1] - YQS[1, 2, 2] + YQS[1, 3, 1]
|
|
3097
|
+
"""
|
|
3098
|
+
elt = self._QS(self._M.monomial(comp.reversed()))
|
|
3099
|
+
return self._from_dict({al.reversed(): c for al,c in elt},
|
|
3100
|
+
coerce=False, remove_zeros=False)
|
|
3101
|
+
|
|
3102
|
+
YQS = Young_Quasisymmetric_Schur
|
|
3103
|
+
|
|
3104
|
+
class dualImmaculate(CombinatorialFreeModule, BindableClass):
|
|
3105
|
+
def __init__(self, QSym):
|
|
3106
|
+
r"""
|
|
3107
|
+
The dual immaculate basis of the quasi-symmetric functions.
|
|
3108
|
+
|
|
3109
|
+
This basis first appears in [BBSSZ2012]_.
|
|
3110
|
+
|
|
3111
|
+
EXAMPLES::
|
|
3112
|
+
|
|
3113
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3114
|
+
sage: dI = QSym.dI()
|
|
3115
|
+
sage: dI([1,3,2])*dI([1]) # long time (6s on sage.math, 2013)
|
|
3116
|
+
dI[1, 1, 3, 2] + dI[2, 3, 2]
|
|
3117
|
+
sage: dI([1,3])*dI([1,1])
|
|
3118
|
+
dI[1, 1, 1, 3] + dI[1, 1, 4] + dI[1, 2, 3] - dI[1, 3, 2] - dI[1, 4, 1] - dI[1, 5] + dI[2, 3, 1] + dI[2, 4]
|
|
3119
|
+
sage: dI([3,1])*dI([2,1]) # long time (7s on sage.math, 2013)
|
|
3120
|
+
dI[1, 1, 5] - dI[1, 4, 1, 1] - dI[1, 4, 2] - 2*dI[1, 5, 1] - dI[1, 6] - dI[2, 4, 1] - dI[2, 5] - dI[3, 1, 3] + dI[3, 2, 1, 1] + dI[3, 2, 2] + dI[3, 3, 1] + dI[4, 1, 1, 1] + 2*dI[4, 2, 1] + dI[4, 3] + dI[5, 1, 1] + dI[5, 2]
|
|
3121
|
+
sage: F = QSym.F()
|
|
3122
|
+
sage: dI(F[1,3,1])
|
|
3123
|
+
-dI[1, 1, 1, 2] + dI[1, 1, 2, 1] - dI[1, 2, 2] + dI[1, 3, 1]
|
|
3124
|
+
sage: F(dI(F([2,1,3])))
|
|
3125
|
+
F[2, 1, 3]
|
|
3126
|
+
"""
|
|
3127
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
3128
|
+
prefix='dI', bracket=False,
|
|
3129
|
+
category=QSym.Bases())
|
|
3130
|
+
|
|
3131
|
+
def _to_Monomial_on_basis(self, J):
|
|
3132
|
+
r"""
|
|
3133
|
+
Expand the dual immaculate function labelled by a composition
|
|
3134
|
+
``J`` in the quasi-symmetric monomial basis.
|
|
3135
|
+
|
|
3136
|
+
INPUT:
|
|
3137
|
+
|
|
3138
|
+
- ``J`` -- a composition
|
|
3139
|
+
|
|
3140
|
+
OUTPUT: a quasi-symmetric function in the monomial basis
|
|
3141
|
+
|
|
3142
|
+
EXAMPLES::
|
|
3143
|
+
|
|
3144
|
+
sage: dI = QuasiSymmetricFunctions(QQ).dI()
|
|
3145
|
+
sage: dI._to_Monomial_on_basis(Composition([1,3]))
|
|
3146
|
+
M[1, 1, 1, 1] + M[1, 1, 2] + M[1, 2, 1] + M[1, 3]
|
|
3147
|
+
sage: dI._to_Monomial_on_basis(Composition([]))
|
|
3148
|
+
M[]
|
|
3149
|
+
sage: dI._to_Monomial_on_basis(Composition([2,1,2]))
|
|
3150
|
+
4*M[1, 1, 1, 1, 1] + 3*M[1, 1, 1, 2] + 2*M[1, 1, 2, 1] + M[1, 1, 3] + M[1, 2, 1, 1] + M[1, 2, 2] + M[2, 1, 1, 1] + M[2, 1, 2]
|
|
3151
|
+
"""
|
|
3152
|
+
M = self.realization_of().Monomial()
|
|
3153
|
+
if not J._list:
|
|
3154
|
+
return M([])
|
|
3155
|
+
C = Compositions()
|
|
3156
|
+
C_size = Compositions(J.size())
|
|
3157
|
+
return M.sum_of_terms( ( (C(I), number_of_fCT(C(I), J)) for I in C_size ),
|
|
3158
|
+
distinct=True )
|
|
3159
|
+
|
|
3160
|
+
@cached_method
|
|
3161
|
+
def _matrix_monomial_to_dual_immaculate(self, n):
|
|
3162
|
+
r"""
|
|
3163
|
+
This function caches the change of basis matrix from the
|
|
3164
|
+
quasisymmetric monomial basis to the dual immaculate basis.
|
|
3165
|
+
|
|
3166
|
+
INPUT:
|
|
3167
|
+
|
|
3168
|
+
- ``J`` -- a composition
|
|
3169
|
+
|
|
3170
|
+
OUTPUT:
|
|
3171
|
+
|
|
3172
|
+
- A list. Each entry in the list is a row in the
|
|
3173
|
+
change-of-basis matrix.
|
|
3174
|
+
|
|
3175
|
+
EXAMPLES::
|
|
3176
|
+
|
|
3177
|
+
sage: dI = QuasiSymmetricFunctions(QQ).dI()
|
|
3178
|
+
sage: dI._matrix_monomial_to_dual_immaculate(3)
|
|
3179
|
+
[[1, -1, -1, 1], [0, 1, -1, 0], [0, 0, 1, -1], [0, 0, 0, 1]]
|
|
3180
|
+
sage: dI._matrix_monomial_to_dual_immaculate(0)
|
|
3181
|
+
[[1]]
|
|
3182
|
+
"""
|
|
3183
|
+
N = NonCommutativeSymmetricFunctions(self.base_ring())
|
|
3184
|
+
I = N.I()
|
|
3185
|
+
S = N.S()
|
|
3186
|
+
mat = []
|
|
3187
|
+
C = Compositions()
|
|
3188
|
+
C_n = Compositions(n)
|
|
3189
|
+
for alp in C_n:
|
|
3190
|
+
row = []
|
|
3191
|
+
expansion = S(I(C(alp)))
|
|
3192
|
+
for bet in C_n:
|
|
3193
|
+
row.append(expansion.coefficient(C(bet)))
|
|
3194
|
+
mat.append(row)
|
|
3195
|
+
return mat
|
|
3196
|
+
|
|
3197
|
+
def _from_Monomial_on_basis(self, J):
|
|
3198
|
+
r"""
|
|
3199
|
+
Expand the monomial quasi-symmetric function labelled by the
|
|
3200
|
+
composition ``J`` in the dual immaculate basis.
|
|
3201
|
+
|
|
3202
|
+
INPUT:
|
|
3203
|
+
|
|
3204
|
+
- ``J`` -- a composition
|
|
3205
|
+
|
|
3206
|
+
OUTPUT: a quasi-symmetric function in the dual immaculate basis
|
|
3207
|
+
|
|
3208
|
+
EXAMPLES::
|
|
3209
|
+
|
|
3210
|
+
sage: dI = QuasiSymmetricFunctions(QQ).dI()
|
|
3211
|
+
sage: dI._from_Monomial_on_basis(Composition([]))
|
|
3212
|
+
dI[]
|
|
3213
|
+
sage: dI._from_Monomial_on_basis(Composition([2,1]))
|
|
3214
|
+
-dI[1, 1, 1] - dI[1, 2] + dI[2, 1]
|
|
3215
|
+
sage: dI._from_Monomial_on_basis(Composition([3,1,2]))
|
|
3216
|
+
-dI[1, 1, 1, 1, 1, 1] + dI[1, 1, 1, 1, 2] + dI[1, 1, 1, 3] - dI[1, 1, 4] - dI[1, 2, 1, 1, 1] + dI[1, 2, 3] + dI[2, 1, 1, 1, 1] - dI[2, 1, 1, 2] + dI[2, 2, 1, 1] - dI[2, 2, 2] - dI[3, 1, 1, 1] + dI[3, 1, 2]
|
|
3217
|
+
"""
|
|
3218
|
+
n = J.size()
|
|
3219
|
+
C = Compositions()
|
|
3220
|
+
C_n = Compositions(n)
|
|
3221
|
+
mat = self._matrix_monomial_to_dual_immaculate(n)
|
|
3222
|
+
column = C_n.list().index(J)
|
|
3223
|
+
return self.sum_of_terms( ( (C(I), mat[C_n.list().index(I)][column])
|
|
3224
|
+
for I in C_n ),
|
|
3225
|
+
distinct=True )
|
|
3226
|
+
|
|
3227
|
+
dI = dualImmaculate
|
|
3228
|
+
|
|
3229
|
+
class HazewinkelLambda(CombinatorialFreeModule, BindableClass):
|
|
3230
|
+
r"""
|
|
3231
|
+
The Hazewinkel lambda basis of the quasi-symmetric functions.
|
|
3232
|
+
|
|
3233
|
+
This basis goes back to [Haz2004]_, albeit it is indexed in a
|
|
3234
|
+
different way here. It is a multiplicative basis in a weak
|
|
3235
|
+
sense of this word (the product of any two basis elements is a
|
|
3236
|
+
basis element, but of course not the one obtained by
|
|
3237
|
+
concatenating the indexing compositions).
|
|
3238
|
+
|
|
3239
|
+
In [Haz2004]_, Hazewinkel showed that the `\mathbf{k}`-algebra
|
|
3240
|
+
`\mathrm{QSym}` is a polynomial algebra. (The proof is correct
|
|
3241
|
+
but rests upon an unproven claim that the lexicographically
|
|
3242
|
+
largest term of the `n`-th shuffle power of a Lyndon word is
|
|
3243
|
+
the `n`-fold concatenation of this Lyndon word with
|
|
3244
|
+
itself, occurring `n!` times in that shuffle power. But this
|
|
3245
|
+
can be deduced from Section 2 of [Rad1979]_. See also
|
|
3246
|
+
Chapter 6 of [GriRei18]_, specifically Theorem 6.5.13, for a
|
|
3247
|
+
complete proof.) More precisely, he showed that
|
|
3248
|
+
`\mathrm{QSym}` is generated, as a free commutative
|
|
3249
|
+
`\mathbf{k}`-algebra, by the elements `\lambda^n(M_I)`, where
|
|
3250
|
+
`n` ranges over the positive integers, and `I` ranges over
|
|
3251
|
+
all compositions which are Lyndon words and whose entries
|
|
3252
|
+
have gcd `1`. Here, `\lambda^n` denotes the `n`-th lambda
|
|
3253
|
+
operation as explained in
|
|
3254
|
+
:meth:`~sage.combinat.ncsf_qsym.qsym.QuasiSymmetricFunctions.Monomial.lambda_of_monomial`.
|
|
3255
|
+
|
|
3256
|
+
Thus, products of these generators form a `\mathbf{k}`-module
|
|
3257
|
+
basis of `\mathrm{QSym}`. We index this basis by compositions
|
|
3258
|
+
here. More precisely, we define the Hazewinkel lambda basis
|
|
3259
|
+
`(\mathrm{HWL}_I)_I` (with `I` ranging over all compositions)
|
|
3260
|
+
as follows:
|
|
3261
|
+
|
|
3262
|
+
Let `I` be a composition. Let `I = I_1 I_2 \ldots I_k` be the
|
|
3263
|
+
Chen-Fox-Lyndon factorization of `I` (see
|
|
3264
|
+
:meth:`~sage.combinat.words.finite_word.FiniteWord_class.lyndon_factorization`).
|
|
3265
|
+
For every `j \in \{1, 2, \ldots , k\}`, let `g_j` be the
|
|
3266
|
+
gcd of the entries of the Lyndon word `I_j`, and let `J_j` be
|
|
3267
|
+
the result of dividing the entries of `I_j` by this gcd. Then,
|
|
3268
|
+
`\mathrm{HWL}_I` is defined to be
|
|
3269
|
+
`\prod_{j=1}^{k} \lambda^{g_j} (M_{J_j})`.
|
|
3270
|
+
|
|
3271
|
+
.. TODO::
|
|
3272
|
+
|
|
3273
|
+
The conversion from the M basis to the HWL basis is
|
|
3274
|
+
currently implemented in the naive way (inverting the
|
|
3275
|
+
base-change matrix in the other direction). This matrix
|
|
3276
|
+
is not triangular (not even after any permutations of
|
|
3277
|
+
the bases), and there could very well be a faster method
|
|
3278
|
+
(the one given by Hazewinkel?).
|
|
3279
|
+
|
|
3280
|
+
EXAMPLES::
|
|
3281
|
+
|
|
3282
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ)
|
|
3283
|
+
sage: HWL = QSym.HazewinkelLambda()
|
|
3284
|
+
sage: M = QSym.M()
|
|
3285
|
+
sage: M(HWL([2]))
|
|
3286
|
+
M[1, 1]
|
|
3287
|
+
sage: M(HWL([1,1]))
|
|
3288
|
+
2*M[1, 1] + M[2]
|
|
3289
|
+
sage: M(HWL([1,2]))
|
|
3290
|
+
M[1, 2]
|
|
3291
|
+
sage: M(HWL([2,1]))
|
|
3292
|
+
3*M[1, 1, 1] + M[1, 2] + M[2, 1]
|
|
3293
|
+
sage: M(HWL(Composition([])))
|
|
3294
|
+
M[]
|
|
3295
|
+
sage: HWL(M([1,1]))
|
|
3296
|
+
HWL[2]
|
|
3297
|
+
sage: HWL(M(Composition([2])))
|
|
3298
|
+
HWL[1, 1] - 2*HWL[2]
|
|
3299
|
+
sage: HWL(M([1]))
|
|
3300
|
+
HWL[1]
|
|
3301
|
+
|
|
3302
|
+
TESTS:
|
|
3303
|
+
|
|
3304
|
+
Transforming from the M-basis into the HWL-basis and back
|
|
3305
|
+
returns us to where we started::
|
|
3306
|
+
|
|
3307
|
+
sage: all( M(HWL(M[I])) == M[I] for I in Compositions(3) )
|
|
3308
|
+
True
|
|
3309
|
+
sage: all( HWL(M(HWL[I])) == HWL[I] for I in Compositions(4) )
|
|
3310
|
+
True
|
|
3311
|
+
|
|
3312
|
+
Checking the HWL basis elements corresponding to Lyndon
|
|
3313
|
+
words::
|
|
3314
|
+
|
|
3315
|
+
sage: all( M(HWL[Composition(I)])
|
|
3316
|
+
....: == M.lambda_of_monomial([i // gcd(I) for i in I], gcd(I))
|
|
3317
|
+
....: for I in LyndonWords(e=3, k=2) )
|
|
3318
|
+
True
|
|
3319
|
+
"""
|
|
3320
|
+
|
|
3321
|
+
def __init__(self, QSym):
|
|
3322
|
+
r"""
|
|
3323
|
+
TESTS::
|
|
3324
|
+
|
|
3325
|
+
sage: HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda()
|
|
3326
|
+
sage: TestSuite(HWL).run()
|
|
3327
|
+
"""
|
|
3328
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
3329
|
+
prefix='HWL', bracket=False,
|
|
3330
|
+
category=QSym.Bases())
|
|
3331
|
+
|
|
3332
|
+
def __init_extra__(self):
|
|
3333
|
+
"""
|
|
3334
|
+
Set up caches for the transition maps to and from the monomial
|
|
3335
|
+
basis, and register them as coercions.
|
|
3336
|
+
|
|
3337
|
+
TESTS::
|
|
3338
|
+
|
|
3339
|
+
sage: HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda()
|
|
3340
|
+
sage: M = QuasiSymmetricFunctions(QQ).Monomial()
|
|
3341
|
+
sage: M2HWL = HWL.coerce_map_from(M); M2HWL
|
|
3342
|
+
Generic morphism:
|
|
3343
|
+
From: Quasisymmetric functions over the Rational Field in the Monomial basis
|
|
3344
|
+
To: Quasisymmetric functions over the Rational Field in the HazewinkelLambda basis
|
|
3345
|
+
sage: HWL2M = M.coerce_map_from(HWL); HWL2M
|
|
3346
|
+
Generic morphism:
|
|
3347
|
+
From: Quasisymmetric functions over the Rational Field in the HazewinkelLambda basis
|
|
3348
|
+
To: Quasisymmetric functions over the Rational Field in the Monomial basis
|
|
3349
|
+
sage: HWL2M(HWL[2])
|
|
3350
|
+
M[1, 1]
|
|
3351
|
+
sage: M2HWL(M[2])
|
|
3352
|
+
HWL[1, 1] - 2*HWL[2]
|
|
3353
|
+
"""
|
|
3354
|
+
M = self.realization_of().M()
|
|
3355
|
+
category = self.realization_of()._category
|
|
3356
|
+
# This changes Monomial into Hazewinkel Lambda
|
|
3357
|
+
M.module_morphism(self._from_Monomial_on_basis,
|
|
3358
|
+
codomain=self, category=category
|
|
3359
|
+
).register_as_coercion()
|
|
3360
|
+
# This changes Hazewinkel Lambda into Monomial
|
|
3361
|
+
self.module_morphism(self._to_Monomial_on_basis,
|
|
3362
|
+
codomain=M, category=category
|
|
3363
|
+
).register_as_coercion()
|
|
3364
|
+
|
|
3365
|
+
# cache for the coordinates of the elements
|
|
3366
|
+
# of the monomial basis with respect to the HWL basis
|
|
3367
|
+
self._M_to_self_cache = {}
|
|
3368
|
+
# cache for the coordinates of the elements
|
|
3369
|
+
# of the HWL basis with respect to the monomial basis
|
|
3370
|
+
self._M_from_self_cache = {}
|
|
3371
|
+
# cache for transition matrices which contain the coordinates of
|
|
3372
|
+
# the elements of the monomial basis with respect to the HWL basis
|
|
3373
|
+
self._M_transition_matrices = {}
|
|
3374
|
+
# cache for transition matrices which contain the coordinates of
|
|
3375
|
+
# the elements of the HWL basis with respect to the monomial basis
|
|
3376
|
+
self._M_inverse_transition_matrices = {}
|
|
3377
|
+
|
|
3378
|
+
def _precompute_cache(self, n, to_self_cache, from_self_cache, transition_matrices, inverse_transition_matrices, from_self_gen_function):
|
|
3379
|
+
r"""
|
|
3380
|
+
Compute the transition matrices between ``self`` and the
|
|
3381
|
+
monomial basis in the homogeneous components of degree `n`.
|
|
3382
|
+
The results are not returned, but rather stored in the caches.
|
|
3383
|
+
|
|
3384
|
+
This assumes that the transition matrices in all degrees smaller
|
|
3385
|
+
than `n` have already been computed and cached!
|
|
3386
|
+
|
|
3387
|
+
INPUT:
|
|
3388
|
+
|
|
3389
|
+
- ``n`` -- nonnegative integer
|
|
3390
|
+
- ``to_self_cache`` -- a cache which stores the coordinates of
|
|
3391
|
+
the elements of the monomial basis with respect to the
|
|
3392
|
+
basis ``self``
|
|
3393
|
+
- ``from_self_cache`` -- a cache which stores the coordinates
|
|
3394
|
+
of the elements of ``self`` with respect to the monomial
|
|
3395
|
+
basis
|
|
3396
|
+
- ``transition_matrices`` -- a cache for transition matrices
|
|
3397
|
+
which contain the coordinates of the elements of the monomial
|
|
3398
|
+
basis with respect to ``self``
|
|
3399
|
+
- ``inverse_transition_matrices`` -- a cache for transition
|
|
3400
|
+
matrices which contain the coordinates of the elements of
|
|
3401
|
+
``self`` with respect to the monomial basis
|
|
3402
|
+
- ``from_self_gen_function`` -- a function which takes a
|
|
3403
|
+
Lyndon word `I` and returns the Hazewinkel Lambda basis
|
|
3404
|
+
element indexed by `I` expanded with respect to the
|
|
3405
|
+
monomial basis (as an element of the monomial basis, not as
|
|
3406
|
+
a dictionary)
|
|
3407
|
+
|
|
3408
|
+
EXAMPLES:
|
|
3409
|
+
|
|
3410
|
+
The examples below demonstrate how the caches are built
|
|
3411
|
+
step by step using the ``_precompute_cache`` method. In order
|
|
3412
|
+
not to influence the outcome of other doctests, we make sure
|
|
3413
|
+
not to use the caches internally used by this class, but
|
|
3414
|
+
rather to create new caches. This allows us to compute the
|
|
3415
|
+
transition matrices for a slight variation of the Hazewinkel
|
|
3416
|
+
Lambda basis, namely the basis whose `I`-th element is given
|
|
3417
|
+
by the simple formula `\prod_{j=1}^{k} M_{I_j}` instead of
|
|
3418
|
+
`\prod_{j=1}^{k} \lambda^{g_j} (M_{J_j})`. We will see that
|
|
3419
|
+
this is only a `\QQ`-basis rather than a `\ZZ`-basis (a
|
|
3420
|
+
reason why the Ditters conjecture took so long to prove)::
|
|
3421
|
+
|
|
3422
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3423
|
+
sage: HWL = QSym.HazewinkelLambda()
|
|
3424
|
+
sage: M = QSym.M()
|
|
3425
|
+
sage: toy_to_self_cache = {}
|
|
3426
|
+
sage: toy_from_self_cache = {}
|
|
3427
|
+
sage: toy_transition_matrices = {}
|
|
3428
|
+
sage: toy_inverse_transition_matrices = {}
|
|
3429
|
+
sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())]
|
|
3430
|
+
sage: l(toy_to_self_cache)
|
|
3431
|
+
[]
|
|
3432
|
+
sage: def toy_gen_function(I):
|
|
3433
|
+
....: return M[I]
|
|
3434
|
+
sage: HWL._precompute_cache(0, toy_to_self_cache,
|
|
3435
|
+
....: toy_from_self_cache,
|
|
3436
|
+
....: toy_transition_matrices,
|
|
3437
|
+
....: toy_inverse_transition_matrices,
|
|
3438
|
+
....: toy_gen_function)
|
|
3439
|
+
sage: l(toy_to_self_cache)
|
|
3440
|
+
[([], [([], 1)])]
|
|
3441
|
+
sage: HWL._precompute_cache(1, toy_to_self_cache,
|
|
3442
|
+
....: toy_from_self_cache,
|
|
3443
|
+
....: toy_transition_matrices,
|
|
3444
|
+
....: toy_inverse_transition_matrices,
|
|
3445
|
+
....: toy_gen_function)
|
|
3446
|
+
sage: l(toy_to_self_cache)
|
|
3447
|
+
[([], [([], 1)]), ([1], [([1], 1)])]
|
|
3448
|
+
sage: HWL._precompute_cache(2, toy_to_self_cache,
|
|
3449
|
+
....: toy_from_self_cache,
|
|
3450
|
+
....: toy_transition_matrices,
|
|
3451
|
+
....: toy_inverse_transition_matrices,
|
|
3452
|
+
....: toy_gen_function)
|
|
3453
|
+
sage: l(toy_to_self_cache)
|
|
3454
|
+
[([], [([], 1)]), ([1], [([1], 1)]), ([1, 1], [([1, 1], 1/2), ([2], -1/2)]), ([2], [([2], 1)])]
|
|
3455
|
+
sage: toy_transition_matrices[2]
|
|
3456
|
+
[ 1/2 -1/2]
|
|
3457
|
+
[ 0 1]
|
|
3458
|
+
sage: toy_inverse_transition_matrices[2]
|
|
3459
|
+
[2 1]
|
|
3460
|
+
[0 1]
|
|
3461
|
+
sage: sorted(toy_transition_matrices)
|
|
3462
|
+
[0, 1, 2]
|
|
3463
|
+
|
|
3464
|
+
As we see from the fractions in the transition matrices, this
|
|
3465
|
+
is only a basis over `\QQ`, not over `\ZZ`.
|
|
3466
|
+
|
|
3467
|
+
Let us try another variation on the definition of the basis:
|
|
3468
|
+
`\prod_{j=1}^{k} \lambda^{g_j} (M_{J_j})` will now be replaced
|
|
3469
|
+
by `\prod_{j=1}^{k} M_{J_j^{g_j}}`, where `J_g` means the
|
|
3470
|
+
`g`-fold concatenation of the composition `J` with itself::
|
|
3471
|
+
|
|
3472
|
+
sage: toy_to_self_cache = {}
|
|
3473
|
+
sage: toy_from_self_cache = {}
|
|
3474
|
+
sage: toy_transition_matrices = {}
|
|
3475
|
+
sage: toy_inverse_transition_matrices = {}
|
|
3476
|
+
sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())]
|
|
3477
|
+
sage: l(toy_to_self_cache)
|
|
3478
|
+
[]
|
|
3479
|
+
sage: def toy_gen_function(I):
|
|
3480
|
+
....: xs = [i // gcd(I) for i in I] * gcd(I)
|
|
3481
|
+
....: return M[xs]
|
|
3482
|
+
sage: HWL._precompute_cache(0, toy_to_self_cache,
|
|
3483
|
+
....: toy_from_self_cache,
|
|
3484
|
+
....: toy_transition_matrices,
|
|
3485
|
+
....: toy_inverse_transition_matrices,
|
|
3486
|
+
....: toy_gen_function)
|
|
3487
|
+
sage: l(toy_to_self_cache)
|
|
3488
|
+
[([], [([], 1)])]
|
|
3489
|
+
sage: HWL._precompute_cache(1, toy_to_self_cache,
|
|
3490
|
+
....: toy_from_self_cache,
|
|
3491
|
+
....: toy_transition_matrices,
|
|
3492
|
+
....: toy_inverse_transition_matrices,
|
|
3493
|
+
....: toy_gen_function)
|
|
3494
|
+
sage: l(toy_to_self_cache)
|
|
3495
|
+
[([], [([], 1)]), ([1], [([1], 1)])]
|
|
3496
|
+
sage: HWL._precompute_cache(2, toy_to_self_cache,
|
|
3497
|
+
....: toy_from_self_cache,
|
|
3498
|
+
....: toy_transition_matrices,
|
|
3499
|
+
....: toy_inverse_transition_matrices,
|
|
3500
|
+
....: toy_gen_function)
|
|
3501
|
+
sage: l(toy_to_self_cache)
|
|
3502
|
+
[([], [([], 1)]), ([1], [([1], 1)]), ([1, 1], [([2], 1)]), ([2], [([1, 1], 1), ([2], -2)])]
|
|
3503
|
+
|
|
3504
|
+
This appears to form another `\ZZ`-basis of
|
|
3505
|
+
`\mathrm{QSym}`, but the appearance is deceiving: it
|
|
3506
|
+
fails to span the degree-`9` part of `\mathrm{QSym}`.
|
|
3507
|
+
(The corresponding computation is not tested as it takes
|
|
3508
|
+
a few minutes.) We have not checked if it spans
|
|
3509
|
+
`\mathrm{QSym}` over `\QQ`.
|
|
3510
|
+
"""
|
|
3511
|
+
# Much of this code is adapted from sage/combinat/sf/dual.py
|
|
3512
|
+
base_ring = self.base_ring()
|
|
3513
|
+
zero = base_ring.zero()
|
|
3514
|
+
|
|
3515
|
+
# Handle the n == 0 case separately
|
|
3516
|
+
if n == 0:
|
|
3517
|
+
part = self._indices([])
|
|
3518
|
+
one = base_ring.one()
|
|
3519
|
+
to_self_cache[ part ] = { part: one }
|
|
3520
|
+
from_self_cache[ part ] = { part: one }
|
|
3521
|
+
transition_matrices[n] = matrix(base_ring, [[one]])
|
|
3522
|
+
inverse_transition_matrices[n] = matrix(base_ring, [[one]])
|
|
3523
|
+
return
|
|
3524
|
+
|
|
3525
|
+
compositions_n = Compositions(n).list()
|
|
3526
|
+
len_compositions_n = 2 ** (n-1) # since n > 0 by now.
|
|
3527
|
+
M = self.realization_of().M()
|
|
3528
|
+
|
|
3529
|
+
# The monomial basis will be called M from now on.
|
|
3530
|
+
|
|
3531
|
+
# This contains the data for the transition matrix from the
|
|
3532
|
+
# monomial basis M to the Hazewinkel lambda basis self.
|
|
3533
|
+
transition_matrix_n = matrix(base_ring, len_compositions_n, len_compositions_n)
|
|
3534
|
+
|
|
3535
|
+
# This first section calculates how the basis elements of the
|
|
3536
|
+
# Hazewinkel lambda basis self decompose in the monomial
|
|
3537
|
+
# basis M.
|
|
3538
|
+
|
|
3539
|
+
# For every composition I of size n, expand self[I] in terms
|
|
3540
|
+
# of the monomial basis M.
|
|
3541
|
+
i = 0
|
|
3542
|
+
for I in compositions_n:
|
|
3543
|
+
# M_coeffs will be M(self[I])._monomial_coefficients
|
|
3544
|
+
M_coeffs = {}
|
|
3545
|
+
|
|
3546
|
+
self_I_in_M_basis = M.prod([from_self_gen_function(self._indices(list(J)))
|
|
3547
|
+
for J in Word(I).lyndon_factorization()])
|
|
3548
|
+
|
|
3549
|
+
j = 0
|
|
3550
|
+
|
|
3551
|
+
for J in compositions_n:
|
|
3552
|
+
if J in self_I_in_M_basis._monomial_coefficients:
|
|
3553
|
+
sp = self_I_in_M_basis._monomial_coefficients[J]
|
|
3554
|
+
M_coeffs[J] = sp
|
|
3555
|
+
transition_matrix_n[i,j] = sp
|
|
3556
|
+
|
|
3557
|
+
j += 1
|
|
3558
|
+
|
|
3559
|
+
from_self_cache[I] = M_coeffs
|
|
3560
|
+
i += 1
|
|
3561
|
+
|
|
3562
|
+
# Save the transition matrix
|
|
3563
|
+
inverse_transition_matrices[n] = transition_matrix_n
|
|
3564
|
+
|
|
3565
|
+
# This second section calculates how the basis elements of the
|
|
3566
|
+
# monomial basis M expand in terms of the basis B. We do this
|
|
3567
|
+
# by inverting the above transition matrix.
|
|
3568
|
+
#
|
|
3569
|
+
# TODO: The way given in Hazewinkel's [Haz2004]_ paper might
|
|
3570
|
+
# be faster.
|
|
3571
|
+
inverse_transition = (~transition_matrix_n).change_ring(base_ring)
|
|
3572
|
+
# Note that we don't simply write
|
|
3573
|
+
# "inverse_transition = ~transition_matrix_n" because that
|
|
3574
|
+
# tends to cast the entries of the matrix into a quotient
|
|
3575
|
+
# field even if this is unnecessary.
|
|
3576
|
+
# MAYBE use .inverse_of_unit() ?
|
|
3577
|
+
|
|
3578
|
+
# TODO: This still looks fragile when the base ring is weird!
|
|
3579
|
+
# Possibly work over ZZ in this method?
|
|
3580
|
+
|
|
3581
|
+
for i in range(len_compositions_n):
|
|
3582
|
+
self_coeffs = {}
|
|
3583
|
+
for j in range(len_compositions_n):
|
|
3584
|
+
if inverse_transition[i,j] != zero:
|
|
3585
|
+
self_coeffs[ compositions_n[j] ] = inverse_transition[i,j]
|
|
3586
|
+
|
|
3587
|
+
to_self_cache[ compositions_n[i] ] = self_coeffs
|
|
3588
|
+
|
|
3589
|
+
transition_matrices[n] = inverse_transition
|
|
3590
|
+
|
|
3591
|
+
def _precompute_M(self, n):
|
|
3592
|
+
"""
|
|
3593
|
+
Compute the transition matrices between ``self`` and the
|
|
3594
|
+
monomial basis in the homogeneous components of degree `n`
|
|
3595
|
+
(and in those of smaller degree, if not already computed).
|
|
3596
|
+
The result is not returned, but rather stored in the cache.
|
|
3597
|
+
|
|
3598
|
+
INPUT:
|
|
3599
|
+
|
|
3600
|
+
- ``n`` -- nonnegative integer
|
|
3601
|
+
|
|
3602
|
+
EXAMPLES:
|
|
3603
|
+
|
|
3604
|
+
The examples below demonstrate how the caches of ``self`` are
|
|
3605
|
+
built step by step using the ``_precompute_M`` method. This
|
|
3606
|
+
demonstration relies on an untouched Hazewinkel Lambda basis
|
|
3607
|
+
(because any computations might have filled the cache already).
|
|
3608
|
+
We obtain such a basis by choosing a ground ring unlikely to
|
|
3609
|
+
appear elsewhere::
|
|
3610
|
+
|
|
3611
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ['hell', 'yeah'])
|
|
3612
|
+
sage: HWL = QSym.HazewinkelLambda()
|
|
3613
|
+
sage: M = QSym.M()
|
|
3614
|
+
sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())]
|
|
3615
|
+
sage: l(HWL._M_to_self_cache)
|
|
3616
|
+
[]
|
|
3617
|
+
sage: HWL._precompute_M(0)
|
|
3618
|
+
sage: l(HWL._M_to_self_cache)
|
|
3619
|
+
[([], [([], 1)])]
|
|
3620
|
+
sage: HWL._precompute_M(1)
|
|
3621
|
+
sage: l(HWL._M_to_self_cache)
|
|
3622
|
+
[([], [([], 1)]), ([1], [([1], 1)])]
|
|
3623
|
+
sage: HWL._precompute_M(2)
|
|
3624
|
+
sage: l(HWL._M_to_self_cache)
|
|
3625
|
+
[([], [([], 1)]),
|
|
3626
|
+
([1], [([1], 1)]),
|
|
3627
|
+
([1, 1], [([2], 1)]),
|
|
3628
|
+
([2], [([1, 1], 1), ([2], -2)])]
|
|
3629
|
+
sage: HWL._M_transition_matrices[2]
|
|
3630
|
+
[ 0 1]
|
|
3631
|
+
[ 1 -2]
|
|
3632
|
+
sage: HWL._M_inverse_transition_matrices[2]
|
|
3633
|
+
[2 1]
|
|
3634
|
+
[1 0]
|
|
3635
|
+
sage: sorted(HWL._M_transition_matrices)
|
|
3636
|
+
[0, 1, 2]
|
|
3637
|
+
|
|
3638
|
+
We did not have to call ``HWL._precompute_M(0)``,
|
|
3639
|
+
``HWL._precompute_M(1)`` and ``HWL._precompute_M(2)``
|
|
3640
|
+
in this order; it would be enough to just call
|
|
3641
|
+
``HWL._precompute_M(2)``::
|
|
3642
|
+
|
|
3643
|
+
sage: QSym = QuasiSymmetricFunctions(ZZ['lol', 'wut'])
|
|
3644
|
+
sage: HWL = QSym.HazewinkelLambda()
|
|
3645
|
+
sage: M = QSym.M()
|
|
3646
|
+
sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())]
|
|
3647
|
+
sage: l(HWL._M_to_self_cache)
|
|
3648
|
+
[]
|
|
3649
|
+
sage: HWL._precompute_M(2)
|
|
3650
|
+
sage: l(HWL._M_to_self_cache)
|
|
3651
|
+
[([], [([], 1)]),
|
|
3652
|
+
([1], [([1], 1)]),
|
|
3653
|
+
([1, 1], [([2], 1)]),
|
|
3654
|
+
([2], [([1, 1], 1), ([2], -2)])]
|
|
3655
|
+
sage: HWL._precompute_M(1)
|
|
3656
|
+
sage: l(HWL._M_to_self_cache)
|
|
3657
|
+
[([], [([], 1)]),
|
|
3658
|
+
([1], [([1], 1)]),
|
|
3659
|
+
([1, 1], [([2], 1)]),
|
|
3660
|
+
([2], [([1, 1], 1), ([2], -2)])]
|
|
3661
|
+
"""
|
|
3662
|
+
l = len(self._M_transition_matrices)
|
|
3663
|
+
M = self.realization_of().M()
|
|
3664
|
+
if l <= n:
|
|
3665
|
+
from sage.misc.cachefunc import cached_function
|
|
3666
|
+
from sage.arith.misc import gcd
|
|
3667
|
+
|
|
3668
|
+
@cached_function
|
|
3669
|
+
def monolambda(I):
|
|
3670
|
+
# expansion of self[I] in monomial basis,
|
|
3671
|
+
# where I is a composition which is a Lyndon word
|
|
3672
|
+
g = gcd(I)
|
|
3673
|
+
I_reduced = [i // g for i in I]
|
|
3674
|
+
return M.lambda_of_monomial(I_reduced, g)
|
|
3675
|
+
for i in range(l, n + 1):
|
|
3676
|
+
self._precompute_cache(i, self._M_to_self_cache,
|
|
3677
|
+
self._M_from_self_cache,
|
|
3678
|
+
self._M_transition_matrices,
|
|
3679
|
+
self._M_inverse_transition_matrices,
|
|
3680
|
+
monolambda)
|
|
3681
|
+
|
|
3682
|
+
def _to_Monomial_on_basis(self, J):
|
|
3683
|
+
r"""
|
|
3684
|
+
Expand the Hazewinkel Lambda basis element labelled by a
|
|
3685
|
+
composition ``J`` in the quasi-symmetric Monomial basis.
|
|
3686
|
+
|
|
3687
|
+
INPUT:
|
|
3688
|
+
|
|
3689
|
+
- ``J`` -- a composition
|
|
3690
|
+
|
|
3691
|
+
OUTPUT: a quasi-symmetric function in the Monomial basis
|
|
3692
|
+
|
|
3693
|
+
EXAMPLES::
|
|
3694
|
+
|
|
3695
|
+
sage: HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda()
|
|
3696
|
+
sage: J = Composition([1, 2, 1])
|
|
3697
|
+
sage: HWL._to_Monomial_on_basis(J)
|
|
3698
|
+
2*M[1, 1, 2] + M[1, 2, 1] + M[1, 3] + M[2, 2]
|
|
3699
|
+
"""
|
|
3700
|
+
n = sum(J)
|
|
3701
|
+
self._precompute_M(n)
|
|
3702
|
+
return self.realization_of().M()._from_dict(self._M_from_self_cache[J])
|
|
3703
|
+
|
|
3704
|
+
def _from_Monomial_on_basis(self, J):
|
|
3705
|
+
r"""
|
|
3706
|
+
Expand the Monomial quasi-symmetric function labelled by the
|
|
3707
|
+
composition ``J`` in the Hazewinkel Lambda basis.
|
|
3708
|
+
|
|
3709
|
+
INPUT:
|
|
3710
|
+
|
|
3711
|
+
- ``J`` -- a composition
|
|
3712
|
+
|
|
3713
|
+
OUTPUT: a quasi-symmetric function in the Hazewinkel lambda basis
|
|
3714
|
+
|
|
3715
|
+
EXAMPLES::
|
|
3716
|
+
|
|
3717
|
+
sage: HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda()
|
|
3718
|
+
sage: J = Composition([1, 2, 1])
|
|
3719
|
+
sage: HWL._from_Monomial_on_basis(J)
|
|
3720
|
+
-2*HWL[1, 1, 2] + HWL[1, 2, 1] - HWL[1, 3] - HWL[2, 2] + 2*HWL[3, 1] - 2*HWL[4]
|
|
3721
|
+
"""
|
|
3722
|
+
n = sum(J)
|
|
3723
|
+
self._precompute_M(n)
|
|
3724
|
+
return self._from_dict(self._M_to_self_cache[J])
|
|
3725
|
+
|
|
3726
|
+
def product_on_basis(self, I, J):
|
|
3727
|
+
"""
|
|
3728
|
+
The product on Hazewinkel Lambda basis elements.
|
|
3729
|
+
|
|
3730
|
+
The product of the basis elements indexed by two compositions
|
|
3731
|
+
`I` and `J` is the basis element obtained by concatenating the
|
|
3732
|
+
Lyndon factorizations of the words `I` and `J`, then reordering
|
|
3733
|
+
the Lyndon factors in nonincreasing order, and finally
|
|
3734
|
+
concatenating them in this order (giving a new composition).
|
|
3735
|
+
|
|
3736
|
+
INPUT:
|
|
3737
|
+
|
|
3738
|
+
- ``I``, ``J`` -- compositions
|
|
3739
|
+
|
|
3740
|
+
OUTPUT:
|
|
3741
|
+
|
|
3742
|
+
- The product of the Hazewinkel Lambda quasi-symmetric
|
|
3743
|
+
functions indexed by ``I`` and ``J``, expressed in the
|
|
3744
|
+
Hazewinkel Lambda basis.
|
|
3745
|
+
|
|
3746
|
+
EXAMPLES::
|
|
3747
|
+
|
|
3748
|
+
sage: HWL = QuasiSymmetricFunctions(QQ).HazewinkelLambda()
|
|
3749
|
+
sage: c1 = Composition([1, 2, 1])
|
|
3750
|
+
sage: c2 = Composition([2, 1, 3, 2])
|
|
3751
|
+
sage: HWL.product_on_basis(c1, c2)
|
|
3752
|
+
HWL[2, 1, 3, 2, 1, 2, 1]
|
|
3753
|
+
sage: HWL.product_on_basis(c1, Composition([]))
|
|
3754
|
+
HWL[1, 2, 1]
|
|
3755
|
+
sage: HWL.product_on_basis(Composition([]), Composition([]))
|
|
3756
|
+
HWL[]
|
|
3757
|
+
|
|
3758
|
+
TESTS::
|
|
3759
|
+
|
|
3760
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
3761
|
+
sage: all( all( M(HWL[I] * HWL[J]) == M(HWL[I]) * M(HWL[J]) # long time
|
|
3762
|
+
....: for I in Compositions(3) )
|
|
3763
|
+
....: for J in Compositions(3) )
|
|
3764
|
+
True
|
|
3765
|
+
"""
|
|
3766
|
+
from sage.misc.flatten import flatten
|
|
3767
|
+
I_factors = [list(i) for i in Word(I).lyndon_factorization()]
|
|
3768
|
+
J_factors = [list(j) for j in Word(J).lyndon_factorization()]
|
|
3769
|
+
# This uses the convenient fact that comparison of lists in
|
|
3770
|
+
# Python works exactly as one wants in Lyndon word theory:
|
|
3771
|
+
# [a_1, a_2, ..., a_n] > [b_1, b_2, ..., b_m] if and only if
|
|
3772
|
+
# either some i satisfies a_i > b_i and (a_j == b_j for all
|
|
3773
|
+
# j < i), or we have n > m and all i <= m satisfy a_i == b_i.
|
|
3774
|
+
new_factors = sorted(I_factors + J_factors, reverse=True)
|
|
3775
|
+
return self.monomial(self._indices(flatten(new_factors)))
|
|
3776
|
+
|
|
3777
|
+
class psi(CombinatorialFreeModule, BindableClass):
|
|
3778
|
+
r"""
|
|
3779
|
+
The Hopf algebra of quasi-symmetric functions in the `\psi` basis.
|
|
3780
|
+
|
|
3781
|
+
The `\psi` basis is defined as a rescaled Hopf dual of the `\Psi`
|
|
3782
|
+
basis of the non-commutative symmetric functions (see Section 3.1
|
|
3783
|
+
of [BDHMN2017]_), where the pairing is
|
|
3784
|
+
|
|
3785
|
+
.. MATH::
|
|
3786
|
+
|
|
3787
|
+
(\psi_I, \Psi_J) = z_I \delta_{I,J},
|
|
3788
|
+
|
|
3789
|
+
where `z_I = 1^{m_1} m_1! 2^{m_2} m_2! \cdots` with `m_i` being the
|
|
3790
|
+
multiplicity of `i` in the composition `I`. Therefore, we call these
|
|
3791
|
+
the *quasi-symmetric power sums of the first kind*.
|
|
3792
|
+
|
|
3793
|
+
Using the duality, we can directly define the `\psi` basis by
|
|
3794
|
+
|
|
3795
|
+
.. MATH::
|
|
3796
|
+
|
|
3797
|
+
\psi_I = \sum_{J \succ I} z_I / \pi_{I,J} M_J,
|
|
3798
|
+
|
|
3799
|
+
where `\pi_{I,J}` is as defined in [NCSF]_.
|
|
3800
|
+
|
|
3801
|
+
The `\psi`-basis is well-defined only when the base ring is a
|
|
3802
|
+
`\QQ`-algebra.
|
|
3803
|
+
|
|
3804
|
+
EXAMPLES::
|
|
3805
|
+
|
|
3806
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3807
|
+
sage: psi = QSym.psi(); psi
|
|
3808
|
+
Quasisymmetric functions over the Rational Field in the psi basis
|
|
3809
|
+
sage: psi.an_element()
|
|
3810
|
+
2*psi[] + 2*psi[1] + 3*psi[1, 1]
|
|
3811
|
+
sage: p = SymmetricFunctions(QQ).p()
|
|
3812
|
+
sage: psi(p[2,2,1])
|
|
3813
|
+
psi[1, 2, 2] + psi[2, 1, 2] + psi[2, 2, 1]
|
|
3814
|
+
sage: all(sum(psi(list(al)) for al in Permutations(la))==psi(p(la)) for la in Partitions(6))
|
|
3815
|
+
True
|
|
3816
|
+
sage: p = SymmetricFunctions(QQ).p()
|
|
3817
|
+
sage: psi(p[3,2,2])
|
|
3818
|
+
psi[2, 2, 3] + psi[2, 3, 2] + psi[3, 2, 2]
|
|
3819
|
+
|
|
3820
|
+
Checking the equivalent definition of `\psi_n`::
|
|
3821
|
+
|
|
3822
|
+
sage: def test_psi(n):
|
|
3823
|
+
....: psi = QuasiSymmetricFunctions(QQ).psi()
|
|
3824
|
+
....: Psi = NonCommutativeSymmetricFunctions(QQ).Psi()
|
|
3825
|
+
....: M = matrix([[psi[I].duality_pairing(Psi[J])
|
|
3826
|
+
....: for I in Compositions(n)]
|
|
3827
|
+
....: for J in Compositions(n)])
|
|
3828
|
+
....: def z(J): return J.to_partition().centralizer_size()
|
|
3829
|
+
....: return M == matrix.diagonal([z(I) for I in Compositions(n)])
|
|
3830
|
+
sage: all(test_psi(k) for k in range(1,5))
|
|
3831
|
+
True
|
|
3832
|
+
"""
|
|
3833
|
+
|
|
3834
|
+
def __init__(self, QSym):
|
|
3835
|
+
r"""
|
|
3836
|
+
Initialize ``self``.
|
|
3837
|
+
|
|
3838
|
+
EXAMPLES::
|
|
3839
|
+
|
|
3840
|
+
sage: psi = QuasiSymmetricFunctions(QQ).psi()
|
|
3841
|
+
sage: TestSuite(psi).run()
|
|
3842
|
+
|
|
3843
|
+
TESTS::
|
|
3844
|
+
|
|
3845
|
+
sage: psi = QuasiSymmetricFunctions(QQ).psi()
|
|
3846
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
3847
|
+
sage: all(psi(M(psi[c])) == psi[c] for n in range(5)
|
|
3848
|
+
....: for c in Compositions(n))
|
|
3849
|
+
True
|
|
3850
|
+
sage: all(M(psi(M[c])) == M[c] for n in range(5)
|
|
3851
|
+
....: for c in Compositions(n))
|
|
3852
|
+
True
|
|
3853
|
+
"""
|
|
3854
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
3855
|
+
prefix='psi', bracket=False,
|
|
3856
|
+
category=QSym.Bases())
|
|
3857
|
+
|
|
3858
|
+
category = self.realization_of()._category
|
|
3859
|
+
Monomial = self.realization_of().Monomial()
|
|
3860
|
+
self.module_morphism(self._to_Monomial_on_basis,
|
|
3861
|
+
codomain=Monomial, category=category
|
|
3862
|
+
).register_as_coercion()
|
|
3863
|
+
Monomial.module_morphism(self._from_Monomial_on_basis,
|
|
3864
|
+
codomain=self, category=category
|
|
3865
|
+
).register_as_coercion()
|
|
3866
|
+
|
|
3867
|
+
def _from_Monomial_on_basis(self, I):
|
|
3868
|
+
r"""
|
|
3869
|
+
Expand a Monomial basis element indexed by ``I`` in the
|
|
3870
|
+
`\psi` basis.
|
|
3871
|
+
|
|
3872
|
+
INPUT:
|
|
3873
|
+
|
|
3874
|
+
- ``I`` -- a composition
|
|
3875
|
+
|
|
3876
|
+
OUTPUT: a quasi-symmetric function in the `\psi` basis
|
|
3877
|
+
|
|
3878
|
+
TESTS::
|
|
3879
|
+
|
|
3880
|
+
sage: psi = QuasiSymmetricFunctions(QQ).psi()
|
|
3881
|
+
sage: I = Composition([2, 3, 2])
|
|
3882
|
+
sage: psi._from_Monomial_on_basis(I)
|
|
3883
|
+
1/2*psi[2, 3, 2] - 2/5*psi[2, 5] - 3/5*psi[5, 2] + 2/7*psi[7]
|
|
3884
|
+
"""
|
|
3885
|
+
R = self.base_ring()
|
|
3886
|
+
minus_one = -R.one()
|
|
3887
|
+
|
|
3888
|
+
def z(J):
|
|
3889
|
+
return R(J.to_partition().centralizer_size())
|
|
3890
|
+
return self._from_dict({J: minus_one**(len(I)-len(J)) / z(J) * coeff_lp(I, J)
|
|
3891
|
+
for J in I.fatter()})
|
|
3892
|
+
|
|
3893
|
+
def _to_Monomial_on_basis(self, I):
|
|
3894
|
+
r"""
|
|
3895
|
+
Expand a `\psi` basis element indexed by ``I`` in the
|
|
3896
|
+
Monomial basis.
|
|
3897
|
+
|
|
3898
|
+
INPUT:
|
|
3899
|
+
|
|
3900
|
+
- ``I`` -- a composition
|
|
3901
|
+
|
|
3902
|
+
OUTPUT: a quasi-symmetric function in the Monomial basis
|
|
3903
|
+
|
|
3904
|
+
TESTS::
|
|
3905
|
+
|
|
3906
|
+
sage: psi = QuasiSymmetricFunctions(QQ).psi()
|
|
3907
|
+
sage: I = Composition([2, 3, 2])
|
|
3908
|
+
sage: psi._to_Monomial_on_basis(I)
|
|
3909
|
+
2*M[2, 3, 2] + 4/5*M[2, 5] + 6/5*M[5, 2] + 12/35*M[7]
|
|
3910
|
+
"""
|
|
3911
|
+
R = self.base_ring()
|
|
3912
|
+
z = R(I.to_partition().centralizer_size())
|
|
3913
|
+
Monomial = self.realization_of().Monomial()
|
|
3914
|
+
return Monomial._from_dict({J: z / coeff_pi(I,J) for J in I.fatter()})
|
|
3915
|
+
|
|
3916
|
+
class phi(CombinatorialFreeModule, BindableClass):
|
|
3917
|
+
r"""
|
|
3918
|
+
The Hopf algebra of quasi-symmetric functions in the `\phi` basis.
|
|
3919
|
+
|
|
3920
|
+
The `\phi` basis is defined as a rescaled Hopf dual of the `\Phi`
|
|
3921
|
+
basis of the non-commutative symmetric functions (see Section 3.1
|
|
3922
|
+
of [BDHMN2017]_), where the pairing is
|
|
3923
|
+
|
|
3924
|
+
.. MATH::
|
|
3925
|
+
|
|
3926
|
+
(\phi_I, \Phi_J) = z_I \delta_{I,J},
|
|
3927
|
+
|
|
3928
|
+
where `z_I = 1^{m_1} m_1! 2^{m_2} m_2! \cdots` with `m_i` being the
|
|
3929
|
+
multiplicity of `i` in the composition `I`. Therefore, we call these
|
|
3930
|
+
the *quasi-symmetric power sums of the second kind*.
|
|
3931
|
+
|
|
3932
|
+
Using the duality, we can directly define the `\phi` basis by
|
|
3933
|
+
|
|
3934
|
+
.. MATH::
|
|
3935
|
+
|
|
3936
|
+
\phi_I = \sum_{J \succ I} z_I / sp_{I,J} M_J,
|
|
3937
|
+
|
|
3938
|
+
where `sp_{I,J}` is as defined in [NCSF]_.
|
|
3939
|
+
|
|
3940
|
+
The `\phi`-basis is well-defined only when the base ring is a
|
|
3941
|
+
`\QQ`-algebra.
|
|
3942
|
+
|
|
3943
|
+
EXAMPLES::
|
|
3944
|
+
|
|
3945
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
|
3946
|
+
sage: phi = QSym.phi(); phi
|
|
3947
|
+
Quasisymmetric functions over the Rational Field in the phi basis
|
|
3948
|
+
sage: phi.an_element()
|
|
3949
|
+
2*phi[] + 2*phi[1] + 3*phi[1, 1]
|
|
3950
|
+
sage: p = SymmetricFunctions(QQ).p()
|
|
3951
|
+
sage: phi(p[2,2,1])
|
|
3952
|
+
phi[1, 2, 2] + phi[2, 1, 2] + phi[2, 2, 1]
|
|
3953
|
+
sage: all(sum(phi(list(al)) for al in Permutations(la))==phi(p(la)) for la in Partitions(6))
|
|
3954
|
+
True
|
|
3955
|
+
sage: p = SymmetricFunctions(QQ).p()
|
|
3956
|
+
sage: phi(p[3,2,2])
|
|
3957
|
+
phi[2, 2, 3] + phi[2, 3, 2] + phi[3, 2, 2]
|
|
3958
|
+
|
|
3959
|
+
Checking the equivalent definition of `\phi_n`::
|
|
3960
|
+
|
|
3961
|
+
sage: def test_phi(n):
|
|
3962
|
+
....: phi = QuasiSymmetricFunctions(QQ).phi()
|
|
3963
|
+
....: Phi = NonCommutativeSymmetricFunctions(QQ).Phi()
|
|
3964
|
+
....: M = matrix([[phi[I].duality_pairing(Phi[J])
|
|
3965
|
+
....: for I in Compositions(n)]
|
|
3966
|
+
....: for J in Compositions(n)])
|
|
3967
|
+
....: def z(J): return J.to_partition().centralizer_size()
|
|
3968
|
+
....: return M == matrix.diagonal([z(I) for I in Compositions(n)])
|
|
3969
|
+
sage: all(test_phi(k) for k in range(1,5))
|
|
3970
|
+
True
|
|
3971
|
+
"""
|
|
3972
|
+
|
|
3973
|
+
def __init__(self, QSym):
|
|
3974
|
+
r"""
|
|
3975
|
+
Initialize ``self``.
|
|
3976
|
+
|
|
3977
|
+
EXAMPLES::
|
|
3978
|
+
|
|
3979
|
+
sage: phi = QuasiSymmetricFunctions(QQ).phi()
|
|
3980
|
+
sage: TestSuite(phi).run()
|
|
3981
|
+
|
|
3982
|
+
TESTS::
|
|
3983
|
+
|
|
3984
|
+
sage: phi = QuasiSymmetricFunctions(QQ).phi()
|
|
3985
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
|
3986
|
+
sage: all(phi(M(phi[c])) == phi[c] for n in range(5)
|
|
3987
|
+
....: for c in Compositions(n))
|
|
3988
|
+
True
|
|
3989
|
+
sage: all(M(phi(M[c])) == M[c] for n in range(5)
|
|
3990
|
+
....: for c in Compositions(n))
|
|
3991
|
+
True
|
|
3992
|
+
"""
|
|
3993
|
+
CombinatorialFreeModule.__init__(self, QSym.base_ring(), Compositions(),
|
|
3994
|
+
prefix='phi', bracket=False,
|
|
3995
|
+
category=QSym.Bases())
|
|
3996
|
+
|
|
3997
|
+
category = self.realization_of()._category
|
|
3998
|
+
Monomial = self.realization_of().Monomial()
|
|
3999
|
+
self.module_morphism(self._to_Monomial_on_basis,
|
|
4000
|
+
codomain=Monomial, category=category
|
|
4001
|
+
).register_as_coercion()
|
|
4002
|
+
Monomial.module_morphism(self._from_Monomial_on_basis,
|
|
4003
|
+
codomain=self, category=category
|
|
4004
|
+
).register_as_coercion()
|
|
4005
|
+
|
|
4006
|
+
def _from_Monomial_on_basis(self, I):
|
|
4007
|
+
r"""
|
|
4008
|
+
Expand a Monomial basis element indexed by ``I`` in the
|
|
4009
|
+
`\phi` basis.
|
|
4010
|
+
|
|
4011
|
+
INPUT:
|
|
4012
|
+
|
|
4013
|
+
- ``I`` -- a composition
|
|
4014
|
+
|
|
4015
|
+
OUTPUT: a quasi-symmetric function in the `\psi` basis
|
|
4016
|
+
|
|
4017
|
+
TESTS::
|
|
4018
|
+
|
|
4019
|
+
sage: phi = QuasiSymmetricFunctions(QQ).phi()
|
|
4020
|
+
sage: I = Composition([3, 2, 2])
|
|
4021
|
+
sage: phi._from_Monomial_on_basis(I)
|
|
4022
|
+
1/2*phi[3, 2, 2] - 1/2*phi[3, 4] - 1/2*phi[5, 2] + 1/3*phi[7]
|
|
4023
|
+
"""
|
|
4024
|
+
R = self.base_ring()
|
|
4025
|
+
minus_one = -R.one()
|
|
4026
|
+
|
|
4027
|
+
def z(J):
|
|
4028
|
+
return R(J.to_partition().centralizer_size())
|
|
4029
|
+
return self._from_dict({J: minus_one**(len(I)-len(J)) * R.prod(J) / (coeff_ell(I, J) * z(J))
|
|
4030
|
+
for J in I.fatter()})
|
|
4031
|
+
|
|
4032
|
+
def _to_Monomial_on_basis(self, I):
|
|
4033
|
+
r"""
|
|
4034
|
+
Expand a `\phi` basis element indexed by ``I`` in the
|
|
4035
|
+
Monomial basis.
|
|
4036
|
+
|
|
4037
|
+
INPUT:
|
|
4038
|
+
|
|
4039
|
+
- ``I`` -- a composition
|
|
4040
|
+
|
|
4041
|
+
OUTPUT: a quasi-symmetric function in the Monomial basis
|
|
4042
|
+
|
|
4043
|
+
TESTS::
|
|
4044
|
+
|
|
4045
|
+
sage: phi = QuasiSymmetricFunctions(QQ).phi()
|
|
4046
|
+
sage: I = Composition([3, 2, 2])
|
|
4047
|
+
sage: phi._to_Monomial_on_basis(I)
|
|
4048
|
+
2*M[3, 2, 2] + M[3, 4] + M[5, 2] + 1/3*M[7]
|
|
4049
|
+
"""
|
|
4050
|
+
R = self.base_ring()
|
|
4051
|
+
z = R(I.to_partition().centralizer_size())
|
|
4052
|
+
Monomial = self.realization_of().Monomial()
|
|
4053
|
+
return Monomial._from_dict({J: z / coeff_sp(I,J) for J in I.fatter()})
|