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,1011 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Shuffle algebras
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Frédéric Chapoton (2013-03): Initial version
|
|
9
|
+
- Matthieu Deneufchatel (2013-07): Implemented dual PBW basis
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# ****************************************************************************
|
|
13
|
+
# Copyright (C) 2013 Frédéric Chapoton <chapoton-math-univ-lyon1-fr>
|
|
14
|
+
#
|
|
15
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
16
|
+
# https://www.gnu.org/licenses/
|
|
17
|
+
# ****************************************************************************
|
|
18
|
+
|
|
19
|
+
from sage.categories.rings import Rings
|
|
20
|
+
from sage.categories.graded_hopf_algebras_with_basis import GradedHopfAlgebrasWithBasis
|
|
21
|
+
from sage.combinat.free_module import CombinatorialFreeModule
|
|
22
|
+
from sage.combinat.words.alphabet import Alphabet
|
|
23
|
+
from sage.combinat.words.words import Words
|
|
24
|
+
from sage.combinat.words.finite_word import FiniteWord_class
|
|
25
|
+
from sage.misc.cachefunc import cached_method
|
|
26
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
27
|
+
from sage.misc.misc_c import prod
|
|
28
|
+
from sage.sets.family import Family
|
|
29
|
+
from sage.rings.integer_ring import ZZ
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ShuffleAlgebra(CombinatorialFreeModule):
|
|
33
|
+
r"""
|
|
34
|
+
The shuffle algebra on some generators over a base ring.
|
|
35
|
+
|
|
36
|
+
Shuffle algebras are commutative and associative algebras, with a
|
|
37
|
+
basis indexed by words. The product of two words `w_1 \cdot w_2` is given
|
|
38
|
+
by the sum over the shuffle product of `w_1` and `w_2`.
|
|
39
|
+
|
|
40
|
+
.. SEEALSO::
|
|
41
|
+
|
|
42
|
+
For more on shuffle products, see
|
|
43
|
+
:mod:`~sage.combinat.words.shuffle_product` and
|
|
44
|
+
:meth:`~sage.combinat.words.finite_word.FiniteWord_class.shuffle()`.
|
|
45
|
+
|
|
46
|
+
REFERENCES:
|
|
47
|
+
|
|
48
|
+
- :wikipedia:`Shuffle algebra`
|
|
49
|
+
|
|
50
|
+
INPUT:
|
|
51
|
+
|
|
52
|
+
- ``R`` -- ring
|
|
53
|
+
|
|
54
|
+
- ``names`` -- generator names (string or an alphabet)
|
|
55
|
+
|
|
56
|
+
EXAMPLES::
|
|
57
|
+
|
|
58
|
+
sage: F = ShuffleAlgebra(QQ, 'xyz'); F
|
|
59
|
+
Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Rational Field
|
|
60
|
+
|
|
61
|
+
sage: mul(F.gens())
|
|
62
|
+
B[xyz] + B[xzy] + B[yxz] + B[yzx] + B[zxy] + B[zyx]
|
|
63
|
+
|
|
64
|
+
sage: mul([ F.gen(i) for i in range(2) ]) + mul([ F.gen(i+1) for i in range(2) ])
|
|
65
|
+
B[xy] + B[yx] + B[yz] + B[zy]
|
|
66
|
+
|
|
67
|
+
sage: S = ShuffleAlgebra(ZZ, 'abcabc'); S
|
|
68
|
+
Shuffle Algebra on 3 generators ['a', 'b', 'c'] over Integer Ring
|
|
69
|
+
sage: S.base_ring()
|
|
70
|
+
Integer Ring
|
|
71
|
+
|
|
72
|
+
sage: G = ShuffleAlgebra(S, 'mn'); G
|
|
73
|
+
Shuffle Algebra on 2 generators ['m', 'n'] over Shuffle Algebra on 3 generators ['a', 'b', 'c'] over Integer Ring
|
|
74
|
+
sage: G.base_ring()
|
|
75
|
+
Shuffle Algebra on 3 generators ['a', 'b', 'c'] over Integer Ring
|
|
76
|
+
|
|
77
|
+
Shuffle algebras commute with their base ring::
|
|
78
|
+
|
|
79
|
+
sage: K = ShuffleAlgebra(QQ,'ab')
|
|
80
|
+
sage: a,b = K.gens()
|
|
81
|
+
sage: K.is_commutative()
|
|
82
|
+
True
|
|
83
|
+
sage: L = ShuffleAlgebra(K,'cd')
|
|
84
|
+
sage: c,d = L.gens()
|
|
85
|
+
sage: L.is_commutative()
|
|
86
|
+
True
|
|
87
|
+
sage: s = a*b^2 * c^3; s
|
|
88
|
+
(12*B[abb]+12*B[bab]+12*B[bba])*B[ccc]
|
|
89
|
+
sage: parent(s)
|
|
90
|
+
Shuffle Algebra on 2 generators ['c', 'd'] over Shuffle Algebra on 2 generators ['a', 'b'] over Rational Field
|
|
91
|
+
sage: c^3 * a * b^2
|
|
92
|
+
(12*B[abb]+12*B[bab]+12*B[bba])*B[ccc]
|
|
93
|
+
|
|
94
|
+
Shuffle algebras are commutative::
|
|
95
|
+
|
|
96
|
+
sage: c^3 * b * a * b == c * a * c * b^2 * c
|
|
97
|
+
True
|
|
98
|
+
|
|
99
|
+
We can also manipulate elements in the basis and coerce elements from our
|
|
100
|
+
base field::
|
|
101
|
+
|
|
102
|
+
sage: F = ShuffleAlgebra(QQ, 'abc')
|
|
103
|
+
sage: B = F.basis()
|
|
104
|
+
sage: B[Word('bb')] * B[Word('ca')]
|
|
105
|
+
B[bbca] + B[bcab] + B[bcba] + B[cabb]
|
|
106
|
+
+ B[cbab] + B[cbba]
|
|
107
|
+
sage: 1 - B[Word('bb')] * B[Word('ca')] / 2
|
|
108
|
+
B[] - 1/2*B[bbca] - 1/2*B[bcab] - 1/2*B[bcba]
|
|
109
|
+
- 1/2*B[cabb] - 1/2*B[cbab] - 1/2*B[cbba]
|
|
110
|
+
|
|
111
|
+
TESTS::
|
|
112
|
+
|
|
113
|
+
sage: R = ShuffleAlgebra(QQ,'x')
|
|
114
|
+
sage: R.is_commutative()
|
|
115
|
+
True
|
|
116
|
+
sage: R = ShuffleAlgebra(QQ,'xy')
|
|
117
|
+
sage: R.is_commutative()
|
|
118
|
+
True
|
|
119
|
+
|
|
120
|
+
Check for a fix when using numbers as generators::
|
|
121
|
+
|
|
122
|
+
sage: A = algebras.Shuffle(QQ,[0,1])
|
|
123
|
+
sage: A_d = A.dual_pbw_basis()
|
|
124
|
+
sage: W = A.basis().keys()
|
|
125
|
+
sage: x = A(W([0,1,0]))
|
|
126
|
+
sage: A_d(x)
|
|
127
|
+
-2*S[001] + S[010]
|
|
128
|
+
"""
|
|
129
|
+
@staticmethod
|
|
130
|
+
def __classcall_private__(cls, R, names, prefix=None):
|
|
131
|
+
"""
|
|
132
|
+
Normalize input to ensure a unique representation.
|
|
133
|
+
|
|
134
|
+
EXAMPLES::
|
|
135
|
+
|
|
136
|
+
sage: F1 = ShuffleAlgebra(QQ, 'xyz')
|
|
137
|
+
sage: F2 = ShuffleAlgebra(QQ, ['x','y','z'])
|
|
138
|
+
sage: F3 = ShuffleAlgebra(QQ, Alphabet('xyz'))
|
|
139
|
+
sage: F1 is F2 and F1 is F3
|
|
140
|
+
True
|
|
141
|
+
"""
|
|
142
|
+
if prefix is None:
|
|
143
|
+
prefix = 'B'
|
|
144
|
+
return super().__classcall__(cls, R,
|
|
145
|
+
Alphabet(names), prefix)
|
|
146
|
+
|
|
147
|
+
def __init__(self, R, names, prefix):
|
|
148
|
+
r"""
|
|
149
|
+
Initialize ``self``.
|
|
150
|
+
|
|
151
|
+
EXAMPLES::
|
|
152
|
+
|
|
153
|
+
sage: F = ShuffleAlgebra(QQ, 'xyz'); F
|
|
154
|
+
Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Rational Field
|
|
155
|
+
sage: TestSuite(F).run() # long time
|
|
156
|
+
|
|
157
|
+
TESTS::
|
|
158
|
+
|
|
159
|
+
sage: ShuffleAlgebra(24, 'toto')
|
|
160
|
+
Traceback (most recent call last):
|
|
161
|
+
...
|
|
162
|
+
TypeError: argument R must be a ring
|
|
163
|
+
|
|
164
|
+
sage: F = ShuffleAlgebra(QQ, 'xyz', prefix='f'); F
|
|
165
|
+
Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Rational Field
|
|
166
|
+
sage: F.gens()
|
|
167
|
+
Family (f[x], f[y], f[z])
|
|
168
|
+
"""
|
|
169
|
+
if R not in Rings():
|
|
170
|
+
raise TypeError("argument R must be a ring")
|
|
171
|
+
self._alphabet = names
|
|
172
|
+
self.__ngens = self._alphabet.cardinality()
|
|
173
|
+
cat = GradedHopfAlgebrasWithBasis(R).Commutative().Connected()
|
|
174
|
+
CombinatorialFreeModule.__init__(self, R, Words(names, infinite=False),
|
|
175
|
+
latex_prefix='', prefix=prefix,
|
|
176
|
+
category=cat)
|
|
177
|
+
|
|
178
|
+
def variable_names(self):
|
|
179
|
+
r"""
|
|
180
|
+
Return the names of the variables.
|
|
181
|
+
|
|
182
|
+
EXAMPLES::
|
|
183
|
+
|
|
184
|
+
sage: R = ShuffleAlgebra(QQ,'xy')
|
|
185
|
+
sage: R.variable_names()
|
|
186
|
+
{'x', 'y'}
|
|
187
|
+
"""
|
|
188
|
+
return self._alphabet
|
|
189
|
+
|
|
190
|
+
def _repr_term(self, t):
|
|
191
|
+
"""
|
|
192
|
+
Return a string representation of the basis element indexed by ``t``.
|
|
193
|
+
|
|
194
|
+
EXAMPLES::
|
|
195
|
+
|
|
196
|
+
sage: R = ShuffleAlgebra(QQ,'xyz')
|
|
197
|
+
sage: R._repr_term(R._indices('xyzxxy'))
|
|
198
|
+
'B[xyzxxy]'
|
|
199
|
+
"""
|
|
200
|
+
return "{!s}[{!s}]".format(self._print_options['prefix'], repr(t)[6:])
|
|
201
|
+
|
|
202
|
+
def _repr_(self):
|
|
203
|
+
r"""
|
|
204
|
+
Text representation of this shuffle algebra.
|
|
205
|
+
|
|
206
|
+
EXAMPLES::
|
|
207
|
+
|
|
208
|
+
sage: F = ShuffleAlgebra(QQ,'xyz')
|
|
209
|
+
sage: F # indirect doctest
|
|
210
|
+
Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Rational Field
|
|
211
|
+
|
|
212
|
+
sage: ShuffleAlgebra(ZZ,'a')
|
|
213
|
+
Shuffle Algebra on one generator ['a'] over Integer Ring
|
|
214
|
+
"""
|
|
215
|
+
if self.__ngens == 1:
|
|
216
|
+
gen = "one generator"
|
|
217
|
+
else:
|
|
218
|
+
gen = "%s generators" % self.__ngens
|
|
219
|
+
return "Shuffle Algebra on " + gen + " %s over %s" % (
|
|
220
|
+
self._alphabet.list(), self.base_ring())
|
|
221
|
+
|
|
222
|
+
@cached_method
|
|
223
|
+
def one_basis(self):
|
|
224
|
+
r"""
|
|
225
|
+
Return the empty word, which index of `1` of this algebra,
|
|
226
|
+
as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
|
|
227
|
+
|
|
228
|
+
EXAMPLES::
|
|
229
|
+
|
|
230
|
+
sage: A = ShuffleAlgebra(QQ,'a')
|
|
231
|
+
sage: A.one_basis()
|
|
232
|
+
word:
|
|
233
|
+
sage: A.one()
|
|
234
|
+
B[]
|
|
235
|
+
"""
|
|
236
|
+
return self.basis().keys()([])
|
|
237
|
+
|
|
238
|
+
def product_on_basis(self, w1, w2):
|
|
239
|
+
r"""
|
|
240
|
+
Return the product of basis elements ``w1`` and ``w2``, as per
|
|
241
|
+
:meth:`AlgebrasWithBasis.ParentMethods.product_on_basis()`.
|
|
242
|
+
|
|
243
|
+
INPUT:
|
|
244
|
+
|
|
245
|
+
- ``w1``, ``w2`` -- basis elements
|
|
246
|
+
|
|
247
|
+
EXAMPLES::
|
|
248
|
+
|
|
249
|
+
sage: A = ShuffleAlgebra(QQ,'abc')
|
|
250
|
+
sage: W = A.basis().keys()
|
|
251
|
+
sage: A.product_on_basis(W("acb"), W("cba"))
|
|
252
|
+
B[acbacb] + B[acbcab] + 2*B[acbcba]
|
|
253
|
+
+ 2*B[accbab] + 4*B[accbba] + B[cabacb]
|
|
254
|
+
+ B[cabcab] + B[cabcba] + B[cacbab]
|
|
255
|
+
+ 2*B[cacbba] + 2*B[cbaacb] + B[cbacab]
|
|
256
|
+
+ B[cbacba]
|
|
257
|
+
|
|
258
|
+
sage: (a,b,c) = A.algebra_generators()
|
|
259
|
+
sage: a * (1-b)^2 * c
|
|
260
|
+
2*B[abbc] - 2*B[abc] + 2*B[abcb] + B[ac]
|
|
261
|
+
- 2*B[acb] + 2*B[acbb] + 2*B[babc]
|
|
262
|
+
- 2*B[bac] + 2*B[bacb] + 2*B[bbac]
|
|
263
|
+
+ 2*B[bbca] - 2*B[bca] + 2*B[bcab]
|
|
264
|
+
+ 2*B[bcba] + B[ca] - 2*B[cab] + 2*B[cabb]
|
|
265
|
+
- 2*B[cba] + 2*B[cbab] + 2*B[cbba]
|
|
266
|
+
"""
|
|
267
|
+
return sum(self.basis()[u] for u in w1.shuffle(w2))
|
|
268
|
+
|
|
269
|
+
def antipode_on_basis(self, w):
|
|
270
|
+
"""
|
|
271
|
+
Return the antipode on the basis element ``w``.
|
|
272
|
+
|
|
273
|
+
EXAMPLES::
|
|
274
|
+
|
|
275
|
+
sage: A = ShuffleAlgebra(QQ,'abc')
|
|
276
|
+
sage: W = A.basis().keys()
|
|
277
|
+
sage: A.antipode_on_basis(W("acb"))
|
|
278
|
+
-B[bca]
|
|
279
|
+
"""
|
|
280
|
+
mone = -self.base_ring().one()
|
|
281
|
+
return self.term(w.reversal(), mone**len(w))
|
|
282
|
+
|
|
283
|
+
def gen(self, i):
|
|
284
|
+
r"""
|
|
285
|
+
Return the ``i``-th generator of the algebra.
|
|
286
|
+
|
|
287
|
+
INPUT:
|
|
288
|
+
|
|
289
|
+
- ``i`` -- integer
|
|
290
|
+
|
|
291
|
+
EXAMPLES::
|
|
292
|
+
|
|
293
|
+
sage: F = ShuffleAlgebra(ZZ,'xyz')
|
|
294
|
+
sage: F.gen(0)
|
|
295
|
+
B[x]
|
|
296
|
+
|
|
297
|
+
sage: F.gen(4)
|
|
298
|
+
Traceback (most recent call last):
|
|
299
|
+
...
|
|
300
|
+
IndexError: argument i (= 4) must be between 0 and 2
|
|
301
|
+
"""
|
|
302
|
+
n = self.__ngens
|
|
303
|
+
if i < 0 or not i < n:
|
|
304
|
+
raise IndexError("argument i (= %s) must be between 0 and %s" % (i, n - 1))
|
|
305
|
+
return self.algebra_generators()[i]
|
|
306
|
+
|
|
307
|
+
def some_elements(self):
|
|
308
|
+
"""
|
|
309
|
+
Return some typical elements.
|
|
310
|
+
|
|
311
|
+
EXAMPLES::
|
|
312
|
+
|
|
313
|
+
sage: F = ShuffleAlgebra(ZZ,'xyz')
|
|
314
|
+
sage: F.some_elements()
|
|
315
|
+
[0, B[], B[x], B[y], B[z], B[xz] + B[zx]]
|
|
316
|
+
"""
|
|
317
|
+
gens = list(self.algebra_generators())
|
|
318
|
+
if gens:
|
|
319
|
+
gens.append(gens[0] * gens[-1])
|
|
320
|
+
return [self.zero(), self.one()] + gens
|
|
321
|
+
|
|
322
|
+
def coproduct_on_basis(self, w):
|
|
323
|
+
"""
|
|
324
|
+
Return the coproduct of the element of the basis indexed by
|
|
325
|
+
the word ``w``.
|
|
326
|
+
|
|
327
|
+
The coproduct is given by deconcatenation.
|
|
328
|
+
|
|
329
|
+
INPUT:
|
|
330
|
+
|
|
331
|
+
- ``w`` -- a word
|
|
332
|
+
|
|
333
|
+
EXAMPLES::
|
|
334
|
+
|
|
335
|
+
sage: F = ShuffleAlgebra(QQ,'ab')
|
|
336
|
+
sage: F.coproduct_on_basis(Word('a'))
|
|
337
|
+
B[] # B[a] + B[a] # B[]
|
|
338
|
+
sage: F.coproduct_on_basis(Word('aba'))
|
|
339
|
+
B[] # B[aba] + B[a] # B[ba]
|
|
340
|
+
+ B[ab] # B[a] + B[aba] # B[]
|
|
341
|
+
sage: F.coproduct_on_basis(Word())
|
|
342
|
+
B[] # B[]
|
|
343
|
+
|
|
344
|
+
TESTS::
|
|
345
|
+
|
|
346
|
+
sage: F = ShuffleAlgebra(QQ,'ab')
|
|
347
|
+
sage: S = F.an_element(); S
|
|
348
|
+
B[] + 2*B[a] + 3*B[b] + B[bab]
|
|
349
|
+
sage: F.coproduct(S)
|
|
350
|
+
B[] # B[] + 2*B[] # B[a]
|
|
351
|
+
+ 3*B[] # B[b] + B[] # B[bab]
|
|
352
|
+
+ 2*B[a] # B[] + 3*B[b] # B[]
|
|
353
|
+
+ B[b] # B[ab] + B[ba] # B[b]
|
|
354
|
+
+ B[bab] # B[]
|
|
355
|
+
sage: F.coproduct(F.one())
|
|
356
|
+
B[] # B[]
|
|
357
|
+
"""
|
|
358
|
+
TS = self.tensor_square()
|
|
359
|
+
return TS.sum_of_monomials((w[:i], w[i:]) for i in range(len(w) + 1))
|
|
360
|
+
|
|
361
|
+
def counit(self, S):
|
|
362
|
+
"""
|
|
363
|
+
Return the counit of ``S``.
|
|
364
|
+
|
|
365
|
+
EXAMPLES::
|
|
366
|
+
|
|
367
|
+
sage: F = ShuffleAlgebra(QQ,'ab')
|
|
368
|
+
sage: S = F.an_element(); S
|
|
369
|
+
B[] + 2*B[a] + 3*B[b] + B[bab]
|
|
370
|
+
sage: F.counit(S)
|
|
371
|
+
1
|
|
372
|
+
"""
|
|
373
|
+
W = self.basis().keys()
|
|
374
|
+
return S.coefficient(W())
|
|
375
|
+
|
|
376
|
+
def degree_on_basis(self, w):
|
|
377
|
+
"""
|
|
378
|
+
Return the degree of the element ``w``.
|
|
379
|
+
|
|
380
|
+
EXAMPLES::
|
|
381
|
+
|
|
382
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
383
|
+
sage: [A.degree_on_basis(x.leading_support()) for x in A.some_elements() if x != 0]
|
|
384
|
+
[0, 1, 1, 2]
|
|
385
|
+
"""
|
|
386
|
+
return ZZ(len(w))
|
|
387
|
+
|
|
388
|
+
@cached_method
|
|
389
|
+
def algebra_generators(self):
|
|
390
|
+
r"""
|
|
391
|
+
Return the generators of this algebra.
|
|
392
|
+
|
|
393
|
+
EXAMPLES::
|
|
394
|
+
|
|
395
|
+
sage: A = ShuffleAlgebra(ZZ,'fgh'); A
|
|
396
|
+
Shuffle Algebra on 3 generators ['f', 'g', 'h'] over Integer Ring
|
|
397
|
+
sage: A.algebra_generators()
|
|
398
|
+
Family (B[f], B[g], B[h])
|
|
399
|
+
|
|
400
|
+
sage: A = ShuffleAlgebra(QQ, ['x1','x2'])
|
|
401
|
+
sage: A.algebra_generators()
|
|
402
|
+
Family (B[x1], B[x2])
|
|
403
|
+
|
|
404
|
+
TESTS::
|
|
405
|
+
|
|
406
|
+
sage: A = ShuffleAlgebra(ZZ,[0,1])
|
|
407
|
+
sage: A.algebra_generators()
|
|
408
|
+
Family (B[0], B[1])
|
|
409
|
+
"""
|
|
410
|
+
Words = self.basis().keys()
|
|
411
|
+
return Family([self.monomial(Words([a])) for a in self._alphabet])
|
|
412
|
+
# FIXME: use this once the keys argument of FiniteFamily will be honoured
|
|
413
|
+
# for the specifying the order of the elements in the family
|
|
414
|
+
# return Family(self._alphabet, lambda a: self.term(self.basis().keys()(a)))
|
|
415
|
+
|
|
416
|
+
gens = algebra_generators
|
|
417
|
+
|
|
418
|
+
def _element_constructor_(self, x):
|
|
419
|
+
r"""
|
|
420
|
+
Convert ``x`` into ``self``.
|
|
421
|
+
|
|
422
|
+
EXAMPLES::
|
|
423
|
+
|
|
424
|
+
sage: R = ShuffleAlgebra(QQ,'xy')
|
|
425
|
+
sage: x, y = R.gens()
|
|
426
|
+
sage: R(3)
|
|
427
|
+
3*B[]
|
|
428
|
+
sage: R(x)
|
|
429
|
+
B[x]
|
|
430
|
+
sage: R('xyy')
|
|
431
|
+
B[xyy]
|
|
432
|
+
sage: R(Word('xyx'))
|
|
433
|
+
B[xyx]
|
|
434
|
+
"""
|
|
435
|
+
if isinstance(x, (str, FiniteWord_class)):
|
|
436
|
+
W = self.basis().keys()
|
|
437
|
+
return self.monomial(W(x))
|
|
438
|
+
|
|
439
|
+
P = x.parent()
|
|
440
|
+
if isinstance(P, ShuffleAlgebra):
|
|
441
|
+
if P is self:
|
|
442
|
+
return x
|
|
443
|
+
if P is not self.base_ring():
|
|
444
|
+
return self.element_class(self, x.monomial_coefficients())
|
|
445
|
+
if isinstance(P, DualPBWBasis):
|
|
446
|
+
return self(P.expansion(x))
|
|
447
|
+
# ok, not a shuffle algebra element (or should not be viewed as one).
|
|
448
|
+
if isinstance(x, str):
|
|
449
|
+
from sage.misc.sage_eval import sage_eval
|
|
450
|
+
return sage_eval(x, locals=self.gens_dict())
|
|
451
|
+
R = self.base_ring()
|
|
452
|
+
# coercion via base ring
|
|
453
|
+
x = R(x)
|
|
454
|
+
if x == 0:
|
|
455
|
+
return self.element_class(self, {})
|
|
456
|
+
else:
|
|
457
|
+
return self.from_base_ring_from_one_basis(x)
|
|
458
|
+
|
|
459
|
+
def _coerce_map_from_(self, R):
|
|
460
|
+
r"""
|
|
461
|
+
Return ``True`` if there is a coercion from ``R`` into ``self``
|
|
462
|
+
and ``False`` otherwise.
|
|
463
|
+
|
|
464
|
+
The things that coerce into ``self`` are
|
|
465
|
+
|
|
466
|
+
- Shuffle Algebras in the same variables over a base with a coercion
|
|
467
|
+
map into ``self.base_ring()``.
|
|
468
|
+
|
|
469
|
+
- Anything with a coercion into ``self.base_ring()``.
|
|
470
|
+
|
|
471
|
+
EXAMPLES::
|
|
472
|
+
|
|
473
|
+
sage: F = ShuffleAlgebra(GF(7), 'xyz'); F
|
|
474
|
+
Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Finite Field of size 7
|
|
475
|
+
|
|
476
|
+
Elements of the shuffle algebra canonically coerce in::
|
|
477
|
+
|
|
478
|
+
sage: x, y, z = F.gens()
|
|
479
|
+
sage: F.coerce(x*y) # indirect doctest
|
|
480
|
+
B[xy] + B[yx]
|
|
481
|
+
|
|
482
|
+
Elements of the integers coerce in, since there is a coerce map
|
|
483
|
+
from `\ZZ` to GF(7)::
|
|
484
|
+
|
|
485
|
+
sage: F.coerce(1) # indirect doctest
|
|
486
|
+
B[]
|
|
487
|
+
|
|
488
|
+
There is no coerce map from `\QQ` to `\GF{7}`::
|
|
489
|
+
|
|
490
|
+
sage: F.coerce(2/3) # indirect doctest
|
|
491
|
+
Traceback (most recent call last):
|
|
492
|
+
...
|
|
493
|
+
TypeError: no canonical coercion from Rational Field to Shuffle Algebra on 3 generators ['x', 'y', 'z'] over Finite Field of size 7
|
|
494
|
+
|
|
495
|
+
Elements of the base ring coerce in::
|
|
496
|
+
|
|
497
|
+
sage: F.coerce(GF(7)(5))
|
|
498
|
+
5*B[]
|
|
499
|
+
|
|
500
|
+
The shuffle algebra over `\ZZ` on `x, y, z` coerces in, since
|
|
501
|
+
`\ZZ` coerces to `\GF{7}`::
|
|
502
|
+
|
|
503
|
+
sage: G = ShuffleAlgebra(ZZ,'xyz')
|
|
504
|
+
sage: Gx,Gy,Gz = G.gens()
|
|
505
|
+
sage: z = F.coerce(Gx**2 * Gy);z
|
|
506
|
+
2*B[xxy] + 2*B[xyx] + 2*B[yxx]
|
|
507
|
+
sage: z.parent() is F
|
|
508
|
+
True
|
|
509
|
+
|
|
510
|
+
However, `\GF{7}` does not coerce to `\ZZ`, so the shuffle
|
|
511
|
+
algebra over `\GF{7}` does not coerce to the one over `\ZZ`::
|
|
512
|
+
|
|
513
|
+
sage: G.coerce(x^3*y)
|
|
514
|
+
Traceback (most recent call last):
|
|
515
|
+
...
|
|
516
|
+
TypeError: no canonical coercion from Shuffle Algebra on 3 generators
|
|
517
|
+
['x', 'y', 'z'] over Finite Field of size 7 to Shuffle Algebra on 3
|
|
518
|
+
generators ['x', 'y', 'z'] over Integer Ring
|
|
519
|
+
|
|
520
|
+
TESTS::
|
|
521
|
+
|
|
522
|
+
sage: F = ShuffleAlgebra(ZZ, 'xyz')
|
|
523
|
+
sage: G = ShuffleAlgebra(QQ, 'xyz')
|
|
524
|
+
sage: H = ShuffleAlgebra(ZZ, 'y')
|
|
525
|
+
sage: F._coerce_map_from_(G)
|
|
526
|
+
False
|
|
527
|
+
sage: G._coerce_map_from_(F)
|
|
528
|
+
True
|
|
529
|
+
sage: F._coerce_map_from_(H)
|
|
530
|
+
False
|
|
531
|
+
sage: F._coerce_map_from_(QQ)
|
|
532
|
+
False
|
|
533
|
+
sage: G._coerce_map_from_(QQ)
|
|
534
|
+
True
|
|
535
|
+
sage: F.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z'))
|
|
536
|
+
False
|
|
537
|
+
sage: F._coerce_map_from_(F.dual_pbw_basis())
|
|
538
|
+
True
|
|
539
|
+
"""
|
|
540
|
+
# shuffle algebras in the same variable over any base that coerces in:
|
|
541
|
+
if isinstance(R, ShuffleAlgebra):
|
|
542
|
+
if R.variable_names() == self.variable_names():
|
|
543
|
+
if self.base_ring().has_coerce_map_from(R.base_ring()):
|
|
544
|
+
return True
|
|
545
|
+
else:
|
|
546
|
+
return False
|
|
547
|
+
|
|
548
|
+
if isinstance(R, DualPBWBasis):
|
|
549
|
+
return self.has_coerce_map_from(R._alg)
|
|
550
|
+
|
|
551
|
+
return self.base_ring().has_coerce_map_from(R)
|
|
552
|
+
|
|
553
|
+
def dual_pbw_basis(self):
|
|
554
|
+
"""
|
|
555
|
+
Return the dual PBW of ``self``.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
560
|
+
sage: A.dual_pbw_basis()
|
|
561
|
+
The dual Poincare-Birkhoff-Witt basis of Shuffle Algebra on 2 generators ['a', 'b'] over Rational Field
|
|
562
|
+
"""
|
|
563
|
+
return DualPBWBasis(self.base_ring(), self._alphabet)
|
|
564
|
+
|
|
565
|
+
def to_dual_pbw_element(self, w):
|
|
566
|
+
"""
|
|
567
|
+
Return the element `w` of ``self`` expressed in the dual PBW basis.
|
|
568
|
+
|
|
569
|
+
INPUT:
|
|
570
|
+
|
|
571
|
+
- ``w`` -- an element of the shuffle algebra
|
|
572
|
+
|
|
573
|
+
EXAMPLES::
|
|
574
|
+
|
|
575
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
576
|
+
sage: f = 2 * A(Word()) + A(Word('ab')); f
|
|
577
|
+
2*B[] + B[ab]
|
|
578
|
+
sage: A.to_dual_pbw_element(f)
|
|
579
|
+
2*S[] + S[ab]
|
|
580
|
+
sage: A.to_dual_pbw_element(A.one())
|
|
581
|
+
S[]
|
|
582
|
+
sage: S = A.dual_pbw_basis()
|
|
583
|
+
sage: elt = S.expansion_on_basis(Word('abba')); elt
|
|
584
|
+
2*B[aabb] + B[abab] + B[abba]
|
|
585
|
+
sage: A.to_dual_pbw_element(elt)
|
|
586
|
+
S[abba]
|
|
587
|
+
sage: A.to_dual_pbw_element(2*A(Word('aabb')) + A(Word('abab')))
|
|
588
|
+
S[abab]
|
|
589
|
+
sage: S.expansion(S('abab'))
|
|
590
|
+
2*B[aabb] + B[abab]
|
|
591
|
+
"""
|
|
592
|
+
D = self.dual_pbw_basis()
|
|
593
|
+
l = {}
|
|
594
|
+
W = self.basis().keys()
|
|
595
|
+
while w != self.zero():
|
|
596
|
+
support = [W(i[0]) for i in list(w)]
|
|
597
|
+
min_elt = W(support[0])
|
|
598
|
+
if len(support) > 1:
|
|
599
|
+
for word in support[1:len(support) - 1]:
|
|
600
|
+
if min_elt.lex_less(word):
|
|
601
|
+
min_elt = W(word)
|
|
602
|
+
coeff = list(w)[support.index(min_elt)][1]
|
|
603
|
+
l[min_elt] = l.get(min_elt, 0) + coeff
|
|
604
|
+
w = w - coeff * D.expansion_on_basis(W(min_elt))
|
|
605
|
+
|
|
606
|
+
return D.sum_of_terms((m, c) for m, c in l.items() if c != 0)
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
class DualPBWBasis(CombinatorialFreeModule):
|
|
610
|
+
r"""
|
|
611
|
+
The basis dual to the Poincaré-Birkhoff-Witt basis of the free algebra.
|
|
612
|
+
|
|
613
|
+
We recursively define the dual PBW basis as the basis of the
|
|
614
|
+
shuffle algebra given by
|
|
615
|
+
|
|
616
|
+
.. MATH::
|
|
617
|
+
|
|
618
|
+
S_w = \begin{cases}
|
|
619
|
+
w & |w| = 1, \\
|
|
620
|
+
x S_u & w = xu \text{ and } w \in \mathrm{Lyn}(X), \\
|
|
621
|
+
\displaystyle \frac{S_{\ell_{i_1}}^{\ast \alpha_1} \ast \cdots
|
|
622
|
+
\ast S_{\ell_{i_k}}^{\ast \alpha_k}}{\alpha_1! \cdots \alpha_k!} &
|
|
623
|
+
w = \ell_{i_1}^{\alpha_1} \cdots \ell_{i_k}^{\alpha_k} \text{ with }
|
|
624
|
+
\ell_1 > \cdots > \ell_k \in \mathrm{Lyn}(X).
|
|
625
|
+
\end{cases}
|
|
626
|
+
|
|
627
|
+
where `S \ast T` denotes the shuffle product of `S` and `T` and
|
|
628
|
+
`\mathrm{Lyn}(X)` is the set of Lyndon words in the alphabet `X`.
|
|
629
|
+
|
|
630
|
+
The definition may be found in Theorem 5.3 of [Reu1993]_.
|
|
631
|
+
|
|
632
|
+
INPUT:
|
|
633
|
+
|
|
634
|
+
- ``R`` -- ring
|
|
635
|
+
|
|
636
|
+
- ``names`` -- names of the generators (string or an alphabet)
|
|
637
|
+
|
|
638
|
+
EXAMPLES::
|
|
639
|
+
|
|
640
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
641
|
+
sage: S
|
|
642
|
+
The dual Poincare-Birkhoff-Witt basis of Shuffle Algebra on 2 generators ['a', 'b'] over Rational Field
|
|
643
|
+
sage: S.one()
|
|
644
|
+
S[]
|
|
645
|
+
sage: S.one_basis()
|
|
646
|
+
word:
|
|
647
|
+
sage: T = ShuffleAlgebra(QQ, 'abcd').dual_pbw_basis(); T
|
|
648
|
+
The dual Poincare-Birkhoff-Witt basis of Shuffle Algebra on 4 generators ['a', 'b', 'c', 'd'] over Rational Field
|
|
649
|
+
sage: T.algebra_generators()
|
|
650
|
+
(S[a], S[b], S[c], S[d])
|
|
651
|
+
|
|
652
|
+
TESTS:
|
|
653
|
+
|
|
654
|
+
We check conversion between the bases::
|
|
655
|
+
|
|
656
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
657
|
+
sage: S = A.dual_pbw_basis()
|
|
658
|
+
sage: W = Words('ab', 5)
|
|
659
|
+
sage: all(S(A(S(w))) == S(w) for w in W)
|
|
660
|
+
True
|
|
661
|
+
sage: all(A(S(A(w))) == A(w) for w in W)
|
|
662
|
+
True
|
|
663
|
+
"""
|
|
664
|
+
@staticmethod
|
|
665
|
+
def __classcall_private__(cls, R, names):
|
|
666
|
+
"""
|
|
667
|
+
Normalize input to ensure a unique representation.
|
|
668
|
+
|
|
669
|
+
EXAMPLES::
|
|
670
|
+
|
|
671
|
+
sage: from sage.algebras.shuffle_algebra import DualPBWBasis
|
|
672
|
+
sage: D1 = DualPBWBasis(QQ, 'ab')
|
|
673
|
+
sage: D2 = DualPBWBasis(QQ, Alphabet('ab'))
|
|
674
|
+
sage: D1 is D2
|
|
675
|
+
True
|
|
676
|
+
"""
|
|
677
|
+
return super().__classcall__(cls, R, Alphabet(names))
|
|
678
|
+
|
|
679
|
+
def __init__(self, R, names):
|
|
680
|
+
"""
|
|
681
|
+
Initialize ``self``.
|
|
682
|
+
|
|
683
|
+
EXAMPLES::
|
|
684
|
+
|
|
685
|
+
sage: D = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
686
|
+
sage: TestSuite(D).run() # long time
|
|
687
|
+
"""
|
|
688
|
+
self._alphabet = names
|
|
689
|
+
self._alg = ShuffleAlgebra(R, names)
|
|
690
|
+
cat = GradedHopfAlgebrasWithBasis(R).Commutative().Connected()
|
|
691
|
+
CombinatorialFreeModule.__init__(self, R, Words(names), prefix='S',
|
|
692
|
+
category=cat)
|
|
693
|
+
|
|
694
|
+
def _repr_term(self, t):
|
|
695
|
+
"""
|
|
696
|
+
Return a string representation of the basis element indexed by ``t``.
|
|
697
|
+
|
|
698
|
+
EXAMPLES::
|
|
699
|
+
|
|
700
|
+
sage: R = ShuffleAlgebra(QQ,'xyz').dual_pbw_basis()
|
|
701
|
+
sage: R._repr_term(R._indices('xyzxxy'))
|
|
702
|
+
'S[xyzxxy]'
|
|
703
|
+
"""
|
|
704
|
+
return "{!s}[{!s}]".format(self._print_options['prefix'], repr(t)[6:])
|
|
705
|
+
|
|
706
|
+
def _repr_(self):
|
|
707
|
+
"""
|
|
708
|
+
Return a string representation of ``self``.
|
|
709
|
+
|
|
710
|
+
EXAMPLES::
|
|
711
|
+
|
|
712
|
+
sage: ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
713
|
+
The dual Poincare-Birkhoff-Witt basis of Shuffle Algebra on 2 generators ['a', 'b'] over Rational Field
|
|
714
|
+
"""
|
|
715
|
+
return "The dual Poincare-Birkhoff-Witt basis of {}".format(self._alg)
|
|
716
|
+
|
|
717
|
+
def _element_constructor_(self, x):
|
|
718
|
+
"""
|
|
719
|
+
Construct an element of ``self`` from ``x``.
|
|
720
|
+
|
|
721
|
+
EXAMPLES::
|
|
722
|
+
|
|
723
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
724
|
+
sage: S = A.dual_pbw_basis()
|
|
725
|
+
sage: S('abaab')
|
|
726
|
+
S[abaab]
|
|
727
|
+
sage: S(Word('aba'))
|
|
728
|
+
S[aba]
|
|
729
|
+
sage: S(A('ab'))
|
|
730
|
+
S[ab]
|
|
731
|
+
"""
|
|
732
|
+
if isinstance(x, (str, FiniteWord_class)):
|
|
733
|
+
W = self.basis().keys()
|
|
734
|
+
x = W(x)
|
|
735
|
+
elif isinstance(x.parent(), ShuffleAlgebra):
|
|
736
|
+
return self._alg.to_dual_pbw_element(self._alg(x))
|
|
737
|
+
return super()._element_constructor_(x)
|
|
738
|
+
|
|
739
|
+
def _coerce_map_from_(self, R):
|
|
740
|
+
"""
|
|
741
|
+
Return ``True`` if there is a coercion from ``R`` into ``self`` and
|
|
742
|
+
``False`` otherwise. The things that coerce into ``self`` are:
|
|
743
|
+
|
|
744
|
+
- Anything that coerces into the associated shuffle algebra of ``self``
|
|
745
|
+
|
|
746
|
+
TESTS::
|
|
747
|
+
|
|
748
|
+
sage: F = ShuffleAlgebra(ZZ, 'xyz').dual_pbw_basis()
|
|
749
|
+
sage: G = ShuffleAlgebra(QQ, 'xyz').dual_pbw_basis()
|
|
750
|
+
sage: H = ShuffleAlgebra(ZZ, 'y').dual_pbw_basis()
|
|
751
|
+
sage: F._coerce_map_from_(G)
|
|
752
|
+
False
|
|
753
|
+
sage: G._coerce_map_from_(F)
|
|
754
|
+
True
|
|
755
|
+
sage: F._coerce_map_from_(H)
|
|
756
|
+
False
|
|
757
|
+
sage: F._coerce_map_from_(QQ)
|
|
758
|
+
False
|
|
759
|
+
sage: G._coerce_map_from_(QQ)
|
|
760
|
+
True
|
|
761
|
+
sage: F.has_coerce_map_from(PolynomialRing(ZZ, 3, 'x,y,z'))
|
|
762
|
+
False
|
|
763
|
+
sage: F._coerce_map_from_(F._alg)
|
|
764
|
+
True
|
|
765
|
+
"""
|
|
766
|
+
return self._alg.has_coerce_map_from(R)
|
|
767
|
+
|
|
768
|
+
def one_basis(self):
|
|
769
|
+
"""
|
|
770
|
+
Return the indexing element of the basis element `1`.
|
|
771
|
+
|
|
772
|
+
EXAMPLES::
|
|
773
|
+
|
|
774
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
775
|
+
sage: S.one_basis()
|
|
776
|
+
word:
|
|
777
|
+
"""
|
|
778
|
+
W = self.basis().keys()
|
|
779
|
+
return W([])
|
|
780
|
+
|
|
781
|
+
def counit(self, S):
|
|
782
|
+
"""
|
|
783
|
+
Return the counit of ``S``.
|
|
784
|
+
|
|
785
|
+
EXAMPLES::
|
|
786
|
+
|
|
787
|
+
sage: F = ShuffleAlgebra(QQ,'ab').dual_pbw_basis()
|
|
788
|
+
sage: (3*F.gen(0)+5*F.gen(1)**2).counit()
|
|
789
|
+
0
|
|
790
|
+
sage: (4*F.one()).counit()
|
|
791
|
+
4
|
|
792
|
+
"""
|
|
793
|
+
W = self.basis().keys()
|
|
794
|
+
return S.coefficient(W())
|
|
795
|
+
|
|
796
|
+
def algebra_generators(self):
|
|
797
|
+
"""
|
|
798
|
+
Return the algebra generators of ``self``.
|
|
799
|
+
|
|
800
|
+
EXAMPLES::
|
|
801
|
+
|
|
802
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
803
|
+
sage: S.algebra_generators()
|
|
804
|
+
(S[a], S[b])
|
|
805
|
+
"""
|
|
806
|
+
W = self.basis().keys()
|
|
807
|
+
return tuple(self.monomial(W([a])) for a in self._alphabet)
|
|
808
|
+
|
|
809
|
+
gens = algebra_generators
|
|
810
|
+
|
|
811
|
+
def gen(self, i):
|
|
812
|
+
"""
|
|
813
|
+
Return the ``i``-th generator of ``self``.
|
|
814
|
+
|
|
815
|
+
EXAMPLES::
|
|
816
|
+
|
|
817
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
818
|
+
sage: S.gen(0)
|
|
819
|
+
S[a]
|
|
820
|
+
sage: S.gen(1)
|
|
821
|
+
S[b]
|
|
822
|
+
"""
|
|
823
|
+
return self.algebra_generators()[i]
|
|
824
|
+
|
|
825
|
+
def some_elements(self):
|
|
826
|
+
"""
|
|
827
|
+
Return some typical elements.
|
|
828
|
+
|
|
829
|
+
EXAMPLES::
|
|
830
|
+
|
|
831
|
+
sage: F = ShuffleAlgebra(QQ,'xyz').dual_pbw_basis()
|
|
832
|
+
sage: F.some_elements()
|
|
833
|
+
[0, S[], S[x], S[y], S[z], S[zx]]
|
|
834
|
+
"""
|
|
835
|
+
gens = list(self.algebra_generators())
|
|
836
|
+
if gens:
|
|
837
|
+
gens.append(gens[0] * gens[-1])
|
|
838
|
+
return [self.zero(), self.one()] + gens
|
|
839
|
+
|
|
840
|
+
def shuffle_algebra(self):
|
|
841
|
+
"""
|
|
842
|
+
Return the associated shuffle algebra of ``self``.
|
|
843
|
+
|
|
844
|
+
EXAMPLES::
|
|
845
|
+
|
|
846
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
847
|
+
sage: S.shuffle_algebra()
|
|
848
|
+
Shuffle Algebra on 2 generators ['a', 'b'] over Rational Field
|
|
849
|
+
"""
|
|
850
|
+
return self._alg
|
|
851
|
+
|
|
852
|
+
def product(self, u, v):
|
|
853
|
+
"""
|
|
854
|
+
Return the product of two elements ``u`` and ``v``.
|
|
855
|
+
|
|
856
|
+
EXAMPLES::
|
|
857
|
+
|
|
858
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
859
|
+
sage: a,b = S.gens()
|
|
860
|
+
sage: S.product(a, b)
|
|
861
|
+
S[ba]
|
|
862
|
+
sage: S.product(b, a)
|
|
863
|
+
S[ba]
|
|
864
|
+
sage: S.product(b^2*a, a*b*a)
|
|
865
|
+
36*S[bbbaaa]
|
|
866
|
+
|
|
867
|
+
TESTS:
|
|
868
|
+
|
|
869
|
+
Check that multiplication agrees with the multiplication in the
|
|
870
|
+
shuffle algebra::
|
|
871
|
+
|
|
872
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
873
|
+
sage: S = A.dual_pbw_basis()
|
|
874
|
+
sage: a,b = S.gens()
|
|
875
|
+
sage: A(a*b)
|
|
876
|
+
B[ab] + B[ba]
|
|
877
|
+
sage: A(a*b*a)
|
|
878
|
+
2*B[aab] + 2*B[aba] + 2*B[baa]
|
|
879
|
+
sage: S(A(a)*A(b)*A(a)) == a*b*a
|
|
880
|
+
True
|
|
881
|
+
"""
|
|
882
|
+
return self(self.expansion(u) * self.expansion(v))
|
|
883
|
+
|
|
884
|
+
def antipode(self, elt):
|
|
885
|
+
"""
|
|
886
|
+
Return the antipode of the element ``elt``.
|
|
887
|
+
|
|
888
|
+
EXAMPLES::
|
|
889
|
+
|
|
890
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
891
|
+
sage: S = A.dual_pbw_basis()
|
|
892
|
+
sage: w = S('abaab').antipode(); w
|
|
893
|
+
S[abaab] - 2*S[ababa] - S[baaba]
|
|
894
|
+
+ 3*S[babaa] - 6*S[bbaaa]
|
|
895
|
+
sage: w.antipode()
|
|
896
|
+
S[abaab]
|
|
897
|
+
"""
|
|
898
|
+
return self(self.expansion(elt).antipode())
|
|
899
|
+
|
|
900
|
+
def coproduct(self, elt):
|
|
901
|
+
"""
|
|
902
|
+
Return the coproduct of the element ``elt``.
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: A = ShuffleAlgebra(QQ, 'ab')
|
|
907
|
+
sage: S = A.dual_pbw_basis()
|
|
908
|
+
sage: S('ab').coproduct()
|
|
909
|
+
S[] # S[ab] + S[a] # S[b]
|
|
910
|
+
+ S[ab] # S[]
|
|
911
|
+
sage: S('ba').coproduct()
|
|
912
|
+
S[] # S[ba] + S[a] # S[b]
|
|
913
|
+
+ S[b] # S[a] + S[ba] # S[]
|
|
914
|
+
|
|
915
|
+
TESTS::
|
|
916
|
+
|
|
917
|
+
sage: all(A.tensor_square()(S(x).coproduct()) == x.coproduct()
|
|
918
|
+
....: for x in A.some_elements())
|
|
919
|
+
True
|
|
920
|
+
sage: all(S.tensor_square()(A(x).coproduct()) == x.coproduct()
|
|
921
|
+
....: for x in S.some_elements())
|
|
922
|
+
True
|
|
923
|
+
"""
|
|
924
|
+
return self.tensor_square()(self.expansion(elt).coproduct())
|
|
925
|
+
|
|
926
|
+
def degree_on_basis(self, w):
|
|
927
|
+
"""
|
|
928
|
+
Return the degree of the element ``w``.
|
|
929
|
+
|
|
930
|
+
EXAMPLES::
|
|
931
|
+
|
|
932
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
933
|
+
sage: [S.degree_on_basis(x.leading_support()) for x in S.some_elements() if x != 0]
|
|
934
|
+
[0, 1, 1, 2]
|
|
935
|
+
"""
|
|
936
|
+
return ZZ(len(w))
|
|
937
|
+
|
|
938
|
+
@lazy_attribute
|
|
939
|
+
def expansion(self):
|
|
940
|
+
"""
|
|
941
|
+
Return the morphism corresponding to the expansion into words of
|
|
942
|
+
the shuffle algebra.
|
|
943
|
+
|
|
944
|
+
EXAMPLES::
|
|
945
|
+
|
|
946
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
947
|
+
sage: f = S('ab') + S('aba')
|
|
948
|
+
sage: S.expansion(f)
|
|
949
|
+
2*B[aab] + B[ab] + B[aba]
|
|
950
|
+
"""
|
|
951
|
+
return self.module_morphism(self.expansion_on_basis, codomain=self._alg)
|
|
952
|
+
|
|
953
|
+
@cached_method
|
|
954
|
+
def expansion_on_basis(self, w):
|
|
955
|
+
r"""
|
|
956
|
+
Return the expansion of `S_w` in words of the shuffle algebra.
|
|
957
|
+
|
|
958
|
+
INPUT:
|
|
959
|
+
|
|
960
|
+
- ``w`` -- a word
|
|
961
|
+
|
|
962
|
+
EXAMPLES::
|
|
963
|
+
|
|
964
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
965
|
+
sage: S.expansion_on_basis(Word())
|
|
966
|
+
B[]
|
|
967
|
+
sage: S.expansion_on_basis(Word()).parent()
|
|
968
|
+
Shuffle Algebra on 2 generators ['a', 'b'] over Rational Field
|
|
969
|
+
sage: S.expansion_on_basis(Word('abba'))
|
|
970
|
+
2*B[aabb] + B[abab] + B[abba]
|
|
971
|
+
sage: S.expansion_on_basis(Word())
|
|
972
|
+
B[]
|
|
973
|
+
sage: S.expansion_on_basis(Word('abab'))
|
|
974
|
+
2*B[aabb] + B[abab]
|
|
975
|
+
"""
|
|
976
|
+
from sage.arith.misc import factorial
|
|
977
|
+
if not w:
|
|
978
|
+
return self._alg.one()
|
|
979
|
+
if len(w) == 1:
|
|
980
|
+
return self._alg.monomial(w)
|
|
981
|
+
if w.is_lyndon():
|
|
982
|
+
W = self.basis().keys()
|
|
983
|
+
letter = W([w[0]])
|
|
984
|
+
expansion = self.expansion_on_basis(W(w[1:]))
|
|
985
|
+
return self._alg.sum_of_terms((letter * i, c)
|
|
986
|
+
for i, c in expansion)
|
|
987
|
+
|
|
988
|
+
lf = w.lyndon_factorization()
|
|
989
|
+
powers = {}
|
|
990
|
+
for i in lf:
|
|
991
|
+
powers[i] = powers.get(i, 0) + 1
|
|
992
|
+
denom = prod(factorial(p) for p in powers.values())
|
|
993
|
+
result = self._alg.prod(self.expansion_on_basis(i) for i in lf)
|
|
994
|
+
return self._alg(result / denom)
|
|
995
|
+
|
|
996
|
+
class Element(CombinatorialFreeModule.Element):
|
|
997
|
+
"""
|
|
998
|
+
An element in the dual PBW basis.
|
|
999
|
+
"""
|
|
1000
|
+
def expand(self):
|
|
1001
|
+
"""
|
|
1002
|
+
Expand ``self`` in words of the shuffle algebra.
|
|
1003
|
+
|
|
1004
|
+
EXAMPLES::
|
|
1005
|
+
|
|
1006
|
+
sage: S = ShuffleAlgebra(QQ, 'ab').dual_pbw_basis()
|
|
1007
|
+
sage: f = S('ab') + S('bab')
|
|
1008
|
+
sage: f.expand()
|
|
1009
|
+
B[ab] + 2*B[abb] + B[bab]
|
|
1010
|
+
"""
|
|
1011
|
+
return self.parent().expansion(self)
|