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,1409 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
r"""
|
|
3
|
+
Gelfand-Tsetlin patterns
|
|
4
|
+
|
|
5
|
+
REFERENCES:
|
|
6
|
+
|
|
7
|
+
.. [BBF] \B. Brubaker, D. Bump, and S. Friedberg.
|
|
8
|
+
Weyl Group Multiple Dirichlet Series: Type A Combinatorial Theory.
|
|
9
|
+
Ann. of Math. Stud., vol. 175, Princeton Univ. Press, New Jersey, 2011.
|
|
10
|
+
|
|
11
|
+
.. [GC50] \I. M. Gelfand and M. L. Cetlin.
|
|
12
|
+
Finite-Dimensional Representations of the Group of Unimodular Matrices.
|
|
13
|
+
Dokl. Akad. Nauk SSSR **71**, pp. 825--828, 1950.
|
|
14
|
+
|
|
15
|
+
.. [Tok88] \T. Tokuyama.
|
|
16
|
+
A Generating Function of Strict Gelfand Patterns and Some Formulas on
|
|
17
|
+
Characters of General Linear Groups.
|
|
18
|
+
J. Math. Soc. Japan **40** (4), pp. 671--685, 1988.
|
|
19
|
+
|
|
20
|
+
AUTHORS:
|
|
21
|
+
|
|
22
|
+
- Travis Scrimshaw (2013-15-03): initial version
|
|
23
|
+
"""
|
|
24
|
+
# ****************************************************************************
|
|
25
|
+
# Copyright (C) 2013 Travis Scrimshaw <tscrim@ucdavis.edu>
|
|
26
|
+
#
|
|
27
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
28
|
+
#
|
|
29
|
+
# This code is distributed in the hope that it will be useful,
|
|
30
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
31
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
32
|
+
# General Public License for more details.
|
|
33
|
+
#
|
|
34
|
+
# The full text of the GPL is available at:
|
|
35
|
+
#
|
|
36
|
+
# https://www.gnu.org/licenses/
|
|
37
|
+
# ****************************************************************************
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
|
|
40
|
+
from sage.structure.parent import Parent
|
|
41
|
+
from sage.structure.list_clone import ClonableArray
|
|
42
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
43
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
44
|
+
from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
|
|
45
|
+
from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
|
|
46
|
+
from sage.misc.cachefunc import cached_method
|
|
47
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
48
|
+
from sage.rings.integer_ring import ZZ
|
|
49
|
+
from sage.combinat.partition import Partitions
|
|
50
|
+
from sage.combinat.tableau import Tableau, SemistandardTableaux
|
|
51
|
+
from sage.combinat.combinatorial_map import combinatorial_map
|
|
52
|
+
from sage.misc.misc_c import prod
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class GelfandTsetlinPattern(ClonableArray,
|
|
56
|
+
metaclass=InheritComparisonClasscallMetaclass):
|
|
57
|
+
r"""
|
|
58
|
+
A Gelfand-Tsetlin (sometimes written as Gelfand-Zetlin or Gelfand-Cetlin)
|
|
59
|
+
pattern. They were originally defined in [GC50]_.
|
|
60
|
+
|
|
61
|
+
A Gelfand-Tsetlin pattern is a triangular array:
|
|
62
|
+
|
|
63
|
+
.. MATH::
|
|
64
|
+
|
|
65
|
+
\begin{array}{ccccccccc}
|
|
66
|
+
a_{1,1} & & a_{1,2} & & a_{1,3} & & \cdots & & a_{1,n} \\
|
|
67
|
+
& a_{2,2} & & a_{2,3} & & \cdots & & a_{2,n} \\
|
|
68
|
+
& & a_{3,3} & & \cdots & & a_{3,n} \\
|
|
69
|
+
& & & \ddots \\
|
|
70
|
+
& & & & a_{n,n}
|
|
71
|
+
\end{array}
|
|
72
|
+
|
|
73
|
+
such that `a_{i,j} \geq a_{i+1,j+1} \geq a_{i,j+1}`.
|
|
74
|
+
|
|
75
|
+
Gelfand-Tsetlin patterns are in bijection with semistandard Young tableaux
|
|
76
|
+
by the following algorithm. Let `G` be a Gelfand-Tsetlin pattern with
|
|
77
|
+
`\lambda^{(k)}` being the `(n-k+1)`-st row (note that this is a partition).
|
|
78
|
+
The definition of `G` implies
|
|
79
|
+
|
|
80
|
+
.. MATH::
|
|
81
|
+
|
|
82
|
+
\lambda^{(0)} \subseteq \lambda^{(1)} \subseteq \cdots \subseteq
|
|
83
|
+
\lambda^{(n)},
|
|
84
|
+
|
|
85
|
+
where `\lambda^{(0)}` is the empty partition, and each skew shape
|
|
86
|
+
`\lambda^{(k)}/\lambda^{(k-1)}` is a horizontal strip. Thus define `T(G)`
|
|
87
|
+
by inserting `k` into the squares of the skew shape
|
|
88
|
+
`\lambda^{(k)}/ \lambda^{(k-1)}`, for `k=1,\dots,n`.
|
|
89
|
+
|
|
90
|
+
To each entry in a Gelfand-Tsetlin pattern, one may attach a decoration of
|
|
91
|
+
a circle or a box (or both or neither). These decorations appear in the
|
|
92
|
+
study of Weyl group multiple Dirichlet series, and are implemented here
|
|
93
|
+
following the exposition in [BBF]_.
|
|
94
|
+
|
|
95
|
+
.. NOTE::
|
|
96
|
+
|
|
97
|
+
We use the "right-hand" rule for determining circled and boxed entries.
|
|
98
|
+
|
|
99
|
+
.. WARNING::
|
|
100
|
+
|
|
101
|
+
The entries in Sage are 0-based and are thought of as flushed to the
|
|
102
|
+
left in a matrix. In other words, the coordinates of entries in the
|
|
103
|
+
Gelfand-Tsetlin patterns are thought of as the matrix:
|
|
104
|
+
|
|
105
|
+
.. MATH::
|
|
106
|
+
|
|
107
|
+
\begin{bmatrix}
|
|
108
|
+
g_{0,0} & g_{0,1} & g_{0,2} & \cdots & g_{0,n-2} & g_{n-1,n-1} \\
|
|
109
|
+
g_{1,0} & g_{1,1} & g_{1,2} & \cdots & g_{1,n-2} \\
|
|
110
|
+
g_{2,0} & g_{2,1} & g_{2,2} & \cdots \\
|
|
111
|
+
\vdots & \vdots & \vdots \\
|
|
112
|
+
g_{n-2,0} & g_{n-2,1} \\
|
|
113
|
+
g_{n-1,0}
|
|
114
|
+
\end{bmatrix}.
|
|
115
|
+
|
|
116
|
+
However, in the discussions, we will be using the **standard**
|
|
117
|
+
numbering system.
|
|
118
|
+
|
|
119
|
+
EXAMPLES::
|
|
120
|
+
|
|
121
|
+
sage: G = GelfandTsetlinPattern([[3, 2, 1], [2, 1], [1]]); G
|
|
122
|
+
[[3, 2, 1], [2, 1], [1]]
|
|
123
|
+
sage: G.pp()
|
|
124
|
+
3 2 1
|
|
125
|
+
2 1
|
|
126
|
+
1
|
|
127
|
+
sage: G = GelfandTsetlinPattern([[7, 7, 4, 0], [7, 7, 3], [7, 5], [5]]); G.pp()
|
|
128
|
+
7 7 4 0
|
|
129
|
+
7 7 3
|
|
130
|
+
7 5
|
|
131
|
+
5
|
|
132
|
+
sage: G.to_tableau().pp()
|
|
133
|
+
1 1 1 1 1 2 2
|
|
134
|
+
2 2 2 2 2 3 3
|
|
135
|
+
3 3 3 4
|
|
136
|
+
"""
|
|
137
|
+
# Note that the width == height, so len(gt) == len(gt[0]) except
|
|
138
|
+
# we don't have to check if it is the entry GT pattern
|
|
139
|
+
@staticmethod
|
|
140
|
+
def __classcall_private__(self, gt):
|
|
141
|
+
"""
|
|
142
|
+
Return ``gt`` as a proper element of :class:`GelfandTsetlinPatterns`.
|
|
143
|
+
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[2,1],[1]])
|
|
147
|
+
sage: G.parent()
|
|
148
|
+
Gelfand-Tsetlin patterns
|
|
149
|
+
sage: TestSuite(G).run()
|
|
150
|
+
"""
|
|
151
|
+
return GelfandTsetlinPatterns()(gt)
|
|
152
|
+
|
|
153
|
+
def check(self):
|
|
154
|
+
"""
|
|
155
|
+
Check that this is a valid Gelfand-Tsetlin pattern.
|
|
156
|
+
|
|
157
|
+
EXAMPLES::
|
|
158
|
+
|
|
159
|
+
sage: G = GelfandTsetlinPatterns()
|
|
160
|
+
sage: G([[3,2,1],[2,1],[1]]).check()
|
|
161
|
+
"""
|
|
162
|
+
assert all(self[i - 1][j] >= self[i][j] >= self[i - 1][j + 1]
|
|
163
|
+
for i in range(1, len(self)) for j in range(len(self[i])))
|
|
164
|
+
|
|
165
|
+
def _hash_(self) -> int:
|
|
166
|
+
"""
|
|
167
|
+
Return the hash value of ``self``.
|
|
168
|
+
|
|
169
|
+
EXAMPLES::
|
|
170
|
+
|
|
171
|
+
sage: G = GelfandTsetlinPatterns()
|
|
172
|
+
sage: gt = G([[3,2,1],[2,1],[1]])
|
|
173
|
+
sage: hash(gt) == hash(gt)
|
|
174
|
+
True
|
|
175
|
+
|
|
176
|
+
Check that :issue:`14717` is fixed::
|
|
177
|
+
|
|
178
|
+
sage: GT = GelfandTsetlinPattern([[2, 1, 0], [2, 0], [1]])
|
|
179
|
+
sage: GT in {}
|
|
180
|
+
False
|
|
181
|
+
"""
|
|
182
|
+
return hash(tuple(map(tuple, self)))
|
|
183
|
+
|
|
184
|
+
def _repr_diagram(self) -> str:
|
|
185
|
+
"""
|
|
186
|
+
Return a string representation of ``self`` as a diagram.
|
|
187
|
+
|
|
188
|
+
EXAMPLES::
|
|
189
|
+
|
|
190
|
+
sage: G = GelfandTsetlinPatterns()
|
|
191
|
+
sage: print(G([[3,2,1],[2,1],[1]])._repr_diagram())
|
|
192
|
+
3 2 1
|
|
193
|
+
2 1
|
|
194
|
+
1
|
|
195
|
+
"""
|
|
196
|
+
ret = ''
|
|
197
|
+
for i, row in enumerate(self):
|
|
198
|
+
if i != 0:
|
|
199
|
+
ret += '\n'
|
|
200
|
+
ret += ' ' * i
|
|
201
|
+
ret += ' '.join('%3s' % val for val in row)
|
|
202
|
+
return ret
|
|
203
|
+
|
|
204
|
+
def pp(self):
|
|
205
|
+
"""
|
|
206
|
+
Pretty print ``self``.
|
|
207
|
+
|
|
208
|
+
EXAMPLES::
|
|
209
|
+
|
|
210
|
+
sage: G = GelfandTsetlinPatterns()
|
|
211
|
+
sage: G([[3,2,1],[2,1],[1]]).pp()
|
|
212
|
+
3 2 1
|
|
213
|
+
2 1
|
|
214
|
+
1
|
|
215
|
+
"""
|
|
216
|
+
print(self._repr_diagram())
|
|
217
|
+
|
|
218
|
+
def _latex_(self) -> str:
|
|
219
|
+
r"""
|
|
220
|
+
Return a `\LaTeX` representation of ``self``.
|
|
221
|
+
|
|
222
|
+
EXAMPLES::
|
|
223
|
+
|
|
224
|
+
sage: G = GelfandTsetlinPatterns()
|
|
225
|
+
sage: latex(G([[3,2,1],[2,1],[1]]))
|
|
226
|
+
\begin{array}{ccccc}
|
|
227
|
+
3 & & 2 & & 1 \\
|
|
228
|
+
& 2 & & 1 & \\
|
|
229
|
+
& & 1 & &
|
|
230
|
+
\end{array}
|
|
231
|
+
sage: latex(G([]))
|
|
232
|
+
\emptyset
|
|
233
|
+
"""
|
|
234
|
+
n = len(self)
|
|
235
|
+
if n == 0:
|
|
236
|
+
return "\\emptyset"
|
|
237
|
+
ret = "\\begin{array}{" + 'c' * (n * 2 - 1) + "}\n"
|
|
238
|
+
for i, row in enumerate(self):
|
|
239
|
+
if i > 0:
|
|
240
|
+
ret += " \\\\\n"
|
|
241
|
+
ret += "& " * i
|
|
242
|
+
ret += " & & ".join(repr(val) for val in row)
|
|
243
|
+
ret += " &" * i
|
|
244
|
+
return ret + "\n\\end{array}"
|
|
245
|
+
|
|
246
|
+
@combinatorial_map(name='to semistandard tableau')
|
|
247
|
+
def to_tableau(self):
|
|
248
|
+
r"""
|
|
249
|
+
Return ``self`` as a semistandard Young tableau.
|
|
250
|
+
|
|
251
|
+
The conversion from a Gelfand-Tsetlin pattern to a semistandard Young
|
|
252
|
+
tableaux is as follows. Let `G` be a Gelfand-Tsetlin pattern with
|
|
253
|
+
`\lambda^{(k)}` being the `(n-k+1)`-st row (note that this is a
|
|
254
|
+
partition). The definition of `G` implies
|
|
255
|
+
|
|
256
|
+
.. MATH::
|
|
257
|
+
|
|
258
|
+
\lambda^{(0)} \subseteq \lambda^{(1)} \subseteq \cdots \subseteq
|
|
259
|
+
\lambda^{(n)},
|
|
260
|
+
|
|
261
|
+
where `\lambda^{(0)}` is the empty partition, and each skew shape
|
|
262
|
+
`\lambda^{(k)} / \lambda^{(k-1)}` is a horizontal strip. Thus define
|
|
263
|
+
`T(G)` by inserting `k` into the squares of the skew shape
|
|
264
|
+
`\lambda^{(k)} / \lambda^{(k-1)}`, for `k=1,\dots,n`.
|
|
265
|
+
|
|
266
|
+
EXAMPLES::
|
|
267
|
+
|
|
268
|
+
sage: G = GelfandTsetlinPatterns()
|
|
269
|
+
sage: elt = G([[3,2,1],[2,1],[1]])
|
|
270
|
+
sage: T = elt.to_tableau(); T
|
|
271
|
+
[[1, 2, 3], [2, 3], [3]]
|
|
272
|
+
sage: T.pp()
|
|
273
|
+
1 2 3
|
|
274
|
+
2 3
|
|
275
|
+
3
|
|
276
|
+
sage: G(T) == elt
|
|
277
|
+
True
|
|
278
|
+
"""
|
|
279
|
+
ret = []
|
|
280
|
+
for i, row in enumerate(reversed(self)):
|
|
281
|
+
for j, val in enumerate(row):
|
|
282
|
+
if j >= len(ret):
|
|
283
|
+
if val == 0:
|
|
284
|
+
break
|
|
285
|
+
ret.append([i + 1] * val)
|
|
286
|
+
else:
|
|
287
|
+
ret[j].extend([i + 1] * (val - len(ret[j])))
|
|
288
|
+
S = SemistandardTableaux(max_entry=len(self))
|
|
289
|
+
return S(ret)
|
|
290
|
+
|
|
291
|
+
@cached_method
|
|
292
|
+
def boxed_entries(self) -> tuple:
|
|
293
|
+
"""
|
|
294
|
+
Return the position of the boxed entries of ``self``.
|
|
295
|
+
|
|
296
|
+
Using the *right-hand* rule, an entry `a_{i,j}` is boxed if
|
|
297
|
+
`a_{i,j} = a_{i-1,j-1}`; i.e., `a_{i,j}` has the same value as its
|
|
298
|
+
neighbor to the northwest.
|
|
299
|
+
|
|
300
|
+
EXAMPLES::
|
|
301
|
+
|
|
302
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[1]])
|
|
303
|
+
sage: G.boxed_entries()
|
|
304
|
+
((1, 0),)
|
|
305
|
+
"""
|
|
306
|
+
ret = [(i, j) for i in range(1, len(self))
|
|
307
|
+
for j, selfij in enumerate(self[i])
|
|
308
|
+
if selfij == self[i - 1][j]]
|
|
309
|
+
return tuple(ret)
|
|
310
|
+
|
|
311
|
+
@cached_method
|
|
312
|
+
def circled_entries(self) -> tuple:
|
|
313
|
+
"""
|
|
314
|
+
Return the circled entries of ``self``.
|
|
315
|
+
|
|
316
|
+
Using the *right-hand* rule, an entry `a_{i,j}` is circled if
|
|
317
|
+
`a_{i,j} = a_{i-1,j}`; i.e., `a_{i,j}` has the same value as its
|
|
318
|
+
neighbor to the northeast.
|
|
319
|
+
|
|
320
|
+
EXAMPLES::
|
|
321
|
+
|
|
322
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[1]])
|
|
323
|
+
sage: G.circled_entries()
|
|
324
|
+
((1, 1), (2, 0))
|
|
325
|
+
"""
|
|
326
|
+
ret = [(i, j) for i in range(1, len(self))
|
|
327
|
+
for j, selfij in enumerate(self[i])
|
|
328
|
+
if selfij == self[i - 1][j + 1]]
|
|
329
|
+
return tuple(ret)
|
|
330
|
+
|
|
331
|
+
@cached_method
|
|
332
|
+
def special_entries(self) -> tuple:
|
|
333
|
+
"""
|
|
334
|
+
Return the special entries.
|
|
335
|
+
|
|
336
|
+
An entry `a_{i,j}` is special if `a_{i-1,j-1} > a_{i,j} > a_{i-1,j}`,
|
|
337
|
+
that is to say, the entry is neither boxed nor circled and is **not**
|
|
338
|
+
in the first row. The name was coined by [Tok88]_.
|
|
339
|
+
|
|
340
|
+
EXAMPLES::
|
|
341
|
+
|
|
342
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[1]])
|
|
343
|
+
sage: G.special_entries()
|
|
344
|
+
()
|
|
345
|
+
sage: G = GelfandTsetlinPattern([[4,2,1],[4,1],[2]])
|
|
346
|
+
sage: G.special_entries()
|
|
347
|
+
((2, 0),)
|
|
348
|
+
"""
|
|
349
|
+
ret = [(i, j) for i in range(1, len(self))
|
|
350
|
+
for j, selfij in enumerate(self[i])
|
|
351
|
+
if self[i - 1][j] > selfij > self[i - 1][j + 1]]
|
|
352
|
+
return tuple(ret)
|
|
353
|
+
|
|
354
|
+
def number_of_boxes(self) -> int:
|
|
355
|
+
"""
|
|
356
|
+
Return the number of boxed entries. See :meth:`boxed_entries()`.
|
|
357
|
+
|
|
358
|
+
EXAMPLES::
|
|
359
|
+
|
|
360
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[1]])
|
|
361
|
+
sage: G.number_of_boxes()
|
|
362
|
+
1
|
|
363
|
+
"""
|
|
364
|
+
return len(self.boxed_entries())
|
|
365
|
+
|
|
366
|
+
def number_of_circles(self) -> int:
|
|
367
|
+
"""
|
|
368
|
+
Return the number of boxed entries. See :meth:`circled_entries()`.
|
|
369
|
+
|
|
370
|
+
EXAMPLES::
|
|
371
|
+
|
|
372
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[1]])
|
|
373
|
+
sage: G.number_of_circles()
|
|
374
|
+
2
|
|
375
|
+
"""
|
|
376
|
+
return len(self.circled_entries())
|
|
377
|
+
|
|
378
|
+
def number_of_special_entries(self) -> int:
|
|
379
|
+
"""
|
|
380
|
+
Return the number of special entries. See :meth:`special_entries()`.
|
|
381
|
+
|
|
382
|
+
EXAMPLES::
|
|
383
|
+
|
|
384
|
+
sage: G = GelfandTsetlinPattern([[4,2,1],[4,1],[2]])
|
|
385
|
+
sage: G.number_of_special_entries()
|
|
386
|
+
1
|
|
387
|
+
"""
|
|
388
|
+
return len(self.special_entries())
|
|
389
|
+
|
|
390
|
+
def is_strict(self) -> bool:
|
|
391
|
+
"""
|
|
392
|
+
Return ``True`` if ``self`` is a strict Gelfand-Tsetlin pattern.
|
|
393
|
+
|
|
394
|
+
A Gelfand-Tsetlin pattern is said to be *strict* if every row is
|
|
395
|
+
strictly decreasing.
|
|
396
|
+
|
|
397
|
+
EXAMPLES::
|
|
398
|
+
|
|
399
|
+
sage: GelfandTsetlinPattern([[7,3,1],[6,2],[4]]).is_strict()
|
|
400
|
+
True
|
|
401
|
+
sage: GelfandTsetlinPattern([[3,2,1],[3,1],[1]]).is_strict()
|
|
402
|
+
True
|
|
403
|
+
sage: GelfandTsetlinPattern([[6,0,0],[3,0],[2]]).is_strict()
|
|
404
|
+
False
|
|
405
|
+
"""
|
|
406
|
+
return not any(row[i] == row[i + 1] for row in self
|
|
407
|
+
for i in range(len(row) - 1))
|
|
408
|
+
|
|
409
|
+
def row_sums(self) -> list:
|
|
410
|
+
r"""
|
|
411
|
+
Return the list of row sums.
|
|
412
|
+
|
|
413
|
+
For a Gelfand-Tsetlin pattern `G`, the `i`-th row sum `d_i` is
|
|
414
|
+
|
|
415
|
+
.. MATH::
|
|
416
|
+
|
|
417
|
+
d_i = d_i(G) = \sum_{j=i}^{n} a_{i,j}.
|
|
418
|
+
|
|
419
|
+
EXAMPLES::
|
|
420
|
+
|
|
421
|
+
sage: G = GelfandTsetlinPattern([[5,3,2,1,0],[4,3,2,0],[4,2,1],[3,2],[3]])
|
|
422
|
+
sage: G.row_sums()
|
|
423
|
+
[11, 9, 7, 5, 3]
|
|
424
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[2]])
|
|
425
|
+
sage: G.row_sums()
|
|
426
|
+
[6, 4, 2]
|
|
427
|
+
"""
|
|
428
|
+
return [sum(self[i][j] for j in range(len(self[i])))
|
|
429
|
+
for i in range(len(self))]
|
|
430
|
+
|
|
431
|
+
def weight(self) -> tuple:
|
|
432
|
+
r"""
|
|
433
|
+
Return the weight of ``self``.
|
|
434
|
+
|
|
435
|
+
Define the weight of `G` to be the content of the tableau to which `G`
|
|
436
|
+
corresponds under the bijection between Gelfand-Tsetlin patterns and
|
|
437
|
+
semistandard tableaux. More precisely,
|
|
438
|
+
|
|
439
|
+
.. MATH::
|
|
440
|
+
|
|
441
|
+
\mathrm{wt}(G) = (d_n, d_{n-1}-d_n, \dots, d_1-d_2),
|
|
442
|
+
|
|
443
|
+
where the `d_i` are the row sums.
|
|
444
|
+
|
|
445
|
+
EXAMPLES::
|
|
446
|
+
|
|
447
|
+
sage: G = GelfandTsetlinPattern([[2,1,0],[1,0],[1]])
|
|
448
|
+
sage: G.weight()
|
|
449
|
+
(1, 0, 2)
|
|
450
|
+
sage: G = GelfandTsetlinPattern([[4,2,1],[3,1],[2]])
|
|
451
|
+
sage: G.weight()
|
|
452
|
+
(2, 2, 3)
|
|
453
|
+
"""
|
|
454
|
+
wt = [self.row_sums()[-1]] + [self.row_sums()[i - 1] - self.row_sums()[i] for i in reversed(range(1, len(self[0])))]
|
|
455
|
+
return tuple(wt)
|
|
456
|
+
|
|
457
|
+
def Tokuyama_coefficient(self, name='t'):
|
|
458
|
+
r"""
|
|
459
|
+
Return the Tokuyama coefficient attached to ``self``.
|
|
460
|
+
|
|
461
|
+
Following the exposition of [BBF]_, Tokuyama's formula asserts
|
|
462
|
+
|
|
463
|
+
.. MATH::
|
|
464
|
+
|
|
465
|
+
\sum_{G} (t+1)^{s(G)} t^{l(G)}
|
|
466
|
+
z_1^{d_{n+1}} z_2^{d_{n}-d_{n+1}} \cdots z_{n+1}^{d_1-d_2}
|
|
467
|
+
=
|
|
468
|
+
s_{\lambda}(z_1,\dots,z_{n+1}) \prod_{i<j} (z_j+tz_i),
|
|
469
|
+
|
|
470
|
+
where the sum is over all strict Gelfand-Tsetlin patterns with fixed
|
|
471
|
+
top row `\lambda + \rho`, with `\lambda` a partition with at most
|
|
472
|
+
`n+1` parts and `\rho = (n, n-1, \ldots, 1, 0)`, and `s_\lambda` is a
|
|
473
|
+
Schur function.
|
|
474
|
+
|
|
475
|
+
INPUT:
|
|
476
|
+
|
|
477
|
+
- ``name`` -- (default: ``'t'``) an alternative name for the
|
|
478
|
+
variable `t`
|
|
479
|
+
|
|
480
|
+
EXAMPLES::
|
|
481
|
+
|
|
482
|
+
sage: P = GelfandTsetlinPattern([[3,2,1],[2,2],[2]])
|
|
483
|
+
sage: P.Tokuyama_coefficient()
|
|
484
|
+
0
|
|
485
|
+
sage: G = GelfandTsetlinPattern([[3,2,1],[3,1],[2]])
|
|
486
|
+
sage: G.Tokuyama_coefficient()
|
|
487
|
+
t^2 + t
|
|
488
|
+
sage: G = GelfandTsetlinPattern([[2,1,0],[1,1],[1]])
|
|
489
|
+
sage: G.Tokuyama_coefficient()
|
|
490
|
+
0
|
|
491
|
+
sage: G = GelfandTsetlinPattern([[5,3,2,1,0],[4,3,2,0],[4,2,1],[3,2],[3]])
|
|
492
|
+
sage: G.Tokuyama_coefficient()
|
|
493
|
+
t^8 + 3*t^7 + 3*t^6 + t^5
|
|
494
|
+
"""
|
|
495
|
+
R = PolynomialRing(ZZ, name)
|
|
496
|
+
t = R.gen(0)
|
|
497
|
+
if not self.is_strict():
|
|
498
|
+
return R.zero()
|
|
499
|
+
return (t + 1)**self.number_of_special_entries() * t**self.number_of_boxes()
|
|
500
|
+
|
|
501
|
+
@combinatorial_map(order=2, name='Bender-Knuth involution')
|
|
502
|
+
def bender_knuth_involution(self, i) -> GelfandTsetlinPattern:
|
|
503
|
+
r"""
|
|
504
|
+
Return the image of ``self`` under the `i`-th Bender-Knuth involution.
|
|
505
|
+
|
|
506
|
+
If the triangle ``self`` has size `n` then this is defined for `0 < i < n`.
|
|
507
|
+
|
|
508
|
+
The entries of ``self`` can take values in any ordered ring. Usually,
|
|
509
|
+
this will be the integers but can also be the rationals or the real numbers.
|
|
510
|
+
|
|
511
|
+
This implements the construction of the Bender-Knuth involution using toggling
|
|
512
|
+
due to Berenstein-Kirillov.
|
|
513
|
+
|
|
514
|
+
This agrees with the Bender-Knuth involution on semistandard tableaux.
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: G = GelfandTsetlinPattern([[5,3,2,1,0],[4,3,2,0],[4,2,1],[3,2],[3]])
|
|
519
|
+
sage: G.bender_knuth_involution(2)
|
|
520
|
+
[[5, 3, 2, 1, 0], [4, 3, 2, 0], [4, 2, 1], [4, 1], [3]]
|
|
521
|
+
|
|
522
|
+
sage: G = GelfandTsetlinPattern([[3,2,0],[2.2,0],[2]])
|
|
523
|
+
sage: G.bender_knuth_involution(2)
|
|
524
|
+
[[3, 2, 0], [2.8..., 2], [2]]
|
|
525
|
+
|
|
526
|
+
TESTS::
|
|
527
|
+
|
|
528
|
+
sage: all(all( G.bender_knuth_involution(i).to_tableau() == G.to_tableau().bender_knuth_involution(i)
|
|
529
|
+
....: for i in range(1,len(G)) ) for G in GelfandTsetlinPatterns(top_row=[3,3,3,0,0]))
|
|
530
|
+
True
|
|
531
|
+
|
|
532
|
+
sage: G = GelfandTsetlinPattern([[2,1,0],[1,0],[0]])
|
|
533
|
+
sage: G.bender_knuth_involution(0)
|
|
534
|
+
Traceback (most recent call last):
|
|
535
|
+
...
|
|
536
|
+
ValueError: must have 0 < 0 < 3
|
|
537
|
+
sage: G.bender_knuth_involution(3)
|
|
538
|
+
Traceback (most recent call last):
|
|
539
|
+
...
|
|
540
|
+
ValueError: must have 0 < 3 < 3
|
|
541
|
+
"""
|
|
542
|
+
n = len(self)
|
|
543
|
+
|
|
544
|
+
def toggle(i, j):
|
|
545
|
+
"""
|
|
546
|
+
Return the toggle of entry 'G[i][j]' in a Gelfand-Tsetlin pattern, 'G'.
|
|
547
|
+
"""
|
|
548
|
+
if i == n-1:
|
|
549
|
+
return self[n-2][0]+self[n-2][1]-self[n-1][0]
|
|
550
|
+
|
|
551
|
+
if j == 0:
|
|
552
|
+
left = self[i-1][0]
|
|
553
|
+
else:
|
|
554
|
+
left = min(self[i-1][j], self[i+1][j-1])
|
|
555
|
+
if j == n-i-1:
|
|
556
|
+
right = self[i-1][j+1]
|
|
557
|
+
else:
|
|
558
|
+
right = max(self[i-1][j+1], self[i+1][j])
|
|
559
|
+
|
|
560
|
+
return left + right - self[i][j]
|
|
561
|
+
|
|
562
|
+
if not 0 < i < n:
|
|
563
|
+
raise ValueError(f"must have 0 < {i} < {n}")
|
|
564
|
+
r = n-i
|
|
565
|
+
P = self.parent()
|
|
566
|
+
data = [list(row) for row in self]
|
|
567
|
+
data[r] = [toggle(r, s) for s in range(i)]
|
|
568
|
+
return P.element_class(P, data)
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
class GelfandTsetlinPatterns(UniqueRepresentation, Parent):
|
|
572
|
+
"""
|
|
573
|
+
Gelfand-Tsetlin patterns.
|
|
574
|
+
|
|
575
|
+
INPUT:
|
|
576
|
+
|
|
577
|
+
- ``n`` -- the width or depth of the array, also known as the rank
|
|
578
|
+
|
|
579
|
+
- ``k`` -- (default: ``None``) if specified, this is the maximum value that
|
|
580
|
+
can occur in the patterns
|
|
581
|
+
|
|
582
|
+
- ``top_row`` -- (default: ``None``) if specified, this is the fixed top
|
|
583
|
+
row of all patterns
|
|
584
|
+
|
|
585
|
+
- ``strict`` -- (default: ``False``) set to ``True`` if all patterns are
|
|
586
|
+
strict patterns
|
|
587
|
+
|
|
588
|
+
TESTS:
|
|
589
|
+
|
|
590
|
+
Check that the number of Gelfand-Tsetlin patterns is equal to the number
|
|
591
|
+
of semistandard Young tableaux::
|
|
592
|
+
|
|
593
|
+
sage: G = GelfandTsetlinPatterns(3,3)
|
|
594
|
+
sage: c = 0
|
|
595
|
+
sage: from sage.combinat.partition import partitions_in_box
|
|
596
|
+
sage: for p in partitions_in_box(3,3):
|
|
597
|
+
....: S = SemistandardTableaux(p, max_entry=3)
|
|
598
|
+
....: c += S.cardinality()
|
|
599
|
+
sage: c == G.cardinality()
|
|
600
|
+
True
|
|
601
|
+
|
|
602
|
+
Note that the top row in reverse of the Gelfand-Tsetlin pattern is the
|
|
603
|
+
shape of the corresponding semistandard Young tableau under the bijection
|
|
604
|
+
described in :meth:`GelfandTsetlinPattern.to_tableau()`::
|
|
605
|
+
|
|
606
|
+
sage: G = GelfandTsetlinPatterns(top_row=[2,2,1])
|
|
607
|
+
sage: S = SemistandardTableaux([2,2,1], max_entry=3)
|
|
608
|
+
sage: G.cardinality() == S.cardinality()
|
|
609
|
+
True
|
|
610
|
+
"""
|
|
611
|
+
@staticmethod
|
|
612
|
+
def __classcall_private__(cls, n=None, k=None, strict=False, top_row=None):
|
|
613
|
+
"""
|
|
614
|
+
Return the correct parent based upon the inputs.
|
|
615
|
+
|
|
616
|
+
EXAMPLES::
|
|
617
|
+
|
|
618
|
+
sage: G = GelfandTsetlinPatterns()
|
|
619
|
+
sage: G2 = GelfandTsetlinPatterns()
|
|
620
|
+
sage: G is G2
|
|
621
|
+
True
|
|
622
|
+
sage: G = GelfandTsetlinPatterns(3,4, strict=True)
|
|
623
|
+
sage: G2 = GelfandTsetlinPatterns(int(3),int(4), strict=True)
|
|
624
|
+
sage: G is G2
|
|
625
|
+
True
|
|
626
|
+
sage: G = GelfandTsetlinPatterns(top_row=[3,1,1])
|
|
627
|
+
sage: G2 = GelfandTsetlinPatterns(top_row=(3,1,1))
|
|
628
|
+
sage: G is G2
|
|
629
|
+
True
|
|
630
|
+
"""
|
|
631
|
+
if top_row is not None:
|
|
632
|
+
top_row = tuple(top_row)
|
|
633
|
+
if any(top_row[i] < top_row[i+1] for i in range(len(top_row)-1)):
|
|
634
|
+
raise ValueError("the top row must be weakly decreasing")
|
|
635
|
+
if n is not None and n != len(top_row):
|
|
636
|
+
raise ValueError("n must be the length of the specified top row")
|
|
637
|
+
return GelfandTsetlinPatternsTopRow(top_row, strict)
|
|
638
|
+
return super().__classcall__(cls, n, k, strict)
|
|
639
|
+
|
|
640
|
+
def __init__(self, n, k, strict):
|
|
641
|
+
"""
|
|
642
|
+
Initialize ``self``.
|
|
643
|
+
|
|
644
|
+
EXAMPLES::
|
|
645
|
+
|
|
646
|
+
sage: G = GelfandTsetlinPatterns()
|
|
647
|
+
sage: TestSuite(G).run()
|
|
648
|
+
sage: G = GelfandTsetlinPatterns(3)
|
|
649
|
+
sage: TestSuite(G).run()
|
|
650
|
+
sage: G = GelfandTsetlinPatterns(3, 3)
|
|
651
|
+
sage: TestSuite(G).run()
|
|
652
|
+
sage: G = GelfandTsetlinPatterns(3, 3, strict=True)
|
|
653
|
+
sage: TestSuite(G).run()
|
|
654
|
+
"""
|
|
655
|
+
self._n = n
|
|
656
|
+
self._k = k
|
|
657
|
+
self._strict = strict
|
|
658
|
+
# Note - if a top row is given, then n and k are not None
|
|
659
|
+
if k is not None and (n is not None or strict):
|
|
660
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
661
|
+
else:
|
|
662
|
+
Parent.__init__(self, category=InfiniteEnumeratedSets())
|
|
663
|
+
|
|
664
|
+
def __contains__(self, gt):
|
|
665
|
+
"""
|
|
666
|
+
Check to see if ``gt`` is in ``self``.
|
|
667
|
+
|
|
668
|
+
EXAMPLES::
|
|
669
|
+
|
|
670
|
+
sage: G = GelfandTsetlinPatterns()
|
|
671
|
+
sage: [[3, 1],[2]] in G
|
|
672
|
+
True
|
|
673
|
+
sage: [[2, 3],[4]] in G
|
|
674
|
+
False
|
|
675
|
+
sage: [[3, 1],[0]] in G
|
|
676
|
+
False
|
|
677
|
+
sage: [] in G
|
|
678
|
+
True
|
|
679
|
+
sage: G = GelfandTsetlinPatterns(3,2)
|
|
680
|
+
sage: [] in G
|
|
681
|
+
False
|
|
682
|
+
sage: [[2,0,0],[1,0],[1]] in G
|
|
683
|
+
True
|
|
684
|
+
sage: [[0,0],[0]] in G
|
|
685
|
+
False
|
|
686
|
+
sage: [[3,0,0],[2,0],[0]] in G
|
|
687
|
+
False
|
|
688
|
+
sage: G = GelfandTsetlinPatterns(3,strict=True)
|
|
689
|
+
sage: [[2,1,0],[2,1],[1]] in G
|
|
690
|
+
True
|
|
691
|
+
sage: [[3,0,0],[3,0],[0]] in G
|
|
692
|
+
False
|
|
693
|
+
"""
|
|
694
|
+
if not isinstance(gt, (list, tuple, GelfandTsetlinPattern)):
|
|
695
|
+
return False
|
|
696
|
+
# Check if it has the correct width/depth (if applicable)
|
|
697
|
+
if self._n is not None and len(gt) != self._n:
|
|
698
|
+
return False
|
|
699
|
+
# Check if it has the correct maximum value
|
|
700
|
+
if self._k is not None and any(val > self._k for row in gt
|
|
701
|
+
for val in row):
|
|
702
|
+
return False
|
|
703
|
+
# Check if it is a GT pattern
|
|
704
|
+
if not all(gt[i-1][j] >= gt[i][j] >= gt[i-1][j+1]
|
|
705
|
+
for i in range(1, len(gt)) for j in range(len(gt[i]))):
|
|
706
|
+
return False
|
|
707
|
+
# Check if it is strict if applicable
|
|
708
|
+
if self._strict and any(gt[i][j] == gt[i][j-1] for i in range(len(gt))
|
|
709
|
+
for j in range(1, len(gt[i]))):
|
|
710
|
+
return False
|
|
711
|
+
return True
|
|
712
|
+
|
|
713
|
+
def _repr_(self):
|
|
714
|
+
"""
|
|
715
|
+
Return a string representation of ``self``.
|
|
716
|
+
|
|
717
|
+
EXAMPLES::
|
|
718
|
+
|
|
719
|
+
sage: GelfandTsetlinPatterns(4)
|
|
720
|
+
Gelfand-Tsetlin patterns of width 4
|
|
721
|
+
sage: GelfandTsetlinPatterns(4, 3, strict=True)
|
|
722
|
+
Strict Gelfand-Tsetlin patterns of width 4 and max value 3
|
|
723
|
+
sage: G = GelfandTsetlinPatterns(k=3, strict=True); G
|
|
724
|
+
Strict Gelfand-Tsetlin patterns with max value 3
|
|
725
|
+
"""
|
|
726
|
+
base = "Gelfand-Tsetlin patterns"
|
|
727
|
+
if self._strict:
|
|
728
|
+
base = "Strict " + base
|
|
729
|
+
if self._n is not None:
|
|
730
|
+
if self._k is not None:
|
|
731
|
+
return base + " of width %s and max value %s" % (self._n, self._k)
|
|
732
|
+
return base + " of width %s" % self._n
|
|
733
|
+
if self._k is not None:
|
|
734
|
+
return base + " with max value %s" % self._k
|
|
735
|
+
return base
|
|
736
|
+
|
|
737
|
+
def _element_constructor_(self, gt):
|
|
738
|
+
"""
|
|
739
|
+
Construct an element of ``self`` from ``gt``.
|
|
740
|
+
|
|
741
|
+
EXAMPLES::
|
|
742
|
+
|
|
743
|
+
sage: G = GelfandTsetlinPatterns(3, 3, strict=True); G
|
|
744
|
+
Strict Gelfand-Tsetlin patterns of width 3 and max value 3
|
|
745
|
+
sage: elt = G([[3,2,1],[2,1],[1]]); elt.pp()
|
|
746
|
+
3 2 1
|
|
747
|
+
2 1
|
|
748
|
+
1
|
|
749
|
+
sage: elt.parent()
|
|
750
|
+
Strict Gelfand-Tsetlin patterns of width 3 and max value 3
|
|
751
|
+
"""
|
|
752
|
+
if isinstance(gt, GelfandTsetlinPattern) and gt.parent() == self:
|
|
753
|
+
return gt
|
|
754
|
+
if isinstance(gt, Tableau):
|
|
755
|
+
gt = [list(x) for x in reversed(gt.to_chain()[1:])]
|
|
756
|
+
n = len(gt)
|
|
757
|
+
for i in range(n):
|
|
758
|
+
while len(gt[i]) < n-i:
|
|
759
|
+
gt[i].append(0)
|
|
760
|
+
if self._n is not None:
|
|
761
|
+
if len(gt) == 0:
|
|
762
|
+
gt = [[0]]
|
|
763
|
+
while self._n != len(gt):
|
|
764
|
+
gt.insert(0, gt[0][:] + [0])
|
|
765
|
+
return self.element_class(self, gt)
|
|
766
|
+
return self.element_class(self, list(gt))
|
|
767
|
+
|
|
768
|
+
Element = GelfandTsetlinPattern
|
|
769
|
+
|
|
770
|
+
def _coerce_map_from_(self, S):
|
|
771
|
+
"""
|
|
772
|
+
TESTS::
|
|
773
|
+
|
|
774
|
+
sage: t = GelfandTsetlinPattern([[1]])
|
|
775
|
+
sage: t == 0
|
|
776
|
+
False
|
|
777
|
+
sage: t == GelfandTsetlinPattern([[1]])
|
|
778
|
+
True
|
|
779
|
+
|
|
780
|
+
Check that :issue:`25919` is fixed::
|
|
781
|
+
|
|
782
|
+
sage: t = GelfandTsetlinPattern([[1]])
|
|
783
|
+
sage: u = GelfandTsetlinPatterns()[1]
|
|
784
|
+
sage: v = GelfandTsetlinPatterns(top_row=(1,))[0]
|
|
785
|
+
sage: t == u
|
|
786
|
+
True
|
|
787
|
+
sage: u == t
|
|
788
|
+
True
|
|
789
|
+
sage: t == v
|
|
790
|
+
True
|
|
791
|
+
sage: v == t
|
|
792
|
+
True
|
|
793
|
+
sage: u == v
|
|
794
|
+
True
|
|
795
|
+
sage: v == u
|
|
796
|
+
True
|
|
797
|
+
"""
|
|
798
|
+
if isinstance(S, GelfandTsetlinPatternsTopRow):
|
|
799
|
+
return True
|
|
800
|
+
|
|
801
|
+
def __iter__(self):
|
|
802
|
+
"""
|
|
803
|
+
Iterate through ``self`` by using a backtracing algorithm.
|
|
804
|
+
|
|
805
|
+
EXAMPLES::
|
|
806
|
+
|
|
807
|
+
sage: L = list(GelfandTsetlinPatterns(3,3))
|
|
808
|
+
sage: c = 0
|
|
809
|
+
sage: from sage.combinat.partition import partitions_in_box
|
|
810
|
+
sage: for p in partitions_in_box(3,3):
|
|
811
|
+
....: S = SemistandardTableaux(p, max_entry=3)
|
|
812
|
+
....: c += S.cardinality()
|
|
813
|
+
sage: c == len(L)
|
|
814
|
+
True
|
|
815
|
+
sage: G = GelfandTsetlinPatterns(3, 3, strict=True)
|
|
816
|
+
sage: all(x.is_strict() for x in G)
|
|
817
|
+
True
|
|
818
|
+
sage: G = GelfandTsetlinPatterns(k=3, strict=True)
|
|
819
|
+
sage: all(x.is_strict() for x in G)
|
|
820
|
+
True
|
|
821
|
+
|
|
822
|
+
Checking iterator when the set is infinite::
|
|
823
|
+
|
|
824
|
+
sage: T = GelfandTsetlinPatterns()
|
|
825
|
+
sage: it = T.__iter__()
|
|
826
|
+
sage: [next(it) for i in range(10)]
|
|
827
|
+
[[],
|
|
828
|
+
[[1]],
|
|
829
|
+
[[2]],
|
|
830
|
+
[[1, 1], [1]],
|
|
831
|
+
[[3]],
|
|
832
|
+
[[2, 1], [1]],
|
|
833
|
+
[[2, 1], [2]],
|
|
834
|
+
[[1, 1, 1], [1, 1], [1]],
|
|
835
|
+
[[4]],
|
|
836
|
+
[[3, 1], [1]]]
|
|
837
|
+
sage: T = GelfandTsetlinPatterns(k=1)
|
|
838
|
+
sage: it = T.__iter__()
|
|
839
|
+
sage: [next(it) for i in range(10)]
|
|
840
|
+
[[],
|
|
841
|
+
[[0]],
|
|
842
|
+
[[1]],
|
|
843
|
+
[[0, 0], [0]],
|
|
844
|
+
[[1, 0], [0]],
|
|
845
|
+
[[1, 0], [1]],
|
|
846
|
+
[[1, 1], [1]],
|
|
847
|
+
[[0, 0, 0], [0, 0], [0]],
|
|
848
|
+
[[1, 0, 0], [0, 0], [0]],
|
|
849
|
+
[[1, 0, 0], [1, 0], [0]]]
|
|
850
|
+
|
|
851
|
+
Check that :issue:`14718` is fixed::
|
|
852
|
+
|
|
853
|
+
sage: T = GelfandTsetlinPatterns(1,3)
|
|
854
|
+
sage: list(T)
|
|
855
|
+
[[[0]],
|
|
856
|
+
[[1]],
|
|
857
|
+
[[2]],
|
|
858
|
+
[[3]]]
|
|
859
|
+
"""
|
|
860
|
+
# Special cases
|
|
861
|
+
if self._n is None:
|
|
862
|
+
yield self.element_class(self, [])
|
|
863
|
+
if self._k is None:
|
|
864
|
+
# Since both `n` and `k` are none, we need special consideration
|
|
865
|
+
# while iterating, so we do so by specifying the top row by
|
|
866
|
+
# using the iterator for partitions
|
|
867
|
+
n = 1
|
|
868
|
+
while True:
|
|
869
|
+
if self._strict:
|
|
870
|
+
P = Partitions(n, max_slope=-1)
|
|
871
|
+
else:
|
|
872
|
+
P = Partitions(n)
|
|
873
|
+
for p in P:
|
|
874
|
+
for x in GelfandTsetlinPatterns(top_row=tuple(p), strict=self._strict):
|
|
875
|
+
yield self.element_class(self, list(x))
|
|
876
|
+
n += 1
|
|
877
|
+
for x in range(self._k+1):
|
|
878
|
+
yield self.element_class(self, [[x]])
|
|
879
|
+
n = 2
|
|
880
|
+
while not self._strict or n <= self._k+1:
|
|
881
|
+
for x in self._list_iter(n):
|
|
882
|
+
yield self.element_class(self, x)
|
|
883
|
+
n += 1
|
|
884
|
+
return
|
|
885
|
+
if self._n < 0:
|
|
886
|
+
return
|
|
887
|
+
if self._n == 0:
|
|
888
|
+
yield self.element_class(self, [])
|
|
889
|
+
return
|
|
890
|
+
if self._n == 1:
|
|
891
|
+
if self._k is not None:
|
|
892
|
+
for x in range(self._k+1):
|
|
893
|
+
yield self.element_class(self, [[x]])
|
|
894
|
+
else:
|
|
895
|
+
k = 1
|
|
896
|
+
while True:
|
|
897
|
+
yield self.element_class(self, [[k]])
|
|
898
|
+
k += 1
|
|
899
|
+
return
|
|
900
|
+
for x in self._list_iter(self._n):
|
|
901
|
+
yield self.element_class(self, x)
|
|
902
|
+
|
|
903
|
+
def _list_iter(self, n):
|
|
904
|
+
"""
|
|
905
|
+
Fast iterator which returns Gelfand-Tsetlin patterns of width ``n`` as
|
|
906
|
+
lists of lists.
|
|
907
|
+
|
|
908
|
+
EXAMPLES::
|
|
909
|
+
|
|
910
|
+
sage: G = GelfandTsetlinPatterns(3, 1)
|
|
911
|
+
sage: L = [x for x in G._list_iter(3)]
|
|
912
|
+
sage: len(L) == G.cardinality()
|
|
913
|
+
True
|
|
914
|
+
sage: type(L[0])
|
|
915
|
+
<class 'list'>
|
|
916
|
+
"""
|
|
917
|
+
# Setup the first row
|
|
918
|
+
iters = [None] * n
|
|
919
|
+
ret = [None] * n
|
|
920
|
+
iters[0] = self._top_row_iter(n)
|
|
921
|
+
ret[0] = next(iters[0])
|
|
922
|
+
min_pos = 0
|
|
923
|
+
iters[1] = self._row_iter(ret[0])
|
|
924
|
+
pos = 1
|
|
925
|
+
while pos >= min_pos:
|
|
926
|
+
try:
|
|
927
|
+
ret[pos] = next(iters[pos])
|
|
928
|
+
pos += 1
|
|
929
|
+
# If we've reached 0 width, yield and backstep
|
|
930
|
+
if pos == n:
|
|
931
|
+
yield ret[:]
|
|
932
|
+
pos -= 1
|
|
933
|
+
continue
|
|
934
|
+
iters[pos] = self._row_iter(ret[pos-1])
|
|
935
|
+
except StopIteration:
|
|
936
|
+
pos -= 1
|
|
937
|
+
|
|
938
|
+
def _top_row_iter(self, n):
|
|
939
|
+
"""
|
|
940
|
+
Helper iterator for the top row.
|
|
941
|
+
|
|
942
|
+
EXAMPLES::
|
|
943
|
+
|
|
944
|
+
sage: G = GelfandTsetlinPatterns(3, 1)
|
|
945
|
+
sage: for x in G._top_row_iter(3): x
|
|
946
|
+
[0, 0, 0]
|
|
947
|
+
[1, 0, 0]
|
|
948
|
+
[1, 1, 0]
|
|
949
|
+
[1, 1, 1]
|
|
950
|
+
sage: G = GelfandTsetlinPatterns(3, 2, strict=True)
|
|
951
|
+
sage: for x in G._top_row_iter(3): x
|
|
952
|
+
[2, 1, 0]
|
|
953
|
+
"""
|
|
954
|
+
row = [-1] * n
|
|
955
|
+
pos = 0
|
|
956
|
+
while pos >= 0:
|
|
957
|
+
if pos == n:
|
|
958
|
+
yield row[:]
|
|
959
|
+
pos -= 1
|
|
960
|
+
continue
|
|
961
|
+
# If it would create an invalid entry, backstep
|
|
962
|
+
if (pos > 0 and (row[pos] >= row[pos-1]
|
|
963
|
+
or (self._strict and row[pos] == row[pos-1]-1))) \
|
|
964
|
+
or (self._k is not None and row[pos] >= self._k):
|
|
965
|
+
row[pos] = -1
|
|
966
|
+
pos -= 1
|
|
967
|
+
continue
|
|
968
|
+
row[pos] += 1
|
|
969
|
+
pos += 1
|
|
970
|
+
|
|
971
|
+
def _row_iter(self, upper_row):
|
|
972
|
+
"""
|
|
973
|
+
Helper iterator for any row with a row above it.
|
|
974
|
+
|
|
975
|
+
EXAMPLES::
|
|
976
|
+
|
|
977
|
+
sage: G = GelfandTsetlinPatterns(3, 4)
|
|
978
|
+
sage: for x in G._row_iter([4,2,1]): x
|
|
979
|
+
[2, 1]
|
|
980
|
+
[2, 2]
|
|
981
|
+
[3, 1]
|
|
982
|
+
[3, 2]
|
|
983
|
+
[4, 1]
|
|
984
|
+
[4, 2]
|
|
985
|
+
sage: G = GelfandTsetlinPatterns(3, 2, strict=True)
|
|
986
|
+
sage: for x in G._row_iter([2, 1, 0]): x
|
|
987
|
+
[1, 0]
|
|
988
|
+
[2, 0]
|
|
989
|
+
[2, 1]
|
|
990
|
+
"""
|
|
991
|
+
row = [x - 1 for x in upper_row[1:]]
|
|
992
|
+
row_len = len(row)
|
|
993
|
+
pos = 0
|
|
994
|
+
while pos >= 0:
|
|
995
|
+
if pos == row_len:
|
|
996
|
+
yield row[:]
|
|
997
|
+
pos -= 1
|
|
998
|
+
continue
|
|
999
|
+
# If it would create an invalid entry, backstep
|
|
1000
|
+
if (pos > 0 and (row[pos] >= row[pos - 1]
|
|
1001
|
+
or (self._strict and row[pos] == row[pos - 1] - 1))) \
|
|
1002
|
+
or row[pos] >= upper_row[pos] \
|
|
1003
|
+
or (self._k is not None and row[pos] >= self._k):
|
|
1004
|
+
row[pos] = upper_row[pos + 1] - 1
|
|
1005
|
+
pos -= 1
|
|
1006
|
+
continue
|
|
1007
|
+
row[pos] += 1
|
|
1008
|
+
pos += 1
|
|
1009
|
+
|
|
1010
|
+
def _toggle_markov_chain(self, chain_state, row, col, direction):
|
|
1011
|
+
"""
|
|
1012
|
+
Helper for coupling from the past. Advance the Markov chain one step.
|
|
1013
|
+
|
|
1014
|
+
INPUT:
|
|
1015
|
+
|
|
1016
|
+
- ``chain_state`` -- a GelfandTsetlin pattern represented as a list of lists
|
|
1017
|
+
- ``row`` -- the row of the cell being modified
|
|
1018
|
+
- ``col`` -- the column of the cell being modified
|
|
1019
|
+
- ``direction`` -- the direction to change the cell 1 = increase, 0 = decrease
|
|
1020
|
+
|
|
1021
|
+
OUTPUT: ``chain_state`` is possibly modified
|
|
1022
|
+
|
|
1023
|
+
TESTS:
|
|
1024
|
+
|
|
1025
|
+
sage: G = GelfandTsetlinPatterns(3,4)
|
|
1026
|
+
sage: state = [[3,2,1],[3,1],[2]]
|
|
1027
|
+
sage: G._toggle_markov_chain(state, 0, 0, 1)
|
|
1028
|
+
sage: state
|
|
1029
|
+
[[4, 2, 1], [3, 1], [2]]
|
|
1030
|
+
sage: G._toggle_markov_chain(state, 1, 1, 1)
|
|
1031
|
+
sage: state
|
|
1032
|
+
[[4, 2, 1], [3, 2], [2]]
|
|
1033
|
+
sage: G._toggle_markov_chain(state, 0, 2, 1)
|
|
1034
|
+
sage: state
|
|
1035
|
+
[[4, 2, 2], [3, 2], [2]]
|
|
1036
|
+
sage: G._toggle_markov_chain(state, 0, 2, 1)
|
|
1037
|
+
sage: state
|
|
1038
|
+
[[4, 2, 2], [3, 2], [2]]
|
|
1039
|
+
sage: G._toggle_markov_chain(state, 0, 2, 0)
|
|
1040
|
+
sage: state
|
|
1041
|
+
[[4, 2, 1], [3, 2], [2]]
|
|
1042
|
+
sage: G._toggle_markov_chain(state, 0, 2, 0)
|
|
1043
|
+
sage: state
|
|
1044
|
+
[[4, 2, 0], [3, 2], [2]]
|
|
1045
|
+
sage: G._toggle_markov_chain(state, 0, 2, 0)
|
|
1046
|
+
sage: state
|
|
1047
|
+
[[4, 2, 0], [3, 2], [2]]
|
|
1048
|
+
"""
|
|
1049
|
+
if direction == 1:
|
|
1050
|
+
upbound = self._k
|
|
1051
|
+
if row != 0:
|
|
1052
|
+
upbound = min(upbound, chain_state[row - 1][col])
|
|
1053
|
+
if self._strict and col > 0:
|
|
1054
|
+
upbound = min(upbound, chain_state[row][col - 1] - 1)
|
|
1055
|
+
if row < self._n and col > 0:
|
|
1056
|
+
upbound = min(upbound, chain_state[row + 1][col - 1])
|
|
1057
|
+
if chain_state[row][col] < upbound:
|
|
1058
|
+
chain_state[row][col] += 1
|
|
1059
|
+
else:
|
|
1060
|
+
lobound = 0
|
|
1061
|
+
if row != 0:
|
|
1062
|
+
lobound = max(lobound, chain_state[row - 1][col + 1])
|
|
1063
|
+
if self._strict and col < self._n - row - 1:
|
|
1064
|
+
lobound = max(lobound, chain_state[row][col + 1] + 1)
|
|
1065
|
+
if row < self._n and col < self._n - row - 1:
|
|
1066
|
+
lobound = max(lobound, chain_state[row + 1][col])
|
|
1067
|
+
if chain_state[row][col] > lobound:
|
|
1068
|
+
chain_state[row][col] -= 1
|
|
1069
|
+
|
|
1070
|
+
def _cftp_upper(self):
|
|
1071
|
+
"""
|
|
1072
|
+
Return the largest member of the poset of Gelfand-Tsetlin patterns having the given ``n`` and ``k``.
|
|
1073
|
+
|
|
1074
|
+
TESTS::
|
|
1075
|
+
|
|
1076
|
+
sage: GelfandTsetlinPatterns(3, 5)._cftp_upper()
|
|
1077
|
+
[[5, 5, 5], [5, 5], [5]]
|
|
1078
|
+
sage: GelfandTsetlinPatterns(3, 5, strict=True)._cftp_upper()
|
|
1079
|
+
[[5, 4, 3], [5, 4], [5]]
|
|
1080
|
+
"""
|
|
1081
|
+
if self._strict:
|
|
1082
|
+
return [[self._k - j for j in range(self._n - i)] for i in range(self._n)]
|
|
1083
|
+
else:
|
|
1084
|
+
return [[self._k for j in range(self._n - i)] for i in range(self._n)]
|
|
1085
|
+
|
|
1086
|
+
def _cftp_lower(self):
|
|
1087
|
+
"""
|
|
1088
|
+
Return the smallest member of the poset of Gelfand-Tsetlin patterns having the given ``n`` and ``k``.
|
|
1089
|
+
|
|
1090
|
+
TESTS::
|
|
1091
|
+
|
|
1092
|
+
sage: GelfandTsetlinPatterns(3, 5)._cftp_lower()
|
|
1093
|
+
[[0, 0, 0], [0, 0], [0]]
|
|
1094
|
+
sage: GelfandTsetlinPatterns(3, 5, strict=True)._cftp_lower()
|
|
1095
|
+
[[2, 1, 0], [1, 0], [0]]
|
|
1096
|
+
"""
|
|
1097
|
+
if self._strict:
|
|
1098
|
+
return [[self._n - j - i - 1 for j in range(self._n - i)] for i in range(self._n)]
|
|
1099
|
+
else:
|
|
1100
|
+
return [[0 for j in range(self._n - i)] for i in range(self._n)]
|
|
1101
|
+
|
|
1102
|
+
def _cftp(self, start_row):
|
|
1103
|
+
"""
|
|
1104
|
+
Implement coupling from the past.
|
|
1105
|
+
|
|
1106
|
+
ALGORITHM:
|
|
1107
|
+
|
|
1108
|
+
The set of Gelfand-Tsetlin patterns can partially ordered by
|
|
1109
|
+
elementwise domination. The partial order has unique maximum
|
|
1110
|
+
and minimum elements that are computed by the methods
|
|
1111
|
+
:meth:`_cftp_upper` and :meth:`_cftp_lower`. We then run the Markov
|
|
1112
|
+
chain that randomly toggles each element up or down from the
|
|
1113
|
+
past until the state reached from the upper and lower start
|
|
1114
|
+
points coalesce as described in [Propp1997]_.
|
|
1115
|
+
|
|
1116
|
+
EXAMPLES::
|
|
1117
|
+
|
|
1118
|
+
sage: G = GelfandTsetlinPatterns(3, 5)
|
|
1119
|
+
sage: G._cftp(0) # random
|
|
1120
|
+
[[5, 3, 2], [4, 2], [3]]
|
|
1121
|
+
sage: G._cftp(0) in G
|
|
1122
|
+
True
|
|
1123
|
+
"""
|
|
1124
|
+
from sage.misc.randstate import current_randstate
|
|
1125
|
+
from sage.misc.randstate import seed, random
|
|
1126
|
+
|
|
1127
|
+
count = self._n * self._k
|
|
1128
|
+
seedlist = [(current_randstate().long_seed(), count)]
|
|
1129
|
+
upper = []
|
|
1130
|
+
lower = []
|
|
1131
|
+
while True:
|
|
1132
|
+
upper = self._cftp_upper()
|
|
1133
|
+
lower = self._cftp_lower()
|
|
1134
|
+
for currseed, count in seedlist:
|
|
1135
|
+
with seed(currseed):
|
|
1136
|
+
for _ in range(count):
|
|
1137
|
+
for row in range(start_row, self._n):
|
|
1138
|
+
for col in range(self._n - row):
|
|
1139
|
+
direction = random() % 2
|
|
1140
|
+
self._toggle_markov_chain(upper, row, col, direction)
|
|
1141
|
+
self._toggle_markov_chain(lower, row, col, direction)
|
|
1142
|
+
if all(x == y for l1, l2 in zip(upper, lower)
|
|
1143
|
+
for x, y in zip(l1, l2)):
|
|
1144
|
+
break
|
|
1145
|
+
count = seedlist[0][1] * 2
|
|
1146
|
+
seedlist.insert(0, (current_randstate().long_seed(), count))
|
|
1147
|
+
return GelfandTsetlinPattern(upper)
|
|
1148
|
+
|
|
1149
|
+
def random_element(self) -> GelfandTsetlinPattern:
|
|
1150
|
+
"""
|
|
1151
|
+
Return a uniformly random Gelfand-Tsetlin pattern.
|
|
1152
|
+
|
|
1153
|
+
EXAMPLES::
|
|
1154
|
+
|
|
1155
|
+
sage: g = GelfandTsetlinPatterns(4, 5)
|
|
1156
|
+
sage: x = g.random_element()
|
|
1157
|
+
sage: x in g
|
|
1158
|
+
True
|
|
1159
|
+
sage: len(x)
|
|
1160
|
+
4
|
|
1161
|
+
sage: all(y in range(5+1) for z in x for y in z)
|
|
1162
|
+
True
|
|
1163
|
+
sage: x.check()
|
|
1164
|
+
|
|
1165
|
+
::
|
|
1166
|
+
|
|
1167
|
+
sage: g = GelfandTsetlinPatterns(4, 5, strict=True)
|
|
1168
|
+
sage: x = g.random_element()
|
|
1169
|
+
sage: x in g
|
|
1170
|
+
True
|
|
1171
|
+
sage: len(x)
|
|
1172
|
+
4
|
|
1173
|
+
sage: all(y in range(5+1) for z in x for y in z)
|
|
1174
|
+
True
|
|
1175
|
+
sage: x.check()
|
|
1176
|
+
sage: x.is_strict()
|
|
1177
|
+
True
|
|
1178
|
+
"""
|
|
1179
|
+
if self._n is not None and self._k is not None:
|
|
1180
|
+
if self._strict and self._k + 1 < self._n:
|
|
1181
|
+
raise ValueError('cannot sample from empty set')
|
|
1182
|
+
elif self._k < 0:
|
|
1183
|
+
raise ValueError('cannot sample from empty set')
|
|
1184
|
+
else:
|
|
1185
|
+
return self._cftp(0)
|
|
1186
|
+
else:
|
|
1187
|
+
raise ValueError('cannot sample from infinite set')
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
class GelfandTsetlinPatternsTopRow(GelfandTsetlinPatterns):
|
|
1191
|
+
"""
|
|
1192
|
+
Gelfand-Tsetlin patterns with a fixed top row.
|
|
1193
|
+
"""
|
|
1194
|
+
|
|
1195
|
+
def __init__(self, top_row, strict):
|
|
1196
|
+
"""
|
|
1197
|
+
Initialize ``self``.
|
|
1198
|
+
|
|
1199
|
+
EXAMPLES::
|
|
1200
|
+
|
|
1201
|
+
sage: G = GelfandTsetlinPatterns(top_row=[4,4,3,1])
|
|
1202
|
+
sage: TestSuite(G).run()
|
|
1203
|
+
|
|
1204
|
+
TESTS:
|
|
1205
|
+
|
|
1206
|
+
Check a border case in :issue:`14765`::
|
|
1207
|
+
|
|
1208
|
+
sage: G = GelfandTsetlinPatterns(top_row=[])
|
|
1209
|
+
sage: list(G)
|
|
1210
|
+
[[]]
|
|
1211
|
+
"""
|
|
1212
|
+
self._row = top_row
|
|
1213
|
+
n = len(top_row)
|
|
1214
|
+
if n == 0:
|
|
1215
|
+
k = 0
|
|
1216
|
+
else:
|
|
1217
|
+
k = top_row[0]
|
|
1218
|
+
GelfandTsetlinPatterns.__init__(self, n, k, strict)
|
|
1219
|
+
|
|
1220
|
+
def _repr_(self) -> str:
|
|
1221
|
+
"""
|
|
1222
|
+
Return a string representation of ``self``.
|
|
1223
|
+
|
|
1224
|
+
EXAMPLES::
|
|
1225
|
+
|
|
1226
|
+
sage: GelfandTsetlinPatterns(top_row=[4,4,3,1])
|
|
1227
|
+
Gelfand-Tsetlin patterns with top row [4, 4, 3, 1]
|
|
1228
|
+
sage: GelfandTsetlinPatterns(top_row=[5,4,3,1], strict=True)
|
|
1229
|
+
Strict Gelfand-Tsetlin patterns with top row [5, 4, 3, 1]
|
|
1230
|
+
"""
|
|
1231
|
+
base = "Gelfand-Tsetlin patterns with top row %s" % list(self._row)
|
|
1232
|
+
if self._strict:
|
|
1233
|
+
base = "Strict " + base
|
|
1234
|
+
return base
|
|
1235
|
+
|
|
1236
|
+
def __contains__(self, gt) -> bool:
|
|
1237
|
+
"""
|
|
1238
|
+
Check if ``gt`` is in ``self``.
|
|
1239
|
+
|
|
1240
|
+
EXAMPLES::
|
|
1241
|
+
|
|
1242
|
+
sage: G = GelfandTsetlinPatterns(top_row=[4,4,1])
|
|
1243
|
+
sage: [[4,4,1], [4,2], [3]] in G
|
|
1244
|
+
True
|
|
1245
|
+
sage: [[4,3,1], [4,2], [3]] in G
|
|
1246
|
+
False
|
|
1247
|
+
"""
|
|
1248
|
+
# Check if the top row matches (if applicable)
|
|
1249
|
+
if gt and tuple(gt[0]) != self._row:
|
|
1250
|
+
return False
|
|
1251
|
+
return GelfandTsetlinPatterns.__contains__(self, gt)
|
|
1252
|
+
|
|
1253
|
+
def __iter__(self):
|
|
1254
|
+
"""
|
|
1255
|
+
Iterate over ``self``.
|
|
1256
|
+
|
|
1257
|
+
EXAMPLES::
|
|
1258
|
+
|
|
1259
|
+
sage: G = GelfandTsetlinPatterns(top_row=[4,2,1])
|
|
1260
|
+
sage: list(G)
|
|
1261
|
+
[[[4, 2, 1], [2, 1], [1]],
|
|
1262
|
+
[[4, 2, 1], [2, 1], [2]],
|
|
1263
|
+
[[4, 2, 1], [2, 2], [2]],
|
|
1264
|
+
[[4, 2, 1], [3, 1], [1]],
|
|
1265
|
+
[[4, 2, 1], [3, 1], [2]],
|
|
1266
|
+
[[4, 2, 1], [3, 1], [3]],
|
|
1267
|
+
[[4, 2, 1], [3, 2], [2]],
|
|
1268
|
+
[[4, 2, 1], [3, 2], [3]],
|
|
1269
|
+
[[4, 2, 1], [4, 1], [1]],
|
|
1270
|
+
[[4, 2, 1], [4, 1], [2]],
|
|
1271
|
+
[[4, 2, 1], [4, 1], [3]],
|
|
1272
|
+
[[4, 2, 1], [4, 1], [4]],
|
|
1273
|
+
[[4, 2, 1], [4, 2], [2]],
|
|
1274
|
+
[[4, 2, 1], [4, 2], [3]],
|
|
1275
|
+
[[4, 2, 1], [4, 2], [4]]]
|
|
1276
|
+
"""
|
|
1277
|
+
# If we enforce strictness, check to see if a specified top row is strict
|
|
1278
|
+
if self._strict and any(self._row[i] == self._row[i + 1] for i in range(self._n - 1)):
|
|
1279
|
+
return
|
|
1280
|
+
if self._n == 0:
|
|
1281
|
+
yield self.element_class(self, [])
|
|
1282
|
+
return
|
|
1283
|
+
if self._n == 1:
|
|
1284
|
+
yield self.element_class(self, [list(self._row)])
|
|
1285
|
+
return
|
|
1286
|
+
# Setup the first row
|
|
1287
|
+
iters = [None] * self._n
|
|
1288
|
+
ret = [None] * self._n
|
|
1289
|
+
ret[0] = list(self._row)
|
|
1290
|
+
min_pos = 1
|
|
1291
|
+
iters[1] = self._row_iter(ret[0])
|
|
1292
|
+
pos = 1
|
|
1293
|
+
while pos >= min_pos:
|
|
1294
|
+
try:
|
|
1295
|
+
ret[pos] = next(iters[pos])
|
|
1296
|
+
pos += 1
|
|
1297
|
+
# If we've reached 0 width, yield and backstep
|
|
1298
|
+
if pos == self._n:
|
|
1299
|
+
yield self.element_class(self, ret[:])
|
|
1300
|
+
pos -= 1
|
|
1301
|
+
continue
|
|
1302
|
+
iters[pos] = self._row_iter(ret[pos - 1])
|
|
1303
|
+
except StopIteration:
|
|
1304
|
+
pos -= 1
|
|
1305
|
+
|
|
1306
|
+
def top_row(self):
|
|
1307
|
+
"""
|
|
1308
|
+
Return the top row of ``self``.
|
|
1309
|
+
|
|
1310
|
+
EXAMPLES::
|
|
1311
|
+
|
|
1312
|
+
sage: G = GelfandTsetlinPatterns(top_row=[4,4,3,1])
|
|
1313
|
+
sage: G.top_row()
|
|
1314
|
+
(4, 4, 3, 1)
|
|
1315
|
+
"""
|
|
1316
|
+
return self._row
|
|
1317
|
+
|
|
1318
|
+
def Tokuyama_formula(self, name='t'):
|
|
1319
|
+
r"""
|
|
1320
|
+
Return the Tokuyama formula of ``self``.
|
|
1321
|
+
|
|
1322
|
+
Following the exposition of [BBF]_, Tokuyama's formula asserts
|
|
1323
|
+
|
|
1324
|
+
.. MATH::
|
|
1325
|
+
|
|
1326
|
+
\sum_{G} (t+1)^{s(G)} t^{l(G)}
|
|
1327
|
+
z_1^{d_{n+1}} z_2^{d_{n}-d_{n+1}} \cdots z_{n+1}^{d_1-d_2}
|
|
1328
|
+
= s_{\lambda} (z_1, \ldots, z_{n+1}) \prod_{i<j} (z_j+tz_i),
|
|
1329
|
+
|
|
1330
|
+
where the sum is over all strict Gelfand-Tsetlin patterns with fixed
|
|
1331
|
+
top row `\lambda+\rho`, with `\lambda` a partition with at most
|
|
1332
|
+
`n+1` parts and `\rho = (n,n-1,\dots,1,0)`, and `s_{\lambda}` is a Schur
|
|
1333
|
+
function.
|
|
1334
|
+
|
|
1335
|
+
INPUT:
|
|
1336
|
+
|
|
1337
|
+
- ``name`` -- (default: ``'t'``) an alternative name for the
|
|
1338
|
+
variable `t`
|
|
1339
|
+
|
|
1340
|
+
EXAMPLES::
|
|
1341
|
+
|
|
1342
|
+
sage: GT = GelfandTsetlinPatterns(top_row=[2,1,0],strict=True)
|
|
1343
|
+
sage: GT.Tokuyama_formula()
|
|
1344
|
+
t^3*x1^2*x2 + t^2*x1*x2^2 + t^2*x1^2*x3 + t^2*x1*x2*x3 + t*x1*x2*x3 + t*x2^2*x3 + t*x1*x3^2 + x2*x3^2
|
|
1345
|
+
sage: GT = GelfandTsetlinPatterns(top_row=[3,2,1],strict=True)
|
|
1346
|
+
sage: GT.Tokuyama_formula()
|
|
1347
|
+
t^3*x1^3*x2^2*x3 + t^2*x1^2*x2^3*x3 + t^2*x1^3*x2*x3^2 + t^2*x1^2*x2^2*x3^2 + t*x1^2*x2^2*x3^2 + t*x1*x2^3*x3^2 + t*x1^2*x2*x3^3 + x1*x2^2*x3^3
|
|
1348
|
+
sage: GT = GelfandTsetlinPatterns(top_row=[1,1,1],strict=True)
|
|
1349
|
+
sage: GT.Tokuyama_formula()
|
|
1350
|
+
0
|
|
1351
|
+
"""
|
|
1352
|
+
n = self._n
|
|
1353
|
+
variables = [name] + ["x%d" % i for i in range(1, n + 1)]
|
|
1354
|
+
R = PolynomialRing(ZZ, names=variables)
|
|
1355
|
+
t = R.gen(0)
|
|
1356
|
+
x = R.gens()[1:]
|
|
1357
|
+
GT = GelfandTsetlinPatterns(top_row=self._row, strict=True)
|
|
1358
|
+
return sum((t + 1)**gt.number_of_special_entries() * t**gt.number_of_boxes() * prod(x[i]**gt.weight()[i] for i in range(n)) for gt in GT)
|
|
1359
|
+
|
|
1360
|
+
def _cftp_upper(self) -> list:
|
|
1361
|
+
"""
|
|
1362
|
+
Return the largest member of the poset of Gelfand-Tsetlin patterns having the given ``top_row``.
|
|
1363
|
+
|
|
1364
|
+
TESTS::
|
|
1365
|
+
|
|
1366
|
+
sage: GelfandTsetlinPatterns(top_row = [5, 4, 3])._cftp_upper()
|
|
1367
|
+
[[5, 4, 3], [5, 4], [5]]
|
|
1368
|
+
"""
|
|
1369
|
+
return [[self._row[j] for j in range(self._n - i)] for i in range(self._n)]
|
|
1370
|
+
|
|
1371
|
+
def _cftp_lower(self) -> list:
|
|
1372
|
+
"""
|
|
1373
|
+
Return the smallest member of the poset of Gelfand-Tsetlin patterns having the given ``top_row``.
|
|
1374
|
+
|
|
1375
|
+
TESTS::
|
|
1376
|
+
|
|
1377
|
+
sage: GelfandTsetlinPatterns(top_row = [5, 4, 3])._cftp_lower()
|
|
1378
|
+
[[5, 4, 3], [4, 3], [3]]
|
|
1379
|
+
"""
|
|
1380
|
+
return [[self._row[i + j] for j in range(self._n - i)] for i in range(self._n)]
|
|
1381
|
+
|
|
1382
|
+
def random_element(self) -> GelfandTsetlinPattern:
|
|
1383
|
+
"""
|
|
1384
|
+
Return a uniformly random Gelfand-Tsetlin pattern with specified top row.
|
|
1385
|
+
|
|
1386
|
+
EXAMPLES::
|
|
1387
|
+
|
|
1388
|
+
sage: g = GelfandTsetlinPatterns(top_row = [4, 3, 1, 1])
|
|
1389
|
+
sage: x = g.random_element()
|
|
1390
|
+
sage: x in g
|
|
1391
|
+
True
|
|
1392
|
+
sage: x[0] == [4, 3, 1, 1]
|
|
1393
|
+
True
|
|
1394
|
+
sage: x.check()
|
|
1395
|
+
|
|
1396
|
+
sage: g = GelfandTsetlinPatterns(top_row=[4, 3, 2, 1], strict=True)
|
|
1397
|
+
sage: x = g.random_element()
|
|
1398
|
+
sage: x in g
|
|
1399
|
+
True
|
|
1400
|
+
sage: x[0] == [4, 3, 2, 1]
|
|
1401
|
+
True
|
|
1402
|
+
sage: x.is_strict()
|
|
1403
|
+
True
|
|
1404
|
+
sage: x.check()
|
|
1405
|
+
"""
|
|
1406
|
+
if self._strict:
|
|
1407
|
+
return self._cftp(1)
|
|
1408
|
+
l = [i for i in self._row if i > 0]
|
|
1409
|
+
return SemistandardTableaux(l, max_entry=self._n).random_element().to_Gelfand_Tsetlin_pattern() # type:ignore
|