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,1180 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
r"""
|
|
3
|
+
Ribbon tableaux
|
|
4
|
+
"""
|
|
5
|
+
# ****************************************************************************
|
|
6
|
+
# Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
|
|
7
|
+
#
|
|
8
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
9
|
+
#
|
|
10
|
+
# This code is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
# General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# The full text of the GPL is available at:
|
|
16
|
+
#
|
|
17
|
+
# https://www.gnu.org/licenses/
|
|
18
|
+
# ****************************************************************************
|
|
19
|
+
import functools
|
|
20
|
+
|
|
21
|
+
from sage.structure.parent import Parent
|
|
22
|
+
from sage.structure.element import parent
|
|
23
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
24
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
|
25
|
+
from sage.categories.sets_cat import Sets
|
|
26
|
+
from sage.rings.integer_ring import ZZ
|
|
27
|
+
from sage.rings.integer import Integer
|
|
28
|
+
from sage.combinat.combinat import CombinatorialElement
|
|
29
|
+
from sage.combinat.skew_partition import SkewPartition, SkewPartitions
|
|
30
|
+
from sage.combinat.skew_tableau import (SkewTableau, SkewTableaux,
|
|
31
|
+
SemistandardSkewTableaux)
|
|
32
|
+
from sage.combinat.tableau import Tableaux
|
|
33
|
+
from sage.combinat.partition import Partition, _Partitions
|
|
34
|
+
from sage.combinat.permutation import to_standard
|
|
35
|
+
from sage.misc.persist import register_unpickle_override
|
|
36
|
+
from . import permutation
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class RibbonTableau(SkewTableau):
|
|
40
|
+
r"""
|
|
41
|
+
A ribbon tableau.
|
|
42
|
+
|
|
43
|
+
A ribbon is a connected skew shape which does not contain any
|
|
44
|
+
`2 \times 2` boxes. A ribbon tableau is a skew tableau
|
|
45
|
+
whose shape is partitioned into ribbons, each of which is filled
|
|
46
|
+
with identical entries.
|
|
47
|
+
|
|
48
|
+
EXAMPLES::
|
|
49
|
+
|
|
50
|
+
sage: rt = RibbonTableau([[None, 1],[2,3]]); rt
|
|
51
|
+
[[None, 1], [2, 3]]
|
|
52
|
+
sage: rt.inner_shape()
|
|
53
|
+
[1]
|
|
54
|
+
sage: rt.outer_shape()
|
|
55
|
+
[2, 2]
|
|
56
|
+
|
|
57
|
+
sage: rt = RibbonTableau([[None, None, 0, 0, 0], [None, 0, 0, 2], [1, 0, 1]]); rt.pp()
|
|
58
|
+
. . 0 0 0
|
|
59
|
+
. 0 0 2
|
|
60
|
+
1 0 1
|
|
61
|
+
|
|
62
|
+
In the previous example, each ribbon is uniquely determined by a
|
|
63
|
+
nonzero entry. The 0 entries are used to fill in the rest of the
|
|
64
|
+
skew shape.
|
|
65
|
+
|
|
66
|
+
.. NOTE::
|
|
67
|
+
|
|
68
|
+
Sanity checks are not performed; lists can contain any object.
|
|
69
|
+
|
|
70
|
+
::
|
|
71
|
+
|
|
72
|
+
sage: RibbonTableau(expr=[[1,1],[[5],[3,4],[1,2]]])
|
|
73
|
+
[[None, 1, 2], [None, 3, 4], [5]]
|
|
74
|
+
|
|
75
|
+
TESTS::
|
|
76
|
+
|
|
77
|
+
sage: RibbonTableau([[0, 0, 3, 0], [1, 1, 0], [2, 0, 4]]).evaluation()
|
|
78
|
+
[2, 1, 1, 1]
|
|
79
|
+
"""
|
|
80
|
+
# The following method is private and will only get called
|
|
81
|
+
# when calling RibbonTableau() directly, and not via element_class
|
|
82
|
+
@staticmethod
|
|
83
|
+
def __classcall_private__(cls, rt=None, expr=None):
|
|
84
|
+
"""
|
|
85
|
+
Return a ribbon tableau object.
|
|
86
|
+
|
|
87
|
+
EXAMPLES::
|
|
88
|
+
|
|
89
|
+
sage: rt = RibbonTableau([[None, 1],[2,3]]); rt
|
|
90
|
+
[[None, 1], [2, 3]]
|
|
91
|
+
sage: TestSuite(rt).run()
|
|
92
|
+
"""
|
|
93
|
+
if expr is not None:
|
|
94
|
+
return RibbonTableaux().from_expr(expr)
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
rt = [tuple(row) for row in rt]
|
|
98
|
+
except TypeError:
|
|
99
|
+
raise TypeError("each element of the ribbon tableau "
|
|
100
|
+
"must be an iterable")
|
|
101
|
+
if not all(row for row in rt):
|
|
102
|
+
raise TypeError("a ribbon tableau cannot have empty rows")
|
|
103
|
+
# calls the inherited __init__ method (of SkewTableau )
|
|
104
|
+
return RibbonTableaux()(rt)
|
|
105
|
+
|
|
106
|
+
def length(self):
|
|
107
|
+
"""
|
|
108
|
+
Return the length of the ribbons into a ribbon tableau.
|
|
109
|
+
|
|
110
|
+
EXAMPLES::
|
|
111
|
+
|
|
112
|
+
sage: RibbonTableau([[None, 1],[2,3]]).length()
|
|
113
|
+
1
|
|
114
|
+
sage: RibbonTableau([[1,0],[2,0]]).length()
|
|
115
|
+
2
|
|
116
|
+
"""
|
|
117
|
+
if self.to_expr() == [[], []]:
|
|
118
|
+
return 0
|
|
119
|
+
|
|
120
|
+
tableau = self.to_expr()[1]
|
|
121
|
+
l = 0
|
|
122
|
+
t = 0
|
|
123
|
+
for k in range(len(tableau)):
|
|
124
|
+
t += len([x for x in tableau[k] if x is not None and x > -1])
|
|
125
|
+
l += len([x for x in tableau[k] if x is not None and x > 0])
|
|
126
|
+
|
|
127
|
+
if l == 0:
|
|
128
|
+
return t
|
|
129
|
+
else:
|
|
130
|
+
return t // l
|
|
131
|
+
|
|
132
|
+
def to_word(self):
|
|
133
|
+
"""
|
|
134
|
+
Return a word obtained from a row reading of ``self``.
|
|
135
|
+
|
|
136
|
+
.. WARNING::
|
|
137
|
+
|
|
138
|
+
Unlike the ``to_word`` method on skew tableaux (which are a
|
|
139
|
+
superclass of this), this method does not filter out
|
|
140
|
+
``None`` entries.
|
|
141
|
+
|
|
142
|
+
EXAMPLES::
|
|
143
|
+
|
|
144
|
+
sage: R = RibbonTableau([[0, 0, 3, 0], [1, 1, 0], [2, 0, 4]])
|
|
145
|
+
sage: R.to_word()
|
|
146
|
+
word: 2041100030
|
|
147
|
+
"""
|
|
148
|
+
from sage.combinat.words.word import Word
|
|
149
|
+
return Word([letter for row in reversed(self) for letter in row])
|
|
150
|
+
|
|
151
|
+
# ===================
|
|
152
|
+
# Ribbon Tableaux
|
|
153
|
+
# ===================
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class RibbonTableaux(UniqueRepresentation, Parent):
|
|
157
|
+
r"""
|
|
158
|
+
Ribbon tableaux.
|
|
159
|
+
|
|
160
|
+
A ribbon tableau is a skew tableau whose skew shape ``shape`` is
|
|
161
|
+
tiled by ribbons of length ``length``. The weight ``weight`` is
|
|
162
|
+
calculated from the labels on the ribbons.
|
|
163
|
+
|
|
164
|
+
.. NOTE::
|
|
165
|
+
|
|
166
|
+
Here we impose the condition that the ribbon tableaux are semistandard.
|
|
167
|
+
|
|
168
|
+
INPUT(Optional):
|
|
169
|
+
|
|
170
|
+
- ``shape`` -- skew shape as a list of lists or an object of type
|
|
171
|
+
SkewPartition
|
|
172
|
+
|
|
173
|
+
- ``length`` -- integer; ``shape`` is partitioned into ribbons of
|
|
174
|
+
length ``length``
|
|
175
|
+
|
|
176
|
+
- ``weight`` -- list of integers; computed from the values of
|
|
177
|
+
nonzero entries labeling the ribbons
|
|
178
|
+
|
|
179
|
+
EXAMPLES::
|
|
180
|
+
|
|
181
|
+
sage: RibbonTableaux([[2,1],[]], [1,1,1], 1)
|
|
182
|
+
Ribbon tableaux of shape [2, 1] / [] and weight [1, 1, 1] with 1-ribbons
|
|
183
|
+
|
|
184
|
+
sage: R = RibbonTableaux([[5,4,3],[2,1]], [2,1], 3)
|
|
185
|
+
sage: for i in R: i.pp(); print("\n")
|
|
186
|
+
. . 0 0 0
|
|
187
|
+
. 0 0 2
|
|
188
|
+
1 0 1
|
|
189
|
+
<BLANKLINE>
|
|
190
|
+
. . 1 0 0
|
|
191
|
+
. 0 0 0
|
|
192
|
+
1 0 2
|
|
193
|
+
<BLANKLINE>
|
|
194
|
+
. . 0 0 0
|
|
195
|
+
. 1 0 1
|
|
196
|
+
2 0 0
|
|
197
|
+
<BLANKLINE>
|
|
198
|
+
|
|
199
|
+
REFERENCES:
|
|
200
|
+
|
|
201
|
+
.. [vanLeeuwen91] Marc. A. A. van Leeuwen, *Edge sequences,
|
|
202
|
+
ribbon tableaux, and an action of affine permutations*.
|
|
203
|
+
Europe J. Combinatorics. **20** (1999).
|
|
204
|
+
http://wwwmathlabo.univ-poitiers.fr/~maavl/pdf/edgeseqs.pdf
|
|
205
|
+
"""
|
|
206
|
+
@staticmethod
|
|
207
|
+
def __classcall_private__(cls, shape=None, weight=None, length=None):
|
|
208
|
+
"""
|
|
209
|
+
Return the correct parent object.
|
|
210
|
+
|
|
211
|
+
EXAMPLES::
|
|
212
|
+
|
|
213
|
+
sage: R = RibbonTableaux([[2,1],[]],[1,1,1],1)
|
|
214
|
+
sage: R2 = RibbonTableaux(SkewPartition([[2,1],[]]),(1,1,1),1)
|
|
215
|
+
sage: R is R2
|
|
216
|
+
True
|
|
217
|
+
"""
|
|
218
|
+
if shape is None and weight is None and length is None:
|
|
219
|
+
return super().__classcall__(cls)
|
|
220
|
+
|
|
221
|
+
return RibbonTableaux_shape_weight_length(shape, weight, length)
|
|
222
|
+
|
|
223
|
+
def __init__(self):
|
|
224
|
+
"""
|
|
225
|
+
EXAMPLES::
|
|
226
|
+
|
|
227
|
+
sage: R = RibbonTableaux()
|
|
228
|
+
sage: TestSuite(R).run()
|
|
229
|
+
"""
|
|
230
|
+
Parent.__init__(self, category=Sets())
|
|
231
|
+
|
|
232
|
+
def _repr_(self):
|
|
233
|
+
"""
|
|
234
|
+
Return a string representation of ``self``.
|
|
235
|
+
|
|
236
|
+
EXAMPLES::
|
|
237
|
+
|
|
238
|
+
sage: RibbonTableaux()
|
|
239
|
+
Ribbon tableaux
|
|
240
|
+
"""
|
|
241
|
+
return "Ribbon tableaux"
|
|
242
|
+
|
|
243
|
+
def _element_constructor_(self, rt):
|
|
244
|
+
"""
|
|
245
|
+
Construct an element of ``self`` from ``rt``.
|
|
246
|
+
|
|
247
|
+
EXAMPLES::
|
|
248
|
+
|
|
249
|
+
sage: R = RibbonTableaux()
|
|
250
|
+
sage: elt = R([[0, 0, 3, 0], [1, 1, 0], [2, 0, 4]]); elt
|
|
251
|
+
[[0, 0, 3, 0], [1, 1, 0], [2, 0, 4]]
|
|
252
|
+
sage: elt.parent() is R
|
|
253
|
+
True
|
|
254
|
+
"""
|
|
255
|
+
return self.element_class(self, rt)
|
|
256
|
+
|
|
257
|
+
def from_expr(self, l):
|
|
258
|
+
"""
|
|
259
|
+
Return a :class:`RibbonTableau` from a MuPAD-Combinat expr for a skew
|
|
260
|
+
tableau. The first list in ``expr`` is the inner shape of the skew
|
|
261
|
+
tableau. The second list are the entries in the rows of the skew
|
|
262
|
+
tableau from bottom to top.
|
|
263
|
+
|
|
264
|
+
Provided primarily for compatibility with MuPAD-Combinat.
|
|
265
|
+
|
|
266
|
+
EXAMPLES::
|
|
267
|
+
|
|
268
|
+
sage: RibbonTableaux().from_expr([[1,1],[[5],[3,4],[1,2]]])
|
|
269
|
+
[[None, 1, 2], [None, 3, 4], [5]]
|
|
270
|
+
"""
|
|
271
|
+
return self.element_class(self, SkewTableaux().from_expr(l))
|
|
272
|
+
|
|
273
|
+
Element = RibbonTableau
|
|
274
|
+
options = Tableaux.options
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class RibbonTableaux_shape_weight_length(RibbonTableaux):
|
|
278
|
+
"""
|
|
279
|
+
Ribbon tableaux of a given shape, weight, and length.
|
|
280
|
+
"""
|
|
281
|
+
@staticmethod
|
|
282
|
+
def __classcall_private__(cls, shape, weight, length):
|
|
283
|
+
"""
|
|
284
|
+
Normalize input to ensure a unique representation.
|
|
285
|
+
|
|
286
|
+
EXAMPLES::
|
|
287
|
+
|
|
288
|
+
sage: R = RibbonTableaux([[2,1],[]],[1,1,1],1)
|
|
289
|
+
sage: R2 = RibbonTableaux(SkewPartition([[2,1],[]]),(1,1,1),1)
|
|
290
|
+
sage: R is R2
|
|
291
|
+
True
|
|
292
|
+
"""
|
|
293
|
+
if shape in _Partitions:
|
|
294
|
+
shape = _Partitions(shape)
|
|
295
|
+
shape = SkewPartition([shape, shape.core(length)])
|
|
296
|
+
else:
|
|
297
|
+
shape = SkewPartition(shape)
|
|
298
|
+
|
|
299
|
+
if shape.size() != length * sum(weight):
|
|
300
|
+
raise ValueError("incompatible shape and weight")
|
|
301
|
+
|
|
302
|
+
return super().__classcall__(cls, shape, tuple(weight), length)
|
|
303
|
+
|
|
304
|
+
def __init__(self, shape, weight, length):
|
|
305
|
+
"""
|
|
306
|
+
EXAMPLES::
|
|
307
|
+
|
|
308
|
+
sage: R = RibbonTableaux([[2,1],[]],[1,1,1],1)
|
|
309
|
+
sage: TestSuite(R).run()
|
|
310
|
+
"""
|
|
311
|
+
self._shape = shape
|
|
312
|
+
self._weight = weight
|
|
313
|
+
self._length = length
|
|
314
|
+
Parent.__init__(self, category=FiniteEnumeratedSets())
|
|
315
|
+
|
|
316
|
+
def __iter__(self):
|
|
317
|
+
"""
|
|
318
|
+
EXAMPLES::
|
|
319
|
+
|
|
320
|
+
sage: RibbonTableaux([[2,1],[]],[1,1,1],1).list()
|
|
321
|
+
[[[1, 3], [2]], [[1, 2], [3]]]
|
|
322
|
+
sage: RibbonTableaux([[2,2],[]],[1,1],2).list()
|
|
323
|
+
[[[0, 0], [1, 2]], [[1, 0], [2, 0]]]
|
|
324
|
+
"""
|
|
325
|
+
for x in graph_implementation_rec(self._shape, self._weight,
|
|
326
|
+
self._length, list_rec):
|
|
327
|
+
yield self.from_expr(x)
|
|
328
|
+
|
|
329
|
+
def _repr_(self) -> str:
|
|
330
|
+
"""
|
|
331
|
+
Return a string representation of ``self``.
|
|
332
|
+
|
|
333
|
+
EXAMPLES::
|
|
334
|
+
|
|
335
|
+
sage: RibbonTableaux([[2,1],[]], [1,1,1], 1)
|
|
336
|
+
Ribbon tableaux of shape [2, 1] / [] and weight [1, 1, 1] with 1-ribbons
|
|
337
|
+
"""
|
|
338
|
+
return "Ribbon tableaux of shape %s and weight %s with %s-ribbons" % (repr(self._shape), list(self._weight), self._length)
|
|
339
|
+
|
|
340
|
+
def __contains__(self, x) -> bool:
|
|
341
|
+
"""
|
|
342
|
+
Note that this just checks to see if ``x`` appears in ``self``.
|
|
343
|
+
|
|
344
|
+
This should be improved to provide actual checking.
|
|
345
|
+
|
|
346
|
+
EXAMPLES::
|
|
347
|
+
|
|
348
|
+
sage: r = RibbonTableaux([[2,2],[]],[1,1],2)
|
|
349
|
+
sage: [[0, 0], [1, 2]] in r
|
|
350
|
+
True
|
|
351
|
+
sage: [[1, 0], [2, 0]] in r
|
|
352
|
+
True
|
|
353
|
+
sage: [[0, 1], [2, 0]] in r
|
|
354
|
+
False
|
|
355
|
+
"""
|
|
356
|
+
try:
|
|
357
|
+
x = RibbonTableau(x)
|
|
358
|
+
except (ValueError, TypeError):
|
|
359
|
+
return False
|
|
360
|
+
return x in self.list()
|
|
361
|
+
|
|
362
|
+
# return x.is_ribbon() and x.shape() == self._shape \
|
|
363
|
+
# and tuple(x.weight()) == self._weight and x in list(self)
|
|
364
|
+
|
|
365
|
+
def cardinality(self):
|
|
366
|
+
"""
|
|
367
|
+
Return the cardinality of ``self``.
|
|
368
|
+
|
|
369
|
+
EXAMPLES::
|
|
370
|
+
|
|
371
|
+
sage: RibbonTableaux([[2,1],[]],[1,1,1],1).cardinality()
|
|
372
|
+
2
|
|
373
|
+
sage: RibbonTableaux([[2,2],[]],[1,1],2).cardinality()
|
|
374
|
+
2
|
|
375
|
+
sage: RibbonTableaux([[4,3,3],[]],[2,1,1,1],2).cardinality()
|
|
376
|
+
5
|
|
377
|
+
|
|
378
|
+
TESTS::
|
|
379
|
+
|
|
380
|
+
sage: RibbonTableaux([6,6,6], [4,2], 3).cardinality()
|
|
381
|
+
6
|
|
382
|
+
sage: RibbonTableaux([3,3,3,2,1], [3,1], 3).cardinality()
|
|
383
|
+
1
|
|
384
|
+
sage: RibbonTableaux([3,3,3,2,1], [2,2], 3).cardinality()
|
|
385
|
+
2
|
|
386
|
+
sage: RibbonTableaux([3,3,3,2,1], [2,1,1], 3).cardinality()
|
|
387
|
+
5
|
|
388
|
+
sage: RibbonTableaux([3,3,3,2,1], [1,1,1,1], 3).cardinality()
|
|
389
|
+
12
|
|
390
|
+
sage: RibbonTableaux([5,4,3,2,1], [2,2,1], 3).cardinality()
|
|
391
|
+
10
|
|
392
|
+
|
|
393
|
+
::
|
|
394
|
+
|
|
395
|
+
sage: RibbonTableaux([8,7,6,5,1,1], [3,2,2,1], 3).cardinality()
|
|
396
|
+
85
|
|
397
|
+
sage: RibbonTableaux([5,4,3,2,1,1,1], [2,2,1], 3).cardinality()
|
|
398
|
+
10
|
|
399
|
+
|
|
400
|
+
::
|
|
401
|
+
|
|
402
|
+
sage: RibbonTableaux([7,7,7,2,1,1], [3,2,0,1,1], 3).cardinality()
|
|
403
|
+
25
|
|
404
|
+
|
|
405
|
+
Weights with some zeros in the middle and end::
|
|
406
|
+
|
|
407
|
+
sage: RibbonTableaux([3,3,3], [0,1,0,2,0], 3).cardinality()
|
|
408
|
+
3
|
|
409
|
+
sage: RibbonTableaux([3,3,3], [1,0,1,0,1,0,0,0], 3).cardinality()
|
|
410
|
+
6
|
|
411
|
+
"""
|
|
412
|
+
# Strip zeros for graph_implementation_rec
|
|
413
|
+
wt = [i for i in self._weight if i != 0]
|
|
414
|
+
return Integer(graph_implementation_rec(self._shape, wt, self._length, count_rec)[0])
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def insertion_tableau(skp, perm, evaluation, tableau, length):
|
|
418
|
+
"""
|
|
419
|
+
INPUT:
|
|
420
|
+
|
|
421
|
+
- ``skp`` -- skew partitions
|
|
422
|
+
|
|
423
|
+
- ``perm, evaluation`` -- nonnegative integers
|
|
424
|
+
|
|
425
|
+
- ``tableau`` -- skew tableau
|
|
426
|
+
|
|
427
|
+
- ``length`` -- integer
|
|
428
|
+
|
|
429
|
+
TESTS::
|
|
430
|
+
|
|
431
|
+
sage: from sage.combinat.ribbon_tableau import insertion_tableau
|
|
432
|
+
sage: insertion_tableau([[1], []], [1], 1, [[], []], 1)
|
|
433
|
+
[[], [[1]]]
|
|
434
|
+
sage: insertion_tableau([[2, 1], []], [1, 1], 2, [[], [[1]]], 1)
|
|
435
|
+
[[], [[2], [1, 2]]]
|
|
436
|
+
sage: insertion_tableau([[2, 1], []], [0, 0], 3, [[], [[2], [1, 2]]], 1)
|
|
437
|
+
[[], [[2], [1, 2]]]
|
|
438
|
+
sage: insertion_tableau([[1, 1], []], [1], 2, [[], [[1]]], 1)
|
|
439
|
+
[[], [[2], [1]]]
|
|
440
|
+
sage: insertion_tableau([[2], []], [0, 1], 2, [[], [[1]]], 1)
|
|
441
|
+
[[], [[1, 2]]]
|
|
442
|
+
sage: insertion_tableau([[2, 1], []], [0, 1], 3, [[], [[2], [1]]], 1)
|
|
443
|
+
[[], [[2], [1, 3]]]
|
|
444
|
+
sage: insertion_tableau([[1, 1], []], [2], 1, [[], []], 2)
|
|
445
|
+
[[], [[1], [0]]]
|
|
446
|
+
sage: insertion_tableau([[2], []], [2, 0], 1, [[], []], 2)
|
|
447
|
+
[[], [[1, 0]]]
|
|
448
|
+
sage: insertion_tableau([[2, 2], []], [0, 2], 2, [[], [[1], [0]]], 2)
|
|
449
|
+
[[], [[1, 2], [0, 0]]]
|
|
450
|
+
sage: insertion_tableau([[2, 2], []], [2, 0], 2, [[], [[1, 0]]], 2)
|
|
451
|
+
[[], [[2, 0], [1, 0]]]
|
|
452
|
+
sage: insertion_tableau([[2, 2], [1]], [3, 0], 1, [[], []], 3)
|
|
453
|
+
[[1], [[1, 0], [0]]]
|
|
454
|
+
"""
|
|
455
|
+
psave = Partition(skp[1])
|
|
456
|
+
partc = skp[1] + [0] * (len(skp[0]) - len(skp[1]))
|
|
457
|
+
|
|
458
|
+
tableau = SkewTableau(expr=tableau).to_expr()[1]
|
|
459
|
+
|
|
460
|
+
for k in range(len(tableau)):
|
|
461
|
+
tableau[-(k + 1)] += [0] * (skp[0][k] - partc[k] - len(tableau[-(k + 1)]))
|
|
462
|
+
|
|
463
|
+
# We construct a tableau from the southwest corner to the northeast one
|
|
464
|
+
tableau = [[0] * (skp[0][k] - partc[k])
|
|
465
|
+
for k in reversed(range(len(tableau), len(skp[0])))] + tableau
|
|
466
|
+
|
|
467
|
+
tableau = SkewTableaux().from_expr([skp[1], tableau]).conjugate()
|
|
468
|
+
tableau = tableau.to_expr()[1]
|
|
469
|
+
|
|
470
|
+
skp = SkewPartition(skp).conjugate().to_list()
|
|
471
|
+
skp[1].extend([0] * (len(skp[0]) - len(skp[1])))
|
|
472
|
+
|
|
473
|
+
if len(perm) > len(skp[0]):
|
|
474
|
+
return None
|
|
475
|
+
|
|
476
|
+
lp = len(perm)
|
|
477
|
+
for k in range(lp):
|
|
478
|
+
if perm[-(k + 1)] != 0:
|
|
479
|
+
tableau[len(tableau) - lp + k][skp[0][lp - (k + 1)] - skp[1][lp - (k + 1)] - 1] = evaluation
|
|
480
|
+
|
|
481
|
+
return SkewTableau(expr=[psave.conjugate(), tableau]).conjugate().to_expr()
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def count_rec(nexts, current, part, weight, length):
|
|
485
|
+
"""
|
|
486
|
+
INPUT:
|
|
487
|
+
|
|
488
|
+
- ``nexts, current, part`` -- skew partitions
|
|
489
|
+
|
|
490
|
+
- ``weight`` -- nonnegative integer list
|
|
491
|
+
|
|
492
|
+
- ``length`` -- integer
|
|
493
|
+
|
|
494
|
+
TESTS::
|
|
495
|
+
|
|
496
|
+
sage: from sage.combinat.ribbon_tableau import count_rec
|
|
497
|
+
sage: count_rec([], [], [[2, 1, 1], []], [2], 2)
|
|
498
|
+
[0]
|
|
499
|
+
sage: count_rec([[0], [1]], [[[2, 1, 1], [0, 0, 2, 0]], [[4], [2, 0, 0, 0]]], [[4, 1, 1], []], [2, 1], 2)
|
|
500
|
+
[1]
|
|
501
|
+
sage: count_rec([], [[[], [2, 2]]], [[2, 2], []], [2], 2)
|
|
502
|
+
[1]
|
|
503
|
+
sage: count_rec([], [[[], [2, 0, 2, 0]]], [[4], []], [2], 2)
|
|
504
|
+
[1]
|
|
505
|
+
sage: count_rec([[1], [1]], [[[2, 2], [0, 0, 2, 0]], [[4], [2, 0, 0, 0]]], [[4, 2], []], [2, 1], 2)
|
|
506
|
+
[2]
|
|
507
|
+
sage: count_rec([[1], [1], [2]], [[[2, 2, 2], [0, 0, 2, 0]], [[4, 1, 1], [0, 2, 0, 0]], [[4, 2], [2, 0, 0, 0]]], [[4, 2, 2], []], [2, 1, 1], 2)
|
|
508
|
+
[4]
|
|
509
|
+
sage: count_rec([[4], [1]], [[[4, 2, 2], [0, 0, 2, 0]], [[4, 3, 1], [0, 2, 0, 0]]], [[4, 3, 3], []], [2, 1, 1, 1], 2)
|
|
510
|
+
[5]
|
|
511
|
+
"""
|
|
512
|
+
if not current:
|
|
513
|
+
return [0]
|
|
514
|
+
if nexts:
|
|
515
|
+
return [sum(j for i in nexts for j in i)]
|
|
516
|
+
else:
|
|
517
|
+
return [len(current)]
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def list_rec(nexts, current, part, weight, length):
|
|
521
|
+
"""
|
|
522
|
+
INPUT:
|
|
523
|
+
|
|
524
|
+
- ``nexts, current, part`` -- skew partitions
|
|
525
|
+
|
|
526
|
+
- ``weight`` -- nonnegative integer list
|
|
527
|
+
|
|
528
|
+
- ``length`` -- integer
|
|
529
|
+
|
|
530
|
+
TESTS::
|
|
531
|
+
|
|
532
|
+
sage: from sage.combinat.ribbon_tableau import list_rec
|
|
533
|
+
sage: list_rec([], [[[], [1]]], [[1], []], [1], 1)
|
|
534
|
+
[[[], [[1]]]]
|
|
535
|
+
sage: list_rec([[[[], [[1]]]]], [[[1], [1, 1]]], [[2, 1], []], [1, 2], 1)
|
|
536
|
+
[[[], [[2], [1, 2]]]]
|
|
537
|
+
sage: list_rec([], [[[1], [3, 0]]], [[2, 2], [1]], [1], 3)
|
|
538
|
+
[[[1], [[1, 0], [0]]]]
|
|
539
|
+
sage: list_rec([[[[], [[2]]]]], [[[1], [1, 1]]], [[2, 1], []], [0, 1, 2], 1)
|
|
540
|
+
[[[], [[3], [2, 3]]]]
|
|
541
|
+
sage: list_rec([], [[[], [2]]], [[1, 1], []], [1], 2)
|
|
542
|
+
[[[], [[1], [0]]]]
|
|
543
|
+
sage: list_rec([], [[[], [2, 0]]], [[2], []], [1], 2)
|
|
544
|
+
[[[], [[1, 0]]]]
|
|
545
|
+
sage: list_rec([[[[], [[1], [0]]]], [[[], [[1, 0]]]]], [[[1, 1], [0, 2]], [[2], [2, 0]]], [[2, 2], []], [1, 1], 2)
|
|
546
|
+
[[[], [[1, 2], [0, 0]]], [[], [[2, 0], [1, 0]]]]
|
|
547
|
+
sage: list_rec([], [[[], [2, 2]]], [[2, 2], []], [2], 2)
|
|
548
|
+
[[[], [[1, 1], [0, 0]]]]
|
|
549
|
+
sage: list_rec([], [[[], [1, 1]]], [[2], []], [2], 1)
|
|
550
|
+
[[[], [[1, 1]]]]
|
|
551
|
+
sage: list_rec([[[[], [[1, 1]]]]], [[[2], [1, 1]]], [[2, 2], []], [2, 2], 1)
|
|
552
|
+
[[[], [[2, 2], [1, 1]]]]
|
|
553
|
+
"""
|
|
554
|
+
if current == [] and nexts == [] and weight == []:
|
|
555
|
+
return [[part[1], []]]
|
|
556
|
+
|
|
557
|
+
# Test if the current nodes is not an empty node
|
|
558
|
+
if not current:
|
|
559
|
+
return []
|
|
560
|
+
|
|
561
|
+
# Test if the current nodes drive us to new solutions
|
|
562
|
+
if nexts:
|
|
563
|
+
return [insertion_tableau(part, curr_i[1], len(weight),
|
|
564
|
+
nexts_ij, length)
|
|
565
|
+
for nexts_i, curr_i in zip(nexts, current)
|
|
566
|
+
for nexts_ij in nexts_i]
|
|
567
|
+
|
|
568
|
+
# The current nodes are at the bottom of the tree
|
|
569
|
+
return [insertion_tableau(part, curr_i[1],
|
|
570
|
+
len(weight), [[], []], length)
|
|
571
|
+
for curr_i in current]
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
# ===============================
|
|
575
|
+
# Spin and Cospin Polynomials
|
|
576
|
+
# ===============================
|
|
577
|
+
def spin_rec(t, nexts, current, part, weight, length):
|
|
578
|
+
"""
|
|
579
|
+
Routine used for constructing the spin polynomial.
|
|
580
|
+
|
|
581
|
+
INPUT:
|
|
582
|
+
|
|
583
|
+
- ``weight`` -- list of nonnegative integers
|
|
584
|
+
|
|
585
|
+
- ``length`` -- the length of the ribbons we're tiling with
|
|
586
|
+
|
|
587
|
+
- ``t`` -- the variable
|
|
588
|
+
|
|
589
|
+
EXAMPLES::
|
|
590
|
+
|
|
591
|
+
sage: from sage.combinat.ribbon_tableau import spin_rec
|
|
592
|
+
sage: sp = SkewPartition
|
|
593
|
+
sage: t = ZZ['t'].gen()
|
|
594
|
+
sage: spin_rec(t, [], [[[], [3, 3]]], sp([[2, 2, 2], []]), [2], 3)
|
|
595
|
+
[t^4]
|
|
596
|
+
sage: spin_rec(t, [[0], [t^4]], [[[2, 1, 1, 1, 1], [0, 3]], [[2, 2, 2], [3, 0]]], sp([[2, 2, 2, 2, 1], []]), [2, 1], 3)
|
|
597
|
+
[t^5]
|
|
598
|
+
sage: spin_rec(t, [], [[[], [3, 3, 0]]], sp([[3, 3], []]), [2], 3)
|
|
599
|
+
[t^2]
|
|
600
|
+
sage: spin_rec(t, [[t^4], [t^3], [t^2]], [[[2, 2, 2], [0, 0, 3]], [[3, 2, 1], [0, 3, 0]], [[3, 3], [3, 0, 0]]], sp([[3, 3, 3], []]), [2, 1], 3)
|
|
601
|
+
[t^6 + t^4 + t^2]
|
|
602
|
+
sage: spin_rec(t, [[t^5], [t^4], [t^6 + t^4 + t^2]], [[[2, 2, 2, 2, 1], [0, 0, 3]], [[3, 3, 1, 1, 1], [0, 3, 0]], [[3, 3, 3], [3, 0, 0]]], sp([[3, 3, 3, 2, 1], []]), [2, 1, 1], 3)
|
|
603
|
+
[2*t^7 + 2*t^5 + t^3]
|
|
604
|
+
"""
|
|
605
|
+
if not current:
|
|
606
|
+
return [parent(t).zero()]
|
|
607
|
+
|
|
608
|
+
tmp = []
|
|
609
|
+
partp = part[0].conjugate()
|
|
610
|
+
ell = len(partp)
|
|
611
|
+
|
|
612
|
+
# compute the contribution of the ribbons added at
|
|
613
|
+
# the current node
|
|
614
|
+
for val in current:
|
|
615
|
+
perms = val[1]
|
|
616
|
+
perm = [partp[i] + ell - (i + 1) - perms[i] for i in reversed(range(ell))]
|
|
617
|
+
perm = to_standard(perm)
|
|
618
|
+
tmp.append(weight[-1] * (length - 1) - perm.number_of_inversions())
|
|
619
|
+
|
|
620
|
+
if nexts:
|
|
621
|
+
return [sum(sum(t**tval * nval for nval in nexts[i])
|
|
622
|
+
for i, tval in enumerate(tmp))]
|
|
623
|
+
return [sum(t**val for val in tmp)]
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
def spin_polynomial_square(part, weight, length):
|
|
627
|
+
r"""
|
|
628
|
+
Return the spin polynomial associated with ``part``, ``weight``, and
|
|
629
|
+
``length``, with the substitution `t \to t^2` made.
|
|
630
|
+
|
|
631
|
+
EXAMPLES::
|
|
632
|
+
|
|
633
|
+
sage: from sage.combinat.ribbon_tableau import spin_polynomial_square
|
|
634
|
+
sage: spin_polynomial_square([6,6,6],[4,2],3)
|
|
635
|
+
t^12 + t^10 + 2*t^8 + t^6 + t^4
|
|
636
|
+
sage: spin_polynomial_square([6,6,6],[4,1,1],3)
|
|
637
|
+
t^12 + 2*t^10 + 3*t^8 + 2*t^6 + t^4
|
|
638
|
+
sage: spin_polynomial_square([3,3,3,2,1], [2,2], 3)
|
|
639
|
+
t^7 + t^5
|
|
640
|
+
sage: spin_polynomial_square([3,3,3,2,1], [2,1,1], 3)
|
|
641
|
+
2*t^7 + 2*t^5 + t^3
|
|
642
|
+
sage: spin_polynomial_square([3,3,3,2,1], [1,1,1,1], 3)
|
|
643
|
+
3*t^7 + 5*t^5 + 3*t^3 + t
|
|
644
|
+
sage: spin_polynomial_square([5,4,3,2,1,1,1], [2,2,1], 3)
|
|
645
|
+
2*t^9 + 6*t^7 + 2*t^5
|
|
646
|
+
sage: spin_polynomial_square([[6]*6, [3,3]], [4,4,2], 3)
|
|
647
|
+
3*t^18 + 5*t^16 + 9*t^14 + 6*t^12 + 3*t^10
|
|
648
|
+
"""
|
|
649
|
+
R = ZZ['t']
|
|
650
|
+
|
|
651
|
+
if part in _Partitions:
|
|
652
|
+
part = SkewPartition([part, _Partitions([])])
|
|
653
|
+
elif part in SkewPartitions():
|
|
654
|
+
part = SkewPartition(part)
|
|
655
|
+
|
|
656
|
+
if part == [[], []] and not weight:
|
|
657
|
+
return R.one()
|
|
658
|
+
|
|
659
|
+
t = R.gen()
|
|
660
|
+
return R(graph_implementation_rec(part, weight, length,
|
|
661
|
+
functools.partial(spin_rec, t))[0])
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
def spin_polynomial(part, weight, length):
|
|
665
|
+
"""
|
|
666
|
+
Return the spin polynomial associated to ``part``, ``weight``, and
|
|
667
|
+
``length``.
|
|
668
|
+
|
|
669
|
+
EXAMPLES::
|
|
670
|
+
|
|
671
|
+
sage: # needs sage.symbolic
|
|
672
|
+
sage: from sage.combinat.ribbon_tableau import spin_polynomial
|
|
673
|
+
sage: spin_polynomial([6,6,6],[4,2],3)
|
|
674
|
+
t^6 + t^5 + 2*t^4 + t^3 + t^2
|
|
675
|
+
sage: spin_polynomial([6,6,6],[4,1,1],3)
|
|
676
|
+
t^6 + 2*t^5 + 3*t^4 + 2*t^3 + t^2
|
|
677
|
+
sage: spin_polynomial([3,3,3,2,1], [2,2], 3)
|
|
678
|
+
t^(7/2) + t^(5/2)
|
|
679
|
+
sage: spin_polynomial([3,3,3,2,1], [2,1,1], 3)
|
|
680
|
+
2*t^(7/2) + 2*t^(5/2) + t^(3/2)
|
|
681
|
+
sage: spin_polynomial([3,3,3,2,1], [1,1,1,1], 3)
|
|
682
|
+
3*t^(7/2) + 5*t^(5/2) + 3*t^(3/2) + sqrt(t)
|
|
683
|
+
sage: spin_polynomial([5,4,3,2,1,1,1], [2,2,1], 3)
|
|
684
|
+
2*t^(9/2) + 6*t^(7/2) + 2*t^(5/2)
|
|
685
|
+
sage: spin_polynomial([[6]*6, [3,3]], [4,4,2], 3)
|
|
686
|
+
3*t^9 + 5*t^8 + 9*t^7 + 6*t^6 + 3*t^5
|
|
687
|
+
"""
|
|
688
|
+
from sage.symbolic.ring import SR
|
|
689
|
+
sp = spin_polynomial_square(part, weight, length)
|
|
690
|
+
t = SR.var('t')
|
|
691
|
+
coeffs = sp.list()
|
|
692
|
+
return sum(c * t**(ZZ(i) / 2) for i, c in enumerate(coeffs))
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
def cospin_polynomial(part, weight, length):
|
|
696
|
+
"""
|
|
697
|
+
Return the cospin polynomial associated to ``part``, ``weight``, and
|
|
698
|
+
``length``.
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: from sage.combinat.ribbon_tableau import cospin_polynomial
|
|
703
|
+
sage: cospin_polynomial([6,6,6],[4,2],3)
|
|
704
|
+
t^4 + t^3 + 2*t^2 + t + 1
|
|
705
|
+
sage: cospin_polynomial([3,3,3,2,1], [3,1], 3)
|
|
706
|
+
1
|
|
707
|
+
sage: cospin_polynomial([3,3,3,2,1], [2,2], 3)
|
|
708
|
+
t + 1
|
|
709
|
+
sage: cospin_polynomial([3,3,3,2,1], [2,1,1], 3)
|
|
710
|
+
t^2 + 2*t + 2
|
|
711
|
+
sage: cospin_polynomial([3,3,3,2,1], [1,1,1,1], 3)
|
|
712
|
+
t^3 + 3*t^2 + 5*t + 3
|
|
713
|
+
sage: cospin_polynomial([5,4,3,2,1,1,1], [2,2,1], 3)
|
|
714
|
+
2*t^2 + 6*t + 2
|
|
715
|
+
sage: cospin_polynomial([[6]*6, [3,3]], [4,4,2], 3)
|
|
716
|
+
3*t^4 + 6*t^3 + 9*t^2 + 5*t + 3
|
|
717
|
+
"""
|
|
718
|
+
R = ZZ['t']
|
|
719
|
+
|
|
720
|
+
# The power in the spin polynomial are all half integers
|
|
721
|
+
# or all integers. Manipulation of expressions need to
|
|
722
|
+
# separate cases
|
|
723
|
+
sp = spin_polynomial_square(part, weight, length)
|
|
724
|
+
if sp == 0:
|
|
725
|
+
return R.zero()
|
|
726
|
+
|
|
727
|
+
coeffs = [c for c in sp.list() if c]
|
|
728
|
+
d = len(coeffs) - 1
|
|
729
|
+
t = R.gen()
|
|
730
|
+
return R(sum(c * t**(d - i) for i, c in enumerate(coeffs)))
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
# //////////////////////////////////////////////////////////////////////////////////////////
|
|
734
|
+
# // Generic function for driving into the graph of partitions coding all ribbons
|
|
735
|
+
# // tableaux of a given shape and weight
|
|
736
|
+
# //////////////////////////////////////////////////////////////////////////////////////////
|
|
737
|
+
# // This function constructs the graph of the set of k-ribbon tableaux
|
|
738
|
+
# // of a given skew shape and a given weight.
|
|
739
|
+
# // The first argument is always a skew partition.
|
|
740
|
+
# // In the case where the inner partition is empty, there is no branch without solutions.
|
|
741
|
+
# // In the other cases, there is in average a lot of branches without solutions.
|
|
742
|
+
# /////////////////////////////////////////////////////////////////////////////////////////
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
def graph_implementation_rec(skp, weight, length, function):
|
|
746
|
+
"""
|
|
747
|
+
TESTS::
|
|
748
|
+
|
|
749
|
+
sage: from sage.combinat.ribbon_tableau import graph_implementation_rec, list_rec
|
|
750
|
+
sage: graph_implementation_rec(SkewPartition([[1], []]), [1], 1, list_rec)
|
|
751
|
+
[[[], [[1]]]]
|
|
752
|
+
sage: graph_implementation_rec(SkewPartition([[2, 1], []]), [1, 2], 1, list_rec)
|
|
753
|
+
[[[], [[2], [1, 2]]]]
|
|
754
|
+
sage: graph_implementation_rec(SkewPartition([[], []]), [0], 1, list_rec)
|
|
755
|
+
[[[], []]]
|
|
756
|
+
"""
|
|
757
|
+
if sum(weight) == 0:
|
|
758
|
+
weight = []
|
|
759
|
+
|
|
760
|
+
partp = skp[0].conjugate()
|
|
761
|
+
ell = len(partp)
|
|
762
|
+
outer = skp[1]
|
|
763
|
+
outer_len = len(outer)
|
|
764
|
+
|
|
765
|
+
# Some tests in order to know if the shape and the weight are compatible.
|
|
766
|
+
if weight and weight[-1] <= len(partp):
|
|
767
|
+
perms = permutation.Permutations([0] * (len(partp) - weight[-1]) + [length] * (weight[-1])).list()
|
|
768
|
+
else:
|
|
769
|
+
return function([], [], skp, weight, length)
|
|
770
|
+
|
|
771
|
+
selection = []
|
|
772
|
+
|
|
773
|
+
for j in range(len(perms)):
|
|
774
|
+
retire = [(val + ell - (i + 1) - perms[j][i]) for i, val in enumerate(partp)]
|
|
775
|
+
retire.sort(reverse=True)
|
|
776
|
+
retire = [val - ell + (i + 1) for i, val in enumerate(retire)]
|
|
777
|
+
|
|
778
|
+
if retire[-1] >= 0 and retire == sorted(retire, reverse=True):
|
|
779
|
+
retire = Partition(retire).conjugate()
|
|
780
|
+
|
|
781
|
+
# Cutting branches if the retired partition has a line strictly included into the inner one
|
|
782
|
+
if len(retire) >= outer_len:
|
|
783
|
+
append = True
|
|
784
|
+
for k in range(outer_len):
|
|
785
|
+
if retire[k] - outer[k] < 0:
|
|
786
|
+
append = False
|
|
787
|
+
break
|
|
788
|
+
if append:
|
|
789
|
+
selection.append([retire, perms[j]])
|
|
790
|
+
|
|
791
|
+
# selection contains the list of current nodes
|
|
792
|
+
|
|
793
|
+
if len(weight) == 1:
|
|
794
|
+
return function([], selection, skp, weight, length)
|
|
795
|
+
else:
|
|
796
|
+
# The recursive calls permit us to construct the list of the sons
|
|
797
|
+
# of all current nodes in selection
|
|
798
|
+
a = [graph_implementation_rec([p[0], outer], weight[:-1], length, function)
|
|
799
|
+
for p in selection]
|
|
800
|
+
return function(a, selection, skp, weight, length)
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
class MultiSkewTableau(CombinatorialElement):
|
|
804
|
+
"""
|
|
805
|
+
A multi skew tableau which is a tuple of skew tableaux.
|
|
806
|
+
|
|
807
|
+
EXAMPLES::
|
|
808
|
+
|
|
809
|
+
sage: s = MultiSkewTableau([ [[None,1],[2,3]], [[1,2],[2]] ])
|
|
810
|
+
sage: s.size()
|
|
811
|
+
6
|
|
812
|
+
sage: s.weight()
|
|
813
|
+
[2, 3, 1]
|
|
814
|
+
sage: s.shape()
|
|
815
|
+
[[2, 2] / [1], [2, 1] / []]
|
|
816
|
+
|
|
817
|
+
TESTS::
|
|
818
|
+
|
|
819
|
+
sage: mst = MultiSkewTableau([ [[None,1],[2,3]], [[1,2],[2]] ])
|
|
820
|
+
sage: TestSuite(mst).run()
|
|
821
|
+
"""
|
|
822
|
+
@staticmethod
|
|
823
|
+
def __classcall_private__(cls, x):
|
|
824
|
+
"""
|
|
825
|
+
Construct a multi skew tableau.
|
|
826
|
+
|
|
827
|
+
EXAMPLES::
|
|
828
|
+
|
|
829
|
+
sage: s = MultiSkewTableau([ [[None,1],[2,3]], [[1,2],[2]] ])
|
|
830
|
+
"""
|
|
831
|
+
if isinstance(x, MultiSkewTableau):
|
|
832
|
+
return x
|
|
833
|
+
return MultiSkewTableaux()([SkewTableau(i) for i in x])
|
|
834
|
+
|
|
835
|
+
def size(self):
|
|
836
|
+
"""
|
|
837
|
+
Return the size of ``self``.
|
|
838
|
+
|
|
839
|
+
This is the sum of the sizes of the skew
|
|
840
|
+
tableaux in ``self``.
|
|
841
|
+
|
|
842
|
+
EXAMPLES::
|
|
843
|
+
|
|
844
|
+
sage: s = SemistandardSkewTableaux([[2,2],[1]]).list()
|
|
845
|
+
sage: a = MultiSkewTableau([s[0],s[1],s[2]])
|
|
846
|
+
sage: a.size()
|
|
847
|
+
9
|
|
848
|
+
"""
|
|
849
|
+
return sum(x.size() for x in self)
|
|
850
|
+
|
|
851
|
+
def weight(self):
|
|
852
|
+
"""
|
|
853
|
+
Return the weight of ``self``.
|
|
854
|
+
|
|
855
|
+
EXAMPLES::
|
|
856
|
+
|
|
857
|
+
sage: s = SemistandardSkewTableaux([[2,2],[1]]).list()
|
|
858
|
+
sage: a = MultiSkewTableau([s[0],s[1],s[2]])
|
|
859
|
+
sage: a.weight()
|
|
860
|
+
[5, 3, 1]
|
|
861
|
+
"""
|
|
862
|
+
weights = [x.weight() for x in self]
|
|
863
|
+
m = max(len(x) for x in weights)
|
|
864
|
+
weight = [0] * m
|
|
865
|
+
for w in weights:
|
|
866
|
+
for i in range(len(w)):
|
|
867
|
+
weight[i] += w[i]
|
|
868
|
+
return weight
|
|
869
|
+
|
|
870
|
+
def shape(self):
|
|
871
|
+
"""
|
|
872
|
+
Return the shape of ``self``.
|
|
873
|
+
|
|
874
|
+
EXAMPLES::
|
|
875
|
+
|
|
876
|
+
sage: s = SemistandardSkewTableaux([[2,2],[1]]).list()
|
|
877
|
+
sage: a = MultiSkewTableau([s[0],s[1],s[2]])
|
|
878
|
+
sage: a.shape()
|
|
879
|
+
[[2, 2] / [1], [2, 2] / [1], [2, 2] / [1]]
|
|
880
|
+
"""
|
|
881
|
+
return [x.shape() for x in self]
|
|
882
|
+
|
|
883
|
+
def inversion_pairs(self):
|
|
884
|
+
"""
|
|
885
|
+
Return a list of the inversion pairs of ``self``.
|
|
886
|
+
|
|
887
|
+
EXAMPLES::
|
|
888
|
+
|
|
889
|
+
sage: s = MultiSkewTableau([ [[2,3],[5,5]], [[1,1],[3,3]], [[2],[6]] ])
|
|
890
|
+
sage: s.inversion_pairs()
|
|
891
|
+
[((0, (0, 0)), (1, (0, 0))),
|
|
892
|
+
((0, (1, 0)), (1, (0, 1))),
|
|
893
|
+
((0, (1, 1)), (1, (0, 0))),
|
|
894
|
+
((0, (1, 1)), (1, (1, 1))),
|
|
895
|
+
((0, (1, 1)), (2, (0, 0))),
|
|
896
|
+
((1, (0, 1)), (2, (0, 0))),
|
|
897
|
+
((1, (1, 1)), (2, (0, 0)))]
|
|
898
|
+
"""
|
|
899
|
+
inv = []
|
|
900
|
+
for k in range(len(self)):
|
|
901
|
+
for b in self[k].cells():
|
|
902
|
+
inv += self._inversion_pairs_from_position(k, b)
|
|
903
|
+
return inv
|
|
904
|
+
|
|
905
|
+
def inversions(self):
|
|
906
|
+
"""
|
|
907
|
+
Return the number of inversion pairs of ``self``.
|
|
908
|
+
|
|
909
|
+
EXAMPLES::
|
|
910
|
+
|
|
911
|
+
sage: t1 = SkewTableau([[1]])
|
|
912
|
+
sage: t2 = SkewTableau([[2]])
|
|
913
|
+
sage: MultiSkewTableau([t1,t1]).inversions()
|
|
914
|
+
0
|
|
915
|
+
sage: MultiSkewTableau([t1,t2]).inversions()
|
|
916
|
+
0
|
|
917
|
+
sage: MultiSkewTableau([t2,t2]).inversions()
|
|
918
|
+
0
|
|
919
|
+
sage: MultiSkewTableau([t2,t1]).inversions()
|
|
920
|
+
1
|
|
921
|
+
sage: s = MultiSkewTableau([ [[2,3],[5,5]], [[1,1],[3,3]], [[2],[6]] ])
|
|
922
|
+
sage: s.inversions()
|
|
923
|
+
7
|
|
924
|
+
"""
|
|
925
|
+
return len(self.inversion_pairs())
|
|
926
|
+
|
|
927
|
+
def _inversion_pairs_from_position(self, k, ij):
|
|
928
|
+
"""
|
|
929
|
+
Return the number of inversions at the cell position `(i,j)` in the
|
|
930
|
+
``k``-th tableaux in ``self``.
|
|
931
|
+
|
|
932
|
+
EXAMPLES::
|
|
933
|
+
|
|
934
|
+
sage: s = MultiSkewTableau([ [[2,3],[5,5]], [[1,1],[3,3]], [[2],[6]] ])
|
|
935
|
+
sage: s._inversion_pairs_from_position(0, (1,1))
|
|
936
|
+
[((0, (1, 1)), (1, (0, 0))),
|
|
937
|
+
((0, (1, 1)), (1, (1, 1))),
|
|
938
|
+
((0, (1, 1)), (2, (0, 0)))]
|
|
939
|
+
sage: s._inversion_pairs_from_position(1, (0,1))
|
|
940
|
+
[((1, (0, 1)), (2, (0, 0)))]
|
|
941
|
+
"""
|
|
942
|
+
pk = k
|
|
943
|
+
pi, pj = ij
|
|
944
|
+
c = pi - pj
|
|
945
|
+
value = self[pk][pi][pj]
|
|
946
|
+
pk_cells = self[pk].cells_by_content(c)
|
|
947
|
+
same_diagonal = [t.cells_by_content(c) for t in self[pk + 1:]]
|
|
948
|
+
above_diagonal = [t.cells_by_content(c + 1) for t in self[pk + 1:]]
|
|
949
|
+
|
|
950
|
+
res = []
|
|
951
|
+
for i, j in pk_cells:
|
|
952
|
+
if pi < i and value > self[pk][i][j]:
|
|
953
|
+
res.append(((pk, (pi, pj)), (pk, (i, j))))
|
|
954
|
+
for k in range(len(same_diagonal)):
|
|
955
|
+
for i, j in same_diagonal[k]:
|
|
956
|
+
if value > self[pk + k + 1][i][j]:
|
|
957
|
+
res.append(((pk, (pi, pj)), (pk + k + 1, (i, j))))
|
|
958
|
+
for k in range(len(above_diagonal)):
|
|
959
|
+
for i, j in above_diagonal[k]:
|
|
960
|
+
if value < self[pk + k + 1][i][j]:
|
|
961
|
+
res.append(((pk, (pi, pj)), (pk + k + 1, (i, j))))
|
|
962
|
+
return res
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
class MultiSkewTableaux(UniqueRepresentation, Parent):
|
|
966
|
+
r"""
|
|
967
|
+
Multiskew tableaux.
|
|
968
|
+
"""
|
|
969
|
+
|
|
970
|
+
def __init__(self, category=None):
|
|
971
|
+
"""
|
|
972
|
+
EXAMPLES::
|
|
973
|
+
|
|
974
|
+
sage: R = MultiSkewTableaux()
|
|
975
|
+
sage: TestSuite(R).run()
|
|
976
|
+
"""
|
|
977
|
+
if category is None:
|
|
978
|
+
category = Sets()
|
|
979
|
+
Parent.__init__(self, category=category)
|
|
980
|
+
|
|
981
|
+
def _repr_(self):
|
|
982
|
+
"""
|
|
983
|
+
Return a string representation of ``self``.
|
|
984
|
+
|
|
985
|
+
EXAMPLES::
|
|
986
|
+
|
|
987
|
+
sage: MultiSkewTableaux()
|
|
988
|
+
Multi Skew Tableaux tableaux
|
|
989
|
+
"""
|
|
990
|
+
return "Multi Skew Tableaux tableaux"
|
|
991
|
+
|
|
992
|
+
def _element_constructor_(self, rt):
|
|
993
|
+
"""
|
|
994
|
+
Construct an element of ``self`` from ``rt``.
|
|
995
|
+
|
|
996
|
+
EXAMPLES::
|
|
997
|
+
|
|
998
|
+
sage: R = MultiSkewTableaux()
|
|
999
|
+
sage: R([[[1, 1], [2]], [[None, 2], [3, 3]]])
|
|
1000
|
+
[[[1, 1], [2]], [[None, 2], [3, 3]]]
|
|
1001
|
+
"""
|
|
1002
|
+
return self.element_class(self, rt)
|
|
1003
|
+
|
|
1004
|
+
Element = MultiSkewTableau
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
class SemistandardMultiSkewTableaux(MultiSkewTableaux):
|
|
1008
|
+
"""
|
|
1009
|
+
Semistandard multi skew tableaux.
|
|
1010
|
+
|
|
1011
|
+
A multi skew tableau is a `k`-tuple of skew tableaux of
|
|
1012
|
+
given shape with a specified total weight.
|
|
1013
|
+
|
|
1014
|
+
EXAMPLES::
|
|
1015
|
+
|
|
1016
|
+
sage: S = SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2]); S
|
|
1017
|
+
Semistandard multi skew tableaux of shape [[2, 1] / [], [2, 2] / [1]] and weight [2, 2, 2]
|
|
1018
|
+
sage: S.list()
|
|
1019
|
+
[[[[1, 1], [2]], [[None, 2], [3, 3]]],
|
|
1020
|
+
[[[1, 2], [2]], [[None, 1], [3, 3]]],
|
|
1021
|
+
[[[1, 3], [2]], [[None, 2], [1, 3]]],
|
|
1022
|
+
[[[1, 3], [2]], [[None, 1], [2, 3]]],
|
|
1023
|
+
[[[1, 1], [3]], [[None, 2], [2, 3]]],
|
|
1024
|
+
[[[1, 2], [3]], [[None, 2], [1, 3]]],
|
|
1025
|
+
[[[1, 2], [3]], [[None, 1], [2, 3]]],
|
|
1026
|
+
[[[2, 2], [3]], [[None, 1], [1, 3]]],
|
|
1027
|
+
[[[1, 3], [3]], [[None, 1], [2, 2]]],
|
|
1028
|
+
[[[2, 3], [3]], [[None, 1], [1, 2]]]]
|
|
1029
|
+
"""
|
|
1030
|
+
@staticmethod
|
|
1031
|
+
def __classcall_private__(cls, shape, weight):
|
|
1032
|
+
"""
|
|
1033
|
+
Normalize input to ensure a unique representation.
|
|
1034
|
+
|
|
1035
|
+
EXAMPLES::
|
|
1036
|
+
|
|
1037
|
+
sage: S1 = SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2])
|
|
1038
|
+
sage: shape_alt = ( SkewPartition([[2,1],[]]), SkewPartition([[2,2],[1]]) )
|
|
1039
|
+
sage: S2 = SemistandardMultiSkewTableaux(shape_alt, (2,2,2))
|
|
1040
|
+
sage: S1 is S2
|
|
1041
|
+
True
|
|
1042
|
+
"""
|
|
1043
|
+
shape = tuple(SkewPartition(x) for x in shape)
|
|
1044
|
+
weight = Partition(weight)
|
|
1045
|
+
|
|
1046
|
+
if sum(weight) != sum(s.size() for s in shape):
|
|
1047
|
+
raise ValueError("the sum of weight must be the sum of the sizes of shape")
|
|
1048
|
+
|
|
1049
|
+
return super().__classcall__(cls, shape, weight)
|
|
1050
|
+
|
|
1051
|
+
def __init__(self, shape, weight):
|
|
1052
|
+
"""
|
|
1053
|
+
TESTS::
|
|
1054
|
+
|
|
1055
|
+
sage: S = SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2])
|
|
1056
|
+
sage: TestSuite(S).run()
|
|
1057
|
+
"""
|
|
1058
|
+
self._shape = shape
|
|
1059
|
+
self._weight = weight
|
|
1060
|
+
MultiSkewTableaux.__init__(self, category=FiniteEnumeratedSets())
|
|
1061
|
+
|
|
1062
|
+
def _repr_(self):
|
|
1063
|
+
"""
|
|
1064
|
+
Return a string representation of ``self``.
|
|
1065
|
+
|
|
1066
|
+
EXAMPLES::
|
|
1067
|
+
|
|
1068
|
+
sage: SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2])
|
|
1069
|
+
Semistandard multi skew tableaux of shape [[2, 1] / [], [2, 2] / [1]] and weight [2, 2, 2]
|
|
1070
|
+
"""
|
|
1071
|
+
return "Semistandard multi skew tableaux of shape %s and weight %s" % (list(self._shape), self._weight)
|
|
1072
|
+
|
|
1073
|
+
def __contains__(self, x):
|
|
1074
|
+
"""
|
|
1075
|
+
TESTS::
|
|
1076
|
+
|
|
1077
|
+
sage: s = SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2])
|
|
1078
|
+
sage: all(i in s for i in s)
|
|
1079
|
+
True
|
|
1080
|
+
"""
|
|
1081
|
+
try:
|
|
1082
|
+
x = MultiSkewTableau(x)
|
|
1083
|
+
except TypeError:
|
|
1084
|
+
return False
|
|
1085
|
+
if x.weight() != list(self._weight):
|
|
1086
|
+
return False
|
|
1087
|
+
if x.shape() != list(self._shape):
|
|
1088
|
+
return False
|
|
1089
|
+
return all(xi.is_semistandard() for xi in x)
|
|
1090
|
+
|
|
1091
|
+
def __iter__(self):
|
|
1092
|
+
r"""
|
|
1093
|
+
Iterate over ``self``.
|
|
1094
|
+
|
|
1095
|
+
EXAMPLES::
|
|
1096
|
+
|
|
1097
|
+
sage: sp = SkewPartitions(3).list()
|
|
1098
|
+
sage: SemistandardMultiSkewTableaux([SkewPartition([[1, 1, 1], []]), SkewPartition([[3], []])],[2,2,2]).list()
|
|
1099
|
+
[[[[1], [2], [3]], [[1, 2, 3]]]]
|
|
1100
|
+
|
|
1101
|
+
sage: a = SkewPartition([[8,7,6,5,1,1],[2,1,1]])
|
|
1102
|
+
sage: weight = [3,3,2]
|
|
1103
|
+
sage: k = 3
|
|
1104
|
+
sage: s = SemistandardMultiSkewTableaux(a.quotient(k),weight)
|
|
1105
|
+
sage: len(s.list())
|
|
1106
|
+
34
|
|
1107
|
+
sage: RibbonTableaux(a,weight,k).cardinality()
|
|
1108
|
+
34
|
|
1109
|
+
|
|
1110
|
+
TESTS:
|
|
1111
|
+
|
|
1112
|
+
Check that :issue:`36196` is fixed::
|
|
1113
|
+
|
|
1114
|
+
sage: shapes = [[[1], [0]], [[1], [0]], [[1], [0]]]
|
|
1115
|
+
sage: weight = [1, 1, 1]
|
|
1116
|
+
sage: SMST = SemistandardMultiSkewTableaux(shapes, weight)
|
|
1117
|
+
sage: list(SMST)
|
|
1118
|
+
[[[[1]], [[2]], [[3]]],
|
|
1119
|
+
[[[2]], [[1]], [[3]]],
|
|
1120
|
+
[[[1]], [[3]], [[2]]],
|
|
1121
|
+
[[[2]], [[3]], [[1]]],
|
|
1122
|
+
[[[3]], [[1]], [[2]]],
|
|
1123
|
+
[[[3]], [[2]], [[1]]]]
|
|
1124
|
+
"""
|
|
1125
|
+
parts = self._shape
|
|
1126
|
+
mu = self._weight
|
|
1127
|
+
|
|
1128
|
+
# Splitting the partition
|
|
1129
|
+
s = [p.size() for p in parts]
|
|
1130
|
+
parts = [p.to_list() for p in parts]
|
|
1131
|
+
|
|
1132
|
+
# Gluing the partitions
|
|
1133
|
+
parttmp = parts[0]
|
|
1134
|
+
for i in range(1, len(parts)):
|
|
1135
|
+
trans = parttmp[0][0]
|
|
1136
|
+
current_part = parts[i]
|
|
1137
|
+
current_part[1] += [0] * (len(current_part[0]) - len(current_part[1]))
|
|
1138
|
+
inner_current = [trans + j for j in current_part[1]]
|
|
1139
|
+
outer_current = [trans + j for j in current_part[0]]
|
|
1140
|
+
parttmp = [outer_current + parttmp[0], inner_current + parttmp[1]]
|
|
1141
|
+
|
|
1142
|
+
# List the corresponding skew tableaux
|
|
1143
|
+
l = (st.to_word() for st in SemistandardSkewTableaux(parttmp, mu))
|
|
1144
|
+
|
|
1145
|
+
S = SkewTableaux()
|
|
1146
|
+
for lk in l:
|
|
1147
|
+
pos = 0 # Double check this
|
|
1148
|
+
lk = list(lk)
|
|
1149
|
+
w = lk[:s[0]]
|
|
1150
|
+
restmp = [S.from_shape_and_word(parts[0], w)]
|
|
1151
|
+
for i in range(1, len(parts)):
|
|
1152
|
+
pos += s[i-1]
|
|
1153
|
+
w = lk[pos: pos + s[i]]
|
|
1154
|
+
restmp.append(S.from_shape_and_word(parts[i], w))
|
|
1155
|
+
yield self.element_class(self, restmp)
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
class RibbonTableau_class(RibbonTableau):
|
|
1159
|
+
"""
|
|
1160
|
+
This exists solely for unpickling ``RibbonTableau_class`` objects.
|
|
1161
|
+
"""
|
|
1162
|
+
|
|
1163
|
+
def __setstate__(self, state):
|
|
1164
|
+
r"""
|
|
1165
|
+
Unpickle old ``RibbonTableau_class`` objects.
|
|
1166
|
+
|
|
1167
|
+
TESTS::
|
|
1168
|
+
|
|
1169
|
+
sage: loads(b'x\x9c5\xcc\xbd\x0e\xc2 \x14@\xe1\xb4Z\x7f\xd0\x07\xc1\x85D}\x8f\x0e\x8d\x1d\t\xb9\x90\x1bJ\xa44\x17\xe8h\xa2\x83\xef-\xda\xb8\x9do9\xcf\xda$\xb0(\xcc4j\x17 \x8b\xe8\xb4\x9e\x82\xca\xa0=\xc2\xcc\xba\x1fo\x8b\x94\xf1\x90\x12\xa3\xea\xf4\xa2\xfaA+\xde7j\x804\xd0\xba-\xe5]\xca\xd4H\xdapI[\xde.\xdf\xe8\x82M\xc2\x85\x8c\x16#\x1b\xe1\x8e\xea\x0f\xda\xf5\xd5\xf9\xdd\xd1\x1e%1>\x14]\x8a\x0e\xdf\xb8\x968"\xceZ|\x00x\xef5\x11')
|
|
1170
|
+
[[None, 1], [2, 3]]
|
|
1171
|
+
sage: loads(dumps( RibbonTableau([[None, 1],[2,3]]) ))
|
|
1172
|
+
[[None, 1], [2, 3]]
|
|
1173
|
+
"""
|
|
1174
|
+
self.__class__ = RibbonTableau
|
|
1175
|
+
self.__init__(RibbonTableaux(), state['_list'])
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
register_unpickle_override('sage.combinat.ribbon_tableau', 'RibbonTableau_class', RibbonTableau_class)
|
|
1179
|
+
register_unpickle_override('sage.combinat.ribbon_tableau', 'RibbonTableaux_shapeweightlength', RibbonTableaux)
|
|
1180
|
+
register_unpickle_override('sage.combinat.ribbon_tableau', 'SemistandardMultiSkewTtableaux_shapeweight', SemistandardMultiSkewTableaux)
|