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,4564 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Strong and weak tableaux
|
|
5
|
+
|
|
6
|
+
There are two types of `k`-tableaux: strong `k`-tableaux and weak `k`-tableaux.
|
|
7
|
+
Standard weak `k`-tableaux correspond to saturated chains in the weak order,
|
|
8
|
+
whereas standard strong `k`-tableaux correspond to saturated chains in the strong Bruhat order.
|
|
9
|
+
For semistandard tableaux, the notion of weak and strong horizontal strip is necessary.
|
|
10
|
+
More information can be found in [LLMS2006]_ .
|
|
11
|
+
|
|
12
|
+
.. SEEALSO:: :meth:`sage.combinat.k_tableau.StrongTableau`, :meth:`sage.combinat.k_tableau.WeakTableau`
|
|
13
|
+
|
|
14
|
+
Authors:
|
|
15
|
+
|
|
16
|
+
- Anne Schilling and Mike Zabrocki (2013): initial version
|
|
17
|
+
- Avi Dalal and Nate Gallup (2013): implementation of `k`-charge
|
|
18
|
+
"""
|
|
19
|
+
#*****************************************************************************
|
|
20
|
+
# Copyright (C) 2013 Anne Schilling <anne at math.ucdavis.edu>
|
|
21
|
+
# Mike Zabrocki <zabrocki at mathstat.yorku.ca>
|
|
22
|
+
#
|
|
23
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
24
|
+
#
|
|
25
|
+
# This code is distributed in the hope that it will be useful,
|
|
26
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
27
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
28
|
+
# General Public License for more details.
|
|
29
|
+
#
|
|
30
|
+
# The full text of the GPL is available at:
|
|
31
|
+
#
|
|
32
|
+
# https://www.gnu.org/licenses/
|
|
33
|
+
#****************************************************************************
|
|
34
|
+
from itertools import repeat
|
|
35
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
36
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
37
|
+
from sage.structure.parent import Parent
|
|
38
|
+
from sage.structure.list_clone import ClonableList
|
|
39
|
+
from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
|
|
40
|
+
from sage.combinat.skew_tableau import SkewTableau, SemistandardSkewTableaux
|
|
41
|
+
from sage.combinat.partition import Partition, Partitions
|
|
42
|
+
from sage.combinat.core import Core
|
|
43
|
+
from sage.rings.integer_ring import ZZ
|
|
44
|
+
from sage.functions.generalized import sgn
|
|
45
|
+
from sage.misc.lazy_import import lazy_import
|
|
46
|
+
from sage.misc.flatten import flatten
|
|
47
|
+
from sage.combinat.skew_partition import SkewPartition
|
|
48
|
+
from sage.combinat.tableau import Tableaux
|
|
49
|
+
from sage.combinat.composition import Composition
|
|
50
|
+
import copy
|
|
51
|
+
|
|
52
|
+
lazy_import('sage.combinat.root_system.weyl_group', 'WeylGroup')
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def WeakTableau(t, k, inner_shape=[], representation='core'):
|
|
56
|
+
r"""
|
|
57
|
+
This is the dispatcher method for the element class of weak `k`-tableaux.
|
|
58
|
+
|
|
59
|
+
Standard weak `k`-tableaux correspond to saturated chains in the weak order.
|
|
60
|
+
There are three formulations of weak tableaux, one in terms of cores, one in terms
|
|
61
|
+
of `k`-bounded partitions, and one in terms of factorizations of affine Grassmannian
|
|
62
|
+
elements. For semistandard weak `k`-tableaux, all letters of the same value have to
|
|
63
|
+
satisfy the conditions of a horizontal strip. In the affine Grassmannian formulation this
|
|
64
|
+
means that all factors are cyclically decreasing elements. For more information, see
|
|
65
|
+
for example [LLMSSZ2013]_.
|
|
66
|
+
|
|
67
|
+
INPUT:
|
|
68
|
+
|
|
69
|
+
- ``t`` -- a weak `k`-tableau in the specified representation:
|
|
70
|
+
|
|
71
|
+
- for the 'core' representation ``t`` is a list of lists where each subtableaux
|
|
72
|
+
should have a `k+1`-core shape; ``None`` is allowed as an entry for skew weak
|
|
73
|
+
`k`-tableaux
|
|
74
|
+
- for the 'bounded' representation ``t`` is a list of lists where each subtableaux
|
|
75
|
+
should have a `k`-bounded shape; ``None`` is allowed as an entry for skew weak
|
|
76
|
+
`k`-tableaux
|
|
77
|
+
- for the 'factorized_permutation' representation ``t`` is either a list of
|
|
78
|
+
cyclically decreasing Weyl group elements or a list of reduced words of cyclically
|
|
79
|
+
decreasing Weyl group elements; to indicate a skew tableau in this representation,
|
|
80
|
+
``inner_shape`` should be the inner shape as a `(k+1)`-core
|
|
81
|
+
|
|
82
|
+
- ``k`` -- positive integer
|
|
83
|
+
|
|
84
|
+
- ``inner_shape`` -- this entry is only relevant for the 'factorized_permutation'
|
|
85
|
+
representation and specifies the inner shape in case the tableau is skew
|
|
86
|
+
(default: ``[]``)
|
|
87
|
+
|
|
88
|
+
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation'
|
|
89
|
+
(default: ``'core'``)
|
|
90
|
+
|
|
91
|
+
EXAMPLES:
|
|
92
|
+
|
|
93
|
+
Here is an example of a weak 3-tableau in core representation::
|
|
94
|
+
|
|
95
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
96
|
+
sage: t.shape()
|
|
97
|
+
[5, 2, 1]
|
|
98
|
+
sage: t.weight()
|
|
99
|
+
(2, 2, 2)
|
|
100
|
+
sage: type(t)
|
|
101
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
102
|
+
|
|
103
|
+
And now we give a skew weak 3-tableau in core representation::
|
|
104
|
+
|
|
105
|
+
sage: ts = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
|
|
106
|
+
sage: ts.shape()
|
|
107
|
+
([5, 2, 1], [1, 1])
|
|
108
|
+
sage: ts.weight()
|
|
109
|
+
(2, 2)
|
|
110
|
+
sage: type(ts)
|
|
111
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
112
|
+
|
|
113
|
+
Next we create the analogue of the first example in bounded representation::
|
|
114
|
+
|
|
115
|
+
sage: tb = WeakTableau([[1,1,2],[2,3],[3]], 3, representation='bounded')
|
|
116
|
+
sage: tb.shape()
|
|
117
|
+
[3, 2, 1]
|
|
118
|
+
sage: tb.weight()
|
|
119
|
+
(2, 2, 2)
|
|
120
|
+
sage: type(tb)
|
|
121
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
|
|
122
|
+
sage: tb.to_core_tableau()
|
|
123
|
+
[[1, 1, 2, 2, 3], [2, 3], [3]]
|
|
124
|
+
sage: t == tb.to_core_tableau()
|
|
125
|
+
True
|
|
126
|
+
|
|
127
|
+
And the analogue of the skew example in bounded representation::
|
|
128
|
+
|
|
129
|
+
sage: tbs = WeakTableau([[None, 1, 2], [None, 2], [1]], 3, representation = "bounded")
|
|
130
|
+
sage: tbs.shape()
|
|
131
|
+
([3, 2, 1], [1, 1])
|
|
132
|
+
sage: tbs.weight()
|
|
133
|
+
(2, 2)
|
|
134
|
+
sage: tbs.to_core_tableau()
|
|
135
|
+
[[None, 1, 1, 2, 2], [None, 2], [1]]
|
|
136
|
+
sage: ts.to_bounded_tableau() == tbs
|
|
137
|
+
True
|
|
138
|
+
|
|
139
|
+
Finally we do the same examples for the factorized permutation representation::
|
|
140
|
+
|
|
141
|
+
sage: tf = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = "factorized_permutation")
|
|
142
|
+
sage: tf.shape()
|
|
143
|
+
[5, 2, 1]
|
|
144
|
+
sage: tf.weight()
|
|
145
|
+
(2, 2, 2)
|
|
146
|
+
sage: type(tf)
|
|
147
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
|
|
148
|
+
sage: tf.to_core_tableau() == t
|
|
149
|
+
True
|
|
150
|
+
|
|
151
|
+
sage: tfs = WeakTableau([[0,3],[2,1]], 3, inner_shape = [1,1], representation = 'factorized_permutation')
|
|
152
|
+
sage: tfs.shape()
|
|
153
|
+
([5, 2, 1], [1, 1])
|
|
154
|
+
sage: tfs.weight()
|
|
155
|
+
(2, 2)
|
|
156
|
+
sage: type(tfs)
|
|
157
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
|
|
158
|
+
sage: tfs.to_core_tableau()
|
|
159
|
+
[[None, 1, 1, 2, 2], [None, 2], [1]]
|
|
160
|
+
|
|
161
|
+
Another way to pass from one representation to another is as follows::
|
|
162
|
+
|
|
163
|
+
sage: ts
|
|
164
|
+
[[None, 1, 1, 2, 2], [None, 2], [1]]
|
|
165
|
+
sage: ts.parent()._representation
|
|
166
|
+
'core'
|
|
167
|
+
sage: ts.representation('bounded')
|
|
168
|
+
[[None, 1, 2], [None, 2], [1]]
|
|
169
|
+
|
|
170
|
+
To test whether a given semistandard tableau is a weak `k`-tableau in the bounded representation,
|
|
171
|
+
one can ask::
|
|
172
|
+
|
|
173
|
+
sage: t = Tableau([[1,1,2],[2,3],[3]])
|
|
174
|
+
sage: t.is_k_tableau(3)
|
|
175
|
+
True
|
|
176
|
+
sage: t = SkewTableau([[None, 1, 2], [None, 2], [1]])
|
|
177
|
+
sage: t.is_k_tableau(3)
|
|
178
|
+
True
|
|
179
|
+
sage: t = SkewTableau([[None, 1, 1], [None, 2], [2]])
|
|
180
|
+
sage: t.is_k_tableau(3)
|
|
181
|
+
False
|
|
182
|
+
|
|
183
|
+
TESTS::
|
|
184
|
+
|
|
185
|
+
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = "bla")
|
|
186
|
+
Traceback (most recent call last):
|
|
187
|
+
...
|
|
188
|
+
NotImplementedError: The representation option needs to be 'core', 'bounded', or 'factorized_permutation'
|
|
189
|
+
"""
|
|
190
|
+
if representation == "core":
|
|
191
|
+
return WeakTableau_core(t, k)
|
|
192
|
+
elif representation == "bounded":
|
|
193
|
+
return WeakTableau_bounded(t, k)
|
|
194
|
+
elif representation == "factorized_permutation":
|
|
195
|
+
return WeakTableau_factorized_permutation(t, k, inner_shape=inner_shape)
|
|
196
|
+
else:
|
|
197
|
+
raise NotImplementedError("The representation option needs to be 'core', 'bounded', or 'factorized_permutation'")
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def WeakTableaux(k, shape , weight, representation='core'):
|
|
201
|
+
r"""
|
|
202
|
+
This is the dispatcher method for the parent class of weak `k`-tableaux.
|
|
203
|
+
|
|
204
|
+
INPUT:
|
|
205
|
+
|
|
206
|
+
- ``k`` -- positive integer
|
|
207
|
+
- ``shape`` -- shape of the weak `k`-tableaux; for the 'core' and
|
|
208
|
+
'factorized_permutation' representation, the shape is inputted as a `(k+1)`-core;
|
|
209
|
+
for the 'bounded' representation, the shape is inputted as a `k`-bounded partition;
|
|
210
|
+
for skew tableaux, the shape is inputted as a tuple of the outer and inner shape
|
|
211
|
+
- ``weight`` -- the weight of the weak `k`-tableaux as a list or tuple
|
|
212
|
+
- ``representation`` -- ``'core'``, ``'bounded'``, or ``'factorized_permutation'`` (default: ``'core'``)
|
|
213
|
+
|
|
214
|
+
EXAMPLES::
|
|
215
|
+
|
|
216
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1])
|
|
217
|
+
sage: T.list()
|
|
218
|
+
[[[1, 3, 4, 5, 6], [2, 6], [4]],
|
|
219
|
+
[[1, 2, 4, 5, 6], [3, 6], [4]],
|
|
220
|
+
[[1, 2, 3, 4, 6], [4, 6], [5]],
|
|
221
|
+
[[1, 2, 3, 4, 5], [4, 5], [6]]]
|
|
222
|
+
sage: T.cardinality()
|
|
223
|
+
4
|
|
224
|
+
|
|
225
|
+
sage: T = WeakTableaux(3, [[5,2,1], [2]], [1,1,1,1])
|
|
226
|
+
sage: T.list()
|
|
227
|
+
[[[None, None, 2, 3, 4], [1, 4], [2]],
|
|
228
|
+
[[None, None, 1, 2, 4], [2, 4], [3]],
|
|
229
|
+
[[None, None, 1, 2, 3], [2, 3], [4]]]
|
|
230
|
+
|
|
231
|
+
sage: T = WeakTableaux(3, [3,2,1], [1,1,1,1,1,1], representation = 'bounded')
|
|
232
|
+
sage: T.list()
|
|
233
|
+
[[[1, 3, 5], [2, 6], [4]],
|
|
234
|
+
[[1, 2, 5], [3, 6], [4]],
|
|
235
|
+
[[1, 2, 3], [4, 6], [5]],
|
|
236
|
+
[[1, 2, 3], [4, 5], [6]]]
|
|
237
|
+
|
|
238
|
+
sage: T = WeakTableaux(3, [[3,2,1], [2]], [1,1,1,1], representation = 'bounded')
|
|
239
|
+
sage: T.list()
|
|
240
|
+
[[[None, None, 3], [1, 4], [2]],
|
|
241
|
+
[[None, None, 1], [2, 4], [3]],
|
|
242
|
+
[[None, None, 1], [2, 3], [4]]]
|
|
243
|
+
|
|
244
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1], representation = 'factorized_permutation')
|
|
245
|
+
sage: T.list()
|
|
246
|
+
[[s0, s3, s2, s1, s3, s0],
|
|
247
|
+
[s0, s3, s2, s3, s1, s0],
|
|
248
|
+
[s0, s2, s3, s2, s1, s0],
|
|
249
|
+
[s2, s0, s3, s2, s1, s0]]
|
|
250
|
+
|
|
251
|
+
sage: T = WeakTableaux(3, [[5,2,1], [2]], [1,1,1,1], representation = 'factorized_permutation')
|
|
252
|
+
sage: T.list()
|
|
253
|
+
[[s0, s3, s2, s3], [s0, s2, s3, s2], [s2, s0, s3, s2]]
|
|
254
|
+
"""
|
|
255
|
+
if representation == "core":
|
|
256
|
+
return WeakTableaux_core(k, shape, weight)
|
|
257
|
+
elif representation == "bounded":
|
|
258
|
+
return WeakTableaux_bounded(k, shape, weight)
|
|
259
|
+
elif representation == "factorized_permutation":
|
|
260
|
+
return WeakTableaux_factorized_permutation(k, shape, weight)
|
|
261
|
+
else:
|
|
262
|
+
raise NotImplementedError("The representation option needs to be 'core', 'bounded', or 'factorized_permutation'")
|
|
263
|
+
|
|
264
|
+
#Abstract class for the elements of weak tableau
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class WeakTableau_abstract(ClonableList,
|
|
268
|
+
metaclass=InheritComparisonClasscallMetaclass):
|
|
269
|
+
r"""
|
|
270
|
+
Abstract class for the various element classes of WeakTableau.
|
|
271
|
+
"""
|
|
272
|
+
|
|
273
|
+
def shape(self):
|
|
274
|
+
r"""
|
|
275
|
+
Return the shape of ``self``.
|
|
276
|
+
|
|
277
|
+
When the tableau is straight, the outer shape is returned.
|
|
278
|
+
When the tableau is skew, the tuple of the outer and inner shape is returned.
|
|
279
|
+
|
|
280
|
+
EXAMPLES::
|
|
281
|
+
|
|
282
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
283
|
+
sage: t.shape()
|
|
284
|
+
[5, 2, 1]
|
|
285
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
286
|
+
sage: t.shape()
|
|
287
|
+
([5, 2, 1], [2])
|
|
288
|
+
|
|
289
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
290
|
+
sage: t.shape()
|
|
291
|
+
[3, 2, 1]
|
|
292
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
293
|
+
sage: t.shape()
|
|
294
|
+
([3, 2, 1], [2])
|
|
295
|
+
|
|
296
|
+
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
|
|
297
|
+
sage: t.shape()
|
|
298
|
+
[5, 2, 1]
|
|
299
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
300
|
+
sage: t.shape()
|
|
301
|
+
([5, 2, 1], [2])
|
|
302
|
+
"""
|
|
303
|
+
return self.parent().shape()
|
|
304
|
+
|
|
305
|
+
def weight(self):
|
|
306
|
+
r"""
|
|
307
|
+
Return the weight of ``self``.
|
|
308
|
+
|
|
309
|
+
The weight is a tuple whose `i`-th entry is the number of labels `i` in the
|
|
310
|
+
bounded representation of ``self``.
|
|
311
|
+
|
|
312
|
+
EXAMPLES::
|
|
313
|
+
|
|
314
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
315
|
+
sage: t.weight()
|
|
316
|
+
(2, 2, 2)
|
|
317
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
318
|
+
sage: t.weight()
|
|
319
|
+
(1, 1, 1, 1)
|
|
320
|
+
sage: t = WeakTableau([[None,2,3],[3]],2)
|
|
321
|
+
sage: t.weight()
|
|
322
|
+
(0, 1, 1)
|
|
323
|
+
|
|
324
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
325
|
+
sage: t.weight()
|
|
326
|
+
(3, 2, 1)
|
|
327
|
+
sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation = 'bounded')
|
|
328
|
+
sage: t.weight()
|
|
329
|
+
(2, 2, 2)
|
|
330
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
331
|
+
sage: t.weight()
|
|
332
|
+
(1, 1, 1, 1)
|
|
333
|
+
|
|
334
|
+
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
|
|
335
|
+
sage: t.weight()
|
|
336
|
+
(3, 2, 1)
|
|
337
|
+
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = 'factorized_permutation')
|
|
338
|
+
sage: t.weight()
|
|
339
|
+
(2, 2, 2)
|
|
340
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
341
|
+
sage: t.weight()
|
|
342
|
+
(2, 2)
|
|
343
|
+
"""
|
|
344
|
+
return self.parent()._weight
|
|
345
|
+
|
|
346
|
+
def size(self):
|
|
347
|
+
r"""
|
|
348
|
+
Return the size of the shape of ``self``.
|
|
349
|
+
|
|
350
|
+
In the bounded representation, the size of the shape is the number of boxes in the
|
|
351
|
+
outer shape minus the number of boxes in the inner shape. For the core and
|
|
352
|
+
factorized permutation representation, the size is the length of the outer shape
|
|
353
|
+
minus the length of the inner shape.
|
|
354
|
+
|
|
355
|
+
.. SEEALSO:: :meth:`sage.combinat.core.Core.length`
|
|
356
|
+
|
|
357
|
+
EXAMPLES::
|
|
358
|
+
|
|
359
|
+
sage: t = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
|
|
360
|
+
sage: t.shape()
|
|
361
|
+
([5, 2, 1], [1, 1])
|
|
362
|
+
sage: t.size()
|
|
363
|
+
4
|
|
364
|
+
sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation='bounded')
|
|
365
|
+
sage: t.shape()
|
|
366
|
+
[3, 2, 1]
|
|
367
|
+
sage: t.size()
|
|
368
|
+
6
|
|
369
|
+
"""
|
|
370
|
+
return self.parent().size()
|
|
371
|
+
|
|
372
|
+
def intermediate_shapes(self):
|
|
373
|
+
r"""
|
|
374
|
+
Return the intermediate shapes of ``self``.
|
|
375
|
+
|
|
376
|
+
A (skew) tableau with letters `1,2,\ldots,\ell` can be viewed as a sequence of shapes,
|
|
377
|
+
where the `i`-th shape is given by the shape of the subtableau on letters `1,2,\ldots,i`.
|
|
378
|
+
The output is the list of these shapes.
|
|
379
|
+
|
|
380
|
+
EXAMPLES::
|
|
381
|
+
|
|
382
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
383
|
+
sage: t.intermediate_shapes()
|
|
384
|
+
[[], [2], [4, 1], [5, 2, 1]]
|
|
385
|
+
|
|
386
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
387
|
+
sage: t.intermediate_shapes()
|
|
388
|
+
[[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]]
|
|
389
|
+
|
|
390
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
391
|
+
sage: t.intermediate_shapes()
|
|
392
|
+
[[], [3], [3, 2], [3, 2, 1]]
|
|
393
|
+
|
|
394
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
395
|
+
sage: t.intermediate_shapes()
|
|
396
|
+
[[2], [3], [3, 1], [3, 1, 1], [3, 2, 1]]
|
|
397
|
+
|
|
398
|
+
sage: t = WeakTableau([[0],[3],[2],[3]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
399
|
+
sage: t.intermediate_shapes()
|
|
400
|
+
[[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]]
|
|
401
|
+
"""
|
|
402
|
+
if self.parent()._representation in ['core', 'bounded']:
|
|
403
|
+
return intermediate_shapes(self)
|
|
404
|
+
else:
|
|
405
|
+
return intermediate_shapes(self.to_core_tableau())
|
|
406
|
+
|
|
407
|
+
def pp(self):
|
|
408
|
+
r"""
|
|
409
|
+
Return a pretty print string of the tableau.
|
|
410
|
+
|
|
411
|
+
EXAMPLES::
|
|
412
|
+
|
|
413
|
+
sage: t = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
|
|
414
|
+
sage: t.pp()
|
|
415
|
+
. 1 1 2 2
|
|
416
|
+
. 2
|
|
417
|
+
1
|
|
418
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
419
|
+
sage: t.pp()
|
|
420
|
+
[s2*s0, s3*s2]
|
|
421
|
+
"""
|
|
422
|
+
if self.parent()._representation in ['core', 'bounded']:
|
|
423
|
+
print(self._repr_diagram())
|
|
424
|
+
else:
|
|
425
|
+
print(self)
|
|
426
|
+
|
|
427
|
+
def __hash__(self):
|
|
428
|
+
r"""
|
|
429
|
+
Return the hash of ``self``.
|
|
430
|
+
|
|
431
|
+
EXAMPLES::
|
|
432
|
+
|
|
433
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1], representation='core')
|
|
434
|
+
sage: t = T[0]
|
|
435
|
+
sage: hash(t) == hash(t)
|
|
436
|
+
True
|
|
437
|
+
sage: T = WeakTableaux(3, [2,2,1], [1,1,1,1,1], representation='bounded')
|
|
438
|
+
sage: t = T[0]
|
|
439
|
+
sage: hash(t) == hash(t)
|
|
440
|
+
True
|
|
441
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1], representation='factorized_permutation')
|
|
442
|
+
sage: t = T[0]
|
|
443
|
+
sage: hash(t) == hash(t)
|
|
444
|
+
True
|
|
445
|
+
"""
|
|
446
|
+
if self.parent()._representation in ['core', 'bounded']:
|
|
447
|
+
return hash(tuple(tuple(x) for x in self)) + hash(self.parent().k)
|
|
448
|
+
else:
|
|
449
|
+
return super().__hash__()
|
|
450
|
+
|
|
451
|
+
def _latex_(self):
|
|
452
|
+
r"""
|
|
453
|
+
Return a latex method for the tableau.
|
|
454
|
+
|
|
455
|
+
EXAMPLES::
|
|
456
|
+
|
|
457
|
+
sage: t = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
|
|
458
|
+
sage: latex(t)
|
|
459
|
+
{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
460
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{5}c}\cline{1-5}
|
|
461
|
+
\lr{}&\lr{1}&\lr{1}&\lr{2}&\lr{2}\\\cline{1-5}
|
|
462
|
+
\lr{}&\lr{2}\\\cline{1-2}
|
|
463
|
+
\lr{1}\\\cline{1-1}
|
|
464
|
+
\end{array}$}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
sage: t = WeakTableau([[0,3],[2,1]], 3, inner_shape = [1,1], representation = 'factorized_permutation')
|
|
468
|
+
sage: latex(t)
|
|
469
|
+
[s_{0}s_{3},s_{2}s_{1}]
|
|
470
|
+
"""
|
|
471
|
+
def chi(x):
|
|
472
|
+
if x is None:
|
|
473
|
+
return ""
|
|
474
|
+
if x in ZZ:
|
|
475
|
+
return x
|
|
476
|
+
return "%s" % x
|
|
477
|
+
if self.parent()._representation in ['core', 'bounded']:
|
|
478
|
+
t = [[chi(x) for x in row] for row in self]
|
|
479
|
+
from .output import tex_from_array
|
|
480
|
+
return tex_from_array(t)
|
|
481
|
+
else:
|
|
482
|
+
return "["+"".join(self[i]._latex_()+',' for i in range(len(self)-1))+self[len(self)-1]._latex_()+"]"
|
|
483
|
+
|
|
484
|
+
def representation(self, representation='core'):
|
|
485
|
+
r"""
|
|
486
|
+
Return the analogue of ``self`` in the specified representation.
|
|
487
|
+
|
|
488
|
+
INPUT:
|
|
489
|
+
|
|
490
|
+
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: ``'core'``)
|
|
491
|
+
|
|
492
|
+
EXAMPLES::
|
|
493
|
+
|
|
494
|
+
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
495
|
+
sage: t.parent()._representation
|
|
496
|
+
'core'
|
|
497
|
+
sage: t.representation('bounded')
|
|
498
|
+
[[1, 1, 2, 4], [2, 3, 5], [3, 4], [5, 6], [6], [7]]
|
|
499
|
+
sage: t.representation('factorized_permutation')
|
|
500
|
+
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
|
|
501
|
+
|
|
502
|
+
sage: tb = WeakTableau([[1, 1, 2, 4], [2, 3, 5], [3, 4], [5, 6], [6], [7]], 4, representation = 'bounded')
|
|
503
|
+
sage: tb.parent()._representation
|
|
504
|
+
'bounded'
|
|
505
|
+
sage: tb.representation('core') == t
|
|
506
|
+
True
|
|
507
|
+
sage: tb.representation('factorized_permutation')
|
|
508
|
+
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
|
|
509
|
+
|
|
510
|
+
sage: tp = WeakTableau([[0],[3,1],[2,1],[0,4],[3,0],[4,2],[1,0]], 4, representation = 'factorized_permutation')
|
|
511
|
+
sage: tp.parent()._representation
|
|
512
|
+
'factorized_permutation'
|
|
513
|
+
sage: tp.representation('core') == t
|
|
514
|
+
True
|
|
515
|
+
sage: tp.representation('bounded') == tb
|
|
516
|
+
True
|
|
517
|
+
"""
|
|
518
|
+
t = self
|
|
519
|
+
if self.parent()._representation in ['bounded', 'factorized_permutation']:
|
|
520
|
+
t = t.to_core_tableau()
|
|
521
|
+
if representation == 'core':
|
|
522
|
+
return t
|
|
523
|
+
elif representation == 'bounded':
|
|
524
|
+
return t.to_bounded_tableau()
|
|
525
|
+
elif representation == 'factorized_permutation':
|
|
526
|
+
return t.to_factorized_permutation_tableau()
|
|
527
|
+
else:
|
|
528
|
+
raise ValueError("The representation must be one of 'core', 'bounded', or 'factorized_permutation'")
|
|
529
|
+
|
|
530
|
+
#Abstract class for the parents of weak tableaux
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
class WeakTableaux_abstract(UniqueRepresentation, Parent):
|
|
534
|
+
r"""
|
|
535
|
+
Abstract class for the various parent classes of WeakTableaux.
|
|
536
|
+
"""
|
|
537
|
+
|
|
538
|
+
def shape(self):
|
|
539
|
+
r"""
|
|
540
|
+
Return the shape of the tableaux of ``self``.
|
|
541
|
+
|
|
542
|
+
When ``self`` is the class of straight tableaux, the outer shape is returned.
|
|
543
|
+
When ``self`` is the class of skew tableaux, the tuple of the outer and inner
|
|
544
|
+
shape is returned.
|
|
545
|
+
|
|
546
|
+
Note that in the 'core' and 'factorized_permutation' representation, the shapes
|
|
547
|
+
are `(k+1)`-cores. In the 'bounded' representation, the shapes are `k`-bounded
|
|
548
|
+
partitions.
|
|
549
|
+
|
|
550
|
+
If the user wants to access the skew shape (even if the inner shape is empty),
|
|
551
|
+
please use ``self._shape``.
|
|
552
|
+
|
|
553
|
+
EXAMPLES::
|
|
554
|
+
|
|
555
|
+
sage: T = WeakTableaux(3, [5,2,2], [2,2,2,1])
|
|
556
|
+
sage: T.shape()
|
|
557
|
+
[5, 2, 2]
|
|
558
|
+
sage: T._shape
|
|
559
|
+
([5, 2, 2], [])
|
|
560
|
+
sage: T = WeakTableaux(3, [[5,2,2], [1]], [2,1,2,1])
|
|
561
|
+
sage: T.shape()
|
|
562
|
+
([5, 2, 2], [1])
|
|
563
|
+
|
|
564
|
+
sage: T = WeakTableaux(3, [3,2,2], [2,2,2,1], representation = 'bounded')
|
|
565
|
+
sage: T.shape()
|
|
566
|
+
[3, 2, 2]
|
|
567
|
+
sage: T._shape
|
|
568
|
+
([3, 2, 2], [])
|
|
569
|
+
sage: T = WeakTableaux(3, [[3,2,2], [1]], [2,1,2,1], representation = 'bounded')
|
|
570
|
+
sage: T.shape()
|
|
571
|
+
([3, 2, 2], [1])
|
|
572
|
+
|
|
573
|
+
sage: T = WeakTableaux(3, [4,1], [2,2], representation = 'factorized_permutation')
|
|
574
|
+
sage: T.shape()
|
|
575
|
+
[4, 1]
|
|
576
|
+
sage: T._shape
|
|
577
|
+
([4, 1], [])
|
|
578
|
+
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], representation = 'factorized_permutation')
|
|
579
|
+
sage: T.shape()
|
|
580
|
+
([6, 2, 1], [2])
|
|
581
|
+
"""
|
|
582
|
+
if self._skew:
|
|
583
|
+
return (self._outer_shape, self._inner_shape)
|
|
584
|
+
return self._outer_shape
|
|
585
|
+
|
|
586
|
+
def size(self):
|
|
587
|
+
r"""
|
|
588
|
+
Return the size of the shape.
|
|
589
|
+
|
|
590
|
+
In the bounded representation, the size of the shape is the number of boxes in the
|
|
591
|
+
outer shape minus the number of boxes in the inner shape. For the core and
|
|
592
|
+
factorized permutation representation, the size is the length of the outer shape
|
|
593
|
+
minus the length of the inner shape.
|
|
594
|
+
|
|
595
|
+
EXAMPLES::
|
|
596
|
+
|
|
597
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1])
|
|
598
|
+
sage: T.size()
|
|
599
|
+
6
|
|
600
|
+
sage: T = WeakTableaux(3, [3,2,1], [1,1,1,1,1,1], representation = 'bounded')
|
|
601
|
+
sage: T.size()
|
|
602
|
+
6
|
|
603
|
+
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], 'factorized_permutation')
|
|
604
|
+
sage: T.size()
|
|
605
|
+
5
|
|
606
|
+
"""
|
|
607
|
+
if self._representation == 'bounded':
|
|
608
|
+
return self._outer_shape.size() - self._inner_shape.size()
|
|
609
|
+
else:
|
|
610
|
+
return self._outer_shape.length() - self._inner_shape.length()
|
|
611
|
+
|
|
612
|
+
def representation(self, representation='core'):
|
|
613
|
+
r"""
|
|
614
|
+
Return the analogue of ``self`` in the specified representation.
|
|
615
|
+
|
|
616
|
+
INPUT:
|
|
617
|
+
|
|
618
|
+
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: ``'core'``)
|
|
619
|
+
|
|
620
|
+
EXAMPLES::
|
|
621
|
+
|
|
622
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1])
|
|
623
|
+
sage: T._representation
|
|
624
|
+
'core'
|
|
625
|
+
sage: T.representation('bounded')
|
|
626
|
+
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
627
|
+
sage: T.representation('factorized_permutation')
|
|
628
|
+
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
629
|
+
|
|
630
|
+
sage: T = WeakTableaux(3, [3,2,1], [1,1,1,1,1,1], representation = 'bounded')
|
|
631
|
+
sage: T._representation
|
|
632
|
+
'bounded'
|
|
633
|
+
sage: T.representation('core')
|
|
634
|
+
Core weak 3-Tableaux of (skew) core shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
635
|
+
sage: T.representation('bounded')
|
|
636
|
+
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
637
|
+
sage: T.representation('bounded') == T
|
|
638
|
+
True
|
|
639
|
+
sage: T.representation('factorized_permutation')
|
|
640
|
+
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
641
|
+
sage: T.representation('factorized_permutation') == T
|
|
642
|
+
False
|
|
643
|
+
|
|
644
|
+
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1], representation = 'factorized_permutation')
|
|
645
|
+
sage: T._representation
|
|
646
|
+
'factorized_permutation'
|
|
647
|
+
sage: T.representation('core')
|
|
648
|
+
Core weak 3-Tableaux of (skew) core shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
649
|
+
sage: T.representation('bounded')
|
|
650
|
+
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
651
|
+
sage: T.representation('factorized_permutation')
|
|
652
|
+
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
|
|
653
|
+
"""
|
|
654
|
+
outer_shape = self._outer_shape
|
|
655
|
+
inner_shape = self._inner_shape
|
|
656
|
+
weight = self._weight
|
|
657
|
+
if (self._representation in ['core', 'factorized_permutation']) and representation == 'bounded':
|
|
658
|
+
outer_shape = outer_shape.to_bounded_partition()
|
|
659
|
+
inner_shape = inner_shape.to_bounded_partition()
|
|
660
|
+
if self._representation == 'bounded' and (representation in ['core', 'factorized_permutation']):
|
|
661
|
+
outer_shape = outer_shape.to_core(self.k)
|
|
662
|
+
inner_shape = inner_shape.to_core(self.k)
|
|
663
|
+
return WeakTableaux(self.k, [outer_shape, inner_shape], weight, representation=representation)
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
#Weak Tableaux in terms of cores
|
|
667
|
+
class WeakTableau_core(WeakTableau_abstract):
|
|
668
|
+
r"""
|
|
669
|
+
A (skew) weak `k`-tableau represented in terms of `(k+1)`-cores.
|
|
670
|
+
"""
|
|
671
|
+
@staticmethod
|
|
672
|
+
def __classcall_private__(cls, t, k):
|
|
673
|
+
r"""
|
|
674
|
+
Implement the shortcut ``WeakTableau_core(t, k)`` to
|
|
675
|
+
``WeakTableaux_core(k, shape , weight)(t)`` where ``shape`` is the
|
|
676
|
+
shape of the tableau and ``weight`` is its weight.
|
|
677
|
+
|
|
678
|
+
TESTS::
|
|
679
|
+
|
|
680
|
+
sage: from sage.combinat.k_tableau import WeakTableau_core
|
|
681
|
+
sage: t = WeakTableau_core([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
682
|
+
sage: t.check()
|
|
683
|
+
sage: type(t)
|
|
684
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
685
|
+
sage: TestSuite(t).run()
|
|
686
|
+
sage: t.parent()._skew
|
|
687
|
+
False
|
|
688
|
+
|
|
689
|
+
sage: t = WeakTableau_core([[None, None, 1, 1, 2], [1, 2], [2]],3)
|
|
690
|
+
sage: t.check()
|
|
691
|
+
sage: type(t)
|
|
692
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
693
|
+
sage: TestSuite(t).run()
|
|
694
|
+
sage: t.parent()._skew
|
|
695
|
+
True
|
|
696
|
+
"""
|
|
697
|
+
if isinstance(t, cls):
|
|
698
|
+
return t
|
|
699
|
+
tab = SkewTableau(list(t))
|
|
700
|
+
outer = Core(tab.outer_shape(),k+1)
|
|
701
|
+
inner = Core(tab.inner_shape(),k+1)
|
|
702
|
+
weight = WeakTableau_bounded.from_core_tableau(t,k).weight()
|
|
703
|
+
return WeakTableaux_core(k, [outer, inner], weight)(t)
|
|
704
|
+
|
|
705
|
+
def __init__(self, parent, t):
|
|
706
|
+
r"""
|
|
707
|
+
Initialization of weak `k`-tableau ``t`` in core representation.
|
|
708
|
+
|
|
709
|
+
INPUT:
|
|
710
|
+
|
|
711
|
+
- ``t`` -- weak tableau in core representation; the input is supposed to be a list
|
|
712
|
+
of lists specifying the rows of the tableau;
|
|
713
|
+
``None`` is allowed as an entry for skew weak `k`-tableaux
|
|
714
|
+
|
|
715
|
+
TESTS::
|
|
716
|
+
|
|
717
|
+
sage: from sage.combinat.k_tableau import WeakTableau_core, WeakTableaux_core
|
|
718
|
+
sage: T = WeakTableaux_core(3,[5,2,1],[2,2,2])
|
|
719
|
+
sage: t = T([[1, 1, 2, 2, 3], [2, 3], [3]]); t
|
|
720
|
+
[[1, 1, 2, 2, 3], [2, 3], [3]]
|
|
721
|
+
sage: c = WeakTableau_core([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
722
|
+
sage: T = WeakTableaux_core(3,[5,2,1],[2,2,2])
|
|
723
|
+
sage: t = T([[1, 1, 2, 2, 3], [2, 3], [3]]); t
|
|
724
|
+
[[1, 1, 2, 2, 3], [2, 3], [3]]
|
|
725
|
+
sage: c == t
|
|
726
|
+
True
|
|
727
|
+
sage: type(t)
|
|
728
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
729
|
+
sage: t.parent()
|
|
730
|
+
Core weak 3-Tableaux of (skew) core shape [5, 2, 1] and weight (2, 2, 2)
|
|
731
|
+
sage: TestSuite(t).run()
|
|
732
|
+
|
|
733
|
+
sage: t = WeakTableau_core([[None, None, 1, 1, 2], [1, 2], [2]],3); t
|
|
734
|
+
[[None, None, 1, 1, 2], [1, 2], [2]]
|
|
735
|
+
sage: t.weight()
|
|
736
|
+
(2, 2)
|
|
737
|
+
sage: t.shape()
|
|
738
|
+
([5, 2, 1], [2])
|
|
739
|
+
sage: TestSuite(t).run()
|
|
740
|
+
"""
|
|
741
|
+
self.k = parent.k
|
|
742
|
+
ClonableList.__init__(self, parent, t)
|
|
743
|
+
|
|
744
|
+
def _repr_diagram(self):
|
|
745
|
+
r"""
|
|
746
|
+
Return a string representation of ``self`` as a diagram.
|
|
747
|
+
|
|
748
|
+
EXAMPLES::
|
|
749
|
+
|
|
750
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
751
|
+
sage: print(t._repr_diagram())
|
|
752
|
+
. . 2 3 4
|
|
753
|
+
1 4
|
|
754
|
+
2
|
|
755
|
+
"""
|
|
756
|
+
t = SkewTableau(list(self))
|
|
757
|
+
return t._repr_diagram()
|
|
758
|
+
|
|
759
|
+
def shape_core(self):
|
|
760
|
+
r"""
|
|
761
|
+
Return the shape of ``self`` as a `(k+1)`-core.
|
|
762
|
+
|
|
763
|
+
When the tableau is straight, the outer shape is returned as a core. When the
|
|
764
|
+
tableau is skew, the tuple of the outer and inner shape is returned as cores.
|
|
765
|
+
|
|
766
|
+
EXAMPLES::
|
|
767
|
+
|
|
768
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
769
|
+
sage: t.shape_core()
|
|
770
|
+
[5, 2, 1]
|
|
771
|
+
|
|
772
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
773
|
+
sage: t.shape_core()
|
|
774
|
+
([5, 2, 1], [2])
|
|
775
|
+
"""
|
|
776
|
+
return self.shape()
|
|
777
|
+
|
|
778
|
+
def shape_bounded(self):
|
|
779
|
+
r"""
|
|
780
|
+
Return the shape of ``self`` as a `k`-bounded partition.
|
|
781
|
+
|
|
782
|
+
When the tableau is straight, the outer shape is returned as a `k`-bounded
|
|
783
|
+
partition. When the tableau is skew, the tuple of the outer and inner shape is
|
|
784
|
+
returned as `k`-bounded partitions.
|
|
785
|
+
|
|
786
|
+
EXAMPLES::
|
|
787
|
+
|
|
788
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
789
|
+
sage: t.shape_bounded()
|
|
790
|
+
[3, 2, 1]
|
|
791
|
+
|
|
792
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
793
|
+
sage: t.shape_bounded()
|
|
794
|
+
([3, 2, 1], [2])
|
|
795
|
+
"""
|
|
796
|
+
if self.parent()._skew:
|
|
797
|
+
return tuple([r.to_bounded_partition() for r in self.shape_core()])
|
|
798
|
+
return self.shape_core().to_bounded_partition()
|
|
799
|
+
|
|
800
|
+
def check(self):
|
|
801
|
+
r"""
|
|
802
|
+
Check that ``self`` is a valid weak `k`-tableau.
|
|
803
|
+
|
|
804
|
+
EXAMPLES::
|
|
805
|
+
|
|
806
|
+
sage: t = WeakTableau([[1, 1, 2], [2]], 2)
|
|
807
|
+
sage: t.check()
|
|
808
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
809
|
+
sage: t.check()
|
|
810
|
+
|
|
811
|
+
TESTS::
|
|
812
|
+
|
|
813
|
+
sage: T = WeakTableaux(2, [3,1], [1,1,1,1])
|
|
814
|
+
sage: t = T([[1,2,3],[3]])
|
|
815
|
+
Traceback (most recent call last):
|
|
816
|
+
...
|
|
817
|
+
ValueError: The weight of the parent does not agree with the weight of the tableau!
|
|
818
|
+
|
|
819
|
+
sage: t = WeakTableau([[1, 2, 2], [1]], 2)
|
|
820
|
+
Traceback (most recent call last):
|
|
821
|
+
...
|
|
822
|
+
ValueError: The tableau is not semistandard!
|
|
823
|
+
"""
|
|
824
|
+
if not self.parent()._weight == WeakTableau_bounded.from_core_tableau(self,self.k).weight():
|
|
825
|
+
raise ValueError("The weight of the parent does not agree with the weight of the tableau!")
|
|
826
|
+
t = SkewTableau(list(self))
|
|
827
|
+
if t not in SemistandardSkewTableaux():
|
|
828
|
+
raise ValueError("The tableau is not semistandard!")
|
|
829
|
+
outer = Core(t.outer_shape(),self.k+1)
|
|
830
|
+
inner = Core(t.inner_shape(),self.k+1)
|
|
831
|
+
if self.parent()._outer_shape != outer:
|
|
832
|
+
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
|
|
833
|
+
if self.parent()._inner_shape != inner:
|
|
834
|
+
raise ValueError("The inner shape of the parent does not agree with the inner shape of the tableau!")
|
|
835
|
+
self.to_bounded_tableau().check()
|
|
836
|
+
|
|
837
|
+
def to_bounded_tableau(self):
|
|
838
|
+
r"""
|
|
839
|
+
Return the bounded representation of the weak `k`-tableau ``self``.
|
|
840
|
+
|
|
841
|
+
Each restricted subtableau of the output is a `k`-bounded partition.
|
|
842
|
+
|
|
843
|
+
EXAMPLES::
|
|
844
|
+
|
|
845
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
846
|
+
sage: c = t.to_bounded_tableau(); c
|
|
847
|
+
[[1, 1, 2], [2, 3], [3]]
|
|
848
|
+
sage: type(c)
|
|
849
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
|
|
850
|
+
|
|
851
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
852
|
+
sage: t.to_bounded_tableau()
|
|
853
|
+
[[None, None, 3], [1, 4], [2]]
|
|
854
|
+
sage: t.to_bounded_tableau().to_core_tableau() == t
|
|
855
|
+
True
|
|
856
|
+
"""
|
|
857
|
+
shapes = [ Core(p,self.k+1).to_bounded_partition() for p in self.intermediate_shapes() ]
|
|
858
|
+
if self.parent()._skew:
|
|
859
|
+
l = [[None]*i for i in shapes[0]]
|
|
860
|
+
else:
|
|
861
|
+
l = []
|
|
862
|
+
for i in range(1,len(shapes)):
|
|
863
|
+
p = shapes[i]
|
|
864
|
+
if len(l) < len(p):
|
|
865
|
+
l += [[]]
|
|
866
|
+
l_new = []
|
|
867
|
+
for j in range(len(l)):
|
|
868
|
+
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
|
|
869
|
+
l = l_new
|
|
870
|
+
return WeakTableau_bounded(l, self.k)
|
|
871
|
+
|
|
872
|
+
def to_factorized_permutation_tableau(self):
|
|
873
|
+
r"""
|
|
874
|
+
Return the factorized permutation representation of the weak `k`-tableau ``self``.
|
|
875
|
+
|
|
876
|
+
EXAMPLES::
|
|
877
|
+
|
|
878
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
879
|
+
sage: c = t.to_factorized_permutation_tableau(); c
|
|
880
|
+
[s2*s0, s3*s2, s1*s0]
|
|
881
|
+
sage: type(c)
|
|
882
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
|
|
883
|
+
sage: c.to_core_tableau() == t
|
|
884
|
+
True
|
|
885
|
+
|
|
886
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
887
|
+
sage: c = t.to_factorized_permutation_tableau(); c
|
|
888
|
+
[s0, s3, s2, s3]
|
|
889
|
+
sage: c._inner_shape
|
|
890
|
+
[2]
|
|
891
|
+
sage: c.to_core_tableau() == t
|
|
892
|
+
True
|
|
893
|
+
|
|
894
|
+
TESTS::
|
|
895
|
+
|
|
896
|
+
sage: t = WeakTableau([], 4)
|
|
897
|
+
sage: c = t.to_factorized_permutation_tableau(); c
|
|
898
|
+
[1]
|
|
899
|
+
sage: c._inner_shape
|
|
900
|
+
[]
|
|
901
|
+
sage: c.to_core_tableau() == t
|
|
902
|
+
True
|
|
903
|
+
"""
|
|
904
|
+
shapes = [ Core(p,self.k+1).to_grassmannian() for p in self.intermediate_shapes() ]
|
|
905
|
+
perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)]
|
|
906
|
+
return WeakTableau_factorized_permutation(perms, self.k, inner_shape=self.parent()._inner_shape)
|
|
907
|
+
|
|
908
|
+
def residues_of_entries(self, v):
|
|
909
|
+
r"""
|
|
910
|
+
Return a list of residues of cells of weak `k`-tableau ``self`` labeled by ``v``.
|
|
911
|
+
|
|
912
|
+
INPUT:
|
|
913
|
+
|
|
914
|
+
- ``v`` -- a label of a cell in ``self``
|
|
915
|
+
|
|
916
|
+
OUTPUT: list of residues
|
|
917
|
+
|
|
918
|
+
EXAMPLES::
|
|
919
|
+
|
|
920
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
921
|
+
sage: t.residues_of_entries(1)
|
|
922
|
+
[0, 1]
|
|
923
|
+
|
|
924
|
+
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
|
|
925
|
+
sage: t.residues_of_entries(1)
|
|
926
|
+
[2, 3]
|
|
927
|
+
"""
|
|
928
|
+
S = set((j - i) % (self.k+1)
|
|
929
|
+
for i in range(len(self))
|
|
930
|
+
for j in range(len(self[i]))
|
|
931
|
+
if self[i][j] == v)
|
|
932
|
+
return sorted(S)
|
|
933
|
+
|
|
934
|
+
def dictionary_of_coordinates_at_residues(self, v):
|
|
935
|
+
r"""
|
|
936
|
+
Return a dictionary assigning to all residues of ``self`` with label ``v`` a list
|
|
937
|
+
of cells with the given residue.
|
|
938
|
+
|
|
939
|
+
INPUT:
|
|
940
|
+
|
|
941
|
+
- ``v`` -- a label of a cell in ``self``
|
|
942
|
+
|
|
943
|
+
OUTPUT: dictionary assigning coordinates in ``self`` to residues
|
|
944
|
+
|
|
945
|
+
EXAMPLES::
|
|
946
|
+
|
|
947
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
948
|
+
sage: t.dictionary_of_coordinates_at_residues(3)
|
|
949
|
+
{0: [(0, 4), (1, 1)], 2: [(2, 0)]}
|
|
950
|
+
|
|
951
|
+
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
|
|
952
|
+
sage: t.dictionary_of_coordinates_at_residues(1)
|
|
953
|
+
{2: [(0, 2)], 3: [(0, 3), (1, 0)]}
|
|
954
|
+
|
|
955
|
+
sage: t = WeakTableau([], 3)
|
|
956
|
+
sage: t.dictionary_of_coordinates_at_residues(1)
|
|
957
|
+
{}
|
|
958
|
+
"""
|
|
959
|
+
d = {}
|
|
960
|
+
for r in self.residues_of_entries(v):
|
|
961
|
+
d[r] = []
|
|
962
|
+
for i in range(len(self)):
|
|
963
|
+
for j in range(len(self[i])):
|
|
964
|
+
if self[i][j] == v and (j - i) % (self.k+1) == r:
|
|
965
|
+
d[r] += [(i,j)]
|
|
966
|
+
return d
|
|
967
|
+
|
|
968
|
+
def list_of_standard_cells(self):
|
|
969
|
+
r"""
|
|
970
|
+
Return a list of lists of the coordinates of the standard cells of ``self``.
|
|
971
|
+
|
|
972
|
+
INPUT:
|
|
973
|
+
|
|
974
|
+
- ``self`` -- a weak `k`-tableau in core representation with partition weight
|
|
975
|
+
|
|
976
|
+
OUTPUT: list of lists of coordinates
|
|
977
|
+
|
|
978
|
+
.. WARNING::
|
|
979
|
+
|
|
980
|
+
This method currently only works for straight weak tableaux with partition
|
|
981
|
+
weight.
|
|
982
|
+
|
|
983
|
+
EXAMPLES::
|
|
984
|
+
|
|
985
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
986
|
+
sage: t.list_of_standard_cells()
|
|
987
|
+
[[(0, 1), (1, 0), (2, 0)], [(0, 0), (0, 2), (1, 1)]]
|
|
988
|
+
sage: t = WeakTableau([[1, 1, 1, 2], [2, 2, 3]], 5)
|
|
989
|
+
sage: t.list_of_standard_cells()
|
|
990
|
+
[[(0, 2), (1, 1), (1, 2)], [(0, 1), (1, 0)], [(0, 0), (0, 3)]]
|
|
991
|
+
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
992
|
+
sage: t.list_of_standard_cells()
|
|
993
|
+
[[(0, 1), (1, 0), (2, 0), (0, 5), (3, 0), (4, 0), (5, 0)], [(0, 0), (0, 2), (1, 1), (2, 1), (1, 2), (3, 1)]]
|
|
994
|
+
|
|
995
|
+
TESTS::
|
|
996
|
+
|
|
997
|
+
sage: t = WeakTableau([],3)
|
|
998
|
+
sage: t.list_of_standard_cells()
|
|
999
|
+
[]
|
|
1000
|
+
|
|
1001
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
1002
|
+
sage: t.list_of_standard_cells()
|
|
1003
|
+
Traceback (most recent call last):
|
|
1004
|
+
...
|
|
1005
|
+
ValueError: This method only works for straight tableaux!
|
|
1006
|
+
|
|
1007
|
+
sage: t = WeakTableau([[1,2],[2]], 3)
|
|
1008
|
+
sage: t.list_of_standard_cells()
|
|
1009
|
+
Traceback (most recent call last):
|
|
1010
|
+
...
|
|
1011
|
+
ValueError: This method only works for weak tableaux with partition weight!
|
|
1012
|
+
"""
|
|
1013
|
+
if self.parent()._skew:
|
|
1014
|
+
raise ValueError("This method only works for straight tableaux!")
|
|
1015
|
+
if self.weight() not in Partitions(sum(self.weight())):
|
|
1016
|
+
raise ValueError("This method only works for weak tableaux with partition weight!")
|
|
1017
|
+
if not self:
|
|
1018
|
+
return []
|
|
1019
|
+
mu = Partition(self.weight()).conjugate()
|
|
1020
|
+
already_used = []
|
|
1021
|
+
out = []
|
|
1022
|
+
for i in range(self[0].count(1)):
|
|
1023
|
+
standard_cells = [(0,self[0].count(1) - i - 1)]
|
|
1024
|
+
r = self[0].count(1) - i - 1
|
|
1025
|
+
for v in range(1,mu[i]):
|
|
1026
|
+
D = self.dictionary_of_coordinates_at_residues(v+1)
|
|
1027
|
+
new_D = {a: b for (a, b) in D.items()
|
|
1028
|
+
if all(x not in already_used for x in b)}
|
|
1029
|
+
r = (r - min([self.k+1 - (x-r) % (self.k+1) for x in new_D])) % (self.k+1)
|
|
1030
|
+
standard_cells.append(new_D[r][-1])
|
|
1031
|
+
already_used += new_D[r]
|
|
1032
|
+
out.append(standard_cells)
|
|
1033
|
+
return out
|
|
1034
|
+
|
|
1035
|
+
def k_charge(self, algorithm='I'):
|
|
1036
|
+
r"""
|
|
1037
|
+
Return the `k`-charge of ``self``.
|
|
1038
|
+
|
|
1039
|
+
INPUT:
|
|
1040
|
+
|
|
1041
|
+
- ``algorithm`` -- (default: ``'I'``) if "I", computes `k`-charge using the `I`
|
|
1042
|
+
algorithm, otherwise uses the `J`-algorithm
|
|
1043
|
+
|
|
1044
|
+
OUTPUT: nonnegative integer
|
|
1045
|
+
|
|
1046
|
+
For the definition of `k`-charge and the various algorithms to compute it see
|
|
1047
|
+
Section 3.3 of [LLMSSZ2013]_.
|
|
1048
|
+
|
|
1049
|
+
.. SEEALSO:: :meth:`k_charge_I` and :meth:`k_charge_J`
|
|
1050
|
+
|
|
1051
|
+
EXAMPLES::
|
|
1052
|
+
|
|
1053
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
1054
|
+
sage: t.k_charge()
|
|
1055
|
+
2
|
|
1056
|
+
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
|
|
1057
|
+
sage: t.k_charge()
|
|
1058
|
+
8
|
|
1059
|
+
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
1060
|
+
sage: t.k_charge()
|
|
1061
|
+
12
|
|
1062
|
+
|
|
1063
|
+
TESTS::
|
|
1064
|
+
|
|
1065
|
+
sage: T = WeakTableaux(4, [13,9,5,3,2,1,1], [4,3,3,2,2,1,1,1])
|
|
1066
|
+
sage: T.cardinality()
|
|
1067
|
+
6
|
|
1068
|
+
sage: all(t.k_charge_I() == t.k_charge_J() for t in T)
|
|
1069
|
+
True
|
|
1070
|
+
"""
|
|
1071
|
+
if algorithm == "I":
|
|
1072
|
+
return self.k_charge_I()
|
|
1073
|
+
return self.k_charge_J()
|
|
1074
|
+
|
|
1075
|
+
def k_charge_I(self):
|
|
1076
|
+
r"""
|
|
1077
|
+
Return the `k`-charge of ``self`` using the `I`-algorithm.
|
|
1078
|
+
|
|
1079
|
+
For the definition of `k`-charge and the `I`-algorithm see Section 3.3 of [LLMSSZ2013]_.
|
|
1080
|
+
|
|
1081
|
+
OUTPUT: nonnegative integer
|
|
1082
|
+
|
|
1083
|
+
.. SEEALSO:: :meth:`k_charge` and :meth:`k_charge_J`
|
|
1084
|
+
|
|
1085
|
+
EXAMPLES::
|
|
1086
|
+
|
|
1087
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
1088
|
+
sage: t.k_charge_I()
|
|
1089
|
+
2
|
|
1090
|
+
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
|
|
1091
|
+
sage: t.k_charge_I()
|
|
1092
|
+
8
|
|
1093
|
+
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
1094
|
+
sage: t.k_charge_I()
|
|
1095
|
+
12
|
|
1096
|
+
|
|
1097
|
+
TESTS::
|
|
1098
|
+
|
|
1099
|
+
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
|
|
1100
|
+
sage: t.k_charge_I()
|
|
1101
|
+
Traceback (most recent call last):
|
|
1102
|
+
...
|
|
1103
|
+
ValueError: k-charge is not defined for skew weak tableaux
|
|
1104
|
+
"""
|
|
1105
|
+
if self.parent()._skew:
|
|
1106
|
+
raise ValueError("k-charge is not defined for skew weak tableaux")
|
|
1107
|
+
stt = self.list_of_standard_cells()
|
|
1108
|
+
kch = 0
|
|
1109
|
+
for sw in stt:
|
|
1110
|
+
Ii = 0
|
|
1111
|
+
for r in range(len(sw)-1):
|
|
1112
|
+
if sw[r][1] < sw[r+1][1]:
|
|
1113
|
+
Ii += 1 + abs(self.parent().diag(sw[r+1],sw[r]))
|
|
1114
|
+
else:
|
|
1115
|
+
Ii += - abs(self.parent().diag(sw[r],sw[r+1]))
|
|
1116
|
+
kch += Ii
|
|
1117
|
+
return kch
|
|
1118
|
+
|
|
1119
|
+
def k_charge_J(self):
|
|
1120
|
+
r"""
|
|
1121
|
+
Return the `k`-charge of ``self`` using the `J`-algorithm.
|
|
1122
|
+
|
|
1123
|
+
For the definition of `k`-charge and the `J`-algorithm see Section 3.3 of [LLMSSZ2013]_.
|
|
1124
|
+
|
|
1125
|
+
OUTPUT: nonnegative integer
|
|
1126
|
+
|
|
1127
|
+
.. SEEALSO:: :meth:`k_charge` and :meth:`k_charge_I`
|
|
1128
|
+
|
|
1129
|
+
EXAMPLES::
|
|
1130
|
+
|
|
1131
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
1132
|
+
sage: t.k_charge_J()
|
|
1133
|
+
2
|
|
1134
|
+
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
|
|
1135
|
+
sage: t.k_charge_J()
|
|
1136
|
+
8
|
|
1137
|
+
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
1138
|
+
sage: t.k_charge_J()
|
|
1139
|
+
12
|
|
1140
|
+
|
|
1141
|
+
TESTS::
|
|
1142
|
+
|
|
1143
|
+
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
|
|
1144
|
+
sage: t.k_charge_I()
|
|
1145
|
+
Traceback (most recent call last):
|
|
1146
|
+
...
|
|
1147
|
+
ValueError: k-charge is not defined for skew weak tableaux
|
|
1148
|
+
|
|
1149
|
+
sage: t = WeakTableau([[1, 1, 2, 3], [2, 4, 4], [3, 6], [5]], 4, representation='bounded')
|
|
1150
|
+
sage: t.k_charge() == t.k_charge(algorithm = 'J')
|
|
1151
|
+
True
|
|
1152
|
+
"""
|
|
1153
|
+
if self.parent()._skew:
|
|
1154
|
+
raise ValueError("k-charge is not defined for skew weak tableaux")
|
|
1155
|
+
stt = self.list_of_standard_cells()
|
|
1156
|
+
kch = 0
|
|
1157
|
+
for sw in stt:
|
|
1158
|
+
Ji = 0
|
|
1159
|
+
for i in range(len(sw)-1):
|
|
1160
|
+
c = (self._height_of_restricted_subword(sw,i+2)+1,0)
|
|
1161
|
+
cdi = self.parent().circular_distance((-c[0]) % (self.k+1),(sw[i][1]-sw[i][0]) % (self.k+1))
|
|
1162
|
+
cdi1 = self.parent().circular_distance((-c[0]) % (self.k+1),(sw[i+1][1]-sw[i+1][0]) % (self.k+1))
|
|
1163
|
+
if (cdi > cdi1):
|
|
1164
|
+
Ji += 1
|
|
1165
|
+
kch += Ji + self.parent().diag(sw[i+1],c)
|
|
1166
|
+
return kch
|
|
1167
|
+
|
|
1168
|
+
def _height_of_restricted_subword(self, sw, r):
|
|
1169
|
+
r"""
|
|
1170
|
+
Return the row of the highest addable cell of the subtableau of ``self`` with letters `\le r`
|
|
1171
|
+
(excluding letters `r` in standard subwords before ``sw``).
|
|
1172
|
+
|
|
1173
|
+
Restrict the weak `k`-tableau ``self`` to letters `\le r` and remove all letters
|
|
1174
|
+
`r` that appeared in a previous standard subword selected by
|
|
1175
|
+
:meth:`list_of_standard_cells`.
|
|
1176
|
+
|
|
1177
|
+
INPUT:
|
|
1178
|
+
|
|
1179
|
+
- ``sw`` -- one of the subwords of standard cells of ``self``
|
|
1180
|
+
- ``r`` -- nonnegative integer
|
|
1181
|
+
|
|
1182
|
+
OUTPUT: nonnegative integer
|
|
1183
|
+
|
|
1184
|
+
EXAMPLES::
|
|
1185
|
+
|
|
1186
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
1187
|
+
sage: s = t.list_of_standard_cells()[0]; s
|
|
1188
|
+
[(0, 1), (1, 0), (2, 0)]
|
|
1189
|
+
sage: t._height_of_restricted_subword(s,2)
|
|
1190
|
+
1
|
|
1191
|
+
|
|
1192
|
+
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
|
|
1193
|
+
sage: s = t.list_of_standard_cells()[0]; s
|
|
1194
|
+
[(0, 0), (1, 0), (0, 1), (2, 0), (0, 3), (1, 1)]
|
|
1195
|
+
sage: t._height_of_restricted_subword(s,4)
|
|
1196
|
+
2
|
|
1197
|
+
|
|
1198
|
+
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
1199
|
+
sage: s = t.list_of_standard_cells()[0]; s
|
|
1200
|
+
[(0, 1), (1, 0), (2, 0), (0, 5), (3, 0), (4, 0), (5, 0)]
|
|
1201
|
+
sage: t._height_of_restricted_subword(s,6)
|
|
1202
|
+
4
|
|
1203
|
+
"""
|
|
1204
|
+
R = [v for v in self.shape().to_partition().cells() if self[v[0]][v[1]] < r]
|
|
1205
|
+
L = [v for v in sw if self[v[0]][v[1]] <= r]
|
|
1206
|
+
return max(v[0] for v in L + R)
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
class WeakTableaux_core(WeakTableaux_abstract):
|
|
1210
|
+
r"""
|
|
1211
|
+
The class of (skew) weak `k`-tableaux in the core representation of shape ``shape``
|
|
1212
|
+
(as `k+1`-core) and weight ``weight``.
|
|
1213
|
+
|
|
1214
|
+
INPUT:
|
|
1215
|
+
|
|
1216
|
+
- ``k`` -- positive integer
|
|
1217
|
+
- ``shape`` -- the shape of the `k`-tableaux represented as a `(k+1)`-core; if the
|
|
1218
|
+
tableaux are skew, the shape is a tuple of the outer and inner shape (both as
|
|
1219
|
+
`(k+1)`-cores)
|
|
1220
|
+
- ``weight`` -- the weight of the `k`-tableaux
|
|
1221
|
+
|
|
1222
|
+
EXAMPLES::
|
|
1223
|
+
|
|
1224
|
+
sage: T = WeakTableaux(3, [4,1], [2,2])
|
|
1225
|
+
sage: T.list()
|
|
1226
|
+
[[[1, 1, 2, 2], [2]]]
|
|
1227
|
+
|
|
1228
|
+
sage: T = WeakTableaux(3, [[5,2,1], [2]], [1,1,1,1])
|
|
1229
|
+
sage: T.list()
|
|
1230
|
+
[[[None, None, 2, 3, 4], [1, 4], [2]],
|
|
1231
|
+
[[None, None, 1, 2, 4], [2, 4], [3]],
|
|
1232
|
+
[[None, None, 1, 2, 3], [2, 3], [4]]]
|
|
1233
|
+
"""
|
|
1234
|
+
|
|
1235
|
+
@staticmethod
|
|
1236
|
+
def __classcall_private__(cls, k, shape, weight):
|
|
1237
|
+
r"""
|
|
1238
|
+
Straighten arguments before unique representation.
|
|
1239
|
+
|
|
1240
|
+
TESTS::
|
|
1241
|
+
|
|
1242
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_core
|
|
1243
|
+
sage: T = WeakTableaux_core(3, [2,1], [1,1,1])
|
|
1244
|
+
sage: TestSuite(T).run()
|
|
1245
|
+
sage: T = WeakTableaux_core(3, [[5,2,1], [2]], [1,1,1,1])
|
|
1246
|
+
sage: TestSuite(T).run()
|
|
1247
|
+
"""
|
|
1248
|
+
if shape == [] or shape[0] in ZZ:
|
|
1249
|
+
shape = (Core(shape, k+1), Core([],k+1))
|
|
1250
|
+
else:
|
|
1251
|
+
shape = tuple([Core(r,k+1) for r in shape])
|
|
1252
|
+
return super().__classcall__(cls, k, shape, tuple(weight))
|
|
1253
|
+
|
|
1254
|
+
def __init__(self, k, shape, weight):
|
|
1255
|
+
r"""
|
|
1256
|
+
Initialize the parent class of (skew) weak `k`-tableaux in core representation.
|
|
1257
|
+
|
|
1258
|
+
INPUT:
|
|
1259
|
+
|
|
1260
|
+
- ``k`` -- positive integer
|
|
1261
|
+
- ``outer_shape`` -- the outer shape of the `k`-tableaux represented as a
|
|
1262
|
+
`(k+1)`-core
|
|
1263
|
+
- ``weight`` -- the weight of the `k`-tableaux
|
|
1264
|
+
- ``inner_shape`` -- the inner shape of the skew `k`-tableaux represented as a
|
|
1265
|
+
`(k+1)`-core; for straight tableaux the inner shape does not need to be
|
|
1266
|
+
specified (default: ``[]``)
|
|
1267
|
+
|
|
1268
|
+
TESTS::
|
|
1269
|
+
|
|
1270
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_core
|
|
1271
|
+
sage: T = WeakTableaux_core(3, [4,1], [2,2])
|
|
1272
|
+
sage: TestSuite(T).run()
|
|
1273
|
+
sage: T = WeakTableaux_core(3, [[5,2,1], [2]], [1,1,1,1])
|
|
1274
|
+
sage: TestSuite(T).run()
|
|
1275
|
+
"""
|
|
1276
|
+
self.k = k
|
|
1277
|
+
self._skew = bool(shape[1])
|
|
1278
|
+
self._outer_shape = shape[0]
|
|
1279
|
+
self._inner_shape = shape[1]
|
|
1280
|
+
self._shape = (self._outer_shape, self._inner_shape)
|
|
1281
|
+
self._weight = weight
|
|
1282
|
+
self._representation = 'core'
|
|
1283
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
1284
|
+
|
|
1285
|
+
def _repr_(self):
|
|
1286
|
+
"""
|
|
1287
|
+
TESTS::
|
|
1288
|
+
|
|
1289
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_core
|
|
1290
|
+
sage: repr(WeakTableaux_core(3, [2,1], [1,1,1]))
|
|
1291
|
+
'Core weak 3-Tableaux of (skew) core shape [2, 1] and weight (1, 1, 1)'
|
|
1292
|
+
sage: repr(WeakTableaux_core(3, [[5,2,1], [2]], [1,1,1,1]))
|
|
1293
|
+
'Core weak 3-Tableaux of (skew) core shape ([5, 2, 1], [2]) and weight (1, 1, 1, 1)'
|
|
1294
|
+
"""
|
|
1295
|
+
return "Core weak %s-Tableaux of (skew) core shape %s and weight %s" % (self.k, self.shape(), self._weight)
|
|
1296
|
+
|
|
1297
|
+
def __iter__(self):
|
|
1298
|
+
r"""
|
|
1299
|
+
TESTS::
|
|
1300
|
+
|
|
1301
|
+
sage: T = WeakTableaux(3, [4,1], [2,2])
|
|
1302
|
+
sage: T.list()
|
|
1303
|
+
[[[1, 1, 2, 2], [2]]]
|
|
1304
|
+
sage: T = WeakTableaux(3, [5,2,2], [2,2,2,1])
|
|
1305
|
+
sage: T.list()
|
|
1306
|
+
[[[1, 1, 3, 3, 4], [2, 2], [3, 3]], [[1, 1, 2, 2, 3], [2, 3], [3, 4]]]
|
|
1307
|
+
sage: T = WeakTableaux(3, [[5,2,2], [1]], [2,1,2,1])
|
|
1308
|
+
sage: T.list()
|
|
1309
|
+
[[[None, 1, 3, 3, 4], [1, 2], [3, 3]],
|
|
1310
|
+
[[None, 1, 2, 3, 3], [1, 3], [2, 4]],
|
|
1311
|
+
[[None, 1, 1, 2, 3], [2, 3], [3, 4]]]
|
|
1312
|
+
"""
|
|
1313
|
+
for t in WeakTableaux_bounded(self.k, [self._outer_shape.to_bounded_partition(), self._inner_shape.to_bounded_partition()], self._weight):
|
|
1314
|
+
yield t.to_core_tableau()
|
|
1315
|
+
|
|
1316
|
+
def diag(self, c, ha):
|
|
1317
|
+
r"""
|
|
1318
|
+
Return the number of diagonals strictly between cells ``c`` and ``ha`` of the same residue as ``c``.
|
|
1319
|
+
|
|
1320
|
+
INPUT:
|
|
1321
|
+
|
|
1322
|
+
- ``c`` -- a cell in the lattice
|
|
1323
|
+
- ``ha`` -- another cell in the lattice with bigger row and smaller column than `c`
|
|
1324
|
+
|
|
1325
|
+
OUTPUT: nonnegative integer
|
|
1326
|
+
|
|
1327
|
+
EXAMPLES::
|
|
1328
|
+
|
|
1329
|
+
sage: T = WeakTableaux(4, [5,2,2], [2,2,2,1])
|
|
1330
|
+
sage: T.diag((1,2),(4,0))
|
|
1331
|
+
0
|
|
1332
|
+
"""
|
|
1333
|
+
return divmod((c[1]-c[0])-(ha[1]-ha[0])-1, self.k+1)[0]
|
|
1334
|
+
|
|
1335
|
+
def circular_distance(self, cr, r):
|
|
1336
|
+
r"""
|
|
1337
|
+
Return the shortest counterclockwise distance between ``cr`` and ``r`` modulo `k+1`.
|
|
1338
|
+
|
|
1339
|
+
INPUT:
|
|
1340
|
+
|
|
1341
|
+
- ``cr``, ``r`` -- nonnegative integers between `0` and `k`
|
|
1342
|
+
|
|
1343
|
+
OUTPUT: positive integer
|
|
1344
|
+
|
|
1345
|
+
EXAMPLES::
|
|
1346
|
+
|
|
1347
|
+
sage: T = WeakTableaux(10, [], [])
|
|
1348
|
+
sage: T.circular_distance(8, 6)
|
|
1349
|
+
2
|
|
1350
|
+
sage: T.circular_distance(8, 8)
|
|
1351
|
+
0
|
|
1352
|
+
sage: T.circular_distance(8, 9)
|
|
1353
|
+
10
|
|
1354
|
+
"""
|
|
1355
|
+
return self.k - ((r+self.k-cr) % (self.k+1))
|
|
1356
|
+
|
|
1357
|
+
Element = WeakTableau_core
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
#Weak tableaux in terms of `k`-bounded partitions
|
|
1361
|
+
class WeakTableau_bounded(WeakTableau_abstract):
|
|
1362
|
+
r"""
|
|
1363
|
+
A (skew) weak `k`-tableau represented in terms of `k`-bounded partitions.
|
|
1364
|
+
"""
|
|
1365
|
+
@staticmethod
|
|
1366
|
+
def __classcall_private__(cls, t, k):
|
|
1367
|
+
r"""
|
|
1368
|
+
Implement the shortcut ``WeakTableau_bounded(t, k)`` to
|
|
1369
|
+
``WeakTableaux_bounded(k, shape, weight)(t)`` where ``shape`` is the
|
|
1370
|
+
shape of the tableau and ``weight`` is its weight.
|
|
1371
|
+
|
|
1372
|
+
TESTS::
|
|
1373
|
+
|
|
1374
|
+
sage: from sage.combinat.k_tableau import WeakTableau_bounded
|
|
1375
|
+
sage: t = WeakTableau_bounded([[1,1,2],[2,3],[3]],3)
|
|
1376
|
+
sage: t.check()
|
|
1377
|
+
sage: type(t)
|
|
1378
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
|
|
1379
|
+
sage: TestSuite(t).run()
|
|
1380
|
+
sage: t.parent()._skew
|
|
1381
|
+
False
|
|
1382
|
+
|
|
1383
|
+
sage: t = WeakTableau_bounded([[None, None, 1], [1, 2], [2]], 3)
|
|
1384
|
+
sage: t.check()
|
|
1385
|
+
sage: type(t)
|
|
1386
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
|
|
1387
|
+
sage: TestSuite(t).run()
|
|
1388
|
+
sage: t.parent()._skew
|
|
1389
|
+
True
|
|
1390
|
+
"""
|
|
1391
|
+
if isinstance(t, cls):
|
|
1392
|
+
return t
|
|
1393
|
+
tab = SkewTableau(list(t))
|
|
1394
|
+
outer = tab.outer_shape()
|
|
1395
|
+
inner = tab.inner_shape()
|
|
1396
|
+
weight = tuple(tab.weight())
|
|
1397
|
+
if outer.conjugate().length() > k:
|
|
1398
|
+
raise ValueError("The shape of %s is not %s-bounded" % (t, k))
|
|
1399
|
+
return WeakTableaux_bounded(k, [outer, inner], weight)(t)
|
|
1400
|
+
|
|
1401
|
+
def __init__(self, parent, t):
|
|
1402
|
+
r"""
|
|
1403
|
+
Initialization of (skew) weak `k`-tableau ``t`` in `k`-bounded representation.
|
|
1404
|
+
|
|
1405
|
+
INPUT:
|
|
1406
|
+
|
|
1407
|
+
- ``t`` -- weak tableau in `k`-bounded representation; the input is supposed to be
|
|
1408
|
+
a list of iterables specifying the rows of the tableau; ``None`` is allowed as an
|
|
1409
|
+
entry for skew weak `k`-tableaux
|
|
1410
|
+
|
|
1411
|
+
TESTS::
|
|
1412
|
+
|
|
1413
|
+
sage: from sage.combinat.k_tableau import WeakTableau_bounded, WeakTableaux_bounded
|
|
1414
|
+
sage: c = WeakTableau_bounded([[1,1,2],[2,3],[3]],3)
|
|
1415
|
+
sage: T = WeakTableaux_bounded(3,[3,2,1],[2,2,2])
|
|
1416
|
+
sage: t = T([[1,1,2],[2,3],[3]]); t
|
|
1417
|
+
[[1, 1, 2], [2, 3], [3]]
|
|
1418
|
+
sage: c == t
|
|
1419
|
+
True
|
|
1420
|
+
sage: type(t)
|
|
1421
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
|
|
1422
|
+
sage: t.parent()
|
|
1423
|
+
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (2, 2, 2)
|
|
1424
|
+
sage: TestSuite(t).run()
|
|
1425
|
+
|
|
1426
|
+
sage: t = WeakTableau_bounded([[None, None, 1], [2, 4], [3]], 3)
|
|
1427
|
+
sage: t.shape()
|
|
1428
|
+
([3, 2, 1], [2])
|
|
1429
|
+
sage: t.weight()
|
|
1430
|
+
(1, 1, 1, 1)
|
|
1431
|
+
sage: TestSuite(t).run()
|
|
1432
|
+
|
|
1433
|
+
sage: t = T([[1,1,3],[2,2],[3]])
|
|
1434
|
+
Traceback (most recent call last):
|
|
1435
|
+
...
|
|
1436
|
+
ValueError: This is not a proper weak 3-tableau
|
|
1437
|
+
"""
|
|
1438
|
+
k = parent.k
|
|
1439
|
+
self.k = k
|
|
1440
|
+
if parent._outer_shape.conjugate().length() > k:
|
|
1441
|
+
raise ValueError("%s is not a %s-bounded tableau" % (t, k))
|
|
1442
|
+
ClonableList.__init__(self, parent, [list(r) for r in t])
|
|
1443
|
+
|
|
1444
|
+
def _repr_diagram(self):
|
|
1445
|
+
r"""
|
|
1446
|
+
Return a string representation of ``self`` as a diagram.
|
|
1447
|
+
|
|
1448
|
+
EXAMPLES::
|
|
1449
|
+
|
|
1450
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
1451
|
+
sage: print(t._repr_diagram())
|
|
1452
|
+
. . 1
|
|
1453
|
+
2 4
|
|
1454
|
+
3
|
|
1455
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
1456
|
+
sage: print(t._repr_diagram())
|
|
1457
|
+
1 1 1
|
|
1458
|
+
2 2
|
|
1459
|
+
3
|
|
1460
|
+
"""
|
|
1461
|
+
t = SkewTableau(list(self))
|
|
1462
|
+
return t._repr_diagram()
|
|
1463
|
+
|
|
1464
|
+
def shape_core(self):
|
|
1465
|
+
r"""
|
|
1466
|
+
Return the shape of ``self`` as `(k+1)`-core.
|
|
1467
|
+
|
|
1468
|
+
When the tableau is straight, the outer shape is returned as a `(k+1)`-core.
|
|
1469
|
+
When the tableau is skew, the tuple of the outer and inner shape is returned as
|
|
1470
|
+
`(k+1)`-cores.
|
|
1471
|
+
|
|
1472
|
+
EXAMPLES::
|
|
1473
|
+
|
|
1474
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
1475
|
+
sage: t.shape_core()
|
|
1476
|
+
[5, 2, 1]
|
|
1477
|
+
|
|
1478
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
1479
|
+
sage: t.shape_core()
|
|
1480
|
+
([5, 2, 1], [2])
|
|
1481
|
+
"""
|
|
1482
|
+
if self.parent()._skew:
|
|
1483
|
+
return tuple([r.to_core(self.k) for r in self.shape_bounded()])
|
|
1484
|
+
return self.shape_bounded().to_core(self.k)
|
|
1485
|
+
|
|
1486
|
+
def shape_bounded(self):
|
|
1487
|
+
r"""
|
|
1488
|
+
Return the shape of ``self`` as `k`-bounded partition.
|
|
1489
|
+
|
|
1490
|
+
When the tableau is straight, the outer shape is returned as a `k`-bounded
|
|
1491
|
+
partition. When the tableau is skew, the tuple of the outer and inner shape is
|
|
1492
|
+
returned as `k`-bounded partitions.
|
|
1493
|
+
|
|
1494
|
+
EXAMPLES::
|
|
1495
|
+
|
|
1496
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
1497
|
+
sage: t.shape_bounded()
|
|
1498
|
+
[3, 2, 1]
|
|
1499
|
+
|
|
1500
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
1501
|
+
sage: t.shape_bounded()
|
|
1502
|
+
([3, 2, 1], [2])
|
|
1503
|
+
"""
|
|
1504
|
+
return self.shape()
|
|
1505
|
+
|
|
1506
|
+
def check(self):
|
|
1507
|
+
r"""
|
|
1508
|
+
Check that ``self`` is a valid weak `k`-tableau.
|
|
1509
|
+
|
|
1510
|
+
EXAMPLES::
|
|
1511
|
+
|
|
1512
|
+
sage: t = WeakTableau([[1,1],[2]], 2, representation = 'bounded')
|
|
1513
|
+
sage: t.check()
|
|
1514
|
+
|
|
1515
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
1516
|
+
sage: t.check()
|
|
1517
|
+
|
|
1518
|
+
TESTS::
|
|
1519
|
+
|
|
1520
|
+
sage: t = WeakTableau([[1,1,3],[2,2],[3]], 3, representation = 'bounded')
|
|
1521
|
+
Traceback (most recent call last):
|
|
1522
|
+
...
|
|
1523
|
+
ValueError: This is not a proper weak 3-tableau
|
|
1524
|
+
|
|
1525
|
+
sage: T = WeakTableaux(3, [3,1], [2,1], representation = 'bounded')
|
|
1526
|
+
sage: t = T([[None, 1,1], [2]])
|
|
1527
|
+
Traceback (most recent call last):
|
|
1528
|
+
...
|
|
1529
|
+
ValueError: The inner shape of the parent does not agree with the inner shape of the tableau!
|
|
1530
|
+
|
|
1531
|
+
sage: t = WeakTableau([[1,1],[1]], 3, representation = 'bounded')
|
|
1532
|
+
Traceback (most recent call last):
|
|
1533
|
+
...
|
|
1534
|
+
ValueError: The tableaux is not semistandard!
|
|
1535
|
+
"""
|
|
1536
|
+
t = SkewTableau(list(self))
|
|
1537
|
+
if t not in SemistandardSkewTableaux():
|
|
1538
|
+
raise ValueError("The tableaux is not semistandard!")
|
|
1539
|
+
if not self.parent()._weight == tuple(t.weight()):
|
|
1540
|
+
raise ValueError("The weight of the parent does not agree with the weight of the tableau!")
|
|
1541
|
+
outer = t.outer_shape()
|
|
1542
|
+
inner = t.inner_shape()
|
|
1543
|
+
if self.parent()._outer_shape != outer:
|
|
1544
|
+
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
|
|
1545
|
+
if self.parent()._inner_shape != inner:
|
|
1546
|
+
raise ValueError("The inner shape of the parent does not agree with the inner shape of the tableau!")
|
|
1547
|
+
if not t.is_k_tableau(self.k):
|
|
1548
|
+
raise ValueError("This is not a proper weak %s-tableau" % (self.k))
|
|
1549
|
+
|
|
1550
|
+
def _is_k_tableau(self):
|
|
1551
|
+
r"""
|
|
1552
|
+
Check whether ``self`` is a valid weak `k`-tableau.
|
|
1553
|
+
|
|
1554
|
+
EXAMPLES::
|
|
1555
|
+
|
|
1556
|
+
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
|
|
1557
|
+
sage: t._is_k_tableau()
|
|
1558
|
+
True
|
|
1559
|
+
|
|
1560
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
1561
|
+
sage: t._is_k_tableau()
|
|
1562
|
+
True
|
|
1563
|
+
"""
|
|
1564
|
+
shapes = self.intermediate_shapes()
|
|
1565
|
+
kshapes = [ la.k_conjugate(self.k) for la in shapes ]
|
|
1566
|
+
return all( kshapes[i+1].contains(kshapes[i]) for i in range(len(shapes)-1) )
|
|
1567
|
+
|
|
1568
|
+
def to_core_tableau(self):
|
|
1569
|
+
r"""
|
|
1570
|
+
Return the weak `k`-tableau ``self`` where the shape of each restricted tableau is a `(k+1)`-core.
|
|
1571
|
+
|
|
1572
|
+
EXAMPLES::
|
|
1573
|
+
|
|
1574
|
+
sage: t = WeakTableau([[1,1,2,4],[2,3,5],[3,4],[5,6],[6],[7]], 4, representation = 'bounded')
|
|
1575
|
+
sage: c = t.to_core_tableau(); c
|
|
1576
|
+
[[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]]
|
|
1577
|
+
sage: type(c)
|
|
1578
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
1579
|
+
sage: t = WeakTableau([], 4, representation = 'bounded')
|
|
1580
|
+
sage: t.to_core_tableau()
|
|
1581
|
+
[]
|
|
1582
|
+
|
|
1583
|
+
sage: from sage.combinat.k_tableau import WeakTableau_bounded
|
|
1584
|
+
sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation = 'bounded')
|
|
1585
|
+
sage: WeakTableau_bounded.from_core_tableau(t.to_core_tableau(),3)
|
|
1586
|
+
[[1, 1, 2], [2, 3], [3]]
|
|
1587
|
+
sage: t == WeakTableau_bounded.from_core_tableau(t.to_core_tableau(),3)
|
|
1588
|
+
True
|
|
1589
|
+
|
|
1590
|
+
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
|
|
1591
|
+
sage: t.to_core_tableau()
|
|
1592
|
+
[[None, None, 1, 2, 4], [2, 4], [3]]
|
|
1593
|
+
sage: t == WeakTableau_bounded.from_core_tableau(t.to_core_tableau(),3)
|
|
1594
|
+
True
|
|
1595
|
+
"""
|
|
1596
|
+
shapes = [ p.to_core(self.k) for p in self.intermediate_shapes() ]
|
|
1597
|
+
if self.parent()._skew:
|
|
1598
|
+
l = [[None]*i for i in shapes[0]]
|
|
1599
|
+
else:
|
|
1600
|
+
l = []
|
|
1601
|
+
for i in range(1,len(shapes)):
|
|
1602
|
+
p = shapes[i]
|
|
1603
|
+
if len(l) < len(p):
|
|
1604
|
+
l += [[]]
|
|
1605
|
+
l_new = []
|
|
1606
|
+
for j in range(len(l)):
|
|
1607
|
+
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
|
|
1608
|
+
l = l_new
|
|
1609
|
+
return WeakTableau_core(l, self.k)
|
|
1610
|
+
|
|
1611
|
+
@classmethod
|
|
1612
|
+
def from_core_tableau(cls, t, k):
|
|
1613
|
+
r"""
|
|
1614
|
+
Construct weak `k`-bounded tableau from in `k`-core tableau.
|
|
1615
|
+
|
|
1616
|
+
EXAMPLES::
|
|
1617
|
+
|
|
1618
|
+
sage: from sage.combinat.k_tableau import WeakTableau_bounded
|
|
1619
|
+
sage: WeakTableau_bounded.from_core_tableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
|
|
1620
|
+
[[1, 1, 2], [2, 3], [3]]
|
|
1621
|
+
|
|
1622
|
+
sage: WeakTableau_bounded.from_core_tableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
1623
|
+
[[None, None, 3], [1, 4], [2]]
|
|
1624
|
+
|
|
1625
|
+
sage: WeakTableau_bounded.from_core_tableau([[None,2,3],[3]], 2)
|
|
1626
|
+
[[None, 2], [3]]
|
|
1627
|
+
"""
|
|
1628
|
+
t = SkewTableau(list(t))
|
|
1629
|
+
shapes = [ Core(p, k+1).to_bounded_partition() for p in intermediate_shapes(t) ] # .to_chain() ]
|
|
1630
|
+
if t.inner_shape() == Partition([]):
|
|
1631
|
+
l = []
|
|
1632
|
+
else:
|
|
1633
|
+
l = [[None]*i for i in shapes[0]]
|
|
1634
|
+
for i in range(1, len(shapes)):
|
|
1635
|
+
p = shapes[i]
|
|
1636
|
+
if len(l) < len(p):
|
|
1637
|
+
l += [[]]
|
|
1638
|
+
l_new = []
|
|
1639
|
+
for j in range(len(l)):
|
|
1640
|
+
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
|
|
1641
|
+
l = l_new
|
|
1642
|
+
return cls(l, k)
|
|
1643
|
+
|
|
1644
|
+
def k_charge(self, algorithm='I'):
|
|
1645
|
+
r"""
|
|
1646
|
+
Return the `k`-charge of ``self``.
|
|
1647
|
+
|
|
1648
|
+
INPUT:
|
|
1649
|
+
|
|
1650
|
+
- ``algorithm`` -- (default: ``'I'``) if "I", computes `k`-charge using the `I`
|
|
1651
|
+
algorithm, otherwise uses the `J`-algorithm
|
|
1652
|
+
|
|
1653
|
+
OUTPUT: nonnegative integer
|
|
1654
|
+
|
|
1655
|
+
For the definition of `k`-charge and the various algorithms to compute it see Section 3.3 of [LLMSSZ2013]_.
|
|
1656
|
+
|
|
1657
|
+
EXAMPLES::
|
|
1658
|
+
|
|
1659
|
+
sage: t = WeakTableau([[1, 1, 2], [2, 3], [3]], 3, representation = 'bounded')
|
|
1660
|
+
sage: t.k_charge()
|
|
1661
|
+
2
|
|
1662
|
+
sage: t = WeakTableau([[1, 3, 5], [2, 6], [4]], 3, representation = 'bounded')
|
|
1663
|
+
sage: t.k_charge()
|
|
1664
|
+
8
|
|
1665
|
+
sage: t = WeakTableau([[1, 1, 2, 4], [2, 3, 5], [3, 4], [5, 6], [6], [7]], 4, representation = 'bounded')
|
|
1666
|
+
sage: t.k_charge()
|
|
1667
|
+
12
|
|
1668
|
+
"""
|
|
1669
|
+
return self.to_core_tableau().k_charge(algorithm=algorithm)
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
class WeakTableaux_bounded(WeakTableaux_abstract):
|
|
1673
|
+
r"""
|
|
1674
|
+
The class of (skew) weak `k`-tableaux in the bounded representation of shape ``shape``
|
|
1675
|
+
(as `k`-bounded partition or tuple of `k`-bounded partitions in the skew case) and
|
|
1676
|
+
weight ``weight``.
|
|
1677
|
+
|
|
1678
|
+
INPUT:
|
|
1679
|
+
|
|
1680
|
+
- ``k`` -- positive integer
|
|
1681
|
+
- ``shape`` -- the shape of the `k`-tableaux represented as a `k`-bounded partition;
|
|
1682
|
+
if the tableaux are skew, the shape is a tuple of the outer and inner shape each
|
|
1683
|
+
represented as a `k`-bounded partition
|
|
1684
|
+
- ``weight`` -- the weight of the `k`-tableaux
|
|
1685
|
+
|
|
1686
|
+
EXAMPLES::
|
|
1687
|
+
|
|
1688
|
+
sage: T = WeakTableaux(3, [3,1], [2,2], representation = 'bounded')
|
|
1689
|
+
sage: T.list()
|
|
1690
|
+
[[[1, 1, 2], [2]]]
|
|
1691
|
+
|
|
1692
|
+
sage: T = WeakTableaux(3, [[3,2,1], [2]], [1,1,1,1], representation = 'bounded')
|
|
1693
|
+
sage: T.list()
|
|
1694
|
+
[[[None, None, 3], [1, 4], [2]],
|
|
1695
|
+
[[None, None, 1], [2, 4], [3]],
|
|
1696
|
+
[[None, None, 1], [2, 3], [4]]]
|
|
1697
|
+
"""
|
|
1698
|
+
@staticmethod
|
|
1699
|
+
def __classcall_private__(cls, k, shape, weight):
|
|
1700
|
+
r"""
|
|
1701
|
+
Straighten arguments before unique representation.
|
|
1702
|
+
|
|
1703
|
+
TESTS::
|
|
1704
|
+
|
|
1705
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_bounded
|
|
1706
|
+
sage: T = WeakTableaux_bounded(3, [2,1], [1,1,1])
|
|
1707
|
+
sage: TestSuite(T).run()
|
|
1708
|
+
sage: T = WeakTableaux_bounded(3, [[3,2,1], [2]], [1,1,1,1])
|
|
1709
|
+
sage: TestSuite(T).run()
|
|
1710
|
+
"""
|
|
1711
|
+
if shape == [] or shape[0] in ZZ:
|
|
1712
|
+
shape = (Partition(shape), Partition([]))
|
|
1713
|
+
else:
|
|
1714
|
+
shape = tuple([Partition(r) for r in shape])
|
|
1715
|
+
return super().__classcall__(cls, k, shape, tuple(weight))
|
|
1716
|
+
|
|
1717
|
+
def __init__(self, k, shape, weight):
|
|
1718
|
+
r"""
|
|
1719
|
+
Initialize the parent class of (skew) weak `k`-tableaux in bounded representation.
|
|
1720
|
+
|
|
1721
|
+
INPUT:
|
|
1722
|
+
|
|
1723
|
+
- ``k`` -- positive integer
|
|
1724
|
+
- ``shape`` -- the shape of the `k`-tableaux represented as a `k`-bounded
|
|
1725
|
+
partition; if the tableaux are skew, the shape is a tuple of the outer and inner
|
|
1726
|
+
shape each represented as a `k`-bounded partition
|
|
1727
|
+
- ``weight`` -- the weight of the `k`-tableaux
|
|
1728
|
+
|
|
1729
|
+
TESTS::
|
|
1730
|
+
|
|
1731
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_bounded
|
|
1732
|
+
sage: T = WeakTableaux_bounded(3, [3,1], [2,2])
|
|
1733
|
+
sage: TestSuite(T).run()
|
|
1734
|
+
sage: T = WeakTableaux_bounded(3, [[3,2,1], [2]], [1,1,1,1])
|
|
1735
|
+
sage: TestSuite(T).run()
|
|
1736
|
+
"""
|
|
1737
|
+
self.k = k
|
|
1738
|
+
self._skew = bool(shape[1])
|
|
1739
|
+
self._outer_shape = Partition(shape[0])
|
|
1740
|
+
self._inner_shape = Partition(shape[1])
|
|
1741
|
+
self._shape = (self._outer_shape, self._inner_shape)
|
|
1742
|
+
self._weight = tuple(weight)
|
|
1743
|
+
self._representation = 'bounded'
|
|
1744
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
1745
|
+
|
|
1746
|
+
def _repr_(self):
|
|
1747
|
+
"""
|
|
1748
|
+
TESTS::
|
|
1749
|
+
|
|
1750
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_bounded
|
|
1751
|
+
sage: repr(WeakTableaux_bounded(3, [2,1], [1,1,1]))
|
|
1752
|
+
'Bounded weak 3-Tableaux of (skew) 3-bounded shape [2, 1] and weight (1, 1, 1)'
|
|
1753
|
+
sage: repr(WeakTableaux_bounded(3, [[3,2,1], [2]], [1,1,1,1]))
|
|
1754
|
+
'Bounded weak 3-Tableaux of (skew) 3-bounded shape ([3, 2, 1], [2]) and weight (1, 1, 1, 1)'
|
|
1755
|
+
"""
|
|
1756
|
+
return "Bounded weak %s-Tableaux of (skew) %s-bounded shape %s and weight %s" % (self.k, self.k, self.shape(), self._weight)
|
|
1757
|
+
|
|
1758
|
+
def __iter__(self):
|
|
1759
|
+
r"""
|
|
1760
|
+
TESTS::
|
|
1761
|
+
|
|
1762
|
+
sage: T = WeakTableaux(3, [3,1], [2,2], representation = 'bounded')
|
|
1763
|
+
sage: T.list()
|
|
1764
|
+
[[[1, 1, 2], [2]]]
|
|
1765
|
+
sage: T = WeakTableaux(3, [3,2,2], [2,2,2,1], representation = 'bounded')
|
|
1766
|
+
sage: T.list()
|
|
1767
|
+
[[[1, 1, 4], [2, 2], [3, 3]], [[1, 1, 2], [2, 3], [3, 4]]]
|
|
1768
|
+
sage: T = WeakTableaux(3, [[3,2,2], [1]], [2,1,2,1], representation = 'bounded')
|
|
1769
|
+
sage: T.list()
|
|
1770
|
+
[[[None, 1, 4], [1, 2], [3, 3]],
|
|
1771
|
+
[[None, 1, 3], [1, 3], [2, 4]],
|
|
1772
|
+
[[None, 1, 1], [2, 3], [3, 4]]]
|
|
1773
|
+
"""
|
|
1774
|
+
for t in SemistandardSkewTableaux([self._outer_shape, self._inner_shape], self._weight):
|
|
1775
|
+
if t.is_k_tableau(self.k):
|
|
1776
|
+
yield self(t)
|
|
1777
|
+
|
|
1778
|
+
Element = WeakTableau_bounded
|
|
1779
|
+
|
|
1780
|
+
#Weak tableaux in terms of factorized permutations
|
|
1781
|
+
|
|
1782
|
+
|
|
1783
|
+
class WeakTableau_factorized_permutation(WeakTableau_abstract):
|
|
1784
|
+
r"""
|
|
1785
|
+
A weak (skew) `k`-tableau represented in terms of factorizations of affine
|
|
1786
|
+
permutations into cyclically decreasing elements.
|
|
1787
|
+
"""
|
|
1788
|
+
@staticmethod
|
|
1789
|
+
def straighten_input(t, k):
|
|
1790
|
+
r"""
|
|
1791
|
+
Straightens input.
|
|
1792
|
+
|
|
1793
|
+
INPUT:
|
|
1794
|
+
|
|
1795
|
+
- ``t`` -- list of reduced words or a list of elements in the Weyl group of type
|
|
1796
|
+
`A_k^{(1)}`
|
|
1797
|
+
- ``k`` -- positive integer
|
|
1798
|
+
|
|
1799
|
+
EXAMPLES::
|
|
1800
|
+
|
|
1801
|
+
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
|
|
1802
|
+
sage: WeakTableau_factorized_permutation.straighten_input([[2,0],[3,2],[1,0]], 3)
|
|
1803
|
+
(s2*s0, s3*s2, s1*s0)
|
|
1804
|
+
sage: W = WeylGroup(['A',4,1])
|
|
1805
|
+
sage: WeakTableau_factorized_permutation.straighten_input([W.an_element(),W.an_element()], 4)
|
|
1806
|
+
(s0*s1*s2*s3*s4, s0*s1*s2*s3*s4)
|
|
1807
|
+
|
|
1808
|
+
TESTS::
|
|
1809
|
+
|
|
1810
|
+
sage: WeakTableau_factorized_permutation.straighten_input([W.an_element(),W.an_element()], 3)
|
|
1811
|
+
Traceback (most recent call last):
|
|
1812
|
+
...
|
|
1813
|
+
ValueError: inconsistent number of rows: should be 4 but got 5
|
|
1814
|
+
"""
|
|
1815
|
+
W = WeylGroup(['A', k, 1], prefix='s')
|
|
1816
|
+
if len(t) > 0:
|
|
1817
|
+
if isinstance(t[0], (list, tuple)):
|
|
1818
|
+
w_tuple = tuple(W.from_reduced_word(p) for p in t)
|
|
1819
|
+
else:
|
|
1820
|
+
w_tuple = tuple(W(r) for r in t)
|
|
1821
|
+
else:
|
|
1822
|
+
w_tuple = tuple([W.one()])
|
|
1823
|
+
return w_tuple
|
|
1824
|
+
|
|
1825
|
+
@staticmethod
|
|
1826
|
+
def __classcall_private__(cls, t, k, inner_shape=[]):
|
|
1827
|
+
r"""
|
|
1828
|
+
Implement the shortcut ``WeakTableau_factorized_permutation(t, k)`` to
|
|
1829
|
+
``WeakTableaux_factorized_permutation(k, shape, weight)(t)``
|
|
1830
|
+
where ``shape`` is the shape of the tableau as a `(k+1)`-core (or a tuple of
|
|
1831
|
+
`(k+1)`-cores if the tableau is skew) and ``weight`` is its weight.
|
|
1832
|
+
|
|
1833
|
+
TESTS::
|
|
1834
|
+
|
|
1835
|
+
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
|
|
1836
|
+
sage: t = WeakTableau_factorized_permutation([[2,0],[3,2],[1,0]], 3)
|
|
1837
|
+
sage: t.check()
|
|
1838
|
+
sage: type(t)
|
|
1839
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
|
|
1840
|
+
sage: TestSuite(t).run()
|
|
1841
|
+
|
|
1842
|
+
sage: t = WeakTableau_factorized_permutation([[0,3],[2,1]], 3, inner_shape = [1,1])
|
|
1843
|
+
sage: t.check()
|
|
1844
|
+
sage: TestSuite(t).run()
|
|
1845
|
+
|
|
1846
|
+
sage: t = WeakTableau_factorized_permutation([], 3); t
|
|
1847
|
+
[1]
|
|
1848
|
+
sage: t.check()
|
|
1849
|
+
sage: TestSuite(t).run()
|
|
1850
|
+
"""
|
|
1851
|
+
if isinstance(t, cls):
|
|
1852
|
+
return t
|
|
1853
|
+
W = WeylGroup(['A', k, 1], prefix='s')
|
|
1854
|
+
w = cls.straighten_input(t, k)
|
|
1855
|
+
weight = tuple(w[i].length() for i in range(len(w) - 1, -1, -1))
|
|
1856
|
+
inner_shape = Core(inner_shape, k + 1)
|
|
1857
|
+
outer_shape = (W.prod(w)*W(inner_shape.to_grassmannian())).affine_grassmannian_to_core()
|
|
1858
|
+
return WeakTableaux_factorized_permutation(k, [outer_shape, inner_shape], weight)(w)
|
|
1859
|
+
|
|
1860
|
+
def __init__(self, parent, t):
|
|
1861
|
+
r"""
|
|
1862
|
+
Initialization of (skew) weak `k`-tableau ``t`` in factorized permutation representation.
|
|
1863
|
+
|
|
1864
|
+
INPUT:
|
|
1865
|
+
|
|
1866
|
+
- ``t`` -- (skew) weak tableau in factorized permutation representation; the input
|
|
1867
|
+
can either be a list of reduced words of cyclically decreasing elements, or a
|
|
1868
|
+
list of cyclically decreasing elements; when the tableau is skew, the inner
|
|
1869
|
+
shape needs to be specified as a `(k+1)`-core
|
|
1870
|
+
|
|
1871
|
+
TESTS::
|
|
1872
|
+
|
|
1873
|
+
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation, WeakTableaux_factorized_permutation
|
|
1874
|
+
sage: c = WeakTableau_factorized_permutation([[2,0],[3,2],[1,0]], 3)
|
|
1875
|
+
sage: T = WeakTableaux_factorized_permutation(3, [5,2,1],[2,2,2])
|
|
1876
|
+
sage: t = T([[2,0],[3,2],[1,0]]); t
|
|
1877
|
+
[s2*s0, s3*s2, s1*s0]
|
|
1878
|
+
sage: c == t
|
|
1879
|
+
True
|
|
1880
|
+
sage: type(t)
|
|
1881
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
|
|
1882
|
+
sage: t.parent()
|
|
1883
|
+
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (2, 2, 2)
|
|
1884
|
+
sage: TestSuite(t).run()
|
|
1885
|
+
|
|
1886
|
+
sage: t = WeakTableau_factorized_permutation([[2,0],[3,2]], 3, inner_shape = [2]); t
|
|
1887
|
+
[s2*s0, s3*s2]
|
|
1888
|
+
sage: t._inner_shape
|
|
1889
|
+
[2]
|
|
1890
|
+
sage: t.weight()
|
|
1891
|
+
(2, 2)
|
|
1892
|
+
sage: t.shape()
|
|
1893
|
+
([5, 2, 1], [2])
|
|
1894
|
+
sage: TestSuite(t).run()
|
|
1895
|
+
|
|
1896
|
+
sage: t = T([[3,0],[0,3],[1,0]])
|
|
1897
|
+
Traceback (most recent call last):
|
|
1898
|
+
...
|
|
1899
|
+
ValueError: The outer shape of the parent does not agree with the outer shape of the tableau!
|
|
1900
|
+
|
|
1901
|
+
sage: t = WeakTableau_factorized_permutation([], 3); t
|
|
1902
|
+
[1]
|
|
1903
|
+
sage: t.parent()._outer_shape
|
|
1904
|
+
[]
|
|
1905
|
+
sage: t.parent()._weight
|
|
1906
|
+
(0,)
|
|
1907
|
+
"""
|
|
1908
|
+
self.k = parent.k
|
|
1909
|
+
self._inner_shape = parent._inner_shape
|
|
1910
|
+
ClonableList.__init__(self, parent, self.straighten_input(t, parent.k))
|
|
1911
|
+
|
|
1912
|
+
def shape_core(self):
|
|
1913
|
+
r"""
|
|
1914
|
+
Return the shape of ``self`` as a `(k+1)`-core.
|
|
1915
|
+
|
|
1916
|
+
When the tableau is straight, the outer shape is returned as a core.
|
|
1917
|
+
When the tableau is skew, the tuple of the outer and inner shape is returned as
|
|
1918
|
+
cores.
|
|
1919
|
+
|
|
1920
|
+
EXAMPLES::
|
|
1921
|
+
|
|
1922
|
+
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
|
|
1923
|
+
sage: t.shape_core()
|
|
1924
|
+
[5, 2, 1]
|
|
1925
|
+
|
|
1926
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
1927
|
+
sage: t.shape()
|
|
1928
|
+
([5, 2, 1], [2])
|
|
1929
|
+
"""
|
|
1930
|
+
return self.shape()
|
|
1931
|
+
|
|
1932
|
+
def shape_bounded(self):
|
|
1933
|
+
r"""
|
|
1934
|
+
Return the shape of ``self`` as a `k`-bounded partition.
|
|
1935
|
+
|
|
1936
|
+
When the tableau is straight, the outer shape is returned as a `k`-bounded
|
|
1937
|
+
partition. When the tableau is skew, the tuple of the outer and inner shape is
|
|
1938
|
+
returned as `k`-bounded partitions.
|
|
1939
|
+
|
|
1940
|
+
EXAMPLES::
|
|
1941
|
+
|
|
1942
|
+
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
|
|
1943
|
+
sage: t.shape_bounded()
|
|
1944
|
+
[3, 2, 1]
|
|
1945
|
+
|
|
1946
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
1947
|
+
sage: t.shape_bounded()
|
|
1948
|
+
([3, 2, 1], [2])
|
|
1949
|
+
"""
|
|
1950
|
+
if self.parent()._skew:
|
|
1951
|
+
return tuple([r.to_bounded_partition() for r in self.shape_core()])
|
|
1952
|
+
return self.shape_core().to_bounded_partition()
|
|
1953
|
+
|
|
1954
|
+
def check(self):
|
|
1955
|
+
r"""
|
|
1956
|
+
Check that ``self`` is a valid weak `k`-tableau.
|
|
1957
|
+
|
|
1958
|
+
EXAMPLES::
|
|
1959
|
+
|
|
1960
|
+
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
|
|
1961
|
+
sage: t.check()
|
|
1962
|
+
|
|
1963
|
+
TESTS::
|
|
1964
|
+
|
|
1965
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, representation = 'factorized_permutation')
|
|
1966
|
+
Traceback (most recent call last):
|
|
1967
|
+
...
|
|
1968
|
+
ValueError: this only works on type 'A' affine Grassmannian elements
|
|
1969
|
+
|
|
1970
|
+
sage: T = WeakTableaux(3, [4,1], [2,1], representation = 'factorized_permutation')
|
|
1971
|
+
sage: t = T([[2],[1],[0]])
|
|
1972
|
+
Traceback (most recent call last):
|
|
1973
|
+
...
|
|
1974
|
+
ValueError: The weight of the parent does not agree with the weight of the tableau!
|
|
1975
|
+
"""
|
|
1976
|
+
weight = tuple(self[i].length() for i in range(len(self) - 1, -1, -1))
|
|
1977
|
+
if not self.parent()._weight == weight:
|
|
1978
|
+
raise ValueError("The weight of the parent does not agree "
|
|
1979
|
+
"with the weight of the tableau!")
|
|
1980
|
+
W = self[0].parent()
|
|
1981
|
+
outer = (W.prod(self)*W((self._inner_shape).to_grassmannian())).affine_grassmannian_to_core()
|
|
1982
|
+
if self.parent()._outer_shape != outer:
|
|
1983
|
+
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
|
|
1984
|
+
if not self._is_k_tableau():
|
|
1985
|
+
raise ValueError("This is not a proper weak %s-tableau" % (self.k))
|
|
1986
|
+
|
|
1987
|
+
def _is_k_tableau(self):
|
|
1988
|
+
r"""
|
|
1989
|
+
Check whether ``self`` is a valid weak `k`-tableau.
|
|
1990
|
+
|
|
1991
|
+
EXAMPLES::
|
|
1992
|
+
|
|
1993
|
+
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
|
|
1994
|
+
sage: t._is_k_tableau()
|
|
1995
|
+
True
|
|
1996
|
+
|
|
1997
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
1998
|
+
sage: t._is_k_tableau()
|
|
1999
|
+
True
|
|
2000
|
+
"""
|
|
2001
|
+
W = self[0].parent()
|
|
2002
|
+
if (W.prod(self)*W(self.parent()._inner_shape.to_grassmannian())).is_affine_grassmannian():
|
|
2003
|
+
return all( r.is_pieri_factor() for r in self )
|
|
2004
|
+
return False
|
|
2005
|
+
|
|
2006
|
+
def to_core_tableau(self):
|
|
2007
|
+
r"""
|
|
2008
|
+
Return the weak `k`-tableau ``self`` where the shape of each restricted tableau is a `(k+1)`-core.
|
|
2009
|
+
|
|
2010
|
+
EXAMPLES::
|
|
2011
|
+
|
|
2012
|
+
sage: t = WeakTableau([[0], [3,1], [2,1], [0,4], [3,0], [4,2], [1,0]], 4, representation = 'factorized_permutation'); t
|
|
2013
|
+
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
|
|
2014
|
+
sage: c = t.to_core_tableau(); c
|
|
2015
|
+
[[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]]
|
|
2016
|
+
sage: type(c)
|
|
2017
|
+
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
|
|
2018
|
+
sage: t = WeakTableau([[]], 4, representation = 'factorized_permutation'); t
|
|
2019
|
+
[1]
|
|
2020
|
+
sage: t.to_core_tableau()
|
|
2021
|
+
[]
|
|
2022
|
+
|
|
2023
|
+
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
|
|
2024
|
+
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = 'factorized_permutation')
|
|
2025
|
+
sage: WeakTableau_factorized_permutation.from_core_tableau(t.to_core_tableau(), 3)
|
|
2026
|
+
[s2*s0, s3*s2, s1*s0]
|
|
2027
|
+
sage: t == WeakTableau_factorized_permutation.from_core_tableau(t.to_core_tableau(), 3)
|
|
2028
|
+
True
|
|
2029
|
+
|
|
2030
|
+
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
|
|
2031
|
+
sage: t.to_core_tableau()
|
|
2032
|
+
[[None, None, 1, 1, 2], [1, 2], [2]]
|
|
2033
|
+
sage: t == WeakTableau_factorized_permutation.from_core_tableau(t.to_core_tableau(), 3)
|
|
2034
|
+
True
|
|
2035
|
+
"""
|
|
2036
|
+
W = self[0].parent()
|
|
2037
|
+
factor = W(self._inner_shape.to_grassmannian())
|
|
2038
|
+
shapes = [factor]
|
|
2039
|
+
for i in range(len(self)-1,-1,-1):
|
|
2040
|
+
factor = self[i]*factor
|
|
2041
|
+
shapes += [factor.affine_grassmannian_to_core()]
|
|
2042
|
+
if self.parent()._skew:
|
|
2043
|
+
l = [[None]*i for i in self._inner_shape]
|
|
2044
|
+
else:
|
|
2045
|
+
l = []
|
|
2046
|
+
for i in range(1,len(shapes)):
|
|
2047
|
+
p = shapes[i]
|
|
2048
|
+
if len(l) < len(p):
|
|
2049
|
+
l += [[]]
|
|
2050
|
+
l_new = []
|
|
2051
|
+
for j in range(len(l)):
|
|
2052
|
+
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
|
|
2053
|
+
l = l_new
|
|
2054
|
+
return WeakTableau_core(l, self.k)
|
|
2055
|
+
|
|
2056
|
+
@classmethod
|
|
2057
|
+
def from_core_tableau(cls, t, k):
|
|
2058
|
+
r"""
|
|
2059
|
+
Construct weak factorized affine permutation tableau from a `k`-core tableau.
|
|
2060
|
+
|
|
2061
|
+
EXAMPLES::
|
|
2062
|
+
|
|
2063
|
+
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
|
|
2064
|
+
sage: WeakTableau_factorized_permutation.from_core_tableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
2065
|
+
[s2*s0, s3*s2, s1*s0]
|
|
2066
|
+
sage: WeakTableau_factorized_permutation.from_core_tableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
|
|
2067
|
+
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
|
|
2068
|
+
sage: WeakTableau_factorized_permutation.from_core_tableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
|
|
2069
|
+
[s0*s3, s2*s1]
|
|
2070
|
+
"""
|
|
2071
|
+
t = SkewTableau(list(t))
|
|
2072
|
+
shapes = [Core(p, k + 1).to_grassmannian()
|
|
2073
|
+
for p in intermediate_shapes(t)] # t.to_chain() ]
|
|
2074
|
+
perms = [shapes[i] * (shapes[i - 1].inverse())
|
|
2075
|
+
for i in range(len(shapes) - 1, 0, -1)]
|
|
2076
|
+
return cls(perms, k, inner_shape=t.inner_shape())
|
|
2077
|
+
|
|
2078
|
+
def k_charge(self, algorithm='I'):
|
|
2079
|
+
r"""
|
|
2080
|
+
Return the `k`-charge of ``self``.
|
|
2081
|
+
|
|
2082
|
+
OUTPUT: nonnegative integer
|
|
2083
|
+
|
|
2084
|
+
EXAMPLES::
|
|
2085
|
+
|
|
2086
|
+
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = 'factorized_permutation')
|
|
2087
|
+
sage: t.k_charge()
|
|
2088
|
+
2
|
|
2089
|
+
sage: t = WeakTableau([[0],[3],[2],[1],[3],[0]], 3, representation = 'factorized_permutation')
|
|
2090
|
+
sage: t.k_charge()
|
|
2091
|
+
8
|
|
2092
|
+
sage: t = WeakTableau([[0],[3,1],[2,1],[0,4],[3,0],[4,2],[1,0]], 4, representation = 'factorized_permutation')
|
|
2093
|
+
sage: t.k_charge()
|
|
2094
|
+
12
|
|
2095
|
+
"""
|
|
2096
|
+
return self.to_core_tableau().k_charge(algorithm=algorithm)
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
class WeakTableaux_factorized_permutation(WeakTableaux_abstract):
|
|
2100
|
+
r"""
|
|
2101
|
+
The class of (skew) weak `k`-tableaux in the factorized permutation representation of shape ``shape`` (as `k+1`-core
|
|
2102
|
+
or tuple of `(k+1)`-cores in the skew case) and weight ``weight``.
|
|
2103
|
+
|
|
2104
|
+
INPUT:
|
|
2105
|
+
|
|
2106
|
+
- ``k`` -- positive integer
|
|
2107
|
+
- ``shape`` -- the shape of the `k`-tableaux represented as a `(k+1)`-core;
|
|
2108
|
+
in the skew case the shape is a tuple of the outer and inner shape both as `(k+1)`-cores
|
|
2109
|
+
- ``weight`` -- the weight of the `k`-tableaux
|
|
2110
|
+
|
|
2111
|
+
EXAMPLES::
|
|
2112
|
+
|
|
2113
|
+
sage: T = WeakTableaux(3, [4,1], [2,2], representation = 'factorized_permutation')
|
|
2114
|
+
sage: T.list()
|
|
2115
|
+
[[s3*s2, s1*s0]]
|
|
2116
|
+
|
|
2117
|
+
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], representation = 'factorized_permutation')
|
|
2118
|
+
sage: T.list()
|
|
2119
|
+
[[s0, s4, s3, s4*s2], [s0, s3, s4, s3*s2], [s3, s0, s4, s3*s2]]
|
|
2120
|
+
"""
|
|
2121
|
+
@staticmethod
|
|
2122
|
+
def __classcall_private__(cls, k, shape, weight):
|
|
2123
|
+
r"""
|
|
2124
|
+
Straighten arguments before unique representation.
|
|
2125
|
+
|
|
2126
|
+
TESTS::
|
|
2127
|
+
|
|
2128
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_factorized_permutation
|
|
2129
|
+
sage: T = WeakTableaux_factorized_permutation(3, [2,1], [1,1,1])
|
|
2130
|
+
sage: TestSuite(T).run()
|
|
2131
|
+
sage: T = WeakTableaux_factorized_permutation(4, [[6,2,1], [2]], [2,1,1,1])
|
|
2132
|
+
sage: TestSuite(T).run() # long time
|
|
2133
|
+
"""
|
|
2134
|
+
if shape == [] or shape[0] in ZZ:
|
|
2135
|
+
shape = (Core(shape, k+1), Core([],k+1))
|
|
2136
|
+
else:
|
|
2137
|
+
shape = tuple([Core(r,k+1) for r in shape])
|
|
2138
|
+
return super().__classcall__(cls, k, shape, tuple(weight))
|
|
2139
|
+
|
|
2140
|
+
def __init__(self, k, shape, weight):
|
|
2141
|
+
r"""
|
|
2142
|
+
Initialize the parent class of weak `k`-tableaux in factorized permutation representation.
|
|
2143
|
+
|
|
2144
|
+
INPUT:
|
|
2145
|
+
|
|
2146
|
+
- ``k`` -- positive integer
|
|
2147
|
+
- ``shape`` -- the shape of the `k`-tableaux represented as a `(k+1)`-core;
|
|
2148
|
+
in the skew case the shape is a tuple of the outer and inner shape both as
|
|
2149
|
+
`(k+1)`-cores
|
|
2150
|
+
- ``weight`` -- the weight of the `k`-tableaux
|
|
2151
|
+
|
|
2152
|
+
TESTS::
|
|
2153
|
+
|
|
2154
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_factorized_permutation
|
|
2155
|
+
sage: T = WeakTableaux_factorized_permutation(3, [4,1], [2,2])
|
|
2156
|
+
sage: TestSuite(T).run()
|
|
2157
|
+
sage: T = WeakTableaux_factorized_permutation(4, [[6,2,1], [2]], [2,1,1,1])
|
|
2158
|
+
sage: TestSuite(T).run() # long time
|
|
2159
|
+
"""
|
|
2160
|
+
self.k = k
|
|
2161
|
+
self._skew = bool(shape[1])
|
|
2162
|
+
self._outer_shape = Core(shape[0], k+1)
|
|
2163
|
+
self._inner_shape = Core(shape[1], k+1)
|
|
2164
|
+
self._shape = (self._outer_shape, self._inner_shape)
|
|
2165
|
+
self._weight = weight
|
|
2166
|
+
self._representation = 'factorized_permutation'
|
|
2167
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
2168
|
+
|
|
2169
|
+
def _repr_(self):
|
|
2170
|
+
"""
|
|
2171
|
+
TESTS::
|
|
2172
|
+
|
|
2173
|
+
sage: from sage.combinat.k_tableau import WeakTableaux_factorized_permutation
|
|
2174
|
+
sage: repr(WeakTableaux_factorized_permutation(3, [2,1], [1,1,1]))
|
|
2175
|
+
'Factorized permutation (skew) weak 3-Tableaux of shape [2, 1] and weight (1, 1, 1)'
|
|
2176
|
+
sage: repr(WeakTableaux_factorized_permutation(4, [[6,2,1], [2]], [2,1,1,1]))
|
|
2177
|
+
'Factorized permutation (skew) weak 4-Tableaux of shape ([6, 2, 1], [2]) and weight (2, 1, 1, 1)'
|
|
2178
|
+
"""
|
|
2179
|
+
return "Factorized permutation (skew) weak %s-Tableaux of shape %s and weight %s" % (self.k, self.shape(), self._weight)
|
|
2180
|
+
|
|
2181
|
+
def __iter__(self):
|
|
2182
|
+
r"""
|
|
2183
|
+
TESTS::
|
|
2184
|
+
|
|
2185
|
+
sage: T = WeakTableaux(3, [4,1], [2,2], representation = 'factorized_permutation')
|
|
2186
|
+
sage: T.list()
|
|
2187
|
+
[[s3*s2, s1*s0]]
|
|
2188
|
+
sage: T = WeakTableaux(3, [5,2,2], [2,2,2,1], representation = 'factorized_permutation')
|
|
2189
|
+
sage: T.list()
|
|
2190
|
+
[[s0, s3*s2, s0*s3, s1*s0], [s3, s2*s0, s3*s2, s1*s0]]
|
|
2191
|
+
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], representation = 'factorized_permutation')
|
|
2192
|
+
sage: T.list()
|
|
2193
|
+
[[s0, s4, s3, s4*s2], [s0, s3, s4, s3*s2], [s3, s0, s4, s3*s2]]
|
|
2194
|
+
"""
|
|
2195
|
+
for t in WeakTableaux_core(self.k, self.shape(), self._weight):
|
|
2196
|
+
yield WeakTableau_factorized_permutation.from_core_tableau(t, self.k)
|
|
2197
|
+
|
|
2198
|
+
Element = WeakTableau_factorized_permutation
|
|
2199
|
+
|
|
2200
|
+
|
|
2201
|
+
######## END weak tableaux BEGIN strong tableaux
|
|
2202
|
+
|
|
2203
|
+
class StrongTableau(ClonableList, metaclass=InheritComparisonClasscallMetaclass):
|
|
2204
|
+
r"""
|
|
2205
|
+
A (standard) strong `k`-tableau is a (saturated) chain in Bruhat order.
|
|
2206
|
+
|
|
2207
|
+
Combinatorially, it is a sequence of embedded `k+1`-cores (subject to some conditions)
|
|
2208
|
+
together with a set of markings.
|
|
2209
|
+
|
|
2210
|
+
A strong cover in terms of cores corresponds to certain translated ribbons. A marking
|
|
2211
|
+
corresponds to the choice of one of the translated ribbons, which is indicated by
|
|
2212
|
+
marking the head (southeast most cell in French notation) of the chosen ribbon. For
|
|
2213
|
+
more information, see [LLMS2006]_ and [LLMSSZ2013]_.
|
|
2214
|
+
|
|
2215
|
+
In Sage, a strong `k`-tableau is created by specifying `k`, a standard strong
|
|
2216
|
+
tableau together with its markings, and a weight `\mu`. Here the standard tableau is
|
|
2217
|
+
represented by a sequence of `k+1`-cores
|
|
2218
|
+
|
|
2219
|
+
.. MATH::
|
|
2220
|
+
|
|
2221
|
+
\lambda^{(0)} \subseteq \lambda^{(1)} \subseteq \cdots \subseteq \lambda^{(m)}
|
|
2222
|
+
|
|
2223
|
+
where each of the `\lambda^{(i)}` is a `k+1`-core. The standard tableau is a filling
|
|
2224
|
+
of the diagram for the core `\lambda^{(m)}/\lambda^{(0)}` where a strong cover
|
|
2225
|
+
is represented by letters `\pm i` in the skew shape `\lambda^{(i)}/\lambda^{(i-1)}`.
|
|
2226
|
+
Each skew `(k+1)`-core `\lambda^{(i)}/\lambda^{(i-1)}` is a ribbon or multiple
|
|
2227
|
+
copies of the same ribbon which are separated by `k+1` diagonals. Precisely one of
|
|
2228
|
+
the copies of the ribbons will be marked in the largest diagonal of the connected
|
|
2229
|
+
component (the 'head' of the ribbon). The marked cells are indicated by negative
|
|
2230
|
+
signs.
|
|
2231
|
+
|
|
2232
|
+
The strong tableau is stored as a standard strong marked tableau (referred to as the
|
|
2233
|
+
standard part of the strong tableau) and a vector representing the weight.
|
|
2234
|
+
|
|
2235
|
+
EXAMPLES::
|
|
2236
|
+
|
|
2237
|
+
sage: StrongTableau( [[-1, -2, -3], [3]], 2, [3] )
|
|
2238
|
+
[[-1, -1, -1], [1]]
|
|
2239
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
|
|
2240
|
+
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]]
|
|
2241
|
+
|
|
2242
|
+
Alternatively, the strong `k`-tableau can also be entered directly in semistandard
|
|
2243
|
+
format and then the standard tableau and the weight are computed and stored::
|
|
2244
|
+
|
|
2245
|
+
sage: T = StrongTableau([[-1,-1,-1],[1]], 2); T
|
|
2246
|
+
[[-1, -1, -1], [1]]
|
|
2247
|
+
sage: T.to_standard_list()
|
|
2248
|
+
[[-1, -2, -3], [3]]
|
|
2249
|
+
sage: T.weight()
|
|
2250
|
+
(3,)
|
|
2251
|
+
sage: T = StrongTableau([[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]], 3); T
|
|
2252
|
+
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]]
|
|
2253
|
+
sage: T.to_standard_list()
|
|
2254
|
+
[[-1, -2, -4, -7], [-3, 6, -6, 8], [4, 7], [-5, -8]]
|
|
2255
|
+
sage: T.weight()
|
|
2256
|
+
(2, 2, 3, 1)
|
|
2257
|
+
"""
|
|
2258
|
+
|
|
2259
|
+
def __init__(self, parent, T):
|
|
2260
|
+
"""
|
|
2261
|
+
INPUT:
|
|
2262
|
+
|
|
2263
|
+
- ``parent`` -- an instance of ``StrongTableaux``
|
|
2264
|
+
- ``T`` -- standard marked strong (possibly skew) `k`-tableau or a semistandard
|
|
2265
|
+
marked strong (possibly skew) `k`-tableau with inner cells represented by
|
|
2266
|
+
``None``
|
|
2267
|
+
|
|
2268
|
+
EXAMPLES::
|
|
2269
|
+
|
|
2270
|
+
sage: T = StrongTableau( [[-1, -2, -3]], 3 ); T
|
|
2271
|
+
[[-1, -2, -3]]
|
|
2272
|
+
sage: T
|
|
2273
|
+
[[-1, -2, -3]]
|
|
2274
|
+
sage: T.weight()
|
|
2275
|
+
(1, 1, 1)
|
|
2276
|
+
sage: T.size()
|
|
2277
|
+
3
|
|
2278
|
+
sage: T.parent()
|
|
2279
|
+
Set of strong 3-tableaux of shape [3] and of weight (1, 1, 1)
|
|
2280
|
+
sage: StrongTableau( [[-1, -2, -3], [3]], 2 )
|
|
2281
|
+
[[-1, -2, -3], [3]]
|
|
2282
|
+
sage: StrongTableau( [[-1, -1, 2], [-2]], 2 )
|
|
2283
|
+
[[-1, -1, 2], [-2]]
|
|
2284
|
+
sage: T = StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[2,1] ); T
|
|
2285
|
+
[[-1, -1, 2], [-2]]
|
|
2286
|
+
sage: T = StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[0,2,1] ); T
|
|
2287
|
+
[[-2, -2, 3], [-3]]
|
|
2288
|
+
sage: T.weight()
|
|
2289
|
+
(0, 2, 1)
|
|
2290
|
+
sage: T.size()
|
|
2291
|
+
3
|
|
2292
|
+
sage: T.parent()
|
|
2293
|
+
Set of strong 2-tableaux of shape [3, 1] and of weight (0, 2, 1)
|
|
2294
|
+
sage: StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[1,2] )
|
|
2295
|
+
Traceback (most recent call last):
|
|
2296
|
+
...
|
|
2297
|
+
ValueError: The weight=(1, 2) and the markings on the standard tableau=[[-1, -2, 3], [-3]] do not agree.
|
|
2298
|
+
sage: StrongTableau( [[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]], 4 )
|
|
2299
|
+
[[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]]
|
|
2300
|
+
sage: StrongTableau( [[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]], 4, weight=[2,2,1] )
|
|
2301
|
+
[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]
|
|
2302
|
+
sage: StrongTableau( [[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
2303
|
+
[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]
|
|
2304
|
+
|
|
2305
|
+
TESTS::
|
|
2306
|
+
|
|
2307
|
+
sage: T = StrongTableau([], 3); T
|
|
2308
|
+
[]
|
|
2309
|
+
sage: T.weight()
|
|
2310
|
+
()
|
|
2311
|
+
sage: T.parent()
|
|
2312
|
+
Set of strong 3-tableaux of shape [] and of weight ()
|
|
2313
|
+
sage: T = StrongTableau( [[None, None], [None, None]], 4, weight=() ); T
|
|
2314
|
+
[[None, None], [None, None]]
|
|
2315
|
+
sage: T.size()
|
|
2316
|
+
0
|
|
2317
|
+
"""
|
|
2318
|
+
self.k = parent.k
|
|
2319
|
+
self._tableau = T
|
|
2320
|
+
ClonableList.__init__(self, parent, T)
|
|
2321
|
+
|
|
2322
|
+
@staticmethod
|
|
2323
|
+
def __classcall_private__(cls, T, k, weight=None):
|
|
2324
|
+
r"""
|
|
2325
|
+
Straighten input and implement the shortcut ``StrongTableau(T, k, weight=None)``
|
|
2326
|
+
to ``StrongTableaux(k, shape, weight)(T)``.
|
|
2327
|
+
|
|
2328
|
+
TESTS::
|
|
2329
|
+
|
|
2330
|
+
sage: t = StrongTableau( [[-1, -2, -3]], 3 )
|
|
2331
|
+
sage: t.parent()
|
|
2332
|
+
Set of strong 3-tableaux of shape [3] and of weight (1, 1, 1)
|
|
2333
|
+
sage: TestSuite(t).run()
|
|
2334
|
+
sage: t = StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[2,1] )
|
|
2335
|
+
sage: TestSuite(t).run()
|
|
2336
|
+
sage: StrongTableau([[-1,-1,-1]], 3)
|
|
2337
|
+
[[-1, -1, -1]]
|
|
2338
|
+
sage: StrongTableau([[None, None, None], [None]], 2)
|
|
2339
|
+
[[None, None, None], [None]]
|
|
2340
|
+
|
|
2341
|
+
sage: StrongTableau([[-1, -2, -2], [1]], 2)
|
|
2342
|
+
Traceback (most recent call last):
|
|
2343
|
+
...
|
|
2344
|
+
ValueError: Unable to parse strong marked tableau : [[-1, -2, -2], [1]]
|
|
2345
|
+
|
|
2346
|
+
sage: StrongTableau([[-1,-1,-1,-1]], 3)
|
|
2347
|
+
Traceback (most recent call last):
|
|
2348
|
+
...
|
|
2349
|
+
ValueError: [4] is not a 4-core
|
|
2350
|
+
|
|
2351
|
+
sage: StrongTableau([[-1, -2], [2]], 3)
|
|
2352
|
+
Traceback (most recent call last):
|
|
2353
|
+
...
|
|
2354
|
+
ValueError: The marks in [[-1, -2], [2]] are not correctly placed.
|
|
2355
|
+
|
|
2356
|
+
sage: StrongTableau([[None, None, None], [None]], 3)
|
|
2357
|
+
Traceback (most recent call last):
|
|
2358
|
+
...
|
|
2359
|
+
ValueError: [3, 1] is not a 4-core
|
|
2360
|
+
|
|
2361
|
+
sage: StrongTableau([[None, -1, 2], [-2]], 2, [2])
|
|
2362
|
+
Traceback (most recent call last):
|
|
2363
|
+
...
|
|
2364
|
+
ValueError: The weight=(2,) and the markings on the standard tableau=[[None, -1, 2], [-2]] do not agree.
|
|
2365
|
+
"""
|
|
2366
|
+
if isinstance(T, cls):
|
|
2367
|
+
return T
|
|
2368
|
+
outer_shape = Core([len(t) for t in T], k + 1)
|
|
2369
|
+
loop = (row.count(None) for row in T)
|
|
2370
|
+
inner_shape = Core([x for x in loop if x], k + 1)
|
|
2371
|
+
Te = [v for row in T for v in row if v is not None] + [0]
|
|
2372
|
+
count_marks = tuple(Te.count(-(i+1)) for i in range(-min(Te)))
|
|
2373
|
+
if not all(v == 1 for v in count_marks):
|
|
2374
|
+
# if T is not standard -> turn into standard
|
|
2375
|
+
if weight is not None and tuple(weight) != count_marks:
|
|
2376
|
+
raise ValueError("Weight = %s and tableau = %s do not agree" % (weight, T))
|
|
2377
|
+
tijseq = StrongTableaux.marked_CST_to_transposition_sequence(T, k)
|
|
2378
|
+
if tijseq is None or len(tijseq) < sum(list(count_marks)):
|
|
2379
|
+
raise ValueError("Unable to parse strong marked tableau : %s" % T)
|
|
2380
|
+
T = StrongTableaux.transpositions_to_standard_strong( tijseq, k, [[None]*r for r in inner_shape] ) # build from scratch
|
|
2381
|
+
T = T.set_weight( count_marks )
|
|
2382
|
+
return T
|
|
2383
|
+
else:
|
|
2384
|
+
if weight is not None:
|
|
2385
|
+
count_marks = tuple(weight) # in the case that it is standard + weight
|
|
2386
|
+
return StrongTableaux.__classcall__(StrongTableaux, k, (outer_shape, inner_shape), count_marks)(T)
|
|
2387
|
+
|
|
2388
|
+
def check(self):
|
|
2389
|
+
r"""
|
|
2390
|
+
Check that ``self`` is a valid strong `k`-tableau.
|
|
2391
|
+
|
|
2392
|
+
This function verifies that the outer and inner shape of the parent class is equal to
|
|
2393
|
+
the outer and inner shape of the tableau, that the tableau portion of ``self`` is
|
|
2394
|
+
a valid standard tableau, that the marks are placed correctly and that the size
|
|
2395
|
+
and weight agree.
|
|
2396
|
+
|
|
2397
|
+
EXAMPLES::
|
|
2398
|
+
|
|
2399
|
+
sage: T = StrongTableau([[-1, -1, -2], [2]], 2)
|
|
2400
|
+
sage: T.check()
|
|
2401
|
+
sage: T = StrongTableau([[None, None, 2, -4, -4], [-1, 4], [-2]], 3)
|
|
2402
|
+
sage: T.check()
|
|
2403
|
+
|
|
2404
|
+
TESTS::
|
|
2405
|
+
|
|
2406
|
+
sage: ST = StrongTableaux(2, [3,1], [1,1,1,1])
|
|
2407
|
+
sage: ST([[-1,-2,3],[-3]])
|
|
2408
|
+
Traceback (most recent call last):
|
|
2409
|
+
...
|
|
2410
|
+
ValueError: The size of the tableau [[-1, -2, 3], [-3]] and weight (1, 1, 1, 1) do not match
|
|
2411
|
+
sage: ST([[-1,-3],[-2],[3]])
|
|
2412
|
+
Traceback (most recent call last):
|
|
2413
|
+
...
|
|
2414
|
+
ValueError: The outer shape of the parent does not agree with the outer shape of the tableau!
|
|
2415
|
+
|
|
2416
|
+
sage: StrongTableau([[-1, -2, 2], [1]], 2)
|
|
2417
|
+
Traceback (most recent call last):
|
|
2418
|
+
...
|
|
2419
|
+
ValueError: The marks in [[-1, -2, 2], [1]] are not correctly placed.
|
|
2420
|
+
|
|
2421
|
+
sage: StrongTableau([[-1, -2, 3], [3]], 2)
|
|
2422
|
+
Traceback (most recent call last):
|
|
2423
|
+
...
|
|
2424
|
+
ValueError: The marks in [[-1, -2, 3], [3]] are not correctly placed.
|
|
2425
|
+
|
|
2426
|
+
sage: StrongTableau([[-1,-2,-4,7],[-3,6,-6,8],[4,-7],[-5,-8]], 3, [2,2,3,1])
|
|
2427
|
+
Traceback (most recent call last):
|
|
2428
|
+
...
|
|
2429
|
+
ValueError: The weight=(2, 2, 3, 1) and the markings on the standard tableau=[[-1, -2, -4, 7], [-3, 6, -6, 8], [4, -7], [-5, -8]] do not agree.
|
|
2430
|
+
"""
|
|
2431
|
+
T = SkewTableau(self.to_standard_list())
|
|
2432
|
+
outer = Core(T.outer_shape(),self.k+1)
|
|
2433
|
+
inner = Core(T.inner_shape(),self.k+1)
|
|
2434
|
+
if self.parent()._outer_shape != outer:
|
|
2435
|
+
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
|
|
2436
|
+
if self.parent()._inner_shape != inner:
|
|
2437
|
+
raise ValueError("The inner shape of the parent does not agree with the inner shape of the tableau!")
|
|
2438
|
+
if not self._is_valid_marked():
|
|
2439
|
+
raise ValueError("The marks in %s are not correctly placed." % (self.to_standard_list()))
|
|
2440
|
+
if not self._is_valid_standard():
|
|
2441
|
+
raise ValueError("At least one shape in %s is not a valid %s-core." % (self.to_standard_list(), self.k+1))
|
|
2442
|
+
if not self.outer_shape().length()-self.inner_shape().length() == self.size():
|
|
2443
|
+
raise ValueError("The size of the tableau %s and weight %s do not match" % (self.to_standard_list(),self.weight()))
|
|
2444
|
+
if not self.is_column_strict_with_weight( self.weight() ):
|
|
2445
|
+
raise ValueError("The weight=%s and the markings on the standard tableau=%s do not agree." % (self.weight(),self.to_standard_list()))
|
|
2446
|
+
|
|
2447
|
+
def __hash__(self):
|
|
2448
|
+
r"""
|
|
2449
|
+
Return the hash of ``self``.
|
|
2450
|
+
|
|
2451
|
+
EXAMPLES::
|
|
2452
|
+
|
|
2453
|
+
sage: t = StrongTableau([[-1, -1, -2], [2]], 2)
|
|
2454
|
+
sage: hash(t) == hash(t)
|
|
2455
|
+
True
|
|
2456
|
+
"""
|
|
2457
|
+
return hash(tuple(tuple(x) for x in self)) + hash(self.parent().k)
|
|
2458
|
+
|
|
2459
|
+
def _is_valid_marked( self ):
|
|
2460
|
+
r"""
|
|
2461
|
+
Check the validity of marks of a potential tableau ``self``.
|
|
2462
|
+
|
|
2463
|
+
This method is called by method :meth:`check` and is not meant to be
|
|
2464
|
+
accessed by the user.
|
|
2465
|
+
|
|
2466
|
+
This method first checks that there is one marked cell for the size of the
|
|
2467
|
+
tableau. Then, for each marked cell, it verifies that the cell below and to the
|
|
2468
|
+
right is not a positive value.
|
|
2469
|
+
|
|
2470
|
+
In other words this checks that the marked cells are at the head of the connected
|
|
2471
|
+
components. This function verifies that the markings of ``self`` are
|
|
2472
|
+
consistent with a strong marked standard tableau.
|
|
2473
|
+
|
|
2474
|
+
INPUT:
|
|
2475
|
+
|
|
2476
|
+
- ``self`` -- list of lists representing a potential *standard* marked tableau
|
|
2477
|
+
|
|
2478
|
+
OUTPUT: boolean; ``True`` if the marks are properly placed in the tableau
|
|
2479
|
+
|
|
2480
|
+
EXAMPLES::
|
|
2481
|
+
|
|
2482
|
+
sage: all( T._is_valid_marked() for T in StrongTableaux.standard_marked_iterator(3, 6))
|
|
2483
|
+
True
|
|
2484
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)._is_valid_marked()
|
|
2485
|
+
True
|
|
2486
|
+
sage: StrongTableau([[-1, -2, 3], [3]], 2)
|
|
2487
|
+
Traceback (most recent call last):
|
|
2488
|
+
...
|
|
2489
|
+
ValueError: The marks in [[-1, -2, 3], [3]] are not correctly placed.
|
|
2490
|
+
|
|
2491
|
+
Marking in the wrong place::
|
|
2492
|
+
|
|
2493
|
+
sage: StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [-2], [2], [3]], 4)
|
|
2494
|
+
Traceback (most recent call last):
|
|
2495
|
+
...
|
|
2496
|
+
ValueError: The marks in [[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [-2], [2], [3]] are not correctly placed.
|
|
2497
|
+
|
|
2498
|
+
No marking on a 2::
|
|
2499
|
+
|
|
2500
|
+
sage: StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [2], [2], [3]], 4)
|
|
2501
|
+
Traceback (most recent call last):
|
|
2502
|
+
...
|
|
2503
|
+
ValueError: Unable to parse strong marked tableau : [[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [2], [2], [3]]
|
|
2504
|
+
|
|
2505
|
+
TESTS::
|
|
2506
|
+
|
|
2507
|
+
sage: StrongTableau([[None, None, None], [None]], 2)._is_valid_marked()
|
|
2508
|
+
True
|
|
2509
|
+
sage: StrongTableau([], 4)._is_valid_marked()
|
|
2510
|
+
True
|
|
2511
|
+
"""
|
|
2512
|
+
T = self.to_standard_list()
|
|
2513
|
+
size = Core([len(t) for t in T], self.k+1).length()
|
|
2514
|
+
inner_size = Core([y for y in (len([x for x in row if x is None]) for row in T) if y > 0], self.k+1).length()
|
|
2515
|
+
if len(set(v for v in flatten(list(T)) if v in ZZ and v < 0)) != size - inner_size:
|
|
2516
|
+
return False # TT does not have exactly self.size() marked cells
|
|
2517
|
+
for i in range(len(T)):
|
|
2518
|
+
for j in range(len(T[i])):
|
|
2519
|
+
v = T[i][j]
|
|
2520
|
+
if v is not None and v < 0 and ((i != 0 and T[i-1][j] == abs(v)) or (j < len(T[i])-1 and T[i][j+1] == abs(v))):
|
|
2521
|
+
return False
|
|
2522
|
+
return True
|
|
2523
|
+
|
|
2524
|
+
def _is_valid_standard( self ):
|
|
2525
|
+
r"""
|
|
2526
|
+
Test if ``self`` has a valid strong (un)marked standard part of the tableau.
|
|
2527
|
+
|
|
2528
|
+
This method is called by method :meth:`check` and is not meant to be
|
|
2529
|
+
accessed by the user.
|
|
2530
|
+
|
|
2531
|
+
This methods returns ``True`` if every intermediate shape (restricted to values
|
|
2532
|
+
less than or equal to `i` for each `i`) is a `k+1`-core and that the length
|
|
2533
|
+
of the `i+1`-restricted core is the length of the `i`-restricted core plus 1.
|
|
2534
|
+
|
|
2535
|
+
OUTPUT: boolean; ``True`` means the standard strong marked tableau is valid
|
|
2536
|
+
|
|
2537
|
+
EXAMPLES::
|
|
2538
|
+
|
|
2539
|
+
sage: all( T._is_valid_standard() for T in StrongTableaux.standard_marked_iterator(4, 6))
|
|
2540
|
+
True
|
|
2541
|
+
|
|
2542
|
+
Inner shape is not a 3-core::
|
|
2543
|
+
|
|
2544
|
+
sage: StrongTableau([[None, None, None], [-1]], 2)
|
|
2545
|
+
Traceback (most recent call last):
|
|
2546
|
+
...
|
|
2547
|
+
ValueError: [3] is not a 3-core
|
|
2548
|
+
|
|
2549
|
+
Restrict to 1 and 2 is not a 5-core::
|
|
2550
|
+
|
|
2551
|
+
sage: StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [-2], [2], [3], [3]], 4)
|
|
2552
|
+
Traceback (most recent call last):
|
|
2553
|
+
...
|
|
2554
|
+
ValueError: At least one shape in [[None, None, -4, 5, -5], [None, None], [-1, -3], [-2], [2], [3], [3]] is not a valid 5-core.
|
|
2555
|
+
|
|
2556
|
+
TESTS::
|
|
2557
|
+
|
|
2558
|
+
sage: StrongTableau([[None, None, None], [None]], 2)._is_valid_standard()
|
|
2559
|
+
True
|
|
2560
|
+
sage: StrongTableau([], 4)._is_valid_standard()
|
|
2561
|
+
True
|
|
2562
|
+
"""
|
|
2563
|
+
Tshapes = intermediate_shapes(self.to_unmarked_standard_list())
|
|
2564
|
+
if not all(Partition(la).is_core(self.k + 1) for la in Tshapes):
|
|
2565
|
+
return False
|
|
2566
|
+
Tsizes = [Core(lam, self.k + 1).length() for lam in Tshapes]
|
|
2567
|
+
return all(Tsizes[i] == Tsizes[i+1]-1 for i in range(len(Tsizes)-1))
|
|
2568
|
+
|
|
2569
|
+
def is_column_strict_with_weight( self, mu ):
|
|
2570
|
+
"""
|
|
2571
|
+
Test if ``self`` is a column strict tableau with respect to the weight ``mu``.
|
|
2572
|
+
|
|
2573
|
+
INPUT:
|
|
2574
|
+
|
|
2575
|
+
- ``mu`` -- a vector of weights
|
|
2576
|
+
|
|
2577
|
+
OUTPUT: boolean; ``True`` means the underlying column strict strong
|
|
2578
|
+
marked tableau is valid
|
|
2579
|
+
|
|
2580
|
+
EXAMPLES::
|
|
2581
|
+
|
|
2582
|
+
sage: StrongTableau([[-1, -2, -3], [3]], 2).is_column_strict_with_weight([3])
|
|
2583
|
+
True
|
|
2584
|
+
sage: StrongTableau([[-1, -2, 3], [-3]], 2).is_column_strict_with_weight([3])
|
|
2585
|
+
False
|
|
2586
|
+
|
|
2587
|
+
TESTS::
|
|
2588
|
+
|
|
2589
|
+
sage: StrongTableau([[None, None, None], [None]], 2).is_column_strict_with_weight([])
|
|
2590
|
+
True
|
|
2591
|
+
sage: StrongTableau([], 4).is_column_strict_with_weight([])
|
|
2592
|
+
True
|
|
2593
|
+
"""
|
|
2594
|
+
ss = 0
|
|
2595
|
+
for i in range(len(mu)):
|
|
2596
|
+
for j in range(mu[i]-1):
|
|
2597
|
+
# the markings should move from left to right
|
|
2598
|
+
if self.content_of_marked_head( ss+j+1 ) >= self.content_of_marked_head( ss+j+2 ):
|
|
2599
|
+
return False
|
|
2600
|
+
ss += mu[i]
|
|
2601
|
+
return True
|
|
2602
|
+
|
|
2603
|
+
def _repr_diagram(self):
|
|
2604
|
+
r"""
|
|
2605
|
+
Return a string representing the pretty print of the tableau.
|
|
2606
|
+
|
|
2607
|
+
EXAMPLES::
|
|
2608
|
+
|
|
2609
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])._repr_diagram()
|
|
2610
|
+
' -1 -1 -2 -3\n -2 3 -3 4\n 2 3\n -3 -4'
|
|
2611
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)._repr_diagram()
|
|
2612
|
+
' . . -1 -2\n . .\n -1 -2\n 1 2\n -3\n 3\n 3\n 3'
|
|
2613
|
+
sage: StrongTableau([], 4)._repr_diagram()
|
|
2614
|
+
''
|
|
2615
|
+
"""
|
|
2616
|
+
return SkewTableau(self.to_list())._repr_diagram()
|
|
2617
|
+
|
|
2618
|
+
def _repr_list(self):
|
|
2619
|
+
r"""
|
|
2620
|
+
Return a string representing the list of lists of the tableau.
|
|
2621
|
+
|
|
2622
|
+
EXAMPLES::
|
|
2623
|
+
|
|
2624
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])._repr_list()
|
|
2625
|
+
'[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]]'
|
|
2626
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)._repr_list()
|
|
2627
|
+
'[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]'
|
|
2628
|
+
sage: StrongTableau([], 4)._repr_list()
|
|
2629
|
+
'[]'
|
|
2630
|
+
"""
|
|
2631
|
+
return repr(self.to_list())
|
|
2632
|
+
|
|
2633
|
+
def _repr_compact(self):
|
|
2634
|
+
"""
|
|
2635
|
+
Return a compact string representation of ``self``.
|
|
2636
|
+
|
|
2637
|
+
EXAMPLES::
|
|
2638
|
+
|
|
2639
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])._repr_compact()
|
|
2640
|
+
'-1,-1,-2,-3/-2,3,-3,4/2,3/-3,-4'
|
|
2641
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)._repr_compact()
|
|
2642
|
+
'.,.,-1,-2/.,./-1,-2/1,2/-3/3/3/3'
|
|
2643
|
+
sage: StrongTableau([],4)._repr_compact()
|
|
2644
|
+
'-'
|
|
2645
|
+
"""
|
|
2646
|
+
return SkewTableau(self.to_list())._repr_compact()
|
|
2647
|
+
|
|
2648
|
+
def _repr_(self):
|
|
2649
|
+
r"""
|
|
2650
|
+
Return a representation of ``self``.
|
|
2651
|
+
|
|
2652
|
+
To display a strong marked tableau we display the semistandard version.
|
|
2653
|
+
|
|
2654
|
+
EXAMPLES::
|
|
2655
|
+
|
|
2656
|
+
sage: StrongTableau( [[-1, -2, -3]], 3 )
|
|
2657
|
+
[[-1, -2, -3]]
|
|
2658
|
+
sage: StrongTableau( [[-1, -2, -3]], 3 , weight=[3])
|
|
2659
|
+
[[-1, -1, -1]]
|
|
2660
|
+
sage: StrongTableau( [], 3 )
|
|
2661
|
+
[]
|
|
2662
|
+
sage: T = StrongTableau([[-1,-2,3],[-3]],2)
|
|
2663
|
+
sage: T
|
|
2664
|
+
[[-1, -2, 3], [-3]]
|
|
2665
|
+
sage: Tableaux.options(display='diagram')
|
|
2666
|
+
sage: T
|
|
2667
|
+
-1 -2 3
|
|
2668
|
+
-3
|
|
2669
|
+
sage: Tableaux.options(convention='French')
|
|
2670
|
+
sage: T
|
|
2671
|
+
-3
|
|
2672
|
+
-1 -2 3
|
|
2673
|
+
sage: Tableaux.options(display='compact')
|
|
2674
|
+
sage: T
|
|
2675
|
+
-1,-2,3/-3
|
|
2676
|
+
sage: Tableaux.options(display='list',convention='English')
|
|
2677
|
+
"""
|
|
2678
|
+
return self.parent().options._dispatch(self, '_repr_', 'display')
|
|
2679
|
+
|
|
2680
|
+
def cell_of_marked_head(self, v):
|
|
2681
|
+
r"""
|
|
2682
|
+
Return location of marked head labeled by ``v`` in the standard part of ``self``.
|
|
2683
|
+
|
|
2684
|
+
Return the coordinates of the ``v``-th marked cell in the strong standard tableau
|
|
2685
|
+
``self``. If there is no mark, then the value returned is `(0, r)` where `r` is
|
|
2686
|
+
the length of the first row.
|
|
2687
|
+
|
|
2688
|
+
INPUT:
|
|
2689
|
+
|
|
2690
|
+
- ``v`` -- integer representing the label in the standard tableau
|
|
2691
|
+
|
|
2692
|
+
OUTPUT: a pair of the coordinates of the marked cell with entry ``v``
|
|
2693
|
+
|
|
2694
|
+
EXAMPLES::
|
|
2695
|
+
|
|
2696
|
+
sage: T = StrongTableau([[-1, -3, 4, -5], [-2], [-4]], 3)
|
|
2697
|
+
sage: [ T.cell_of_marked_head(i) for i in range(1,7)]
|
|
2698
|
+
[(0, 0), (1, 0), (0, 1), (2, 0), (0, 3), (0, 4)]
|
|
2699
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
2700
|
+
sage: [ T.cell_of_marked_head(i) for i in range(1,7)]
|
|
2701
|
+
[(2, 0), (0, 2), (2, 1), (0, 3), (4, 0), (0, 4)]
|
|
2702
|
+
|
|
2703
|
+
TESTS::
|
|
2704
|
+
|
|
2705
|
+
sage: StrongTableau([],4).cell_of_marked_head(4)
|
|
2706
|
+
(0, 0)
|
|
2707
|
+
"""
|
|
2708
|
+
T = self.to_standard_list()
|
|
2709
|
+
if T == []:
|
|
2710
|
+
return (0,0)
|
|
2711
|
+
for i in range(len(T)):
|
|
2712
|
+
for j in range(len(T[i])):
|
|
2713
|
+
if T[i][j] == -v:
|
|
2714
|
+
return (i,j)
|
|
2715
|
+
return (0,len(T[0]))
|
|
2716
|
+
|
|
2717
|
+
def content_of_marked_head(self, v):
|
|
2718
|
+
r"""
|
|
2719
|
+
Return the diagonal of the marked label ``v`` in the standard part of ``self``.
|
|
2720
|
+
|
|
2721
|
+
Return the content (the `j-i` coordinate of the cell) of the ``v``-th marked cell
|
|
2722
|
+
in the strong standard tableau ``self``. If there is no mark, then the value
|
|
2723
|
+
returned is the size of first row.
|
|
2724
|
+
|
|
2725
|
+
INPUT:
|
|
2726
|
+
|
|
2727
|
+
- ``v`` -- integer representing the label in the standard tableau
|
|
2728
|
+
|
|
2729
|
+
OUTPUT: integer representing the residue of the location of the mark
|
|
2730
|
+
|
|
2731
|
+
EXAMPLES::
|
|
2732
|
+
|
|
2733
|
+
sage: [ StrongTableau([[-1, -3, 4, -5], [-2], [-4]], 3).content_of_marked_head(i) for i in range(1,7)]
|
|
2734
|
+
[0, -1, 1, -2, 3, 4]
|
|
2735
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
2736
|
+
sage: [ T.content_of_marked_head(i) for i in range(1,7)]
|
|
2737
|
+
[-2, 2, -1, 3, -4, 4]
|
|
2738
|
+
|
|
2739
|
+
TESTS::
|
|
2740
|
+
|
|
2741
|
+
sage: StrongTableau([],4).content_of_marked_head(4)
|
|
2742
|
+
0
|
|
2743
|
+
"""
|
|
2744
|
+
c = self.cell_of_marked_head(v)
|
|
2745
|
+
return c[1]-c[0]
|
|
2746
|
+
|
|
2747
|
+
def cells_of_marked_ribbon(self, v):
|
|
2748
|
+
r"""
|
|
2749
|
+
Return a list of all cells the marked ribbon labeled by ``v`` in the standard part of ``self``.
|
|
2750
|
+
|
|
2751
|
+
Return the list of coordinates of the cells which are in the marked
|
|
2752
|
+
ribbon with label ``v`` in the standard part of the tableau. Note that
|
|
2753
|
+
the result is independent of the weight of the tableau.
|
|
2754
|
+
|
|
2755
|
+
The cells are listed from largest content (where the mark is located)
|
|
2756
|
+
to the smallest. Hence, the first entry in this list will be the marked cell.
|
|
2757
|
+
|
|
2758
|
+
INPUT:
|
|
2759
|
+
|
|
2760
|
+
- ``v`` -- the entry of the standard tableau
|
|
2761
|
+
|
|
2762
|
+
OUTPUT:
|
|
2763
|
+
|
|
2764
|
+
- a list of pairs representing the coordinates of the cells of
|
|
2765
|
+
the marked ribbon
|
|
2766
|
+
|
|
2767
|
+
EXAMPLES::
|
|
2768
|
+
|
|
2769
|
+
sage: T = StrongTableau([[-1, -1, -2, -2, 3], [2, -3], [-3]],3)
|
|
2770
|
+
sage: T.to_standard_list()
|
|
2771
|
+
[[-1, -2, -3, -4, 6], [4, -6], [-5]]
|
|
2772
|
+
sage: T.cells_of_marked_ribbon(1)
|
|
2773
|
+
[(0, 0)]
|
|
2774
|
+
sage: T.cells_of_marked_ribbon(4)
|
|
2775
|
+
[(0, 3)]
|
|
2776
|
+
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)
|
|
2777
|
+
sage: T.cells_of_marked_ribbon(6)
|
|
2778
|
+
[(1, 2), (1, 1)]
|
|
2779
|
+
sage: T.cells_of_marked_ribbon(9)
|
|
2780
|
+
[]
|
|
2781
|
+
sage: T = StrongTableau([[None, None, -1, -1, 3], [1, -3], [-3]],3)
|
|
2782
|
+
sage: T.to_standard_list()
|
|
2783
|
+
[[None, None, -1, -2, 4], [2, -4], [-3]]
|
|
2784
|
+
sage: T.cells_of_marked_ribbon(1)
|
|
2785
|
+
[(0, 2)]
|
|
2786
|
+
|
|
2787
|
+
TESTS::
|
|
2788
|
+
|
|
2789
|
+
sage: StrongTableau([],3).cells_of_marked_ribbon(1)
|
|
2790
|
+
[]
|
|
2791
|
+
"""
|
|
2792
|
+
d = self.content_of_marked_head(v)
|
|
2793
|
+
T = SkewTableau(self.to_unmarked_standard_list())
|
|
2794
|
+
cells = []
|
|
2795
|
+
while d is not None:
|
|
2796
|
+
adt = [c for c in T.cells_by_content(d) if T[c[0]][c[1]] == v]
|
|
2797
|
+
if adt == []:
|
|
2798
|
+
d = None
|
|
2799
|
+
else:
|
|
2800
|
+
d -= 1
|
|
2801
|
+
cells += adt
|
|
2802
|
+
return cells
|
|
2803
|
+
|
|
2804
|
+
def cell_of_highest_head( self, v ):
|
|
2805
|
+
"""
|
|
2806
|
+
Return the cell of the highest head of label ``v`` in the standard part of ``self``.
|
|
2807
|
+
|
|
2808
|
+
Return the cell where the head of the ribbon in the highest row is located
|
|
2809
|
+
in the underlying standard tableau. If there is no cell with entry ``v`` then
|
|
2810
|
+
the cell returned is `(0, r)` where `r` is the length of the first row.
|
|
2811
|
+
|
|
2812
|
+
This cell is calculated by iterating through the diagonals of the tableau.
|
|
2813
|
+
|
|
2814
|
+
INPUT:
|
|
2815
|
+
|
|
2816
|
+
- ``v`` -- integer indicating the label in the standard tableau
|
|
2817
|
+
|
|
2818
|
+
OUTPUT: a pair of integers indicating the coordinates of the head of
|
|
2819
|
+
the highest ribbon with label ``v``
|
|
2820
|
+
|
|
2821
|
+
EXAMPLES::
|
|
2822
|
+
|
|
2823
|
+
sage: T = StrongTableau([[-1,2,-3],[-2,3],[3]], 1)
|
|
2824
|
+
sage: [T.cell_of_highest_head(v) for v in range(1,5)]
|
|
2825
|
+
[(0, 0), (1, 0), (2, 0), (0, 3)]
|
|
2826
|
+
sage: T = StrongTableau([[None,None,-3,4],[3,-4]],2)
|
|
2827
|
+
sage: [T.cell_of_highest_head(v) for v in range(1,5)]
|
|
2828
|
+
[(1, 0), (1, 1), (0, 4), (0, 4)]
|
|
2829
|
+
|
|
2830
|
+
TESTS::
|
|
2831
|
+
|
|
2832
|
+
sage: StrongTableau([],2).cell_of_highest_head(1)
|
|
2833
|
+
(0, 0)
|
|
2834
|
+
"""
|
|
2835
|
+
Tlist = SkewTableau(self.to_standard_list())
|
|
2836
|
+
if Tlist == []:
|
|
2837
|
+
return (0, 0)
|
|
2838
|
+
r = len(Tlist[0])
|
|
2839
|
+
dout = (0, r)
|
|
2840
|
+
for d in range(-len(Tlist),r+1):
|
|
2841
|
+
for c in Tlist.cells_by_content(d):
|
|
2842
|
+
if nabs(Tlist[c[0]][c[1]]) == v:
|
|
2843
|
+
dout = c
|
|
2844
|
+
if dout != (0, r) and dout[1]-dout[0] != d:
|
|
2845
|
+
return dout
|
|
2846
|
+
return dout
|
|
2847
|
+
|
|
2848
|
+
def content_of_highest_head( self, v ):
|
|
2849
|
+
r"""
|
|
2850
|
+
Return the diagonal of the highest head of the cells labeled ``v`` in the standard part of ``self``.
|
|
2851
|
+
|
|
2852
|
+
Return the content of the cell of the head in the highest row of all ribbons labeled by ``v`` of
|
|
2853
|
+
the underlying standard tableau. If there is no cell with entry ``v`` then
|
|
2854
|
+
the value returned is the length of the first row.
|
|
2855
|
+
|
|
2856
|
+
INPUT:
|
|
2857
|
+
|
|
2858
|
+
- ``v`` -- integer representing the label in the standard tableau
|
|
2859
|
+
|
|
2860
|
+
OUTPUT: an integer representing the content of the head of the highest
|
|
2861
|
+
ribbon with label ``v``
|
|
2862
|
+
|
|
2863
|
+
EXAMPLES::
|
|
2864
|
+
|
|
2865
|
+
sage: [StrongTableau([[-1,2,-3],[-2,3],[3]], 1).content_of_highest_head(v) for v in range(1,5)]
|
|
2866
|
+
[0, -1, -2, 3]
|
|
2867
|
+
|
|
2868
|
+
TESTS::
|
|
2869
|
+
|
|
2870
|
+
sage: StrongTableau([], 4).content_of_highest_head(1)
|
|
2871
|
+
0
|
|
2872
|
+
sage: StrongTableau([[-1,-1]], 4).content_of_highest_head(3)
|
|
2873
|
+
2
|
|
2874
|
+
"""
|
|
2875
|
+
c = self.cell_of_highest_head(v)
|
|
2876
|
+
return c[1]-c[0]
|
|
2877
|
+
|
|
2878
|
+
def cells_head_dictionary(self):
|
|
2879
|
+
r"""
|
|
2880
|
+
Return a dictionary with the locations of the heads of all markings.
|
|
2881
|
+
|
|
2882
|
+
Return a dictionary of values and lists of cells where the heads with the values
|
|
2883
|
+
are located.
|
|
2884
|
+
|
|
2885
|
+
OUTPUT:
|
|
2886
|
+
|
|
2887
|
+
- a dictionary with keys the entries in the tableau and values are the coordinates
|
|
2888
|
+
of the heads with those entries
|
|
2889
|
+
|
|
2890
|
+
EXAMPLES::
|
|
2891
|
+
|
|
2892
|
+
sage: T = StrongTableau([[-1,-2,-4,7],[-3,6,-6,8],[4,-7],[-5,-8]], 3)
|
|
2893
|
+
sage: T.cells_head_dictionary()
|
|
2894
|
+
{1: [(0, 0)],
|
|
2895
|
+
2: [(0, 1)],
|
|
2896
|
+
3: [(1, 0)],
|
|
2897
|
+
4: [(2, 0), (0, 2)],
|
|
2898
|
+
5: [(3, 0)],
|
|
2899
|
+
6: [(1, 2)],
|
|
2900
|
+
7: [(2, 1), (0, 3)],
|
|
2901
|
+
8: [(3, 1), (1, 3)]}
|
|
2902
|
+
sage: T = StrongTableau([[None, 4, -4, -6, -7, 8, 8, -8], [None, -5, 8, 8, 8], [-3, 6]],3)
|
|
2903
|
+
sage: T.cells_head_dictionary()
|
|
2904
|
+
{1: [(2, 0)],
|
|
2905
|
+
2: [(0, 2)],
|
|
2906
|
+
3: [(1, 1)],
|
|
2907
|
+
4: [(2, 1), (0, 3)],
|
|
2908
|
+
5: [(0, 4)],
|
|
2909
|
+
6: [(1, 4), (0, 7)]}
|
|
2910
|
+
sage: StrongTableau([[None, None], [None, -1]], 4).cells_head_dictionary()
|
|
2911
|
+
{1: [(1, 1)]}
|
|
2912
|
+
|
|
2913
|
+
TESTS::
|
|
2914
|
+
|
|
2915
|
+
sage: StrongTableau([[None, None], [None]], 4).cells_head_dictionary()
|
|
2916
|
+
{}
|
|
2917
|
+
sage: StrongTableau([],4).cells_head_dictionary()
|
|
2918
|
+
{}
|
|
2919
|
+
"""
|
|
2920
|
+
return StrongTableaux.cells_head_dictionary(self.to_unmarked_standard_list())
|
|
2921
|
+
|
|
2922
|
+
def cells_of_heads(self, v):
|
|
2923
|
+
r"""
|
|
2924
|
+
Return a list of cells of the heads with label ``v`` in the standard part of ``self``.
|
|
2925
|
+
|
|
2926
|
+
A list of cells which are heads of the ribbons with label ``v`` in the
|
|
2927
|
+
standard part of the tableau ``self``. If there is no cell labelled by ``v`` then return the empty
|
|
2928
|
+
list.
|
|
2929
|
+
|
|
2930
|
+
INPUT:
|
|
2931
|
+
|
|
2932
|
+
- ``v`` -- integer label
|
|
2933
|
+
|
|
2934
|
+
OUTPUT: a list of pairs of integers of the coordinates of the heads of
|
|
2935
|
+
the ribbons with label ``v``
|
|
2936
|
+
|
|
2937
|
+
EXAMPLES::
|
|
2938
|
+
|
|
2939
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
2940
|
+
sage: T.cells_of_heads(1)
|
|
2941
|
+
[(2, 0)]
|
|
2942
|
+
sage: T.cells_of_heads(2)
|
|
2943
|
+
[(3, 0), (0, 2)]
|
|
2944
|
+
sage: T.cells_of_heads(3)
|
|
2945
|
+
[(2, 1)]
|
|
2946
|
+
sage: T.cells_of_heads(4)
|
|
2947
|
+
[(3, 1), (0, 3)]
|
|
2948
|
+
sage: T.cells_of_heads(5)
|
|
2949
|
+
[(4, 0)]
|
|
2950
|
+
sage: T.cells_of_heads(6)
|
|
2951
|
+
[]
|
|
2952
|
+
|
|
2953
|
+
TESTS::
|
|
2954
|
+
|
|
2955
|
+
sage: StrongTableau([[None, None], [None]], 4).cells_of_heads(1)
|
|
2956
|
+
[]
|
|
2957
|
+
sage: StrongTableau([],4).cells_of_heads(1)
|
|
2958
|
+
[]
|
|
2959
|
+
"""
|
|
2960
|
+
dout = self.cells_head_dictionary()
|
|
2961
|
+
if v in dout:
|
|
2962
|
+
return dout[v]
|
|
2963
|
+
else:
|
|
2964
|
+
return []
|
|
2965
|
+
|
|
2966
|
+
def contents_of_heads(self, v):
|
|
2967
|
+
r"""
|
|
2968
|
+
A list of contents of the cells which are heads of the ribbons with label ``v``.
|
|
2969
|
+
|
|
2970
|
+
If there is no cell labelled by ``v`` then return the empty list.
|
|
2971
|
+
|
|
2972
|
+
INPUT:
|
|
2973
|
+
|
|
2974
|
+
- ``v`` -- integer label
|
|
2975
|
+
|
|
2976
|
+
OUTPUT: list of integers of the content of the heads of the ribbons
|
|
2977
|
+
with label ``v``
|
|
2978
|
+
|
|
2979
|
+
EXAMPLES::
|
|
2980
|
+
|
|
2981
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
2982
|
+
sage: T.contents_of_heads(1)
|
|
2983
|
+
[-2]
|
|
2984
|
+
sage: T.contents_of_heads(2)
|
|
2985
|
+
[-3, 2]
|
|
2986
|
+
sage: T.contents_of_heads(3)
|
|
2987
|
+
[-1]
|
|
2988
|
+
sage: T.contents_of_heads(4)
|
|
2989
|
+
[-2, 3]
|
|
2990
|
+
sage: T.contents_of_heads(5)
|
|
2991
|
+
[-4]
|
|
2992
|
+
sage: T.contents_of_heads(6)
|
|
2993
|
+
[]
|
|
2994
|
+
|
|
2995
|
+
TESTS::
|
|
2996
|
+
|
|
2997
|
+
sage: StrongTableau([[None, None], [None]], 4).contents_of_heads(1)
|
|
2998
|
+
[]
|
|
2999
|
+
sage: StrongTableau([],4).contents_of_heads(1)
|
|
3000
|
+
[]
|
|
3001
|
+
"""
|
|
3002
|
+
return [c[1]-c[0] for c in self.cells_of_heads(v)]
|
|
3003
|
+
|
|
3004
|
+
def entries_by_content(self, diag):
|
|
3005
|
+
r"""
|
|
3006
|
+
Return the entries on the diagonal of ``self``.
|
|
3007
|
+
|
|
3008
|
+
Return the entries in the tableau that are in the cells `(i,j)` with
|
|
3009
|
+
`j-i` equal to ``diag`` (that is, with content equal to ``diag``).
|
|
3010
|
+
|
|
3011
|
+
INPUT:
|
|
3012
|
+
|
|
3013
|
+
- ``diag`` -- integer indicating the diagonal
|
|
3014
|
+
|
|
3015
|
+
OUTPUT: list (perhaps empty) of labels on the diagonal ``diag``
|
|
3016
|
+
|
|
3017
|
+
EXAMPLES::
|
|
3018
|
+
|
|
3019
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
3020
|
+
sage: T.entries_by_content(0)
|
|
3021
|
+
[]
|
|
3022
|
+
sage: T.entries_by_content(1)
|
|
3023
|
+
[]
|
|
3024
|
+
sage: T.entries_by_content(2)
|
|
3025
|
+
[-1]
|
|
3026
|
+
sage: T.entries_by_content(-2)
|
|
3027
|
+
[-1, 2]
|
|
3028
|
+
|
|
3029
|
+
TESTS::
|
|
3030
|
+
|
|
3031
|
+
sage: StrongTableau([[None, None], [None]], 4).entries_by_content(1)
|
|
3032
|
+
[]
|
|
3033
|
+
sage: StrongTableau([],4).entries_by_content(1)
|
|
3034
|
+
[]
|
|
3035
|
+
"""
|
|
3036
|
+
return SkewTableau(self.to_list()).entries_by_content(diag)
|
|
3037
|
+
|
|
3038
|
+
def entries_by_content_standard(self, diag):
|
|
3039
|
+
r"""
|
|
3040
|
+
Return the entries on the diagonal of the standard part of ``self``.
|
|
3041
|
+
|
|
3042
|
+
Return the entries in the tableau that are in the cells `(i,j)` with
|
|
3043
|
+
`j-i` equal to ``diag`` (that is, with content equal to ``diag``) in the
|
|
3044
|
+
standard tableau.
|
|
3045
|
+
|
|
3046
|
+
INPUT:
|
|
3047
|
+
|
|
3048
|
+
- ``diag`` -- integer indicating the diagonal
|
|
3049
|
+
|
|
3050
|
+
OUTPUT: list (perhaps empty) of labels on the diagonal ``diag``
|
|
3051
|
+
|
|
3052
|
+
EXAMPLES::
|
|
3053
|
+
|
|
3054
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
3055
|
+
sage: T.entries_by_content_standard(0)
|
|
3056
|
+
[]
|
|
3057
|
+
sage: T.entries_by_content_standard(1)
|
|
3058
|
+
[]
|
|
3059
|
+
sage: T.entries_by_content_standard(2)
|
|
3060
|
+
[-2]
|
|
3061
|
+
sage: T.entries_by_content_standard(-2)
|
|
3062
|
+
[-1, 4]
|
|
3063
|
+
|
|
3064
|
+
TESTS::
|
|
3065
|
+
|
|
3066
|
+
sage: StrongTableau([[None, None], [None]], 4).entries_by_content_standard(1)
|
|
3067
|
+
[]
|
|
3068
|
+
sage: StrongTableau([],4).entries_by_content_standard(1)
|
|
3069
|
+
[]
|
|
3070
|
+
"""
|
|
3071
|
+
return SkewTableau(self.to_standard_list()).entries_by_content(diag)
|
|
3072
|
+
|
|
3073
|
+
def ribbons_above_marked(self, v):
|
|
3074
|
+
r"""
|
|
3075
|
+
Number of ribbons of label ``v`` higher than the marked ribbon in the standard part.
|
|
3076
|
+
|
|
3077
|
+
Return the number of copies of the ribbon with label ``v`` in the standard part
|
|
3078
|
+
of ``self`` which are in a higher row than the marked ribbon. Note that the result
|
|
3079
|
+
is independent of the weight of the tableau.
|
|
3080
|
+
|
|
3081
|
+
INPUT:
|
|
3082
|
+
|
|
3083
|
+
- ``v`` -- the entry of the standard tableau
|
|
3084
|
+
|
|
3085
|
+
OUTPUT:
|
|
3086
|
+
|
|
3087
|
+
- an integer representing the number of copies of the ribbon above the marked
|
|
3088
|
+
ribbon
|
|
3089
|
+
|
|
3090
|
+
EXAMPLES::
|
|
3091
|
+
|
|
3092
|
+
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)
|
|
3093
|
+
sage: T.ribbons_above_marked(4)
|
|
3094
|
+
1
|
|
3095
|
+
sage: T.ribbons_above_marked(6)
|
|
3096
|
+
0
|
|
3097
|
+
sage: T.ribbons_above_marked(9)
|
|
3098
|
+
0
|
|
3099
|
+
sage: StrongTableau([[-1,-2,-3,-4],[2,3,4],[3,4],[4]], 1).ribbons_above_marked(4)
|
|
3100
|
+
3
|
|
3101
|
+
|
|
3102
|
+
TESTS::
|
|
3103
|
+
|
|
3104
|
+
sage: StrongTableau([[None, None], [None]], 4).ribbons_above_marked(1)
|
|
3105
|
+
0
|
|
3106
|
+
sage: StrongTableau([],4).ribbons_above_marked(1)
|
|
3107
|
+
0
|
|
3108
|
+
"""
|
|
3109
|
+
d = self.content_of_marked_head(v)
|
|
3110
|
+
count = 0
|
|
3111
|
+
for i in range(self.k+1, len(self.to_standard_list())+d, self.k+1):
|
|
3112
|
+
count += int(v in self.entries_by_content_standard(d-i))
|
|
3113
|
+
return count
|
|
3114
|
+
|
|
3115
|
+
def height_of_ribbon(self, v):
|
|
3116
|
+
r"""
|
|
3117
|
+
The number of rows occupied by one of the ribbons with label ``v``.
|
|
3118
|
+
|
|
3119
|
+
The number of rows occupied by the marked ribbon with label ``v``
|
|
3120
|
+
(and by consequence the number of rows occupied by any ribbon with the same label)
|
|
3121
|
+
in the standard part of ``self``.
|
|
3122
|
+
|
|
3123
|
+
INPUT:
|
|
3124
|
+
|
|
3125
|
+
- ``v`` -- the label of the standard marked tableau
|
|
3126
|
+
|
|
3127
|
+
OUTPUT: nonnegative integer representing the number of rows
|
|
3128
|
+
occupied by the ribbon which is marked
|
|
3129
|
+
|
|
3130
|
+
EXAMPLES::
|
|
3131
|
+
|
|
3132
|
+
sage: T = StrongTableau([[-1, -1, -2, -2, 3], [2, -3], [-3]],3)
|
|
3133
|
+
sage: T.to_standard_list()
|
|
3134
|
+
[[-1, -2, -3, -4, 6], [4, -6], [-5]]
|
|
3135
|
+
sage: T.height_of_ribbon(1)
|
|
3136
|
+
1
|
|
3137
|
+
sage: T.height_of_ribbon(4)
|
|
3138
|
+
1
|
|
3139
|
+
sage: T = StrongTableau([[None,None,1,-2],[None,-3,4,-5],[-1,3],[-4,5]], 3)
|
|
3140
|
+
sage: T.height_of_ribbon(3)
|
|
3141
|
+
2
|
|
3142
|
+
sage: T.height_of_ribbon(6)
|
|
3143
|
+
0
|
|
3144
|
+
|
|
3145
|
+
TESTS::
|
|
3146
|
+
|
|
3147
|
+
sage: StrongTableau([[None, None], [None]], 4).height_of_ribbon(1)
|
|
3148
|
+
0
|
|
3149
|
+
sage: StrongTableau([],4).height_of_ribbon(1)
|
|
3150
|
+
0
|
|
3151
|
+
"""
|
|
3152
|
+
return len(set(c[0] for c in self.cells_of_marked_ribbon(v)))
|
|
3153
|
+
|
|
3154
|
+
def number_of_connected_components(self, v):
|
|
3155
|
+
r"""
|
|
3156
|
+
Number of connected components of ribbons with label ``v`` in the standard part.
|
|
3157
|
+
|
|
3158
|
+
The number of connected components is calculated by finding the number of cells
|
|
3159
|
+
with label ``v`` in the standard part of the tableau and dividing by the number
|
|
3160
|
+
of cells in the ribbon.
|
|
3161
|
+
|
|
3162
|
+
INPUT:
|
|
3163
|
+
|
|
3164
|
+
- ``v`` -- the label of the standard marked tableau
|
|
3165
|
+
|
|
3166
|
+
OUTPUT: nonnegative integer representing the number of connected
|
|
3167
|
+
components
|
|
3168
|
+
|
|
3169
|
+
EXAMPLES::
|
|
3170
|
+
|
|
3171
|
+
sage: T = StrongTableau([[-1, -1, -2, -2, 3], [2, -3], [-3]],3)
|
|
3172
|
+
sage: T.to_standard_list()
|
|
3173
|
+
[[-1, -2, -3, -4, 6], [4, -6], [-5]]
|
|
3174
|
+
sage: T.number_of_connected_components(1)
|
|
3175
|
+
1
|
|
3176
|
+
sage: T.number_of_connected_components(4)
|
|
3177
|
+
2
|
|
3178
|
+
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)
|
|
3179
|
+
sage: T.number_of_connected_components(6)
|
|
3180
|
+
1
|
|
3181
|
+
sage: T.number_of_connected_components(9)
|
|
3182
|
+
0
|
|
3183
|
+
|
|
3184
|
+
TESTS::
|
|
3185
|
+
|
|
3186
|
+
sage: StrongTableau([[None, None], [None]], 4).number_of_connected_components(1)
|
|
3187
|
+
0
|
|
3188
|
+
sage: StrongTableau([],4).number_of_connected_components(1)
|
|
3189
|
+
0
|
|
3190
|
+
"""
|
|
3191
|
+
sz = len(self.cells_of_marked_ribbon(v))
|
|
3192
|
+
if sz == 0:
|
|
3193
|
+
return 0
|
|
3194
|
+
T = self.to_standard_list()
|
|
3195
|
+
nocells = len([i for i in range(len(T)) for j in range(len(T[i])) if T[i][j] == v])+1
|
|
3196
|
+
return ZZ(nocells/sz)
|
|
3197
|
+
|
|
3198
|
+
def intermediate_shapes(self):
|
|
3199
|
+
r"""
|
|
3200
|
+
Return the intermediate shapes of ``self``.
|
|
3201
|
+
|
|
3202
|
+
A (skew) tableau with letters `1, 2, \ldots, \ell` can be viewed as a sequence of
|
|
3203
|
+
shapes, where the `i`-th shape is given by the shape of the subtableau on letters
|
|
3204
|
+
`1, 2, \ldots, i`.
|
|
3205
|
+
|
|
3206
|
+
The output is the list of these shapes. The marked cells are ignored so to
|
|
3207
|
+
recover the strong tableau one would need the intermediate shapes and the
|
|
3208
|
+
:meth:`content_of_marked_head` for each pair of adjacent shapes in the list.
|
|
3209
|
+
|
|
3210
|
+
OUTPUT: list of lists of integers representing `k+1`-cores
|
|
3211
|
+
|
|
3212
|
+
EXAMPLES::
|
|
3213
|
+
|
|
3214
|
+
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
|
|
3215
|
+
sage: T.intermediate_shapes()
|
|
3216
|
+
[[], [2], [3, 1, 1], [4, 3, 2, 1], [4, 4, 2, 2]]
|
|
3217
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
3218
|
+
sage: T.intermediate_shapes()
|
|
3219
|
+
[[2, 2], [3, 2, 1, 1], [4, 2, 2, 2], [4, 2, 2, 2, 1, 1, 1, 1]]
|
|
3220
|
+
|
|
3221
|
+
TESTS::
|
|
3222
|
+
|
|
3223
|
+
sage: StrongTableau([[None, None], [None]], 4).intermediate_shapes()
|
|
3224
|
+
[[2, 1]]
|
|
3225
|
+
sage: StrongTableau([],4).intermediate_shapes()
|
|
3226
|
+
[[]]
|
|
3227
|
+
"""
|
|
3228
|
+
return intermediate_shapes(self.to_unmarked_list())
|
|
3229
|
+
|
|
3230
|
+
def pp( self ):
|
|
3231
|
+
r"""
|
|
3232
|
+
Print the strong tableau ``self`` in pretty print format.
|
|
3233
|
+
|
|
3234
|
+
EXAMPLES::
|
|
3235
|
+
|
|
3236
|
+
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
|
|
3237
|
+
sage: T.pp()
|
|
3238
|
+
-1 -1 -2 -3
|
|
3239
|
+
-2 3 -3 4
|
|
3240
|
+
2 3
|
|
3241
|
+
-3 -4
|
|
3242
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
3243
|
+
sage: T.pp()
|
|
3244
|
+
. . -1 -2
|
|
3245
|
+
. .
|
|
3246
|
+
-1 -2
|
|
3247
|
+
1 2
|
|
3248
|
+
-3
|
|
3249
|
+
3
|
|
3250
|
+
3
|
|
3251
|
+
3
|
|
3252
|
+
sage: Tableaux.options(convention='French')
|
|
3253
|
+
sage: T.pp()
|
|
3254
|
+
3
|
|
3255
|
+
3
|
|
3256
|
+
3
|
|
3257
|
+
-3
|
|
3258
|
+
1 2
|
|
3259
|
+
-1 -2
|
|
3260
|
+
. .
|
|
3261
|
+
. . -1 -2
|
|
3262
|
+
sage: Tableaux.options(convention='English')
|
|
3263
|
+
"""
|
|
3264
|
+
print(self._repr_diagram())
|
|
3265
|
+
|
|
3266
|
+
def outer_shape( self ):
|
|
3267
|
+
r"""
|
|
3268
|
+
Return the outer shape of ``self``.
|
|
3269
|
+
|
|
3270
|
+
This method returns the outer shape of ``self`` as viewed as a ``Core``.
|
|
3271
|
+
The outer shape of a strong tableau is always a `(k+1)`-core.
|
|
3272
|
+
|
|
3273
|
+
OUTPUT:
|
|
3274
|
+
|
|
3275
|
+
- a `(k+1)`-core
|
|
3276
|
+
|
|
3277
|
+
EXAMPLES::
|
|
3278
|
+
|
|
3279
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).outer_shape()
|
|
3280
|
+
[4, 2, 2, 2, 1, 1, 1, 1]
|
|
3281
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1]).outer_shape()
|
|
3282
|
+
[4, 4, 2, 2]
|
|
3283
|
+
|
|
3284
|
+
TESTS::
|
|
3285
|
+
|
|
3286
|
+
sage: StrongTableau([[None, None], [None]], 4).outer_shape()
|
|
3287
|
+
[2, 1]
|
|
3288
|
+
sage: StrongTableau([],4).outer_shape()
|
|
3289
|
+
[]
|
|
3290
|
+
"""
|
|
3291
|
+
return self.parent().outer_shape()
|
|
3292
|
+
|
|
3293
|
+
def inner_shape( self ):
|
|
3294
|
+
r"""
|
|
3295
|
+
Return the inner shape of ``self``.
|
|
3296
|
+
|
|
3297
|
+
If ``self`` is a strong skew tableau, then this method returns the inner shape
|
|
3298
|
+
(the shape of the cells labelled with ``None``).
|
|
3299
|
+
If ``self`` is not skew, then the inner shape is empty.
|
|
3300
|
+
|
|
3301
|
+
OUTPUT:
|
|
3302
|
+
|
|
3303
|
+
- a `(k+1)`-core
|
|
3304
|
+
|
|
3305
|
+
EXAMPLES::
|
|
3306
|
+
|
|
3307
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).inner_shape()
|
|
3308
|
+
[2, 2]
|
|
3309
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1]).inner_shape()
|
|
3310
|
+
[]
|
|
3311
|
+
|
|
3312
|
+
TESTS::
|
|
3313
|
+
|
|
3314
|
+
sage: StrongTableau([[None, None], [None]], 4).inner_shape()
|
|
3315
|
+
[2, 1]
|
|
3316
|
+
sage: StrongTableau([],4).inner_shape()
|
|
3317
|
+
[]
|
|
3318
|
+
"""
|
|
3319
|
+
return self.parent().inner_shape()
|
|
3320
|
+
|
|
3321
|
+
def shape( self ):
|
|
3322
|
+
r"""
|
|
3323
|
+
Return the shape of ``self``.
|
|
3324
|
+
|
|
3325
|
+
If ``self`` is a skew tableau then return a pair of `k+1`-cores consisting of the
|
|
3326
|
+
outer and the inner shape. If ``self`` is strong tableau with no inner shape then
|
|
3327
|
+
return a `k+1`-core.
|
|
3328
|
+
|
|
3329
|
+
INPUT:
|
|
3330
|
+
|
|
3331
|
+
- ``form`` -- argument to indicate ``'inner'``, ``'outer'`` or
|
|
3332
|
+
``'skew'`` (default: ``'outer'``)
|
|
3333
|
+
|
|
3334
|
+
OUTPUT: a `k+1`-core or a pair of `k+1`-cores if form is not
|
|
3335
|
+
``'inner'`` or ``'outer'``
|
|
3336
|
+
|
|
3337
|
+
EXAMPLES::
|
|
3338
|
+
|
|
3339
|
+
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
|
|
3340
|
+
sage: T.shape()
|
|
3341
|
+
([4, 2, 2, 2, 1, 1, 1, 1], [2, 2])
|
|
3342
|
+
sage: StrongTableau([[-1, -2, 3], [-3]], 2).shape()
|
|
3343
|
+
[3, 1]
|
|
3344
|
+
sage: type(StrongTableau([[-1, -2, 3], [-3]], 2).shape())
|
|
3345
|
+
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
|
|
3346
|
+
|
|
3347
|
+
TESTS::
|
|
3348
|
+
|
|
3349
|
+
sage: StrongTableau([[None, None, None], [None]], 2).shape()
|
|
3350
|
+
([3, 1], [3, 1])
|
|
3351
|
+
sage: StrongTableau([],4).shape()
|
|
3352
|
+
[]
|
|
3353
|
+
"""
|
|
3354
|
+
return self.parent().shape()
|
|
3355
|
+
|
|
3356
|
+
def weight( self ):
|
|
3357
|
+
r"""
|
|
3358
|
+
Return the weight of the tableau.
|
|
3359
|
+
|
|
3360
|
+
The weight is a list of nonnegative integers indicating the number of 1s,
|
|
3361
|
+
number of 2s, number of 3s, etc.
|
|
3362
|
+
|
|
3363
|
+
OUTPUT: list of nonnegative integers
|
|
3364
|
+
|
|
3365
|
+
EXAMPLES::
|
|
3366
|
+
|
|
3367
|
+
sage: T = StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3); T.weight()
|
|
3368
|
+
(1, 1, 1, 1, 1)
|
|
3369
|
+
sage: T.set_weight([3,1,1]).weight()
|
|
3370
|
+
(3, 1, 1)
|
|
3371
|
+
sage: StrongTableau([[-1,-1,-2,-3],[-2,3,-3,4],[2,3],[-3,-4]], 3).weight()
|
|
3372
|
+
(2, 2, 3, 1)
|
|
3373
|
+
|
|
3374
|
+
TESTS::
|
|
3375
|
+
|
|
3376
|
+
sage: StrongTableau([[None, None], [None]], 4).weight()
|
|
3377
|
+
()
|
|
3378
|
+
sage: StrongTableau([],4).weight()
|
|
3379
|
+
()
|
|
3380
|
+
"""
|
|
3381
|
+
return self.parent()._weight
|
|
3382
|
+
|
|
3383
|
+
def size( self ):
|
|
3384
|
+
"""
|
|
3385
|
+
Return the size of the strong tableau.
|
|
3386
|
+
|
|
3387
|
+
The size of the strong tableau is the sum of the entries in the
|
|
3388
|
+
:meth:`weight`. It will also be equal to the length of the
|
|
3389
|
+
outer shape (as a `k+1`-core) minus the length of the inner shape.
|
|
3390
|
+
|
|
3391
|
+
.. SEEALSO:: :meth:`sage.combinat.core.Core.length`
|
|
3392
|
+
|
|
3393
|
+
OUTPUT: nonnegative integer
|
|
3394
|
+
|
|
3395
|
+
EXAMPLES::
|
|
3396
|
+
|
|
3397
|
+
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3).size()
|
|
3398
|
+
5
|
|
3399
|
+
sage: StrongTableau([[None, None, -1, 2], [-2], [-3]], 3).size()
|
|
3400
|
+
3
|
|
3401
|
+
|
|
3402
|
+
TESTS::
|
|
3403
|
+
|
|
3404
|
+
sage: StrongTableau([[None, None], [None]], 4).size()
|
|
3405
|
+
0
|
|
3406
|
+
sage: StrongTableau([],4).size()
|
|
3407
|
+
0
|
|
3408
|
+
"""
|
|
3409
|
+
return sum(self.weight())
|
|
3410
|
+
|
|
3411
|
+
def to_list( self ):
|
|
3412
|
+
"""
|
|
3413
|
+
Return the marked column strict (possibly skew) tableau as a list of lists.
|
|
3414
|
+
|
|
3415
|
+
OUTPUT: list of lists of integers or ``None``
|
|
3416
|
+
|
|
3417
|
+
EXAMPLES::
|
|
3418
|
+
|
|
3419
|
+
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3).set_weight([2,1,1,1]).to_list()
|
|
3420
|
+
[[-1, -1, -2, 3], [-3], [-4]]
|
|
3421
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_list()
|
|
3422
|
+
[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]
|
|
3423
|
+
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1]).to_list()
|
|
3424
|
+
[[-1, -1, -1, 2], [-2], [-3]]
|
|
3425
|
+
|
|
3426
|
+
TESTS::
|
|
3427
|
+
|
|
3428
|
+
sage: StrongTableau([[None, None], [None]], 4).to_list()
|
|
3429
|
+
[[None, None], [None]]
|
|
3430
|
+
sage: StrongTableau([],4).to_list()
|
|
3431
|
+
[]
|
|
3432
|
+
"""
|
|
3433
|
+
def f(v):
|
|
3434
|
+
# f is a function which maps v or -v to the weight value corresponding to the partition mu
|
|
3435
|
+
if v is None:
|
|
3436
|
+
return None
|
|
3437
|
+
else:
|
|
3438
|
+
return sgn(v)*min([i for i in range(len(self.weight())+1) if sum(self.weight()[:i]) >= abs(v)])
|
|
3439
|
+
return [[f(v) for v in row] for row in self.to_standard_list()]
|
|
3440
|
+
|
|
3441
|
+
def to_unmarked_list( self ):
|
|
3442
|
+
"""
|
|
3443
|
+
Return the tableau as a list of lists with markings removed.
|
|
3444
|
+
|
|
3445
|
+
Return the list of lists of the rows of the tableau where the markings have been
|
|
3446
|
+
removed.
|
|
3447
|
+
|
|
3448
|
+
OUTPUT: list of lists of integers or ``None``
|
|
3449
|
+
|
|
3450
|
+
EXAMPLES::
|
|
3451
|
+
|
|
3452
|
+
sage: T = StrongTableau( [[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1])
|
|
3453
|
+
sage: T.to_unmarked_list()
|
|
3454
|
+
[[1, 1, 1, 2], [2], [3]]
|
|
3455
|
+
sage: TT = T.set_weight([2,1,1,1])
|
|
3456
|
+
sage: TT.to_unmarked_list()
|
|
3457
|
+
[[1, 1, 2, 3], [3], [4]]
|
|
3458
|
+
sage: StrongTableau( [[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_unmarked_list()
|
|
3459
|
+
[[None, None, 1, 2], [None, None], [1, 2], [1, 2], [3], [3], [3], [3]]
|
|
3460
|
+
|
|
3461
|
+
TESTS::
|
|
3462
|
+
|
|
3463
|
+
sage: StrongTableau([[None, None], [None]], 4).to_unmarked_list()
|
|
3464
|
+
[[None, None], [None]]
|
|
3465
|
+
sage: StrongTableau([],4).to_unmarked_list()
|
|
3466
|
+
[]
|
|
3467
|
+
"""
|
|
3468
|
+
return [[nabs(v) for v in row] for row in self.to_list()]
|
|
3469
|
+
|
|
3470
|
+
def to_standard_list(self):
|
|
3471
|
+
"""
|
|
3472
|
+
Return the underlying standard strong tableau as a list of lists.
|
|
3473
|
+
|
|
3474
|
+
Internally, for a strong tableau the standard strong tableau and its weight
|
|
3475
|
+
is stored separately. This method returns the underlying standard part.
|
|
3476
|
+
|
|
3477
|
+
OUTPUT: list of lists of integers or ``None``
|
|
3478
|
+
|
|
3479
|
+
EXAMPLES::
|
|
3480
|
+
|
|
3481
|
+
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1]).to_standard_list()
|
|
3482
|
+
[[-1, -2, -3, 4], [-4], [-5]]
|
|
3483
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_standard_list()
|
|
3484
|
+
[[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]]
|
|
3485
|
+
|
|
3486
|
+
TESTS::
|
|
3487
|
+
|
|
3488
|
+
sage: StrongTableau([[None, None], [None]], 4).to_standard_list()
|
|
3489
|
+
[[None, None], [None]]
|
|
3490
|
+
sage: StrongTableau([],4).to_standard_list()
|
|
3491
|
+
[]
|
|
3492
|
+
"""
|
|
3493
|
+
return self._tableau
|
|
3494
|
+
|
|
3495
|
+
def to_standard_tableau(self):
|
|
3496
|
+
"""
|
|
3497
|
+
Return the underlying standard strong tableau as a ``StrongTableau`` object.
|
|
3498
|
+
|
|
3499
|
+
Internally, for a strong tableau the standard strong tableau and its weight
|
|
3500
|
+
is stored separately. This method returns the underlying standard part as a
|
|
3501
|
+
``StrongTableau``.
|
|
3502
|
+
|
|
3503
|
+
OUTPUT: a strong tableau with standard weight
|
|
3504
|
+
|
|
3505
|
+
EXAMPLES::
|
|
3506
|
+
|
|
3507
|
+
sage: T = StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1])
|
|
3508
|
+
sage: T.to_standard_tableau()
|
|
3509
|
+
[[-1, -2, -3, 4], [-4], [-5]]
|
|
3510
|
+
sage: T.to_standard_tableau() == T.to_standard_list()
|
|
3511
|
+
False
|
|
3512
|
+
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_standard_tableau()
|
|
3513
|
+
[[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]]
|
|
3514
|
+
|
|
3515
|
+
TESTS::
|
|
3516
|
+
|
|
3517
|
+
sage: StrongTableau([[None, None], [None]], 4).to_standard_tableau()
|
|
3518
|
+
[[None, None], [None]]
|
|
3519
|
+
sage: StrongTableau([],4).to_standard_tableau()
|
|
3520
|
+
[]
|
|
3521
|
+
"""
|
|
3522
|
+
return StrongTableau(self._tableau, self.k)
|
|
3523
|
+
|
|
3524
|
+
def to_unmarked_standard_list( self ):
|
|
3525
|
+
"""
|
|
3526
|
+
Return the standard part of the tableau as a list of lists with markings removed.
|
|
3527
|
+
|
|
3528
|
+
Return the list of lists of the rows of the tableau where the markings have been
|
|
3529
|
+
removed.
|
|
3530
|
+
|
|
3531
|
+
OUTPUT: list of lists of integers or ``None``
|
|
3532
|
+
|
|
3533
|
+
EXAMPLES::
|
|
3534
|
+
|
|
3535
|
+
sage: StrongTableau( [[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1]).to_unmarked_standard_list()
|
|
3536
|
+
[[1, 2, 3, 4], [4], [5]]
|
|
3537
|
+
sage: StrongTableau( [[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_unmarked_standard_list()
|
|
3538
|
+
[[None, None, 2, 4], [None, None], [1, 3], [2, 4], [5], [5], [5], [5]]
|
|
3539
|
+
|
|
3540
|
+
TESTS::
|
|
3541
|
+
|
|
3542
|
+
sage: StrongTableau([[None, None], [None]], 4).to_unmarked_standard_list()
|
|
3543
|
+
[[None, None], [None]]
|
|
3544
|
+
sage: StrongTableau([],4).to_unmarked_standard_list()
|
|
3545
|
+
[]
|
|
3546
|
+
"""
|
|
3547
|
+
return [[nabs(l) for l in x] for x in self.to_standard_list()]
|
|
3548
|
+
|
|
3549
|
+
def _latex_(self):
|
|
3550
|
+
r"""
|
|
3551
|
+
Return a latex method for the tableau.
|
|
3552
|
+
|
|
3553
|
+
EXAMPLES::
|
|
3554
|
+
|
|
3555
|
+
sage: T = StrongTableau( [[None, -1, -2, 3], [2, -3]], 2, weight=[2,1] )
|
|
3556
|
+
sage: Tableaux.options(convention = "English")
|
|
3557
|
+
sage: latex(T)
|
|
3558
|
+
{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
3559
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{4}c}\cline{1-4}
|
|
3560
|
+
\lr{}&\lr{1^\ast}&\lr{1^\ast}&\lr{2}\\\cline{1-4}
|
|
3561
|
+
\lr{1}&\lr{2^\ast}\\\cline{1-2}
|
|
3562
|
+
\end{array}$}
|
|
3563
|
+
}
|
|
3564
|
+
sage: Tableaux.options(convention = "French")
|
|
3565
|
+
sage: latex(T)
|
|
3566
|
+
{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
3567
|
+
\raisebox{-.6ex}{$\begin{array}[t]{*{4}c}\cline{1-2}
|
|
3568
|
+
\lr{1}&\lr{2^\ast}\\\cline{1-4}
|
|
3569
|
+
\lr{}&\lr{1^\ast}&\lr{1^\ast}&\lr{2}\\\cline{1-4}
|
|
3570
|
+
\end{array}$}
|
|
3571
|
+
}
|
|
3572
|
+
"""
|
|
3573
|
+
def chi(x):
|
|
3574
|
+
if x is None:
|
|
3575
|
+
return ""
|
|
3576
|
+
if x in ZZ:
|
|
3577
|
+
s = "%s" % abs(x)
|
|
3578
|
+
if x < 0:
|
|
3579
|
+
s += "^\\ast"
|
|
3580
|
+
return s
|
|
3581
|
+
return "%s" % x
|
|
3582
|
+
T = [[chi(x) for x in row] for row in self.to_list()]
|
|
3583
|
+
from .output import tex_from_array
|
|
3584
|
+
return tex_from_array(T)
|
|
3585
|
+
|
|
3586
|
+
def restrict( self, r ):
|
|
3587
|
+
r"""
|
|
3588
|
+
Restrict the standard part of the tableau to the labels `1, 2, \ldots, r`.
|
|
3589
|
+
|
|
3590
|
+
Return the tableau consisting of the labels of the standard part of ``self``
|
|
3591
|
+
restricted to the labels of `1` through ``r``. The result is another
|
|
3592
|
+
``StrongTableau`` object.
|
|
3593
|
+
|
|
3594
|
+
INPUT:
|
|
3595
|
+
|
|
3596
|
+
- ``r`` -- integer
|
|
3597
|
+
|
|
3598
|
+
OUTPUT: a strong tableau
|
|
3599
|
+
|
|
3600
|
+
EXAMPLES::
|
|
3601
|
+
|
|
3602
|
+
sage: T = StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [-2], [2], [2], [3]], 4, weight=[1,1,1,1,1])
|
|
3603
|
+
sage: T.restrict(3)
|
|
3604
|
+
[[None, None], [None, None], [-1, -3], [-2], [2], [2], [3]]
|
|
3605
|
+
sage: TT = T.restrict(0)
|
|
3606
|
+
sage: TT
|
|
3607
|
+
[[None, None], [None, None]]
|
|
3608
|
+
sage: TT == StrongTableau( [[None, None], [None, None]], 4 )
|
|
3609
|
+
True
|
|
3610
|
+
sage: T.restrict(5) == T
|
|
3611
|
+
True
|
|
3612
|
+
|
|
3613
|
+
TESTS::
|
|
3614
|
+
|
|
3615
|
+
sage: StrongTableau([[None, None], [None]], 4).restrict(1)
|
|
3616
|
+
[[None, None], [None]]
|
|
3617
|
+
sage: StrongTableau([],4).restrict(1)
|
|
3618
|
+
[]
|
|
3619
|
+
"""
|
|
3620
|
+
rr = sum(self.weight()[:r])
|
|
3621
|
+
rest_tab = [y for y in ([x for x in row if x is None or abs(x) <= rr] for row in self.to_standard_list()) if y]
|
|
3622
|
+
new_parent = StrongTableaux( self.k, (Core([len(x) for x in rest_tab], self.k+1), self.inner_shape()), self.weight()[:r] )
|
|
3623
|
+
return new_parent(rest_tab)
|
|
3624
|
+
|
|
3625
|
+
def set_weight( self, mu ):
|
|
3626
|
+
"""
|
|
3627
|
+
Set a new weight ``mu`` for ``self``.
|
|
3628
|
+
|
|
3629
|
+
This method first tests if the underlying standard tableau is column-strict with
|
|
3630
|
+
respect to the weight ``mu``. If it is, then it changes the weight and returns
|
|
3631
|
+
the tableau; otherwise it raises an error.
|
|
3632
|
+
|
|
3633
|
+
INPUT:
|
|
3634
|
+
|
|
3635
|
+
- ``mu`` -- list of nonnegative integers representing the new weight
|
|
3636
|
+
|
|
3637
|
+
EXAMPLES::
|
|
3638
|
+
|
|
3639
|
+
sage: StrongTableau( [[-1, -2, -3], [3]], 2 ).set_weight( [3] )
|
|
3640
|
+
[[-1, -1, -1], [1]]
|
|
3641
|
+
sage: StrongTableau( [[-1, -2, -3], [3]], 2 ).set_weight( [0,3] )
|
|
3642
|
+
[[-2, -2, -2], [2]]
|
|
3643
|
+
sage: StrongTableau( [[-1, -2, 3], [-3]], 2 ).set_weight( [2, 0, 1] )
|
|
3644
|
+
[[-1, -1, 3], [-3]]
|
|
3645
|
+
sage: StrongTableau( [[-1, -2, 3], [-3]], 2 ).set_weight( [3] )
|
|
3646
|
+
Traceback (most recent call last):
|
|
3647
|
+
...
|
|
3648
|
+
ValueError: [[-1, -2, 3], [-3]] is not a semistandard strong tableau with respect to the partition [3]
|
|
3649
|
+
|
|
3650
|
+
TESTS::
|
|
3651
|
+
|
|
3652
|
+
sage: StrongTableau([[None, None], [None]], 4).set_weight([])
|
|
3653
|
+
[[None, None], [None]]
|
|
3654
|
+
sage: StrongTableau([],4).set_weight([])
|
|
3655
|
+
[]
|
|
3656
|
+
"""
|
|
3657
|
+
if sum(mu) != self.size() or self.is_column_strict_with_weight( mu ):
|
|
3658
|
+
return StrongTableaux.__classcall__(StrongTableaux, self.k, (self.outer_shape(), self.inner_shape()), tuple(mu))(self.to_standard_list())
|
|
3659
|
+
else:
|
|
3660
|
+
raise ValueError("%s is not a semistandard strong tableau with respect to the partition %s" % (self, mu))
|
|
3661
|
+
|
|
3662
|
+
def left_action( self, tij ):
|
|
3663
|
+
r"""
|
|
3664
|
+
Action of transposition ``tij`` on ``self`` by adding marked ribbons.
|
|
3665
|
+
|
|
3666
|
+
Computes the left action of the transposition ``tij`` on the tableau.
|
|
3667
|
+
If ``tij`` acting on the element of the affine Grassmannian raises the length by 1,
|
|
3668
|
+
then this function will add a cell to the standard tableau.
|
|
3669
|
+
|
|
3670
|
+
INPUT:
|
|
3671
|
+
|
|
3672
|
+
- ``tij`` -- a transposition represented as a pair `(i, j)`
|
|
3673
|
+
|
|
3674
|
+
OUTPUT: ``self`` after it has been modified by the action of the transposition ``tij``
|
|
3675
|
+
|
|
3676
|
+
EXAMPLES::
|
|
3677
|
+
|
|
3678
|
+
sage: StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[1,1,1,1] ).left_action([0,1])
|
|
3679
|
+
[[None, -1, -2, -3, 5], [3, -5], [-4]]
|
|
3680
|
+
sage: StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[1,1,1,1] ).left_action([4,5])
|
|
3681
|
+
[[None, -1, -2, -3, -5], [3, 5], [-4]]
|
|
3682
|
+
sage: T = StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[1,1,1,1] )
|
|
3683
|
+
sage: T.left_action([-3,-2])
|
|
3684
|
+
[[None, -1, -2, -3], [3], [-4], [-5]]
|
|
3685
|
+
sage: T = StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[3,1] )
|
|
3686
|
+
sage: T.left_action([-3,-2])
|
|
3687
|
+
[[None, -1, -1, -1], [1], [-2], [-3]]
|
|
3688
|
+
sage: T
|
|
3689
|
+
[[None, -1, -1, -1], [1], [-2]]
|
|
3690
|
+
sage: T.check()
|
|
3691
|
+
sage: T.weight()
|
|
3692
|
+
(3, 1)
|
|
3693
|
+
|
|
3694
|
+
TESTS::
|
|
3695
|
+
|
|
3696
|
+
sage: StrongTableau([[None, None], [None]], 4).left_action([-2,-1])
|
|
3697
|
+
[[None, None], [None], [-1]]
|
|
3698
|
+
sage: StrongTableau([],4).left_action([0,1])
|
|
3699
|
+
[[-1]]
|
|
3700
|
+
"""
|
|
3701
|
+
T = StrongTableaux._left_action_list(copy.deepcopy( self.to_standard_list() ), tij, self.size()+1, self.k)
|
|
3702
|
+
return StrongTableau( T, self.k, self.weight()+(1,) )
|
|
3703
|
+
|
|
3704
|
+
def follows_tableau( self ):
|
|
3705
|
+
r"""
|
|
3706
|
+
Return a list of strong marked tableaux with length one longer than ``self``.
|
|
3707
|
+
|
|
3708
|
+
Return list of all strong tableaux obtained from ``self`` by extending to a core
|
|
3709
|
+
which follows the shape of ``self`` in the strong order.
|
|
3710
|
+
|
|
3711
|
+
OUTPUT: list of strong tableaux which follow ``self`` in strong order
|
|
3712
|
+
|
|
3713
|
+
EXAMPLES::
|
|
3714
|
+
|
|
3715
|
+
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
|
|
3716
|
+
sage: T.follows_tableau()
|
|
3717
|
+
[[[-1, -1, -2, -3, 5, 5, -5], [-2, 3, -3, 4], [2, 3], [-3, -4]],
|
|
3718
|
+
[[-1, -1, -2, -3, 5], [-2, 3, -3, 4], [2, 3, 5], [-3, -4], [-5]],
|
|
3719
|
+
[[-1, -1, -2, -3, 5], [-2, 3, -3, 4], [2, 3, -5], [-3, -4], [5]],
|
|
3720
|
+
[[-1, -1, -2, -3, -5], [-2, 3, -3, 4], [2, 3, 5], [-3, -4], [5]],
|
|
3721
|
+
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4], [-5], [5], [5]]]
|
|
3722
|
+
sage: StrongTableau([[-1,-2],[-3,-4]],3).follows_tableau()
|
|
3723
|
+
[[[-1, -2, 5, 5, -5], [-3, -4]], [[-1, -2, 5], [-3, -4], [-5]],
|
|
3724
|
+
[[-1, -2, -5], [-3, -4], [5]], [[-1, -2], [-3, -4], [-5], [5], [5]]]
|
|
3725
|
+
|
|
3726
|
+
TESTS::
|
|
3727
|
+
|
|
3728
|
+
sage: StrongTableau([[None, None], [None]], 4).follows_tableau()
|
|
3729
|
+
[[[None, None, -1], [None]], [[None, None], [None, -1]], [[None, None], [None], [-1]]]
|
|
3730
|
+
sage: StrongTableau([],4).follows_tableau()
|
|
3731
|
+
[[[-1]]]
|
|
3732
|
+
"""
|
|
3733
|
+
v = self.size()+1
|
|
3734
|
+
out = []
|
|
3735
|
+
for T in StrongTableaux.follows_tableau_unsigned_standard( self.to_standard_list(), self.k ):
|
|
3736
|
+
for m in StrongTableaux.cells_head_dictionary(T)[v]:
|
|
3737
|
+
TT = copy.deepcopy(T)
|
|
3738
|
+
TT[m[0]][m[1]] = -v
|
|
3739
|
+
out.append(StrongTableau(TT, self.k, self.weight()+(1,)))
|
|
3740
|
+
return out
|
|
3741
|
+
|
|
3742
|
+
def spin_of_ribbon( self, v ):
|
|
3743
|
+
r"""
|
|
3744
|
+
Return the spin of the ribbon with label ``v`` in the standard part of ``self``.
|
|
3745
|
+
|
|
3746
|
+
The spin of a ribbon is an integer statistic. It is the sum of `(h-1) r` plus
|
|
3747
|
+
the number of connected components above the marked one where `h` is the height
|
|
3748
|
+
of the marked ribbon and `r` is the number of connected components.
|
|
3749
|
+
|
|
3750
|
+
.. SEEALSO:: :meth:`height_of_ribbon`, :meth:`number_of_connected_components`,
|
|
3751
|
+
:meth:`ribbons_above_marked`
|
|
3752
|
+
|
|
3753
|
+
INPUT:
|
|
3754
|
+
|
|
3755
|
+
- ``v`` -- a label of the standard part of the tableau
|
|
3756
|
+
|
|
3757
|
+
OUTPUT: integer value representing the spin of the ribbon with label ``v``
|
|
3758
|
+
|
|
3759
|
+
EXAMPLES::
|
|
3760
|
+
|
|
3761
|
+
sage: T = StrongTableau([[-1,-2,5,6],[-3,-4,-7,8],[-5,-6],[7,-8]], 3)
|
|
3762
|
+
sage: [T.spin_of_ribbon(v) for v in range(1,9)]
|
|
3763
|
+
[0, 0, 0, 0, 0, 0, 1, 0]
|
|
3764
|
+
sage: T = StrongTableau([[None,None,-1,-3],[-2,3,-3,4],[2,3],[-3,-4]], 3)
|
|
3765
|
+
sage: [T.spin_of_ribbon(v) for v in range(1,7)]
|
|
3766
|
+
[0, 1, 0, 0, 1, 0]
|
|
3767
|
+
|
|
3768
|
+
TESTS::
|
|
3769
|
+
|
|
3770
|
+
sage: StrongTableau([[None, None], [None]], 4).spin_of_ribbon(1)
|
|
3771
|
+
0
|
|
3772
|
+
sage: StrongTableau([],4).spin_of_ribbon(1)
|
|
3773
|
+
0
|
|
3774
|
+
"""
|
|
3775
|
+
return (self.height_of_ribbon(v)-1)*self.number_of_connected_components(v)+self.ribbons_above_marked(v)
|
|
3776
|
+
|
|
3777
|
+
def spin( self ):
|
|
3778
|
+
r"""
|
|
3779
|
+
Return the spin statistic of the tableau ``self``.
|
|
3780
|
+
|
|
3781
|
+
The spin is an integer statistic on a strong marked tableau. It is
|
|
3782
|
+
the sum of `(h-1) r` plus the number of connected components above the
|
|
3783
|
+
marked one where `h` is the height of the marked ribbon and `r` is
|
|
3784
|
+
the number of connected components.
|
|
3785
|
+
|
|
3786
|
+
.. SEEALSO:: :meth:`height_of_ribbon`, :meth:`number_of_connected_components`,
|
|
3787
|
+
:meth:`ribbons_above_marked`
|
|
3788
|
+
|
|
3789
|
+
The `k`-Schur functions with a parameter `t` can be defined as
|
|
3790
|
+
|
|
3791
|
+
.. MATH::
|
|
3792
|
+
|
|
3793
|
+
s^{(k)}_\lambda[X; t] = \sum_T t^{spin(T)} m_{weight(T)}[X]
|
|
3794
|
+
|
|
3795
|
+
where the sum is over all column strict marked strong `k`-tableaux
|
|
3796
|
+
of shape `\lambda` and partition content.
|
|
3797
|
+
|
|
3798
|
+
OUTPUT: integer value representing the spin
|
|
3799
|
+
|
|
3800
|
+
EXAMPLES::
|
|
3801
|
+
|
|
3802
|
+
sage: StrongTableau([[-1,-2,5,6],[-3,-4,-7,8],[-5,-6],[7,-8]], 3, [2,2,3,1]).spin()
|
|
3803
|
+
1
|
|
3804
|
+
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1]).spin()
|
|
3805
|
+
2
|
|
3806
|
+
sage: StrongTableau([[None,None,-1,-3],[-2,3,-3,4],[2,3],[-3,-4]], 3).spin()
|
|
3807
|
+
2
|
|
3808
|
+
sage: ks3 = SymmetricFunctions(QQ['t'].fraction_field()).kschur(3)
|
|
3809
|
+
sage: t = ks3.realization_of().t
|
|
3810
|
+
sage: m = ks3.ambient().realization_of().m()
|
|
3811
|
+
sage: myks221 = sum(sum(t**T.spin() for T in StrongTableaux(3,[3,2,1],weight=mu))*m(mu) for mu in Partitions(5, max_part=3))
|
|
3812
|
+
sage: myks221 == m(ks3[2,2,1])
|
|
3813
|
+
True
|
|
3814
|
+
sage: h = ks3.ambient().realization_of().h()
|
|
3815
|
+
sage: Core([4,4,2,2],4).to_bounded_partition()
|
|
3816
|
+
[2, 2, 2, 2]
|
|
3817
|
+
sage: ks3[2,2,2,2].lift().scalar(h[3,3,2]) == sum( t**T.spin() for T in StrongTableaux(3, [4,4,2,2], weight=[3,3,2]) )
|
|
3818
|
+
True
|
|
3819
|
+
|
|
3820
|
+
TESTS::
|
|
3821
|
+
|
|
3822
|
+
sage: StrongTableau([[None, None], [None]], 4).spin()
|
|
3823
|
+
0
|
|
3824
|
+
sage: StrongTableau([],4).spin()
|
|
3825
|
+
0
|
|
3826
|
+
"""
|
|
3827
|
+
return sum(self.spin_of_ribbon(v) for v in range(1,self.size()+1))
|
|
3828
|
+
|
|
3829
|
+
def to_transposition_sequence( self ):
|
|
3830
|
+
"""
|
|
3831
|
+
Return a list of transpositions corresponding to ``self``.
|
|
3832
|
+
|
|
3833
|
+
Given a strong column strict tableau ``self`` returns the list of transpositions
|
|
3834
|
+
which when applied to the left of an empty tableau gives the corresponding strong
|
|
3835
|
+
standard tableau.
|
|
3836
|
+
|
|
3837
|
+
OUTPUT: list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}`
|
|
3838
|
+
|
|
3839
|
+
EXAMPLES::
|
|
3840
|
+
|
|
3841
|
+
sage: T = StrongTableau([[-1, -1, -1], [1]],2)
|
|
3842
|
+
sage: T.to_transposition_sequence()
|
|
3843
|
+
[[2, 3], [1, 2], [0, 1]]
|
|
3844
|
+
sage: T = StrongTableau([[-1, -1, 2], [-2]],2)
|
|
3845
|
+
sage: T.to_transposition_sequence()
|
|
3846
|
+
[[-1, 0], [1, 2], [0, 1]]
|
|
3847
|
+
sage: T = StrongTableau([[None, -1, 2, -3], [-2, 3]],2)
|
|
3848
|
+
sage: T.to_transposition_sequence()
|
|
3849
|
+
[[3, 4], [-1, 0], [1, 2]]
|
|
3850
|
+
|
|
3851
|
+
TESTS::
|
|
3852
|
+
|
|
3853
|
+
sage: StrongTableau([[None, None], [None]], 4).to_transposition_sequence()
|
|
3854
|
+
[]
|
|
3855
|
+
sage: StrongTableau([],4).to_transposition_sequence()
|
|
3856
|
+
[]
|
|
3857
|
+
"""
|
|
3858
|
+
return StrongTableaux.marked_CST_to_transposition_sequence( self.to_standard_list(), self.k )
|
|
3859
|
+
|
|
3860
|
+
|
|
3861
|
+
class StrongTableaux(UniqueRepresentation, Parent):
|
|
3862
|
+
|
|
3863
|
+
def __init__( self, k, shape, weight ):
|
|
3864
|
+
r"""
|
|
3865
|
+
TESTS::
|
|
3866
|
+
|
|
3867
|
+
sage: strongT = StrongTableaux(2, [3,1], weight=[2,1])
|
|
3868
|
+
sage: TestSuite(strongT).run()
|
|
3869
|
+
|
|
3870
|
+
sage: strongT = StrongTableaux(0, [2,2], weight=[2,2])
|
|
3871
|
+
Traceback (most recent call last):
|
|
3872
|
+
...
|
|
3873
|
+
ValueError: The input k has to be a positive integer
|
|
3874
|
+
"""
|
|
3875
|
+
self._outer_shape = shape[0]
|
|
3876
|
+
self._inner_shape = shape[1]
|
|
3877
|
+
self.k = k
|
|
3878
|
+
if weight is None:
|
|
3879
|
+
self._weight = (1,)*(self._outer_shape.length()-self._inner_shape.length())
|
|
3880
|
+
else:
|
|
3881
|
+
self._weight = weight
|
|
3882
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
3883
|
+
|
|
3884
|
+
@staticmethod
|
|
3885
|
+
def __classcall_private__(cls, k, shape, weight=None):
|
|
3886
|
+
r"""
|
|
3887
|
+
Straighten arguments before unique representation.
|
|
3888
|
+
|
|
3889
|
+
TESTS::
|
|
3890
|
+
|
|
3891
|
+
sage: ST3 = StrongTableaux(3, [2,2], weight=[1,1,1,1])
|
|
3892
|
+
sage: TestSuite(ST3).run()
|
|
3893
|
+
"""
|
|
3894
|
+
if k <= 0:
|
|
3895
|
+
raise ValueError("The input k has to be a positive integer")
|
|
3896
|
+
if shape == [] or shape[0] in ZZ:
|
|
3897
|
+
outer_shape = Core(shape,k+1)
|
|
3898
|
+
inner_shape = Core([],k+1)
|
|
3899
|
+
else:
|
|
3900
|
+
outer_shape = Core(shape[0],k+1)
|
|
3901
|
+
inner_shape = Core(shape[1],k+1)
|
|
3902
|
+
if weight is not None:
|
|
3903
|
+
weight = tuple(weight)
|
|
3904
|
+
return super().__classcall__(cls, k, (outer_shape, inner_shape), weight)
|
|
3905
|
+
|
|
3906
|
+
def _repr_( self ):
|
|
3907
|
+
r"""
|
|
3908
|
+
Return the representation of ``self``.
|
|
3909
|
+
|
|
3910
|
+
EXAMPLES::
|
|
3911
|
+
|
|
3912
|
+
sage: StrongTableaux(3, [2,2], weight=[1,1,1,1])
|
|
3913
|
+
Set of strong 3-tableaux of shape [2, 2] and of weight (1, 1, 1, 1)
|
|
3914
|
+
sage: StrongTableaux(3, [2,2])
|
|
3915
|
+
Set of strong 3-tableaux of shape [2, 2] and of weight (1, 1, 1, 1)
|
|
3916
|
+
sage: StrongTableaux(3, [[2,2],[1]], weight=[0,0,2,1])
|
|
3917
|
+
Set of strong 3-tableaux of shape [[2, 2], [1]] and of weight (0, 0, 2, 1)
|
|
3918
|
+
sage: StrongTableaux(3, [[],[]], weight=[])
|
|
3919
|
+
Set of strong 3-tableaux of shape [] and of weight ()
|
|
3920
|
+
"""
|
|
3921
|
+
if self._inner_shape == Core([],self.k+1):
|
|
3922
|
+
s = "Set of strong %s-tableaux" % self.k
|
|
3923
|
+
s += " of shape %s" % self._outer_shape
|
|
3924
|
+
else:
|
|
3925
|
+
s = "Set of strong %s-tableaux" % self.k
|
|
3926
|
+
s += " of shape [%s, %s]" % (self._outer_shape, self._inner_shape)
|
|
3927
|
+
s += "%sand of weight %s" % (" ",self._weight)
|
|
3928
|
+
return s
|
|
3929
|
+
|
|
3930
|
+
options = Tableaux.options
|
|
3931
|
+
|
|
3932
|
+
def _an_element_(self):
|
|
3933
|
+
r"""
|
|
3934
|
+
Return the first generated element of the class of ``StrongTableaux``.
|
|
3935
|
+
|
|
3936
|
+
EXAMPLES::
|
|
3937
|
+
|
|
3938
|
+
sage: ST = StrongTableaux(3, [3], weight=[3])
|
|
3939
|
+
sage: ST.an_element()
|
|
3940
|
+
[[-1, -1, -1]]
|
|
3941
|
+
"""
|
|
3942
|
+
return next(iter(self))
|
|
3943
|
+
|
|
3944
|
+
def outer_shape(self):
|
|
3945
|
+
r"""
|
|
3946
|
+
Return the outer shape of the class of strong tableaux.
|
|
3947
|
+
|
|
3948
|
+
OUTPUT: a `k+1`-core
|
|
3949
|
+
|
|
3950
|
+
EXAMPLES::
|
|
3951
|
+
|
|
3952
|
+
sage: StrongTableaux( 2, [3,1] ).outer_shape()
|
|
3953
|
+
[3, 1]
|
|
3954
|
+
sage: type(StrongTableaux( 2, [3,1] ).outer_shape())
|
|
3955
|
+
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
|
|
3956
|
+
sage: StrongTableaux( 4, [[2,1], [1]] ).outer_shape()
|
|
3957
|
+
[2, 1]
|
|
3958
|
+
"""
|
|
3959
|
+
return self._outer_shape
|
|
3960
|
+
|
|
3961
|
+
def inner_shape(self):
|
|
3962
|
+
r"""
|
|
3963
|
+
Return the inner shape of the class of strong tableaux.
|
|
3964
|
+
|
|
3965
|
+
OUTPUT: a `k+1`-core
|
|
3966
|
+
|
|
3967
|
+
EXAMPLES::
|
|
3968
|
+
|
|
3969
|
+
sage: StrongTableaux( 2, [3,1] ).inner_shape()
|
|
3970
|
+
[]
|
|
3971
|
+
sage: type(StrongTableaux( 2, [3,1] ).inner_shape())
|
|
3972
|
+
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
|
|
3973
|
+
sage: StrongTableaux( 4, [[2,1], [1]] ).inner_shape()
|
|
3974
|
+
[1]
|
|
3975
|
+
"""
|
|
3976
|
+
return self._inner_shape
|
|
3977
|
+
|
|
3978
|
+
def shape(self):
|
|
3979
|
+
r"""
|
|
3980
|
+
Return the shape of ``self``.
|
|
3981
|
+
|
|
3982
|
+
If the ``self`` has an inner shape return a pair consisting of an inner and
|
|
3983
|
+
an outer shape. If the inner shape is empty then return only the outer shape.
|
|
3984
|
+
|
|
3985
|
+
OUTPUT: a `k+1`-core or a pair of `k+1`-cores
|
|
3986
|
+
|
|
3987
|
+
EXAMPLES::
|
|
3988
|
+
|
|
3989
|
+
sage: StrongTableaux( 2, [3,1] ).shape()
|
|
3990
|
+
[3, 1]
|
|
3991
|
+
sage: type(StrongTableaux( 2, [3,1] ).shape())
|
|
3992
|
+
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
|
|
3993
|
+
sage: StrongTableaux( 4, [[2,1], [1]] ).shape()
|
|
3994
|
+
([2, 1], [1])
|
|
3995
|
+
"""
|
|
3996
|
+
if self._inner_shape:
|
|
3997
|
+
return (self._outer_shape, self._inner_shape)
|
|
3998
|
+
return self._outer_shape
|
|
3999
|
+
|
|
4000
|
+
def __iter__(self):
|
|
4001
|
+
r"""
|
|
4002
|
+
TESTS::
|
|
4003
|
+
|
|
4004
|
+
sage: ST = StrongTableaux(3, [4,1], weight=[2,2])
|
|
4005
|
+
sage: ST.list()
|
|
4006
|
+
[[[-1, -1, -2, -2], [2]], [[-1, -1, 2, -2], [-2]]]
|
|
4007
|
+
sage: ST = StrongTableaux(3, [5,2,2], weight=[2,2,2,1])
|
|
4008
|
+
sage: ST.cardinality()
|
|
4009
|
+
14
|
|
4010
|
+
sage: StrongTableaux(3, [5,2,2], weight=[3,3,1]).list()
|
|
4011
|
+
[[[-1, -1, -1, -2, -2], [-2, 2], [2, -3]], [[-1, -1, -1, 2, -2], [-2, -2], [2, -3]], [[-1, -1, -1, -2, -3], [-2, -2], [2, 2]]]
|
|
4012
|
+
sage: StrongTableaux(3, [4,1,1]).cardinality()
|
|
4013
|
+
10
|
|
4014
|
+
sage: StrongTableaux(3, [5,2,2], weight=[6,1]).list() # there are no strong column strict tableaux of shape [5,2,2] and weight (6,1)
|
|
4015
|
+
[]
|
|
4016
|
+
sage: StrongTableaux(3, [[5,2,2], [3,1,1]], weight=[2,1]).list()
|
|
4017
|
+
[[[None, None, None, -1, -1], [None, 1], [None, -2]],
|
|
4018
|
+
[[None, None, None, 1, -1], [None, -1], [None, -2]],
|
|
4019
|
+
[[None, None, None, -1, -2], [None, -1], [None, 1]]]
|
|
4020
|
+
sage: StrongTableaux(2, [[4,3,3,2,2,1,1], [2,1,1]], weight=[1,1,1,1]).cardinality()
|
|
4021
|
+
150
|
|
4022
|
+
sage: StrongTableaux(2, [[7,5,3,1], [2,1,1]], weight=[2,2]).cardinality()
|
|
4023
|
+
18
|
|
4024
|
+
sage: StrongTableaux(2, [[3,1],[3,1]]).list()
|
|
4025
|
+
[[[None, None, None], [None]]]
|
|
4026
|
+
sage: StrongTableaux(4, []).list()
|
|
4027
|
+
[[]]
|
|
4028
|
+
"""
|
|
4029
|
+
size = sum(self._weight)
|
|
4030
|
+
if size == 0:
|
|
4031
|
+
yield self([[None]*(row) for row in self._inner_shape])
|
|
4032
|
+
else:
|
|
4033
|
+
for unT in StrongTableaux.standard_unmarked_iterator( self.k, size, self._outer_shape, self._inner_shape ):
|
|
4034
|
+
yield from StrongTableaux.marked_given_unmarked_and_weight_iterator( unT, self.k, self._weight )
|
|
4035
|
+
|
|
4036
|
+
@classmethod
|
|
4037
|
+
def standard_unmarked_iterator( cls, k, size, outer_shape=None, inner_shape=[] ):
|
|
4038
|
+
r"""
|
|
4039
|
+
An iterator for standard unmarked strong tableaux.
|
|
4040
|
+
|
|
4041
|
+
An iterator which generates all unmarked tableaux of a given ``size`` which are
|
|
4042
|
+
contained in ``outer_shape`` and which contain the ``inner_shape``.
|
|
4043
|
+
|
|
4044
|
+
These are built recursively by building all standard marked strong tableaux of
|
|
4045
|
+
size ``size`` `-1` and adding all possible covers.
|
|
4046
|
+
|
|
4047
|
+
If ``outer_shape`` is ``None`` then there is no restriction on the shape of the
|
|
4048
|
+
tableaux which are created.
|
|
4049
|
+
|
|
4050
|
+
INPUT:
|
|
4051
|
+
|
|
4052
|
+
- ``k``, ``size`` -- positive integers
|
|
4053
|
+
- ``outer_shape`` -- list representing a `k+1`-core (default: ``None``)
|
|
4054
|
+
- ``inner_shape`` -- list representing a `k+1`-core (default: ``[]``)
|
|
4055
|
+
|
|
4056
|
+
OUTPUT:
|
|
4057
|
+
|
|
4058
|
+
- an iterator which lists all standard strong unmarked tableaux with ``size``
|
|
4059
|
+
cells and which are contained in ``outer_shape`` and contain ``inner_shape``
|
|
4060
|
+
|
|
4061
|
+
EXAMPLES::
|
|
4062
|
+
|
|
4063
|
+
sage: list(StrongTableaux.standard_unmarked_iterator(2, 3))
|
|
4064
|
+
[[[1, 2, 3], [3]], [[1, 2], [3], [3]], [[1, 3, 3], [2]], [[1, 3], [2], [3]]]
|
|
4065
|
+
sage: list(StrongTableaux.standard_unmarked_iterator(2, 1, inner_shape=[1,1]))
|
|
4066
|
+
[[[None, 1, 1], [None]], [[None, 1], [None], [1]]]
|
|
4067
|
+
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,4)))
|
|
4068
|
+
10
|
|
4069
|
+
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,6)))
|
|
4070
|
+
98
|
|
4071
|
+
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,4, inner_shape=[2,2])))
|
|
4072
|
+
92
|
|
4073
|
+
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,4, outer_shape=[5,2,2,1], inner_shape=[2,2])))
|
|
4074
|
+
10
|
|
4075
|
+
|
|
4076
|
+
TESTS::
|
|
4077
|
+
|
|
4078
|
+
sage: list(StrongTableaux.standard_unmarked_iterator(2,0, outer_shape=[3,1], inner_shape=[3,1]))
|
|
4079
|
+
[[[None, None, None], [None]]]
|
|
4080
|
+
sage: list(StrongTableaux.standard_unmarked_iterator(4,0, outer_shape=[]))
|
|
4081
|
+
[[]]
|
|
4082
|
+
"""
|
|
4083
|
+
if size == 0:
|
|
4084
|
+
if outer_shape is None or Core(outer_shape,k+1).contains(inner_shape):
|
|
4085
|
+
yield [[None]*(inner_shape[i]) for i in range(len(inner_shape))]
|
|
4086
|
+
else:
|
|
4087
|
+
for T in cls.standard_unmarked_iterator(k, size-1, outer_shape, inner_shape):
|
|
4088
|
+
for TT in cls.follows_tableau_unsigned_standard(T, k):
|
|
4089
|
+
if outer_shape is None or Core(outer_shape, k+1).contains([len(r) for r in TT]):
|
|
4090
|
+
yield TT
|
|
4091
|
+
|
|
4092
|
+
@classmethod
|
|
4093
|
+
def marked_given_unmarked_and_weight_iterator(cls, unmarkedT, k, weight):
|
|
4094
|
+
r"""
|
|
4095
|
+
An iterator generating strong marked tableaux from an unmarked strong tableau.
|
|
4096
|
+
|
|
4097
|
+
Iterator which lists all marked tableaux of weight ``weight`` such that the
|
|
4098
|
+
standard unmarked part of the tableau is equal to ``unmarkedT``.
|
|
4099
|
+
|
|
4100
|
+
INPUT:
|
|
4101
|
+
|
|
4102
|
+
- ``unmarkedT`` -- list of lists representing a strong unmarked tableau
|
|
4103
|
+
- ``k`` -- positive integer
|
|
4104
|
+
- ``weight`` -- list of nonnegative integers indicating the weight
|
|
4105
|
+
|
|
4106
|
+
OUTPUT: an iterator that returns ``StrongTableau`` objects
|
|
4107
|
+
|
|
4108
|
+
EXAMPLES::
|
|
4109
|
+
|
|
4110
|
+
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [3])
|
|
4111
|
+
sage: list(ST)
|
|
4112
|
+
[[[-1, -1, -1], [1]]]
|
|
4113
|
+
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [0,3])
|
|
4114
|
+
sage: list(ST)
|
|
4115
|
+
[[[-2, -2, -2], [2]]]
|
|
4116
|
+
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [1,2])
|
|
4117
|
+
sage: list(ST)
|
|
4118
|
+
[[[-1, -2, -2], [2]]]
|
|
4119
|
+
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [2,1])
|
|
4120
|
+
sage: list(ST)
|
|
4121
|
+
[[[-1, -1, 2], [-2]], [[-1, -1, -2], [2]]]
|
|
4122
|
+
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[None, None, 1, 2, 4], [2, 4], [3]], 3, [3,1])
|
|
4123
|
+
sage: list(ST)
|
|
4124
|
+
[]
|
|
4125
|
+
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[None, None, 1, 2, 4], [2, 4], [3]], 3, [2,2])
|
|
4126
|
+
sage: list(ST)
|
|
4127
|
+
[[[None, None, -1, -1, 2], [1, -2], [-2]],
|
|
4128
|
+
[[None, None, -1, -1, -2], [1, 2], [-2]]]
|
|
4129
|
+
|
|
4130
|
+
TESTS::
|
|
4131
|
+
|
|
4132
|
+
sage: list(StrongTableaux.marked_given_unmarked_and_weight_iterator([[None, None, None],[None]], 2, []))
|
|
4133
|
+
[[[None, None, None], [None]]]
|
|
4134
|
+
sage: list(StrongTableaux.marked_given_unmarked_and_weight_iterator([], 4, weight=[]))
|
|
4135
|
+
[[]]
|
|
4136
|
+
"""
|
|
4137
|
+
td = StrongTableaux.cells_head_dictionary(unmarkedT)
|
|
4138
|
+
if td == {}: # the tableau is empty
|
|
4139
|
+
yield StrongTableau(unmarkedT, k, [])
|
|
4140
|
+
else:
|
|
4141
|
+
import itertools
|
|
4142
|
+
dsc = Composition(weight).descents()
|
|
4143
|
+
for m in itertools.product(*[td[key] for key in sorted(td)]):
|
|
4144
|
+
if all(((m[i][1]-m[i][0] < m[i+1][1]-m[i+1][0]) or (i in dsc))
|
|
4145
|
+
for i in range(len(m)-1)):
|
|
4146
|
+
yield StrongTableaux.add_marking(unmarkedT, m, k, weight)
|
|
4147
|
+
|
|
4148
|
+
@classmethod
|
|
4149
|
+
def add_marking( cls, unmarkedT, marking, k, weight ):
|
|
4150
|
+
r"""
|
|
4151
|
+
Add markings to a partially marked strong tableau.
|
|
4152
|
+
|
|
4153
|
+
Given a partially marked standard tableau and a list of cells where the marks
|
|
4154
|
+
should be placed along with a ``weight``, return the semi-standard marked strong
|
|
4155
|
+
tableau. The marking should complete the marking so that the result is a
|
|
4156
|
+
strong standard marked tableau.
|
|
4157
|
+
|
|
4158
|
+
INPUT:
|
|
4159
|
+
|
|
4160
|
+
- ``unmarkedT`` -- list of lists which is a partially marked strong `k`-tableau
|
|
4161
|
+
- ``marking`` -- list of pairs of coordinates where cells are to be marked
|
|
4162
|
+
- ``k`` -- positive integer
|
|
4163
|
+
- ``weight`` -- tuple of the weight of the output tableau
|
|
4164
|
+
|
|
4165
|
+
OUTPUT: a ``StrongTableau`` object
|
|
4166
|
+
|
|
4167
|
+
EXAMPLES::
|
|
4168
|
+
|
|
4169
|
+
sage: StrongTableaux.add_marking([[None,1,2],[2]], [(0,1), (1,0)], 2, [1,1])
|
|
4170
|
+
[[None, -1, 2], [-2]]
|
|
4171
|
+
sage: StrongTableaux.add_marking([[None,1,2],[2]], [(0,1), (1,0)], 2, [2])
|
|
4172
|
+
Traceback (most recent call last):
|
|
4173
|
+
...
|
|
4174
|
+
ValueError: The weight=(2,) and the markings on the standard tableau=[[None, -1, 2], [-2]] do not agree.
|
|
4175
|
+
sage: StrongTableaux.add_marking([[None,1,2],[2]], [(0,1), (0,2)], 2, [2])
|
|
4176
|
+
[[None, -1, -1], [1]]
|
|
4177
|
+
|
|
4178
|
+
TESTS::
|
|
4179
|
+
|
|
4180
|
+
sage: StrongTableaux.add_marking([[None,None,None],[None]], [], 2, [])
|
|
4181
|
+
[[None, None, None], [None]]
|
|
4182
|
+
sage: StrongTableaux.add_marking([], [], 2, [])
|
|
4183
|
+
[]
|
|
4184
|
+
"""
|
|
4185
|
+
def msgn(c, v):
|
|
4186
|
+
if c in marking:
|
|
4187
|
+
return -v
|
|
4188
|
+
else:
|
|
4189
|
+
return v
|
|
4190
|
+
return StrongTableau([[msgn((i,j),unmarkedT[i][j]) for j in range(len(unmarkedT[i]))] for i in range(len(unmarkedT))], k, weight )
|
|
4191
|
+
|
|
4192
|
+
@classmethod
|
|
4193
|
+
def _left_action_list( cls, Tlist, tij, v, k ):
|
|
4194
|
+
r"""
|
|
4195
|
+
Act by the transposition ``tij`` if it increases the size of the tableau by 1.
|
|
4196
|
+
|
|
4197
|
+
This method modifies the tableau ``Tlist`` instead of returning a copy.
|
|
4198
|
+
|
|
4199
|
+
INPUT:
|
|
4200
|
+
|
|
4201
|
+
- ``Tlist`` -- a partial standard strong `k`-tableau as a list of lists
|
|
4202
|
+
- ``tij`` -- a pair of integers representing a transposition
|
|
4203
|
+
- ``v`` -- the label to add to the tableau
|
|
4204
|
+
- ``k`` -- positive integer
|
|
4205
|
+
|
|
4206
|
+
OUTPUT: list of lists, in particular, it is ``Tlist``
|
|
4207
|
+
|
|
4208
|
+
EXAMPLES::
|
|
4209
|
+
|
|
4210
|
+
sage: StrongTableaux._left_action_list( [[None]], [1,2], 10, 2 )
|
|
4211
|
+
[[None, -10]]
|
|
4212
|
+
sage: StrongTableaux._left_action_list( [[None]], [1,2], 10, 1 )
|
|
4213
|
+
[[None, -10], [10]]
|
|
4214
|
+
sage: StrongTableaux._left_action_list( [[None]], [2,3], 10, 1 )
|
|
4215
|
+
Traceback (most recent call last):
|
|
4216
|
+
...
|
|
4217
|
+
ValueError: [2, 3] is not a single step up in the strong lattice
|
|
4218
|
+
sage: StrongTableaux._left_action_list( [[None]], [3,4], 10, 1 )
|
|
4219
|
+
[[None, 10], [10]]
|
|
4220
|
+
sage: T = StrongTableaux._left_action_list( [[None]], [1,2], 10, 2 )
|
|
4221
|
+
sage: StrongTableaux._left_action_list( T, [2,3], 4, 2 )
|
|
4222
|
+
[[None, -10, -4], [4]]
|
|
4223
|
+
sage: T
|
|
4224
|
+
[[None, -10, -4], [4]]
|
|
4225
|
+
"""
|
|
4226
|
+
innershape = Core([len(r) for r in Tlist], k + 1)
|
|
4227
|
+
outershape = innershape.affine_symmetric_group_action(tij, transposition=True)
|
|
4228
|
+
if outershape.length() == innershape.length() + 1:
|
|
4229
|
+
for c in SkewPartition([outershape.to_partition(),innershape.to_partition()]).cells():
|
|
4230
|
+
while c[0] >= len(Tlist):
|
|
4231
|
+
Tlist.append([])
|
|
4232
|
+
Tlist[c[0]].append(v)
|
|
4233
|
+
if len(Tlist[c[0]])-c[0] == tij[1]:
|
|
4234
|
+
Tlist[c[0]][-1] = -Tlist[c[0]][-1] # mark the cell that is on the j-1 diagonal
|
|
4235
|
+
return Tlist
|
|
4236
|
+
|
|
4237
|
+
raise ValueError("%s is not a single step up in the strong lattice" % tij)
|
|
4238
|
+
|
|
4239
|
+
@classmethod
|
|
4240
|
+
def follows_tableau_unsigned_standard( cls, Tlist, k ):
|
|
4241
|
+
r"""
|
|
4242
|
+
Return a list of strong tableaux one longer in length than ``Tlist``.
|
|
4243
|
+
|
|
4244
|
+
Return list of all standard strong tableaux obtained from ``Tlist`` by extending to
|
|
4245
|
+
a core which follows the shape of ``Tlist`` in the strong order. It does not put
|
|
4246
|
+
the markings on the last entry that it adds but it does keep the markings on all
|
|
4247
|
+
entries smaller. The objects returned are not ``StrongTableau`` objects (and
|
|
4248
|
+
cannot be) because the last entry will not properly marked.
|
|
4249
|
+
|
|
4250
|
+
INPUT:
|
|
4251
|
+
|
|
4252
|
+
- ``Tlist`` -- a filling of a `k+1`-core as a list of lists
|
|
4253
|
+
- ``k`` -- integer
|
|
4254
|
+
|
|
4255
|
+
OUTPUT: list of strong tableaux which follow ``Tlist`` in strong order
|
|
4256
|
+
|
|
4257
|
+
EXAMPLES::
|
|
4258
|
+
|
|
4259
|
+
sage: StrongTableaux.follows_tableau_unsigned_standard([[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]], 3)
|
|
4260
|
+
[[[-1, -1, -2, -3, 5, 5, 5], [-2, 3, -3, 4], [2, 3], [-3, -4]],
|
|
4261
|
+
[[-1, -1, -2, -3, 5], [-2, 3, -3, 4], [2, 3, 5], [-3, -4], [5]],
|
|
4262
|
+
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4], [5], [5], [5]]]
|
|
4263
|
+
sage: StrongTableaux.follows_tableau_unsigned_standard([[None,-1],[-2,-3]],3)
|
|
4264
|
+
[[[None, -1, 4, 4, 4], [-2, -3]], [[None, -1, 4], [-2, -3], [4]],
|
|
4265
|
+
[[None, -1], [-2, -3], [4], [4], [4]]]
|
|
4266
|
+
|
|
4267
|
+
TESTS::
|
|
4268
|
+
|
|
4269
|
+
sage: StrongTableaux.follows_tableau_unsigned_standard([[None, None, None], [None]], 2)
|
|
4270
|
+
[[[None, None, None, 1], [None, 1]], [[None, None, None], [None], [1]]]
|
|
4271
|
+
sage: StrongTableaux.follows_tableau_unsigned_standard([], 4)
|
|
4272
|
+
[[[1]]]
|
|
4273
|
+
"""
|
|
4274
|
+
v = 1 + max((abs(v) for rows in Tlist for v in rows if v is not None),
|
|
4275
|
+
default=0)
|
|
4276
|
+
out = []
|
|
4277
|
+
sh = Core([len(r) for r in Tlist], k + 1)
|
|
4278
|
+
for ga in sh.strong_covers():
|
|
4279
|
+
T = copy.deepcopy(Tlist)
|
|
4280
|
+
T += [[] for _ in repeat(None, len(ga) - len(T))]
|
|
4281
|
+
for c in SkewPartition([ga.to_partition(), sh.to_partition()]).cells():
|
|
4282
|
+
T[c[0]] += [v]
|
|
4283
|
+
out.append(T)
|
|
4284
|
+
return out
|
|
4285
|
+
|
|
4286
|
+
@classmethod
|
|
4287
|
+
def standard_marked_iterator( cls, k, size, outer_shape=None, inner_shape=[] ):
|
|
4288
|
+
r"""
|
|
4289
|
+
An iterator for generating standard strong marked tableaux.
|
|
4290
|
+
|
|
4291
|
+
An iterator which generates all standard marked `k`-tableaux of a given ``size``
|
|
4292
|
+
which are contained in ``outer_shape`` and contain the ``inner_shape``.
|
|
4293
|
+
If ``outer_shape`` is ``None`` then there is no restriction on the shape of the
|
|
4294
|
+
tableaux which are created.
|
|
4295
|
+
|
|
4296
|
+
INPUT:
|
|
4297
|
+
|
|
4298
|
+
- ``k`` -- positive integer
|
|
4299
|
+
- ``size`` -- positive integer
|
|
4300
|
+
- ``outer_shape`` -- list which is a `k+1`-core (default: ``None``)
|
|
4301
|
+
- ``inner_shape`` -- list which is a `k+1`-core (default: ``[]``)
|
|
4302
|
+
|
|
4303
|
+
OUTPUT:
|
|
4304
|
+
|
|
4305
|
+
- an iterator which returns the standard marked tableaux with ``size`` cells
|
|
4306
|
+
and that are contained in ``outer_shape`` and contain ``inner_shape``
|
|
4307
|
+
|
|
4308
|
+
EXAMPLES::
|
|
4309
|
+
|
|
4310
|
+
sage: list(StrongTableaux.standard_marked_iterator(2, 3))
|
|
4311
|
+
[[[-1, -2, 3], [-3]], [[-1, -2, -3], [3]], [[-1, -2], [-3], [3]], [[-1, 3, -3], [-2]], [[-1, 3], [-2], [-3]], [[-1, -3], [-2], [3]]]
|
|
4312
|
+
sage: list(StrongTableaux.standard_marked_iterator(2, 1, inner_shape=[1,1]))
|
|
4313
|
+
[[[None, 1, -1], [None]], [[None, 1], [None], [-1]], [[None, -1], [None], [1]]]
|
|
4314
|
+
sage: len(list(StrongTableaux.standard_marked_iterator(4,4)))
|
|
4315
|
+
10
|
|
4316
|
+
sage: len(list(StrongTableaux.standard_marked_iterator(4,6)))
|
|
4317
|
+
140
|
|
4318
|
+
sage: len(list(StrongTableaux.standard_marked_iterator(4,4, inner_shape=[2,2])))
|
|
4319
|
+
200
|
|
4320
|
+
sage: len(list(StrongTableaux.standard_marked_iterator(4,4, outer_shape=[5,2,2,1], inner_shape=[2,2])))
|
|
4321
|
+
24
|
|
4322
|
+
|
|
4323
|
+
TESTS::
|
|
4324
|
+
|
|
4325
|
+
sage: list(StrongTableaux.standard_marked_iterator(2,0,inner_shape=[3,1]))
|
|
4326
|
+
[[[None, None, None], [None]]]
|
|
4327
|
+
sage: list(StrongTableaux.standard_marked_iterator(4,0))
|
|
4328
|
+
[[]]
|
|
4329
|
+
"""
|
|
4330
|
+
for T in cls.standard_unmarked_iterator( k, size, outer_shape, inner_shape ):
|
|
4331
|
+
yield from cls.marked_given_unmarked_and_weight_iterator( T, k, [1]*(size) )
|
|
4332
|
+
|
|
4333
|
+
@classmethod
|
|
4334
|
+
def cells_head_dictionary( cls, T ):
|
|
4335
|
+
r"""
|
|
4336
|
+
Return a dictionary with the locations of the heads of all markings.
|
|
4337
|
+
|
|
4338
|
+
Return a dictionary of values and lists of cells where the heads with the values
|
|
4339
|
+
are located in a strong standard unmarked tableau ``T``.
|
|
4340
|
+
|
|
4341
|
+
INPUT:
|
|
4342
|
+
|
|
4343
|
+
- ``T`` -- a strong standard unmarked tableau as a list of lists
|
|
4344
|
+
|
|
4345
|
+
OUTPUT:
|
|
4346
|
+
|
|
4347
|
+
- a dictionary with keys the entries in the tableau and values are the coordinates
|
|
4348
|
+
of the heads with those entries
|
|
4349
|
+
|
|
4350
|
+
EXAMPLES::
|
|
4351
|
+
|
|
4352
|
+
sage: StrongTableaux.cells_head_dictionary([[1,2,4,7],[3,6,6,8],[4,7],[5,8]])
|
|
4353
|
+
{1: [(0, 0)],
|
|
4354
|
+
2: [(0, 1)],
|
|
4355
|
+
3: [(1, 0)],
|
|
4356
|
+
4: [(2, 0), (0, 2)],
|
|
4357
|
+
5: [(3, 0)],
|
|
4358
|
+
6: [(1, 2)],
|
|
4359
|
+
7: [(2, 1), (0, 3)],
|
|
4360
|
+
8: [(3, 1), (1, 3)]}
|
|
4361
|
+
sage: StrongTableaux.cells_head_dictionary([[None, 2, 2, 4, 5, 6, 6, 6], [None, 3, 6, 6, 6], [1, 4]])
|
|
4362
|
+
{1: [(2, 0)],
|
|
4363
|
+
2: [(0, 2)],
|
|
4364
|
+
3: [(1, 1)],
|
|
4365
|
+
4: [(2, 1), (0, 3)],
|
|
4366
|
+
5: [(0, 4)],
|
|
4367
|
+
6: [(1, 4), (0, 7)]}
|
|
4368
|
+
|
|
4369
|
+
TESTS::
|
|
4370
|
+
|
|
4371
|
+
sage: StrongTableaux.cells_head_dictionary([[None, None, None],[None]])
|
|
4372
|
+
{}
|
|
4373
|
+
sage: StrongTableaux.cells_head_dictionary([])
|
|
4374
|
+
{}
|
|
4375
|
+
"""
|
|
4376
|
+
if T == []:
|
|
4377
|
+
return {}
|
|
4378
|
+
ST = SkewTableau(T)
|
|
4379
|
+
dout = {}
|
|
4380
|
+
for i in range(-len(T), len(T[0])):
|
|
4381
|
+
nextv = ST.entries_by_content(i + 1)
|
|
4382
|
+
for c in ST.cells_by_content(i):
|
|
4383
|
+
v = T[c[0]][c[1]]
|
|
4384
|
+
if v not in nextv:
|
|
4385
|
+
if v in dout:
|
|
4386
|
+
dout[v] += [c]
|
|
4387
|
+
else:
|
|
4388
|
+
dout[v] = [c]
|
|
4389
|
+
return dout
|
|
4390
|
+
|
|
4391
|
+
@classmethod
|
|
4392
|
+
def marked_CST_to_transposition_sequence(self, T, k):
|
|
4393
|
+
"""
|
|
4394
|
+
Return a list of transpositions corresponding to ``T``.
|
|
4395
|
+
|
|
4396
|
+
Given a strong column strict tableau ``T`` returns the list of transpositions
|
|
4397
|
+
which when applied to the left of an empty tableau gives the corresponding strong
|
|
4398
|
+
standard tableau.
|
|
4399
|
+
|
|
4400
|
+
INPUT:
|
|
4401
|
+
|
|
4402
|
+
- ``T`` -- a non-empty column strict tableau as a list of lists
|
|
4403
|
+
- ``k`` -- positive integer
|
|
4404
|
+
|
|
4405
|
+
OUTPUT: list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}`
|
|
4406
|
+
|
|
4407
|
+
EXAMPLES::
|
|
4408
|
+
|
|
4409
|
+
sage: CST_to_trans = StrongTableaux.marked_CST_to_transposition_sequence
|
|
4410
|
+
sage: CST_to_trans([[-1, -1, -1], [1]], 2)
|
|
4411
|
+
[[2, 3], [1, 2], [0, 1]]
|
|
4412
|
+
sage: CST_to_trans([], 2)
|
|
4413
|
+
[]
|
|
4414
|
+
sage: CST_to_trans([[-2, -2, -2], [2]], 2)
|
|
4415
|
+
[[2, 3], [1, 2], [0, 1]]
|
|
4416
|
+
sage: CST_to_trans([[-1, -2, -2, -2, -2], [-2, 2], [2]], 3)
|
|
4417
|
+
[[4, 5], [3, 4], [2, 3], [1, 2], [-1, 0], [0, 1]]
|
|
4418
|
+
sage: CST_to_trans([[-1, -2, -5, 5, -5, 5, -5], [-3, -4, 5, 5], [5]],3)
|
|
4419
|
+
[[5, 7], [3, 5], [2, 3], [0, 1], [-1, 0], [1, 2], [0, 1]]
|
|
4420
|
+
sage: CST_to_trans([[-1, -2, -3, 4, -7], [-4, -6], [-5, 6]],3)
|
|
4421
|
+
[[4, 5], [-1, 1], [-2, -1], [-1, 0], [2, 3], [1, 2], [0, 1]]
|
|
4422
|
+
|
|
4423
|
+
TESTS::
|
|
4424
|
+
|
|
4425
|
+
sage: StrongTableaux.marked_CST_to_transposition_sequence([[None, None, None], [None]], 2)
|
|
4426
|
+
[]
|
|
4427
|
+
sage: StrongTableaux.marked_CST_to_transposition_sequence([], 4)
|
|
4428
|
+
[]
|
|
4429
|
+
"""
|
|
4430
|
+
LL = list(T)
|
|
4431
|
+
if not LL or all(v is None for v in sum(LL,[])):
|
|
4432
|
+
return []
|
|
4433
|
+
marks = [v for row in T for v in row if v is not None and v < 0] + [0]
|
|
4434
|
+
m = -min(marks) # the largest marked cell
|
|
4435
|
+
transeq = [] # start with the empty list and append on the right
|
|
4436
|
+
sh = Core([len(r) for r in T], k + 1)
|
|
4437
|
+
j = max(c - r for r, row in enumerate(LL) for c, val in enumerate(row)
|
|
4438
|
+
if val == -m)
|
|
4439
|
+
P = sh.to_partition()
|
|
4440
|
+
for l in range(k):
|
|
4441
|
+
msh = sh.affine_symmetric_group_action([j-l,j+1], transposition=True)
|
|
4442
|
+
mP = msh.to_partition()
|
|
4443
|
+
# my worry here is that the affine symmetric group action might apply an invalid
|
|
4444
|
+
# transposition but get something of the right length anyway. How do I test if it is applying
|
|
4445
|
+
# a valid or invalid transposition?
|
|
4446
|
+
if msh.length() == sh.length() - 1:
|
|
4447
|
+
# if applying t_{j-l,j+1} reduces the size of the shape by 1
|
|
4448
|
+
valcells = [] # values in all the cells except content j
|
|
4449
|
+
regcells = [] # values in the cells with content j
|
|
4450
|
+
valid = True
|
|
4451
|
+
for (x,y) in SkewPartition([P, mP]).cells():
|
|
4452
|
+
if y-x != j:
|
|
4453
|
+
if LL[x][y] != m:
|
|
4454
|
+
valid = False
|
|
4455
|
+
break
|
|
4456
|
+
valcells.append(LL[x][y])
|
|
4457
|
+
else:
|
|
4458
|
+
regcells.append(LL[x][y])
|
|
4459
|
+
if valid and regcells == [-m]:
|
|
4460
|
+
# if all labels that are not content j are v and the label
|
|
4461
|
+
# with content j = -m
|
|
4462
|
+
mcells = mP.cells()
|
|
4463
|
+
MM = [[LL[a][b] for b in range(len(LL[a])) if (a,b) in mcells]
|
|
4464
|
+
for a in range(len(mP))]
|
|
4465
|
+
transeq = self.marked_CST_to_transposition_sequence(MM, k)
|
|
4466
|
+
if transeq is not None:
|
|
4467
|
+
return [[j-l, j+1]] + transeq
|
|
4468
|
+
|
|
4469
|
+
@classmethod
|
|
4470
|
+
def transpositions_to_standard_strong( self, transeq, k, emptyTableau=[] ):
|
|
4471
|
+
"""
|
|
4472
|
+
Return a strong tableau corresponding to a sequence of transpositions.
|
|
4473
|
+
|
|
4474
|
+
This method returns the action by left multiplication on the empty strong tableau
|
|
4475
|
+
by transpositions specified by ``transeq``.
|
|
4476
|
+
|
|
4477
|
+
INPUT:
|
|
4478
|
+
|
|
4479
|
+
- ``transeq`` -- a sequence of transpositions `t_{ij}` (a list of pairs)
|
|
4480
|
+
- ``emptyTableau`` -- (default: ``[]``) an empty list or a skew strong tableau
|
|
4481
|
+
possibly consisting of ``None`` entries
|
|
4482
|
+
|
|
4483
|
+
OUTPUT: a ``StrongTableau`` object
|
|
4484
|
+
|
|
4485
|
+
EXAMPLES::
|
|
4486
|
+
|
|
4487
|
+
sage: StrongTableaux.transpositions_to_standard_strong([[0,1]], 2)
|
|
4488
|
+
[[-1]]
|
|
4489
|
+
sage: StrongTableaux.transpositions_to_standard_strong([[-2,-1], [2,3]], 2, [[None, None]])
|
|
4490
|
+
[[None, None, -1], [1], [-2]]
|
|
4491
|
+
sage: StrongTableaux.transpositions_to_standard_strong([[2, 3], [1, 2], [0, 1]], 2)
|
|
4492
|
+
[[-1, -2, -3], [3]]
|
|
4493
|
+
sage: StrongTableaux.transpositions_to_standard_strong([[-1, 0], [1, 2], [0, 1]], 2)
|
|
4494
|
+
[[-1, -2, 3], [-3]]
|
|
4495
|
+
sage: StrongTableaux.transpositions_to_standard_strong([[3, 4], [-1, 0], [1, 2]], 2, [[None]])
|
|
4496
|
+
[[None, -1, 2, -3], [-2, 3]]
|
|
4497
|
+
|
|
4498
|
+
TESTS::
|
|
4499
|
+
|
|
4500
|
+
sage: StrongTableaux.transpositions_to_standard_strong([], 2, [[None, None, None], [None]])
|
|
4501
|
+
[[None, None, None], [None]]
|
|
4502
|
+
sage: StrongTableaux.transpositions_to_standard_strong([], 4, [])
|
|
4503
|
+
[]
|
|
4504
|
+
"""
|
|
4505
|
+
out = copy.deepcopy(emptyTableau)
|
|
4506
|
+
for i in range(1,len(transeq)+1):
|
|
4507
|
+
out = StrongTableaux._left_action_list(out, transeq[-i], i, k)
|
|
4508
|
+
return StrongTableau(out, k, weight=(1,)*len(transeq))
|
|
4509
|
+
|
|
4510
|
+
Element = StrongTableau
|
|
4511
|
+
|
|
4512
|
+
#### common or global functions related to weak/strong tableaux
|
|
4513
|
+
|
|
4514
|
+
|
|
4515
|
+
def nabs(v):
|
|
4516
|
+
r"""
|
|
4517
|
+
Return the absolute value of ``v`` or ``None``.
|
|
4518
|
+
|
|
4519
|
+
INPUT:
|
|
4520
|
+
|
|
4521
|
+
- ``v`` -- either an integer or ``None``
|
|
4522
|
+
|
|
4523
|
+
OUTPUT: either a nonnegative integer or ``None``
|
|
4524
|
+
|
|
4525
|
+
EXAMPLES::
|
|
4526
|
+
|
|
4527
|
+
sage: from sage.combinat.k_tableau import nabs
|
|
4528
|
+
sage: nabs(None)
|
|
4529
|
+
sage: nabs(-3)
|
|
4530
|
+
3
|
|
4531
|
+
sage: nabs(None)
|
|
4532
|
+
"""
|
|
4533
|
+
if v is None:
|
|
4534
|
+
return v
|
|
4535
|
+
else:
|
|
4536
|
+
return abs(v)
|
|
4537
|
+
|
|
4538
|
+
|
|
4539
|
+
def intermediate_shapes(t):
|
|
4540
|
+
r"""
|
|
4541
|
+
Return the intermediate shapes of tableau ``t``.
|
|
4542
|
+
|
|
4543
|
+
A (skew) tableau with letters `1, 2,\ldots, \ell` can be viewed as a sequence of
|
|
4544
|
+
shapes, where the `i`-th shape is given by the shape of the subtableau on letters
|
|
4545
|
+
`1, 2, \ldots, i`. The output is the list of these shapes.
|
|
4546
|
+
|
|
4547
|
+
OUTPUT: list of lists representing partitions
|
|
4548
|
+
|
|
4549
|
+
EXAMPLES::
|
|
4550
|
+
|
|
4551
|
+
sage: from sage.combinat.k_tableau import intermediate_shapes
|
|
4552
|
+
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
|
|
4553
|
+
sage: intermediate_shapes(t)
|
|
4554
|
+
[[], [2], [4, 1], [5, 2, 1]]
|
|
4555
|
+
|
|
4556
|
+
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
|
|
4557
|
+
sage: intermediate_shapes(t)
|
|
4558
|
+
[[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]]
|
|
4559
|
+
"""
|
|
4560
|
+
shapes = []
|
|
4561
|
+
t = SkewTableau(list(t))
|
|
4562
|
+
for i in range(len(t.weight())+1):
|
|
4563
|
+
shapes += [ t.restrict(i).outer_shape()]
|
|
4564
|
+
return shapes
|