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