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,2403 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.graphs sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Rigged configuration elements
|
|
5
|
+
|
|
6
|
+
A rigged configuration element is a sequence of
|
|
7
|
+
:class:`~sage.combinat.rigged_configurations.rigged_partition.RiggedPartition`
|
|
8
|
+
objects.
|
|
9
|
+
|
|
10
|
+
AUTHORS:
|
|
11
|
+
|
|
12
|
+
- Travis Scrimshaw (2010-09-26): initial version
|
|
13
|
+
- Travis Scrimshaw (2012-10-25): added virtual rigged configurations
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# ****************************************************************************
|
|
17
|
+
# Copyright (C) 2010-2012 Travis Scrimshaw <tscrim@ucdavis.edu>
|
|
18
|
+
#
|
|
19
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
20
|
+
#
|
|
21
|
+
# This code is distributed in the hope that it will be useful,
|
|
22
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
23
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
24
|
+
# General Public License for more details.
|
|
25
|
+
#
|
|
26
|
+
# The full text of the GPL is available at:
|
|
27
|
+
#
|
|
28
|
+
# https://www.gnu.org/licenses/
|
|
29
|
+
# ****************************************************************************
|
|
30
|
+
from sage.misc.cachefunc import cached_method
|
|
31
|
+
from sage.structure.list_clone import ClonableArray
|
|
32
|
+
from sage.rings.integer import Integer
|
|
33
|
+
from sage.rings.integer_ring import ZZ
|
|
34
|
+
from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition, RiggedPartitionTypeB
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
####################################################
|
|
38
|
+
# Base classes for rigged configuration elements #
|
|
39
|
+
####################################################
|
|
40
|
+
|
|
41
|
+
class RiggedConfigurationElement(ClonableArray):
|
|
42
|
+
"""
|
|
43
|
+
A rigged configuration for simply-laced types.
|
|
44
|
+
|
|
45
|
+
For more information on rigged configurations, see
|
|
46
|
+
:class:`RiggedConfigurations`. For rigged configurations for
|
|
47
|
+
non-simply-laced types, use :class:`RCNonSimplyLacedElement`.
|
|
48
|
+
|
|
49
|
+
Typically to create a specific rigged configuration, the user will pass in
|
|
50
|
+
the optional argument ``partition_list`` and if the user wants to specify
|
|
51
|
+
the rigging values, give the optional argument ``rigging_list`` as well.
|
|
52
|
+
If ``rigging_list`` is not passed, the rigging values are set to the
|
|
53
|
+
corresponding vacancy numbers.
|
|
54
|
+
|
|
55
|
+
INPUT:
|
|
56
|
+
|
|
57
|
+
- ``parent`` -- the parent of this element
|
|
58
|
+
|
|
59
|
+
- ``rigged_partitions`` -- list of rigged partitions
|
|
60
|
+
|
|
61
|
+
There are two optional arguments to explicitly construct a rigged
|
|
62
|
+
configuration. The first is ``partition_list`` which gives a list of
|
|
63
|
+
partitions, and the second is ``rigging_list`` which is a list of
|
|
64
|
+
corresponding lists of riggings. If only partition_list is specified,
|
|
65
|
+
then it sets the rigging equal to the calculated vacancy numbers.
|
|
66
|
+
|
|
67
|
+
If we are constructing a rigged configuration from a rigged configuration
|
|
68
|
+
(say of another type) and we don't want to recompute the vacancy numbers,
|
|
69
|
+
we can use the ``use_vacancy_numbers`` to avoid the recomputation.
|
|
70
|
+
|
|
71
|
+
EXAMPLES:
|
|
72
|
+
|
|
73
|
+
Type `A_n^{(1)}` examples::
|
|
74
|
+
|
|
75
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
76
|
+
sage: RC(partition_list=[[2], [2, 2], [2], [2]])
|
|
77
|
+
<BLANKLINE>
|
|
78
|
+
0[ ][ ]0
|
|
79
|
+
<BLANKLINE>
|
|
80
|
+
-2[ ][ ]-2
|
|
81
|
+
-2[ ][ ]-2
|
|
82
|
+
<BLANKLINE>
|
|
83
|
+
2[ ][ ]2
|
|
84
|
+
<BLANKLINE>
|
|
85
|
+
-2[ ][ ]-2
|
|
86
|
+
<BLANKLINE>
|
|
87
|
+
|
|
88
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[1, 1], [1, 1]])
|
|
89
|
+
sage: RC(partition_list=[[], [], [], []])
|
|
90
|
+
<BLANKLINE>
|
|
91
|
+
(/)
|
|
92
|
+
<BLANKLINE>
|
|
93
|
+
(/)
|
|
94
|
+
<BLANKLINE>
|
|
95
|
+
(/)
|
|
96
|
+
<BLANKLINE>
|
|
97
|
+
(/)
|
|
98
|
+
<BLANKLINE>
|
|
99
|
+
|
|
100
|
+
Type `D_n^{(1)}` examples::
|
|
101
|
+
|
|
102
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
103
|
+
sage: RC(partition_list=[[3], [3,2], [4], [3]])
|
|
104
|
+
<BLANKLINE>
|
|
105
|
+
-1[ ][ ][ ]-1
|
|
106
|
+
<BLANKLINE>
|
|
107
|
+
1[ ][ ][ ]1
|
|
108
|
+
0[ ][ ]0
|
|
109
|
+
<BLANKLINE>
|
|
110
|
+
-3[ ][ ][ ][ ]-3
|
|
111
|
+
<BLANKLINE>
|
|
112
|
+
-1[ ][ ][ ]-1
|
|
113
|
+
<BLANKLINE>
|
|
114
|
+
|
|
115
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[1, 1], [2, 1]])
|
|
116
|
+
sage: RC(partition_list=[[1], [1,1], [1], [1]])
|
|
117
|
+
<BLANKLINE>
|
|
118
|
+
1[ ]1
|
|
119
|
+
<BLANKLINE>
|
|
120
|
+
0[ ]0
|
|
121
|
+
0[ ]0
|
|
122
|
+
<BLANKLINE>
|
|
123
|
+
0[ ]0
|
|
124
|
+
<BLANKLINE>
|
|
125
|
+
0[ ]0
|
|
126
|
+
<BLANKLINE>
|
|
127
|
+
sage: elt = RC(partition_list=[[1], [1,1], [1], [1]], rigging_list=[[0], [0,0], [0], [0]]); elt
|
|
128
|
+
<BLANKLINE>
|
|
129
|
+
1[ ]0
|
|
130
|
+
<BLANKLINE>
|
|
131
|
+
0[ ]0
|
|
132
|
+
0[ ]0
|
|
133
|
+
<BLANKLINE>
|
|
134
|
+
0[ ]0
|
|
135
|
+
<BLANKLINE>
|
|
136
|
+
0[ ]0
|
|
137
|
+
<BLANKLINE>
|
|
138
|
+
|
|
139
|
+
sage: from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition
|
|
140
|
+
sage: RC2 = RiggedConfigurations(['D', 5, 1], [[2, 1], [3, 1]])
|
|
141
|
+
sage: l = [RiggedPartition()] + list(elt)
|
|
142
|
+
sage: ascii_art(RC2(*l))
|
|
143
|
+
(/) 1[ ]0 0[ ]0 0[ ]0 0[ ]0
|
|
144
|
+
0[ ]0
|
|
145
|
+
sage: ascii_art(RC2(*l, use_vacancy_numbers=True))
|
|
146
|
+
(/) 1[ ]0 0[ ]0 0[ ]0 0[ ]0
|
|
147
|
+
0[ ]0
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def __init__(self, parent, rigged_partitions=[], **options):
|
|
151
|
+
r"""
|
|
152
|
+
Construct a rigged configuration element.
|
|
153
|
+
|
|
154
|
+
.. WARNING::
|
|
155
|
+
|
|
156
|
+
This changes the vacancy numbers of the rigged partitions, so
|
|
157
|
+
if the rigged partitions comes from another rigged configuration,
|
|
158
|
+
a deep copy should be made before being passed here. We do not
|
|
159
|
+
make a deep copy here because the crystal operators generate
|
|
160
|
+
their own rigged partitions. See :issue:`17054`.
|
|
161
|
+
|
|
162
|
+
EXAMPLES::
|
|
163
|
+
|
|
164
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
|
|
165
|
+
sage: RC(partition_list=[[], [], [], []])
|
|
166
|
+
<BLANKLINE>
|
|
167
|
+
(/)
|
|
168
|
+
<BLANKLINE>
|
|
169
|
+
(/)
|
|
170
|
+
<BLANKLINE>
|
|
171
|
+
(/)
|
|
172
|
+
<BLANKLINE>
|
|
173
|
+
(/)
|
|
174
|
+
<BLANKLINE>
|
|
175
|
+
sage: RC(partition_list=[[1], [1], [], []])
|
|
176
|
+
<BLANKLINE>
|
|
177
|
+
-1[ ]-1
|
|
178
|
+
<BLANKLINE>
|
|
179
|
+
0[ ]0
|
|
180
|
+
<BLANKLINE>
|
|
181
|
+
(/)
|
|
182
|
+
<BLANKLINE>
|
|
183
|
+
(/)
|
|
184
|
+
<BLANKLINE>
|
|
185
|
+
sage: elt = RC(partition_list=[[1], [1], [], []], rigging_list=[[-1], [0], [], []]); elt
|
|
186
|
+
<BLANKLINE>
|
|
187
|
+
-1[ ]-1
|
|
188
|
+
<BLANKLINE>
|
|
189
|
+
0[ ]0
|
|
190
|
+
<BLANKLINE>
|
|
191
|
+
(/)
|
|
192
|
+
<BLANKLINE>
|
|
193
|
+
(/)
|
|
194
|
+
<BLANKLINE>
|
|
195
|
+
sage: TestSuite(elt).run()
|
|
196
|
+
"""
|
|
197
|
+
n = options.get('n', parent._cartan_type.rank())
|
|
198
|
+
if "partition_list" in options:
|
|
199
|
+
data = options["partition_list"]
|
|
200
|
+
if len(data) == 0:
|
|
201
|
+
# Create a size n array of empty rigged tableau since no tableau
|
|
202
|
+
# were given
|
|
203
|
+
nu = [RiggedPartition() for _ in range(n)]
|
|
204
|
+
else:
|
|
205
|
+
if len(data) != n: # otherwise n should be equal to the number of tableaux
|
|
206
|
+
raise ValueError("incorrect number of partitions")
|
|
207
|
+
|
|
208
|
+
nu = []
|
|
209
|
+
if "rigging_list" in options:
|
|
210
|
+
rigging_data = options["rigging_list"]
|
|
211
|
+
|
|
212
|
+
if len(rigging_data) != n:
|
|
213
|
+
raise ValueError("incorrect number of riggings")
|
|
214
|
+
|
|
215
|
+
for i in range(n):
|
|
216
|
+
nu.append(RiggedPartition(tuple(data[i]),
|
|
217
|
+
list(rigging_data[i])))
|
|
218
|
+
else:
|
|
219
|
+
for partition_data in data:
|
|
220
|
+
nu.append(RiggedPartition(tuple(partition_data)))
|
|
221
|
+
elif n == len(rigged_partitions) and isinstance(rigged_partitions[0], RiggedPartition):
|
|
222
|
+
# The isinstance check is to make sure we are not in the n == 1 special case because
|
|
223
|
+
# Parent's __call__ always passes at least 1 argument to the element constructor
|
|
224
|
+
|
|
225
|
+
if options.get('use_vacancy_numbers', False):
|
|
226
|
+
ClonableArray.__init__(self, parent, rigged_partitions)
|
|
227
|
+
return
|
|
228
|
+
nu = rigged_partitions
|
|
229
|
+
else:
|
|
230
|
+
# Otherwise we did not receive any info, create a size n array of
|
|
231
|
+
# empty rigged partitions
|
|
232
|
+
nu = []
|
|
233
|
+
for i in range(n):
|
|
234
|
+
nu.append(RiggedPartition())
|
|
235
|
+
# raise ValueError("Invalid input")
|
|
236
|
+
# raise ValueError("Incorrect number of rigged partitions")
|
|
237
|
+
|
|
238
|
+
# Set the vacancy numbers
|
|
239
|
+
for a, partition in enumerate(nu):
|
|
240
|
+
# If the partition is empty, there's nothing to do
|
|
241
|
+
if len(partition) <= 0:
|
|
242
|
+
continue
|
|
243
|
+
|
|
244
|
+
# Setup the first block
|
|
245
|
+
block_len = partition[0]
|
|
246
|
+
vac_num = parent._calc_vacancy_number(nu, a, block_len)
|
|
247
|
+
|
|
248
|
+
for i, row_len in enumerate(partition):
|
|
249
|
+
# If we've gone to a different sized block, then update the
|
|
250
|
+
# values which change when moving to a new block size
|
|
251
|
+
if block_len != row_len:
|
|
252
|
+
vac_num = parent._calc_vacancy_number(nu, a, row_len)
|
|
253
|
+
block_len = row_len
|
|
254
|
+
|
|
255
|
+
partition.vacancy_numbers[i] = vac_num
|
|
256
|
+
if partition.rigging[i] is None:
|
|
257
|
+
partition.rigging[i] = partition.vacancy_numbers[i]
|
|
258
|
+
|
|
259
|
+
ClonableArray.__init__(self, parent, nu)
|
|
260
|
+
|
|
261
|
+
def check(self):
|
|
262
|
+
"""
|
|
263
|
+
Check the rigged configuration is properly defined.
|
|
264
|
+
|
|
265
|
+
There is nothing to check here.
|
|
266
|
+
|
|
267
|
+
EXAMPLES::
|
|
268
|
+
|
|
269
|
+
sage: RC = crystals.infinity.RiggedConfigurations(['A', 4])
|
|
270
|
+
sage: b = RC.module_generators[0].f_string([1,2,1,1,2,4,2,3,3,2])
|
|
271
|
+
sage: b.check()
|
|
272
|
+
"""
|
|
273
|
+
pass
|
|
274
|
+
|
|
275
|
+
def _repr_(self):
|
|
276
|
+
"""
|
|
277
|
+
Return a string representation of ``self``.
|
|
278
|
+
|
|
279
|
+
EXAMPLES::
|
|
280
|
+
|
|
281
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
282
|
+
sage: elt = RC(partition_list=[[2], [3,1], [3], [3]]); elt
|
|
283
|
+
<BLANKLINE>
|
|
284
|
+
-1[ ][ ]-1
|
|
285
|
+
<BLANKLINE>
|
|
286
|
+
2[ ][ ][ ]2
|
|
287
|
+
0[ ]0
|
|
288
|
+
<BLANKLINE>
|
|
289
|
+
-2[ ][ ][ ]-2
|
|
290
|
+
<BLANKLINE>
|
|
291
|
+
-2[ ][ ][ ]-2
|
|
292
|
+
<BLANKLINE>
|
|
293
|
+
sage: RC.options(display='horizontal')
|
|
294
|
+
sage: elt
|
|
295
|
+
-1[ ][ ]-1 2[ ][ ][ ]2 -2[ ][ ][ ]-2 -2[ ][ ][ ]-2
|
|
296
|
+
0[ ]0
|
|
297
|
+
sage: RC.options._reset()
|
|
298
|
+
"""
|
|
299
|
+
return self.parent().options._dispatch(self, '_repr_', 'display')
|
|
300
|
+
|
|
301
|
+
def _repr_vertical(self):
|
|
302
|
+
"""
|
|
303
|
+
Return the string representation of ``self`` vertically.
|
|
304
|
+
|
|
305
|
+
EXAMPLES::
|
|
306
|
+
|
|
307
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
308
|
+
sage: print(RC(partition_list=[[2], [3,1], [3], [3]])._repr_vertical())
|
|
309
|
+
<BLANKLINE>
|
|
310
|
+
-1[ ][ ]-1
|
|
311
|
+
<BLANKLINE>
|
|
312
|
+
2[ ][ ][ ]2
|
|
313
|
+
0[ ]0
|
|
314
|
+
<BLANKLINE>
|
|
315
|
+
-2[ ][ ][ ]-2
|
|
316
|
+
<BLANKLINE>
|
|
317
|
+
-2[ ][ ][ ]-2
|
|
318
|
+
<BLANKLINE>
|
|
319
|
+
sage: print(RC(partition_list=[[],[],[],[]])._repr_vertical())
|
|
320
|
+
<BLANKLINE>
|
|
321
|
+
(/)
|
|
322
|
+
<BLANKLINE>
|
|
323
|
+
(/)
|
|
324
|
+
<BLANKLINE>
|
|
325
|
+
(/)
|
|
326
|
+
<BLANKLINE>
|
|
327
|
+
(/)
|
|
328
|
+
<BLANKLINE>
|
|
329
|
+
"""
|
|
330
|
+
ret_str = ""
|
|
331
|
+
for tableau in self:
|
|
332
|
+
ret_str += "\n" + repr(tableau)
|
|
333
|
+
return ret_str
|
|
334
|
+
|
|
335
|
+
def _repr_horizontal(self):
|
|
336
|
+
"""
|
|
337
|
+
Return the string representation of ``self`` horizontally.
|
|
338
|
+
|
|
339
|
+
EXAMPLES::
|
|
340
|
+
|
|
341
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
342
|
+
sage: print(RC(partition_list=[[2], [3,1], [3], [3]])._repr_horizontal())
|
|
343
|
+
-1[ ][ ]-1 2[ ][ ][ ]2 -2[ ][ ][ ]-2 -2[ ][ ][ ]-2
|
|
344
|
+
0[ ]0
|
|
345
|
+
sage: print(RC(partition_list=[[],[],[],[]])._repr_horizontal())
|
|
346
|
+
(/) (/) (/) (/)
|
|
347
|
+
"""
|
|
348
|
+
tab_str = [repr(x).splitlines() for x in self]
|
|
349
|
+
height = max(len(t) for t in tab_str)
|
|
350
|
+
widths = [max(len(x) for x in t) for t in tab_str]
|
|
351
|
+
ret_str = ''
|
|
352
|
+
for i in range(height):
|
|
353
|
+
if i != 0:
|
|
354
|
+
ret_str += '\n'
|
|
355
|
+
for j,t in enumerate(tab_str):
|
|
356
|
+
if j != 0:
|
|
357
|
+
ret_str += ' '
|
|
358
|
+
if i < len(t):
|
|
359
|
+
ret_str += t[i] + ' ' * (widths[j]-len(t[i]))
|
|
360
|
+
else:
|
|
361
|
+
ret_str += ' ' * widths[j]
|
|
362
|
+
return ret_str
|
|
363
|
+
|
|
364
|
+
def _latex_(self):
|
|
365
|
+
r"""
|
|
366
|
+
Return the LaTeX representation of ``self``.
|
|
367
|
+
|
|
368
|
+
EXAMPLES::
|
|
369
|
+
|
|
370
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
371
|
+
sage: latex(RC(partition_list=[[2], [3,1], [3], [3]]))
|
|
372
|
+
{
|
|
373
|
+
\begin{array}[t]{r|c|c|l}
|
|
374
|
+
\cline{2-3} -1 &\phantom{|}&\phantom{|}& -1 \\
|
|
375
|
+
\cline{2-3}
|
|
376
|
+
\end{array}
|
|
377
|
+
}
|
|
378
|
+
\quad
|
|
379
|
+
{
|
|
380
|
+
\begin{array}[t]{r|c|c|c|l}
|
|
381
|
+
\cline{2-4} 2 &\phantom{|}&\phantom{|}&\phantom{|}& 2 \\
|
|
382
|
+
\cline{2-4} 0 &\phantom{|}& \multicolumn{3 }{l}{ 0 } \\
|
|
383
|
+
\cline{2-2}
|
|
384
|
+
\end{array}
|
|
385
|
+
}
|
|
386
|
+
\quad
|
|
387
|
+
{
|
|
388
|
+
\begin{array}[t]{r|c|c|c|l}
|
|
389
|
+
\cline{2-4} -2 &\phantom{|}&\phantom{|}&\phantom{|}& -2 \\
|
|
390
|
+
\cline{2-4}
|
|
391
|
+
\end{array}
|
|
392
|
+
}
|
|
393
|
+
\quad
|
|
394
|
+
{
|
|
395
|
+
\begin{array}[t]{r|c|c|c|l}
|
|
396
|
+
\cline{2-4} -2 &\phantom{|}&\phantom{|}&\phantom{|}& -2 \\
|
|
397
|
+
\cline{2-4}
|
|
398
|
+
\end{array}
|
|
399
|
+
}
|
|
400
|
+
sage: latex(RC(partition_list=[[],[],[],[]]))
|
|
401
|
+
{\emptyset}
|
|
402
|
+
\quad
|
|
403
|
+
{\emptyset}
|
|
404
|
+
\quad
|
|
405
|
+
{\emptyset}
|
|
406
|
+
\quad
|
|
407
|
+
{\emptyset}
|
|
408
|
+
"""
|
|
409
|
+
ret_string = self[0]._latex_()
|
|
410
|
+
|
|
411
|
+
for partition in self[1:]:
|
|
412
|
+
ret_string += "\n\\quad\n" + partition._latex_()
|
|
413
|
+
|
|
414
|
+
return ret_string
|
|
415
|
+
|
|
416
|
+
def _ascii_art_(self):
|
|
417
|
+
"""
|
|
418
|
+
Return an ASCII art representation of ``self``.
|
|
419
|
+
|
|
420
|
+
EXAMPLES::
|
|
421
|
+
|
|
422
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
423
|
+
sage: ascii_art(RC(partition_list=[[2], [3,1], [3], [3]]))
|
|
424
|
+
-1[ ][ ]-1 2[ ][ ][ ]2 -2[ ][ ][ ]-2 -2[ ][ ][ ]-2
|
|
425
|
+
0[ ]0
|
|
426
|
+
sage: ascii_art(RC(partition_list=[[],[],[],[]]))
|
|
427
|
+
(/) (/) (/) (/)
|
|
428
|
+
sage: RC = RiggedConfigurations(['D', 7, 1], [[3,3],[5,2],[4,3],[2,3],[4,4],[3,1],[1,4],[2,2]])
|
|
429
|
+
sage: elt = RC(partition_list=[[2],[3,2,1],[2,2,1,1],[2,2,1,1,1,1],[3,2,1,1,1,1],[2,1,1],[2,2]],
|
|
430
|
+
....: rigging_list=[[2],[1,0,0],[4,1,2,1],[1,0,0,0,0,0],[0,1,0,0,0,0],[0,0,0],[0,0]])
|
|
431
|
+
sage: ascii_art(elt)
|
|
432
|
+
3[ ][ ]2 1[ ][ ][ ]1 4[ ][ ]4 2[ ][ ]1 0[ ][ ][ ]0 0[ ][ ]0 0[ ][ ]0
|
|
433
|
+
2[ ][ ]0 4[ ][ ]1 2[ ][ ]0 2[ ][ ]1 0[ ]0 0[ ][ ]0
|
|
434
|
+
1[ ]0 3[ ]2 0[ ]0 0[ ]0 0[ ]0
|
|
435
|
+
3[ ]1 0[ ]0 0[ ]0
|
|
436
|
+
0[ ]0 0[ ]0
|
|
437
|
+
0[ ]0 0[ ]0
|
|
438
|
+
sage: Partitions.options(convention='French')
|
|
439
|
+
sage: ascii_art(elt)
|
|
440
|
+
0[ ]0 0[ ]0
|
|
441
|
+
0[ ]0 0[ ]0
|
|
442
|
+
3[ ]1 0[ ]0 0[ ]0
|
|
443
|
+
1[ ]0 3[ ]2 0[ ]0 0[ ]0 0[ ]0
|
|
444
|
+
2[ ][ ]0 4[ ][ ]1 2[ ][ ]0 2[ ][ ]1 0[ ]0 0[ ][ ]0
|
|
445
|
+
3[ ][ ]2 1[ ][ ][ ]1 4[ ][ ]4 2[ ][ ]1 0[ ][ ][ ]0 0[ ][ ]0 0[ ][ ]0
|
|
446
|
+
sage: Partitions.options._reset()
|
|
447
|
+
"""
|
|
448
|
+
from sage.combinat.partition import Partitions
|
|
449
|
+
if Partitions.options.convention == "French":
|
|
450
|
+
baseline = lambda s: 0
|
|
451
|
+
else:
|
|
452
|
+
baseline = len
|
|
453
|
+
from sage.typeset.ascii_art import AsciiArt
|
|
454
|
+
s = repr(self[0]).splitlines()
|
|
455
|
+
ret = AsciiArt(s, baseline=baseline(s))
|
|
456
|
+
for tableau in self[1:]:
|
|
457
|
+
s = repr(tableau).splitlines()
|
|
458
|
+
ret += AsciiArt([" "], baseline=baseline(s)) + AsciiArt(s, baseline=baseline(s))
|
|
459
|
+
return ret
|
|
460
|
+
|
|
461
|
+
def nu(self):
|
|
462
|
+
r"""
|
|
463
|
+
Return the list `\nu` of rigged partitions of this rigged
|
|
464
|
+
configuration element.
|
|
465
|
+
|
|
466
|
+
OUTPUT: the `\nu` array as a list
|
|
467
|
+
|
|
468
|
+
EXAMPLES::
|
|
469
|
+
|
|
470
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
471
|
+
sage: RC(partition_list=[[2], [2,2], [2], [2]]).nu()
|
|
472
|
+
[0[ ][ ]0
|
|
473
|
+
, -2[ ][ ]-2
|
|
474
|
+
-2[ ][ ]-2
|
|
475
|
+
, 2[ ][ ]2
|
|
476
|
+
, -2[ ][ ]-2
|
|
477
|
+
]
|
|
478
|
+
"""
|
|
479
|
+
return list(self)
|
|
480
|
+
|
|
481
|
+
# TODO: Change e/f to work for all types
|
|
482
|
+
def e(self, a):
|
|
483
|
+
r"""
|
|
484
|
+
Return the action of the crystal operator `e_a` on ``self``.
|
|
485
|
+
|
|
486
|
+
This implements the method defined in [CrysStructSchilling06]_ which
|
|
487
|
+
finds the value `k` which is the length of the string with the
|
|
488
|
+
smallest negative rigging of smallest length. Then it removes a box
|
|
489
|
+
from a string of length `k` in the `a`-th rigged partition, keeping all
|
|
490
|
+
colabels fixed and increasing the new label by one. If no such string
|
|
491
|
+
exists, then `e_a` is undefined.
|
|
492
|
+
|
|
493
|
+
This method can also be used when the underlying Cartan matrix is a
|
|
494
|
+
Borcherds-Cartan matrix. In this case, then method of [SS2018]_ is
|
|
495
|
+
used, where the new label is increased by half of the `a`-th diagonal
|
|
496
|
+
entry of the underlying Borcherds-Cartan matrix. This method will also
|
|
497
|
+
return ``None`` if `a` is imaginary and the smallest rigging in the
|
|
498
|
+
`a`-th rigged partition is not exactly half of the `a`-th diagonal entry
|
|
499
|
+
of the Borcherds-Cartan matrix.
|
|
500
|
+
|
|
501
|
+
INPUT:
|
|
502
|
+
|
|
503
|
+
- ``a`` -- the index of the partition to remove a box
|
|
504
|
+
|
|
505
|
+
OUTPUT: the resulting rigged configuration element
|
|
506
|
+
|
|
507
|
+
EXAMPLES::
|
|
508
|
+
|
|
509
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
|
|
510
|
+
sage: elt = RC(partition_list=[[1], [1], [1], [1]])
|
|
511
|
+
sage: elt.e(3)
|
|
512
|
+
sage: elt.e(1)
|
|
513
|
+
<BLANKLINE>
|
|
514
|
+
(/)
|
|
515
|
+
<BLANKLINE>
|
|
516
|
+
0[ ]0
|
|
517
|
+
<BLANKLINE>
|
|
518
|
+
0[ ]0
|
|
519
|
+
<BLANKLINE>
|
|
520
|
+
-1[ ]-1
|
|
521
|
+
<BLANKLINE>
|
|
522
|
+
|
|
523
|
+
sage: A = CartanMatrix([[-2,-1],[-1,-2]], borcherds=True)
|
|
524
|
+
sage: RC = crystals.infinity.RiggedConfigurations(A)
|
|
525
|
+
sage: nu0 = RC(partition_list=[[],[]])
|
|
526
|
+
sage: nu = nu0.f_string([1,0,0,0])
|
|
527
|
+
sage: ascii_art(nu.e(0))
|
|
528
|
+
5[ ]3 4[ ]3
|
|
529
|
+
5[ ]1
|
|
530
|
+
"""
|
|
531
|
+
if a not in self.parent()._rc_index_inverse:
|
|
532
|
+
raise ValueError("{} is not in the index set".format(a))
|
|
533
|
+
a = self.parent()._rc_index_inverse[a]
|
|
534
|
+
M = self.parent()._cartan_matrix
|
|
535
|
+
|
|
536
|
+
new_list = self[a][:]
|
|
537
|
+
new_vac_nums = self[a].vacancy_numbers[:]
|
|
538
|
+
new_rigging = self[a].rigging[:]
|
|
539
|
+
|
|
540
|
+
# Separate out one of the Borcherds cases
|
|
541
|
+
if M[a,a] != 2:
|
|
542
|
+
k = None
|
|
543
|
+
set_vac_num = True
|
|
544
|
+
if new_rigging[-1] != -M[a,a] // 2:
|
|
545
|
+
return None
|
|
546
|
+
new_list.pop()
|
|
547
|
+
new_vac_nums.pop()
|
|
548
|
+
new_rigging.pop()
|
|
549
|
+
else:
|
|
550
|
+
# Find k and perform e_a
|
|
551
|
+
k = None
|
|
552
|
+
num_rows = len(new_list)
|
|
553
|
+
cur_rigging = -1
|
|
554
|
+
rigging_index = None
|
|
555
|
+
for i in range(num_rows):
|
|
556
|
+
if new_rigging[i] <= cur_rigging:
|
|
557
|
+
cur_rigging = new_rigging[i]
|
|
558
|
+
rigging_index = i
|
|
559
|
+
|
|
560
|
+
# If we've not found a valid k
|
|
561
|
+
if rigging_index is None:
|
|
562
|
+
return None
|
|
563
|
+
|
|
564
|
+
# Note that because the riggings are weakly decreasing, we will always
|
|
565
|
+
# remove the last box on of a block
|
|
566
|
+
k = new_list[rigging_index]
|
|
567
|
+
set_vac_num = False
|
|
568
|
+
if k == 1:
|
|
569
|
+
new_list.pop()
|
|
570
|
+
new_vac_nums.pop()
|
|
571
|
+
new_rigging.pop()
|
|
572
|
+
else:
|
|
573
|
+
new_list[rigging_index] -= 1
|
|
574
|
+
cur_rigging += M[a,a] // 2
|
|
575
|
+
# Properly sort the riggings
|
|
576
|
+
j = rigging_index + 1
|
|
577
|
+
# Update the vacancy number if the row lengths are the same
|
|
578
|
+
if j < num_rows and new_list[j] == new_list[rigging_index]:
|
|
579
|
+
new_vac_nums[rigging_index] = new_vac_nums[j]
|
|
580
|
+
set_vac_num = True
|
|
581
|
+
while j < num_rows and new_list[j] == new_list[rigging_index] \
|
|
582
|
+
and new_rigging[j] > cur_rigging:
|
|
583
|
+
new_rigging[j-1] = new_rigging[j] # Shuffle it along
|
|
584
|
+
j += 1
|
|
585
|
+
new_rigging[j-1] = cur_rigging
|
|
586
|
+
|
|
587
|
+
new_partitions = []
|
|
588
|
+
for b in range(len(self)):
|
|
589
|
+
if b != a:
|
|
590
|
+
new_partitions.append(self._generate_partition_e(a, b, k))
|
|
591
|
+
else:
|
|
592
|
+
# Update the vacancy numbers and the rigging
|
|
593
|
+
for i in range(len(new_vac_nums)):
|
|
594
|
+
if k is not None and new_list[i] < k:
|
|
595
|
+
break
|
|
596
|
+
|
|
597
|
+
new_vac_nums[i] += M[a,b]
|
|
598
|
+
new_rigging[i] += M[a,b]
|
|
599
|
+
|
|
600
|
+
if k != 1 and not set_vac_num: # If we did not remove a row nor found another row of length k-1
|
|
601
|
+
new_vac_nums[rigging_index] += 2
|
|
602
|
+
|
|
603
|
+
new_partitions.append(RiggedPartition(new_list, new_rigging, new_vac_nums))
|
|
604
|
+
|
|
605
|
+
ret_RC = self.__class__(self.parent(), new_partitions, use_vacancy_numbers=True)
|
|
606
|
+
nu = ret_RC.nu()
|
|
607
|
+
if k != 1 and not set_vac_num: # If we did not remove a row nor found another row of length k-1
|
|
608
|
+
# Update that row's vacancy number
|
|
609
|
+
ret_RC[a].vacancy_numbers[rigging_index] = \
|
|
610
|
+
self.parent()._calc_vacancy_number(nu, a, nu[a][rigging_index])
|
|
611
|
+
return ret_RC
|
|
612
|
+
|
|
613
|
+
def _generate_partition_e(self, a, b, k):
|
|
614
|
+
r"""
|
|
615
|
+
Generate a new partition for a given value of `a` by updating the
|
|
616
|
+
vacancy numbers and preserving co-labels for the map `e_a`.
|
|
617
|
+
|
|
618
|
+
INPUT:
|
|
619
|
+
|
|
620
|
+
- ``a`` -- the index of the partition we operated on
|
|
621
|
+
- ``b`` -- the index of the partition to generate
|
|
622
|
+
- ``k`` -- the length of the string with the smallest negative
|
|
623
|
+
rigging of smallest length
|
|
624
|
+
|
|
625
|
+
OUTPUT: the constructed rigged partition
|
|
626
|
+
|
|
627
|
+
TESTS::
|
|
628
|
+
|
|
629
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
|
|
630
|
+
sage: RC(partition_list=[[1], [1], [1], [1]])._generate_partition_e(1, 2, 1)
|
|
631
|
+
-1[ ]-1
|
|
632
|
+
<BLANKLINE>
|
|
633
|
+
"""
|
|
634
|
+
# Check to make sure we will do something
|
|
635
|
+
if not self.parent()._cartan_matrix[a,b]:
|
|
636
|
+
return self[b]
|
|
637
|
+
|
|
638
|
+
new_list = self[b]._list
|
|
639
|
+
new_vac_nums = self[b].vacancy_numbers[:]
|
|
640
|
+
new_rigging = self[b].rigging[:]
|
|
641
|
+
|
|
642
|
+
# Update the vacancy numbers and the rigging
|
|
643
|
+
value = self.parent()._cartan_matrix[b,a]
|
|
644
|
+
for i in range(len(new_vac_nums)):
|
|
645
|
+
if k is not None and new_list[i] < k:
|
|
646
|
+
break
|
|
647
|
+
|
|
648
|
+
new_vac_nums[i] += value
|
|
649
|
+
new_rigging[i] += value
|
|
650
|
+
|
|
651
|
+
return RiggedPartition(new_list, new_rigging, new_vac_nums)
|
|
652
|
+
|
|
653
|
+
def f(self, a):
|
|
654
|
+
r"""
|
|
655
|
+
Return the action of the crystal operator `f_a` on ``self``.
|
|
656
|
+
|
|
657
|
+
This implements the method defined in [CrysStructSchilling06]_ which
|
|
658
|
+
finds the value `k` which is the length of the string with the
|
|
659
|
+
smallest nonpositive rigging of largest length. Then it adds a box from
|
|
660
|
+
a string of length `k` in the `a`-th rigged partition, keeping all
|
|
661
|
+
colabels fixed and decreasing the new label by one. If no such string
|
|
662
|
+
exists, then it adds a new string of length 1 with label `-1`. However
|
|
663
|
+
we need to modify the definition to work for `B(\infty)` by removing
|
|
664
|
+
the condition that the resulting rigged configuration is valid.
|
|
665
|
+
|
|
666
|
+
This method can also be used when the underlying Cartan matrix is a
|
|
667
|
+
Borcherds-Cartan matrix. In this case, then method of [SS2018]_ is
|
|
668
|
+
used, where the new label is decreased by half of the `a`-th diagonal
|
|
669
|
+
entry of the underlying Borcherds-Cartan matrix.
|
|
670
|
+
|
|
671
|
+
INPUT:
|
|
672
|
+
|
|
673
|
+
- ``a`` -- the index of the partition to add a box
|
|
674
|
+
|
|
675
|
+
OUTPUT: the resulting rigged configuration element
|
|
676
|
+
|
|
677
|
+
EXAMPLES::
|
|
678
|
+
|
|
679
|
+
sage: RC = crystals.infinity.RiggedConfigurations(['A', 3])
|
|
680
|
+
sage: nu0 = RC.module_generators[0]
|
|
681
|
+
sage: nu0.f(2)
|
|
682
|
+
<BLANKLINE>
|
|
683
|
+
(/)
|
|
684
|
+
<BLANKLINE>
|
|
685
|
+
-2[ ]-1
|
|
686
|
+
<BLANKLINE>
|
|
687
|
+
(/)
|
|
688
|
+
<BLANKLINE>
|
|
689
|
+
|
|
690
|
+
sage: A = CartanMatrix([[-2,-1],[-1,-2]], borcherds=True)
|
|
691
|
+
sage: RC = crystals.infinity.RiggedConfigurations(A)
|
|
692
|
+
sage: nu0 = RC(partition_list=[[],[]])
|
|
693
|
+
sage: nu = nu0.f_string([1,0,0,0])
|
|
694
|
+
sage: ascii_art(nu.f(0))
|
|
695
|
+
9[ ]7 6[ ]5
|
|
696
|
+
9[ ]5
|
|
697
|
+
9[ ]3
|
|
698
|
+
9[ ]1
|
|
699
|
+
"""
|
|
700
|
+
if a not in self.parent()._rc_index_inverse:
|
|
701
|
+
raise ValueError("{} is not in the index set".format(a))
|
|
702
|
+
a = self.parent()._rc_index_inverse[a]
|
|
703
|
+
M = self.parent()._cartan_matrix
|
|
704
|
+
|
|
705
|
+
new_list = self[a][:]
|
|
706
|
+
new_vac_nums = self[a].vacancy_numbers[:]
|
|
707
|
+
new_rigging = self[a].rigging[:]
|
|
708
|
+
|
|
709
|
+
# Find k and perform f_a
|
|
710
|
+
k = None
|
|
711
|
+
add_index = -1 # Index where we will add our row too
|
|
712
|
+
rigging_index = None # Index which we will pull the rigging from
|
|
713
|
+
cur_rigging = ZZ.zero()
|
|
714
|
+
num_rows = len(new_list)
|
|
715
|
+
for i in reversed(range(num_rows)):
|
|
716
|
+
# If we need to increment a row, look for when we change rows for
|
|
717
|
+
# the correct index.
|
|
718
|
+
if add_index is None and new_list[i] != new_list[rigging_index]:
|
|
719
|
+
add_index = i+1
|
|
720
|
+
|
|
721
|
+
if new_rigging[i] <= cur_rigging:
|
|
722
|
+
cur_rigging = new_rigging[i]
|
|
723
|
+
k = new_list[i]
|
|
724
|
+
rigging_index = i
|
|
725
|
+
add_index = None
|
|
726
|
+
|
|
727
|
+
# If we've not found a valid k
|
|
728
|
+
if k is None:
|
|
729
|
+
new_list.append(1)
|
|
730
|
+
new_rigging.append(-M[a,a] // 2)
|
|
731
|
+
new_vac_nums.append(None)
|
|
732
|
+
k = 0
|
|
733
|
+
add_index = num_rows
|
|
734
|
+
num_rows += 1 # We've added a row
|
|
735
|
+
else:
|
|
736
|
+
if add_index is None: # We are adding to the first row in the list
|
|
737
|
+
add_index = 0
|
|
738
|
+
new_list[add_index] += 1
|
|
739
|
+
new_rigging.insert(add_index, new_rigging[rigging_index] - M[a,a] // 2)
|
|
740
|
+
new_vac_nums.insert(add_index, None)
|
|
741
|
+
new_rigging.pop(rigging_index + 1) # add 1 for the insertion
|
|
742
|
+
new_vac_nums.pop(rigging_index + 1)
|
|
743
|
+
|
|
744
|
+
new_partitions = []
|
|
745
|
+
for b in range(len(self)):
|
|
746
|
+
if b != a:
|
|
747
|
+
new_partitions.append(self._generate_partition_f(a, b, k))
|
|
748
|
+
else:
|
|
749
|
+
# Update the vacancy numbers and the rigging
|
|
750
|
+
for i in range(num_rows):
|
|
751
|
+
if new_list[i] <= k:
|
|
752
|
+
break
|
|
753
|
+
|
|
754
|
+
if i != add_index:
|
|
755
|
+
new_vac_nums[i] -= M[a,b]
|
|
756
|
+
new_rigging[i] -= M[a,b]
|
|
757
|
+
|
|
758
|
+
new_partitions.append(RiggedPartition(new_list, new_rigging, new_vac_nums))
|
|
759
|
+
|
|
760
|
+
new_partitions[a].vacancy_numbers[add_index] = \
|
|
761
|
+
self.parent()._calc_vacancy_number(new_partitions, a,
|
|
762
|
+
new_partitions[a][add_index])
|
|
763
|
+
|
|
764
|
+
# Note that we do not need to sort the rigging since if there was a
|
|
765
|
+
# smaller rigging in a larger row, then `k` would be larger.
|
|
766
|
+
return self.__class__(self.parent(), new_partitions, use_vacancy_numbers=True)
|
|
767
|
+
|
|
768
|
+
def _generate_partition_f(self, a, b, k):
|
|
769
|
+
r"""
|
|
770
|
+
Generate a new partition for a given value of `a` by updating the
|
|
771
|
+
vacancy numbers and preserving co-labels for the map `f_a`.
|
|
772
|
+
|
|
773
|
+
INPUT:
|
|
774
|
+
|
|
775
|
+
- ``a`` -- the index of the partition we operated on
|
|
776
|
+
- ``b`` -- the index of the partition to generate
|
|
777
|
+
- ``k`` -- the length of the string with smallest nonpositive rigging
|
|
778
|
+
of largest length
|
|
779
|
+
|
|
780
|
+
OUTPUT: the constructed rigged partition
|
|
781
|
+
|
|
782
|
+
TESTS::
|
|
783
|
+
|
|
784
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
|
|
785
|
+
sage: RC(partition_list=[[1], [1], [1], [1]])._generate_partition_f(1, 2, 1)
|
|
786
|
+
0[ ]0
|
|
787
|
+
<BLANKLINE>
|
|
788
|
+
"""
|
|
789
|
+
# Check to make sure we will do something
|
|
790
|
+
if not self.parent()._cartan_matrix[a,b]:
|
|
791
|
+
return self[b]
|
|
792
|
+
|
|
793
|
+
new_list = self[b]._list
|
|
794
|
+
new_vac_nums = self[b].vacancy_numbers[:]
|
|
795
|
+
new_rigging = self[b].rigging[:]
|
|
796
|
+
|
|
797
|
+
# Update the vacancy numbers and the rigging
|
|
798
|
+
value = self.parent()._cartan_matrix[b,a]
|
|
799
|
+
for i in range(len(new_vac_nums)):
|
|
800
|
+
if new_list[i] <= k:
|
|
801
|
+
break
|
|
802
|
+
|
|
803
|
+
new_vac_nums[i] -= value
|
|
804
|
+
new_rigging[i] -= value
|
|
805
|
+
|
|
806
|
+
return RiggedPartition(new_list, new_rigging, new_vac_nums)
|
|
807
|
+
|
|
808
|
+
def epsilon(self, a):
|
|
809
|
+
r"""
|
|
810
|
+
Return `\varepsilon_a` of ``self``.
|
|
811
|
+
|
|
812
|
+
Let `x_{\ell}` be the smallest string of `\nu^{(a)}` or `0` if
|
|
813
|
+
`\nu^{(a)} = \emptyset`, then we have
|
|
814
|
+
`\varepsilon_a = -\min(0, x_{\ell})`.
|
|
815
|
+
|
|
816
|
+
EXAMPLES::
|
|
817
|
+
|
|
818
|
+
sage: La = RootSystem(['B',2]).weight_lattice().fundamental_weights()
|
|
819
|
+
sage: RC = crystals.RiggedConfigurations(La[1]+La[2])
|
|
820
|
+
sage: I = RC.index_set()
|
|
821
|
+
sage: matrix([[rc.epsilon(i) for i in I] for rc in RC[:4]])
|
|
822
|
+
[0 0]
|
|
823
|
+
[1 0]
|
|
824
|
+
[0 1]
|
|
825
|
+
[0 2]
|
|
826
|
+
"""
|
|
827
|
+
a = self.parent()._rc_index_inverse[a]
|
|
828
|
+
if not self[a]:
|
|
829
|
+
return ZZ.zero()
|
|
830
|
+
return Integer(-min(0, *self[a].rigging))
|
|
831
|
+
|
|
832
|
+
def phi(self, a):
|
|
833
|
+
r"""
|
|
834
|
+
Return `\varphi_a` of ``self``.
|
|
835
|
+
|
|
836
|
+
Let `x_{\ell}` be the smallest string of `\nu^{(a)}` or `0` if
|
|
837
|
+
`\nu^{(a)} = \emptyset`, then we have
|
|
838
|
+
`\varepsilon_a = p_{\infty}^{(a)} - \min(0, x_{\ell})`.
|
|
839
|
+
|
|
840
|
+
EXAMPLES::
|
|
841
|
+
|
|
842
|
+
sage: La = RootSystem(['B',2]).weight_lattice().fundamental_weights()
|
|
843
|
+
sage: RC = crystals.RiggedConfigurations(La[1]+La[2])
|
|
844
|
+
sage: I = RC.index_set()
|
|
845
|
+
sage: matrix([[rc.phi(i) for i in I] for rc in RC[:4]])
|
|
846
|
+
[1 1]
|
|
847
|
+
[0 3]
|
|
848
|
+
[0 2]
|
|
849
|
+
[1 1]
|
|
850
|
+
"""
|
|
851
|
+
a = self.parent()._rc_index_inverse[a]
|
|
852
|
+
p_inf = self.parent()._calc_vacancy_number(self, a, float("inf"))
|
|
853
|
+
if not self[a]:
|
|
854
|
+
return Integer(p_inf)
|
|
855
|
+
return Integer(p_inf - min(0, *self[a].rigging))
|
|
856
|
+
|
|
857
|
+
def vacancy_number(self, a, i):
|
|
858
|
+
r"""
|
|
859
|
+
Return the vacancy number `p_i^{(a)}`.
|
|
860
|
+
|
|
861
|
+
INPUT:
|
|
862
|
+
|
|
863
|
+
- ``a`` -- the index of the rigged partition
|
|
864
|
+
|
|
865
|
+
- ``i`` -- the row of the rigged partition
|
|
866
|
+
|
|
867
|
+
EXAMPLES::
|
|
868
|
+
|
|
869
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
870
|
+
sage: elt = RC(partition_list=[[1], [2,1], [1], []])
|
|
871
|
+
sage: elt.vacancy_number(2, 3)
|
|
872
|
+
-2
|
|
873
|
+
sage: elt.vacancy_number(2, 2)
|
|
874
|
+
-2
|
|
875
|
+
sage: elt.vacancy_number(2, 1)
|
|
876
|
+
-1
|
|
877
|
+
|
|
878
|
+
sage: RC = RiggedConfigurations(['D',4,1], [[2,1], [2,1]])
|
|
879
|
+
sage: x = RC(partition_list=[[3], [3,1,1], [2], [3,1]]); ascii_art(x)
|
|
880
|
+
-1[ ][ ][ ]-1 1[ ][ ][ ]1 0[ ][ ]0 -3[ ][ ][ ]-3
|
|
881
|
+
0[ ]0 -1[ ]-1
|
|
882
|
+
0[ ]0
|
|
883
|
+
sage: x.vacancy_number(2,2)
|
|
884
|
+
1
|
|
885
|
+
"""
|
|
886
|
+
a = self.parent()._rc_index_inverse[a]
|
|
887
|
+
return self.parent()._calc_vacancy_number(self, a, i)
|
|
888
|
+
|
|
889
|
+
def partition_rigging_lists(self):
|
|
890
|
+
"""
|
|
891
|
+
Return the list of partitions and the associated list of riggings
|
|
892
|
+
of ``self``.
|
|
893
|
+
|
|
894
|
+
EXAMPLES::
|
|
895
|
+
|
|
896
|
+
sage: RC = RiggedConfigurations(['A',3,1], [[1,2],[2,2]])
|
|
897
|
+
sage: rc = RC(partition_list=[[2],[1],[1]], rigging_list=[[-1],[0],[-1]]); rc
|
|
898
|
+
<BLANKLINE>
|
|
899
|
+
-1[ ][ ]-1
|
|
900
|
+
<BLANKLINE>
|
|
901
|
+
1[ ]0
|
|
902
|
+
<BLANKLINE>
|
|
903
|
+
-1[ ]-1
|
|
904
|
+
<BLANKLINE>
|
|
905
|
+
sage: rc.partition_rigging_lists()
|
|
906
|
+
[[[2], [1], [1]], [[-1], [0], [-1]]]
|
|
907
|
+
"""
|
|
908
|
+
partitions = []
|
|
909
|
+
riggings = []
|
|
910
|
+
for p in self:
|
|
911
|
+
partitions.append(list(p))
|
|
912
|
+
riggings.append(list(p.rigging))
|
|
913
|
+
return [partitions, riggings]
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
class RCNonSimplyLacedElement(RiggedConfigurationElement):
|
|
917
|
+
"""
|
|
918
|
+
Rigged configuration elements for non-simply-laced types.
|
|
919
|
+
|
|
920
|
+
TESTS::
|
|
921
|
+
|
|
922
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
923
|
+
sage: RC = crystals.infinity.RiggedConfigurations(vct)
|
|
924
|
+
sage: elt = RC.module_generators[0].f_string([1,0,2,2,0,1]); elt
|
|
925
|
+
<BLANKLINE>
|
|
926
|
+
-2[ ][ ]-1
|
|
927
|
+
<BLANKLINE>
|
|
928
|
+
-2[ ]-1
|
|
929
|
+
-2[ ]-1
|
|
930
|
+
<BLANKLINE>
|
|
931
|
+
-2[ ][ ]-1
|
|
932
|
+
<BLANKLINE>
|
|
933
|
+
sage: TestSuite(elt).run()
|
|
934
|
+
"""
|
|
935
|
+
|
|
936
|
+
def to_virtual_configuration(self):
|
|
937
|
+
"""
|
|
938
|
+
Return the corresponding rigged configuration in the virtual crystal.
|
|
939
|
+
|
|
940
|
+
EXAMPLES::
|
|
941
|
+
|
|
942
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
|
|
943
|
+
sage: elt = RC(partition_list=[[3],[2]]); elt
|
|
944
|
+
<BLANKLINE>
|
|
945
|
+
0[ ][ ][ ]0
|
|
946
|
+
<BLANKLINE>
|
|
947
|
+
0[ ][ ]0
|
|
948
|
+
sage: elt.to_virtual_configuration()
|
|
949
|
+
<BLANKLINE>
|
|
950
|
+
0[ ][ ][ ]0
|
|
951
|
+
<BLANKLINE>
|
|
952
|
+
0[ ][ ][ ][ ]0
|
|
953
|
+
<BLANKLINE>
|
|
954
|
+
0[ ][ ][ ]0
|
|
955
|
+
"""
|
|
956
|
+
return self.parent().to_virtual(self)
|
|
957
|
+
|
|
958
|
+
def e(self, a):
|
|
959
|
+
r"""
|
|
960
|
+
Return the action of `e_a` on ``self``.
|
|
961
|
+
|
|
962
|
+
This works by lifting into the virtual configuration, then applying
|
|
963
|
+
|
|
964
|
+
.. MATH::
|
|
965
|
+
|
|
966
|
+
e^v_a = \prod_{j \in \iota(a)} \hat{e}_j^{\gamma_j}
|
|
967
|
+
|
|
968
|
+
and pulling back.
|
|
969
|
+
|
|
970
|
+
EXAMPLES::
|
|
971
|
+
|
|
972
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
973
|
+
sage: RC = crystals.infinity.RiggedConfigurations(vct)
|
|
974
|
+
sage: elt = RC(partition_list=[[2],[1,1],[2]], rigging_list=[[-1],[-1,-1],[-1]])
|
|
975
|
+
sage: ascii_art(elt.e(0))
|
|
976
|
+
0[ ]0 -2[ ]-1 -2[ ][ ]-1
|
|
977
|
+
-2[ ]-1
|
|
978
|
+
sage: ascii_art(elt.e(1))
|
|
979
|
+
-3[ ][ ]-2 0[ ]1 -3[ ][ ]-2
|
|
980
|
+
sage: ascii_art(elt.e(2))
|
|
981
|
+
-2[ ][ ]-1 -2[ ]-1 0[ ]0
|
|
982
|
+
-2[ ]-1
|
|
983
|
+
"""
|
|
984
|
+
vct = self.parent()._folded_ct
|
|
985
|
+
L = []
|
|
986
|
+
gamma = vct.scaling_factors()
|
|
987
|
+
for i in vct.folding_orbit()[a]:
|
|
988
|
+
L.extend([i]*gamma[a])
|
|
989
|
+
virtual_rc = self.parent().to_virtual(self).e_string(L)
|
|
990
|
+
if virtual_rc is None:
|
|
991
|
+
return None
|
|
992
|
+
return self.parent().from_virtual(virtual_rc)
|
|
993
|
+
|
|
994
|
+
def f(self, a):
|
|
995
|
+
r"""
|
|
996
|
+
Return the action of `f_a` on ``self``.
|
|
997
|
+
|
|
998
|
+
This works by lifting into the virtual configuration, then applying
|
|
999
|
+
|
|
1000
|
+
.. MATH::
|
|
1001
|
+
|
|
1002
|
+
f^v_a = \prod_{j \in \iota(a)} \hat{f}_j^{\gamma_j}
|
|
1003
|
+
|
|
1004
|
+
and pulling back.
|
|
1005
|
+
|
|
1006
|
+
EXAMPLES::
|
|
1007
|
+
|
|
1008
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
1009
|
+
sage: RC = crystals.infinity.RiggedConfigurations(vct)
|
|
1010
|
+
sage: elt = RC(partition_list=[[2],[1,1],[2]], rigging_list=[[-1],[-1,-1],[-1]])
|
|
1011
|
+
sage: ascii_art(elt.f(0))
|
|
1012
|
+
-4[ ][ ][ ]-2 -2[ ]-1 -2[ ][ ]-1
|
|
1013
|
+
-2[ ]-1
|
|
1014
|
+
sage: ascii_art(elt.f(1))
|
|
1015
|
+
-1[ ][ ]0 -2[ ][ ]-2 -1[ ][ ]0
|
|
1016
|
+
-2[ ]-1
|
|
1017
|
+
sage: ascii_art(elt.f(2))
|
|
1018
|
+
-2[ ][ ]-1 -2[ ]-1 -4[ ][ ][ ]-2
|
|
1019
|
+
-2[ ]-1
|
|
1020
|
+
"""
|
|
1021
|
+
vct = self.parent()._folded_ct
|
|
1022
|
+
L = []
|
|
1023
|
+
gamma = vct.scaling_factors()
|
|
1024
|
+
for i in vct.folding_orbit()[a]:
|
|
1025
|
+
L.extend([i]*gamma[a])
|
|
1026
|
+
virtual_rc = self.parent().to_virtual(self).f_string(L)
|
|
1027
|
+
if virtual_rc is None:
|
|
1028
|
+
return None
|
|
1029
|
+
return self.parent().from_virtual(virtual_rc)
|
|
1030
|
+
|
|
1031
|
+
##########################################################
|
|
1032
|
+
# Highest weight crystal rigged configuration elements #
|
|
1033
|
+
##########################################################
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
class RCHighestWeightElement(RiggedConfigurationElement):
|
|
1037
|
+
"""
|
|
1038
|
+
Rigged configurations in highest weight crystals.
|
|
1039
|
+
|
|
1040
|
+
TESTS::
|
|
1041
|
+
|
|
1042
|
+
sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1043
|
+
sage: RC = crystals.RiggedConfigurations(['A',2,1], La[0])
|
|
1044
|
+
sage: elt = RC(partition_list=[[1,1],[1],[2]]); elt
|
|
1045
|
+
<BLANKLINE>
|
|
1046
|
+
-1[ ]-1
|
|
1047
|
+
-1[ ]-1
|
|
1048
|
+
<BLANKLINE>
|
|
1049
|
+
1[ ]1
|
|
1050
|
+
<BLANKLINE>
|
|
1051
|
+
-1[ ][ ]-1
|
|
1052
|
+
<BLANKLINE>
|
|
1053
|
+
sage: TestSuite(elt).run()
|
|
1054
|
+
"""
|
|
1055
|
+
|
|
1056
|
+
def check(self):
|
|
1057
|
+
"""
|
|
1058
|
+
Make sure all of the riggings are less than or equal to the
|
|
1059
|
+
vacancy number.
|
|
1060
|
+
|
|
1061
|
+
TESTS::
|
|
1062
|
+
|
|
1063
|
+
sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1064
|
+
sage: RC = crystals.RiggedConfigurations(['A',2,1], La[0])
|
|
1065
|
+
sage: elt = RC(partition_list=[[1,1],[1],[2]])
|
|
1066
|
+
sage: elt.check()
|
|
1067
|
+
"""
|
|
1068
|
+
for a, partition in enumerate(self):
|
|
1069
|
+
for i, vac_num in enumerate(partition.vacancy_numbers):
|
|
1070
|
+
if vac_num < partition.rigging[i]:
|
|
1071
|
+
raise ValueError("rigging can be at most the vacancy number")
|
|
1072
|
+
|
|
1073
|
+
def f(self, a):
|
|
1074
|
+
r"""
|
|
1075
|
+
Return the action of the crystal operator `f_a` on ``self``.
|
|
1076
|
+
|
|
1077
|
+
This implements the method defined in [CrysStructSchilling06]_ which
|
|
1078
|
+
finds the value `k` which is the length of the string with the
|
|
1079
|
+
smallest nonpositive rigging of largest length. Then it adds a box
|
|
1080
|
+
from a string of length `k` in the `a`-th rigged partition, keeping
|
|
1081
|
+
all colabels fixed and decreasing the new label by one. If no such
|
|
1082
|
+
string exists, then it adds a new string of length 1 with label `-1`.
|
|
1083
|
+
If any of the resulting vacancy numbers are larger than the labels
|
|
1084
|
+
(i.e. it is an invalid rigged configuration), then `f_a` is
|
|
1085
|
+
undefined.
|
|
1086
|
+
|
|
1087
|
+
INPUT:
|
|
1088
|
+
|
|
1089
|
+
- ``a`` -- the index of the partition to add a box
|
|
1090
|
+
|
|
1091
|
+
OUTPUT: the resulting rigged configuration element
|
|
1092
|
+
|
|
1093
|
+
EXAMPLES::
|
|
1094
|
+
|
|
1095
|
+
sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1096
|
+
sage: RC = crystals.RiggedConfigurations(['A',2,1], La[0])
|
|
1097
|
+
sage: elt = RC(partition_list=[[1,1],[1],[2]])
|
|
1098
|
+
sage: elt.f(0)
|
|
1099
|
+
<BLANKLINE>
|
|
1100
|
+
-2[ ][ ]-2
|
|
1101
|
+
-1[ ]-1
|
|
1102
|
+
<BLANKLINE>
|
|
1103
|
+
1[ ]1
|
|
1104
|
+
<BLANKLINE>
|
|
1105
|
+
0[ ][ ]0
|
|
1106
|
+
<BLANKLINE>
|
|
1107
|
+
sage: elt.f(1)
|
|
1108
|
+
<BLANKLINE>
|
|
1109
|
+
0[ ]0
|
|
1110
|
+
0[ ]0
|
|
1111
|
+
<BLANKLINE>
|
|
1112
|
+
-1[ ]-1
|
|
1113
|
+
-1[ ]-1
|
|
1114
|
+
<BLANKLINE>
|
|
1115
|
+
0[ ][ ]0
|
|
1116
|
+
<BLANKLINE>
|
|
1117
|
+
sage: elt.f(2)
|
|
1118
|
+
"""
|
|
1119
|
+
if not self.phi(a):
|
|
1120
|
+
return None
|
|
1121
|
+
return RiggedConfigurationElement.f(self, a)
|
|
1122
|
+
|
|
1123
|
+
def weight(self):
|
|
1124
|
+
"""
|
|
1125
|
+
Return the weight of ``self``.
|
|
1126
|
+
|
|
1127
|
+
EXAMPLES::
|
|
1128
|
+
|
|
1129
|
+
sage: La = RootSystem(['A',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1130
|
+
sage: B = crystals.RiggedConfigurations(['A',2,1], La[0])
|
|
1131
|
+
sage: mg = B.module_generators[0]
|
|
1132
|
+
sage: mg.f_string([0,1,2,0]).weight()
|
|
1133
|
+
-Lambda[0] + Lambda[1] + Lambda[2] - 2*delta
|
|
1134
|
+
"""
|
|
1135
|
+
P = self.parent().weight_lattice_realization()
|
|
1136
|
+
alpha = list(P.simple_roots())
|
|
1137
|
+
return self.parent()._wt - sum(sum(x) * alpha[i] for i,x in enumerate(self))
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
class RCHWNonSimplyLacedElement(RCNonSimplyLacedElement):
|
|
1141
|
+
"""
|
|
1142
|
+
Rigged configurations in highest weight crystals.
|
|
1143
|
+
|
|
1144
|
+
TESTS::
|
|
1145
|
+
|
|
1146
|
+
sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1147
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
1148
|
+
sage: RC = crystals.RiggedConfigurations(vct, La[0])
|
|
1149
|
+
sage: elt = RC(partition_list=[[1,1],[2],[2]]); ascii_art(elt)
|
|
1150
|
+
-1[ ]-1 2[ ][ ]2 -2[ ][ ]-2
|
|
1151
|
+
-1[ ]-1
|
|
1152
|
+
sage: TestSuite(elt).run()
|
|
1153
|
+
"""
|
|
1154
|
+
|
|
1155
|
+
def check(self):
|
|
1156
|
+
"""
|
|
1157
|
+
Make sure all of the riggings are less than or equal to the
|
|
1158
|
+
vacancy number.
|
|
1159
|
+
|
|
1160
|
+
TESTS::
|
|
1161
|
+
|
|
1162
|
+
sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1163
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
1164
|
+
sage: RC = crystals.RiggedConfigurations(vct, La[0])
|
|
1165
|
+
sage: elt = RC(partition_list=[[1,1],[2],[2]])
|
|
1166
|
+
sage: elt.check()
|
|
1167
|
+
"""
|
|
1168
|
+
for partition in self:
|
|
1169
|
+
for i, vac_num in enumerate(partition.vacancy_numbers):
|
|
1170
|
+
if vac_num < partition.rigging[i]:
|
|
1171
|
+
raise ValueError("rigging can be at most the vacancy number")
|
|
1172
|
+
|
|
1173
|
+
def f(self, a):
|
|
1174
|
+
r"""
|
|
1175
|
+
Return the action of `f_a` on ``self``.
|
|
1176
|
+
|
|
1177
|
+
This works by lifting into the virtual configuration, then applying
|
|
1178
|
+
|
|
1179
|
+
.. MATH::
|
|
1180
|
+
|
|
1181
|
+
f^v_a = \prod_{j \in \iota(a)} \hat{f}_j^{\gamma_j}
|
|
1182
|
+
|
|
1183
|
+
and pulling back.
|
|
1184
|
+
|
|
1185
|
+
EXAMPLES::
|
|
1186
|
+
|
|
1187
|
+
sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1188
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
1189
|
+
sage: RC = crystals.RiggedConfigurations(vct, La[0])
|
|
1190
|
+
sage: elt = RC(partition_list=[[1,1],[2],[2]])
|
|
1191
|
+
sage: elt.f(0)
|
|
1192
|
+
sage: ascii_art(elt.f(1))
|
|
1193
|
+
0[ ]0 0[ ][ ]0 -1[ ][ ]-1
|
|
1194
|
+
0[ ]0 -1[ ]-1
|
|
1195
|
+
sage: elt.f(2)
|
|
1196
|
+
"""
|
|
1197
|
+
if not self.phi(a):
|
|
1198
|
+
return None
|
|
1199
|
+
return RCNonSimplyLacedElement.f(self, a)
|
|
1200
|
+
|
|
1201
|
+
# FIXME: Do not duplicate with the simply-laced HW RC element class
|
|
1202
|
+
def weight(self):
|
|
1203
|
+
"""
|
|
1204
|
+
Return the weight of ``self``.
|
|
1205
|
+
|
|
1206
|
+
EXAMPLES::
|
|
1207
|
+
|
|
1208
|
+
sage: La = RootSystem(['C',2,1]).weight_lattice(extended=True).fundamental_weights()
|
|
1209
|
+
sage: vct = CartanType(['C',2,1]).as_folding()
|
|
1210
|
+
sage: B = crystals.RiggedConfigurations(vct, La[0])
|
|
1211
|
+
sage: mg = B.module_generators[0]
|
|
1212
|
+
sage: mg.f_string([0,1,2]).weight()
|
|
1213
|
+
2*Lambda[1] - Lambda[2] - delta
|
|
1214
|
+
"""
|
|
1215
|
+
P = self.parent().weight_lattice_realization()
|
|
1216
|
+
alpha = list(P.simple_roots())
|
|
1217
|
+
return self.parent()._wt - sum(sum(x) * alpha[i] for i,x in enumerate(self))
|
|
1218
|
+
|
|
1219
|
+
##############################################
|
|
1220
|
+
# KR crystal rigged configuration elements #
|
|
1221
|
+
##############################################
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
class KRRiggedConfigurationElement(RiggedConfigurationElement):
|
|
1225
|
+
r"""
|
|
1226
|
+
`U_q^{\prime}(\mathfrak{g})` rigged configurations.
|
|
1227
|
+
|
|
1228
|
+
EXAMPLES:
|
|
1229
|
+
|
|
1230
|
+
We can go between :class:`rigged configurations <RiggedConfigurations>`
|
|
1231
|
+
and tensor products of :class:`tensor products of KR tableaux
|
|
1232
|
+
<sage.combinat.rigged_configurations.tensor_product_kr_tableaux.TensorProductOfKirillovReshetikhinTableaux>`::
|
|
1233
|
+
|
|
1234
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[1,1], [2,1]])
|
|
1235
|
+
sage: rc_elt = RC(partition_list=[[1], [1,1], [1], [1]])
|
|
1236
|
+
sage: tp_krtab = rc_elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); tp_krtab
|
|
1237
|
+
[[-2]] (X) [[1], [2]]
|
|
1238
|
+
sage: tp_krcrys = rc_elt.to_tensor_product_of_kirillov_reshetikhin_crystals(); tp_krcrys
|
|
1239
|
+
[[[-2]], [[1], [2]]]
|
|
1240
|
+
sage: tp_krcrys == tp_krtab.to_tensor_product_of_kirillov_reshetikhin_crystals()
|
|
1241
|
+
True
|
|
1242
|
+
sage: RC(tp_krcrys) == rc_elt
|
|
1243
|
+
True
|
|
1244
|
+
sage: RC(tp_krtab) == rc_elt
|
|
1245
|
+
True
|
|
1246
|
+
sage: tp_krtab.to_rigged_configuration() == rc_elt
|
|
1247
|
+
True
|
|
1248
|
+
"""
|
|
1249
|
+
|
|
1250
|
+
def __init__(self, parent, rigged_partitions=[], **options):
|
|
1251
|
+
r"""
|
|
1252
|
+
Construct a rigged configuration element.
|
|
1253
|
+
|
|
1254
|
+
EXAMPLES::
|
|
1255
|
+
|
|
1256
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
|
|
1257
|
+
sage: RC(partition_list=[[], [], [], []])
|
|
1258
|
+
<BLANKLINE>
|
|
1259
|
+
(/)
|
|
1260
|
+
<BLANKLINE>
|
|
1261
|
+
(/)
|
|
1262
|
+
<BLANKLINE>
|
|
1263
|
+
(/)
|
|
1264
|
+
<BLANKLINE>
|
|
1265
|
+
(/)
|
|
1266
|
+
<BLANKLINE>
|
|
1267
|
+
sage: RC(partition_list=[[1], [1], [], []])
|
|
1268
|
+
<BLANKLINE>
|
|
1269
|
+
-1[ ]-1
|
|
1270
|
+
<BLANKLINE>
|
|
1271
|
+
0[ ]0
|
|
1272
|
+
<BLANKLINE>
|
|
1273
|
+
(/)
|
|
1274
|
+
<BLANKLINE>
|
|
1275
|
+
(/)
|
|
1276
|
+
<BLANKLINE>
|
|
1277
|
+
sage: elt = RC(partition_list=[[1], [1], [], []], rigging_list=[[-1], [0], [], []]); elt
|
|
1278
|
+
<BLANKLINE>
|
|
1279
|
+
-1[ ]-1
|
|
1280
|
+
<BLANKLINE>
|
|
1281
|
+
0[ ]0
|
|
1282
|
+
<BLANKLINE>
|
|
1283
|
+
(/)
|
|
1284
|
+
<BLANKLINE>
|
|
1285
|
+
(/)
|
|
1286
|
+
<BLANKLINE>
|
|
1287
|
+
sage: TestSuite(elt).run()
|
|
1288
|
+
"""
|
|
1289
|
+
n = len(parent._rc_index)
|
|
1290
|
+
if "KT_constructor" in options:
|
|
1291
|
+
# Used only by the Kleber tree
|
|
1292
|
+
# Not recommended to be called by the user since it avoids safety
|
|
1293
|
+
# checks for speed
|
|
1294
|
+
data = options["KT_constructor"]
|
|
1295
|
+
shape_data = data[0]
|
|
1296
|
+
rigging_data = data[1]
|
|
1297
|
+
vac_data = data[2]
|
|
1298
|
+
nu = [RiggedPartition(a, b, c)
|
|
1299
|
+
for a, b, c in zip(shape_data, rigging_data, vac_data)]
|
|
1300
|
+
# Special display case
|
|
1301
|
+
if parent.cartan_type().type() == 'B':
|
|
1302
|
+
nu[-1] = RiggedPartitionTypeB(nu[-1])
|
|
1303
|
+
ClonableArray.__init__(self, parent, nu)
|
|
1304
|
+
return
|
|
1305
|
+
RiggedConfigurationElement.__init__(self, parent, rigged_partitions, n=n, **options)
|
|
1306
|
+
# Special display case
|
|
1307
|
+
if parent.cartan_type().type() == 'B':
|
|
1308
|
+
self._set_mutable()
|
|
1309
|
+
self[-1] = RiggedPartitionTypeB(self[-1])
|
|
1310
|
+
self.set_immutable()
|
|
1311
|
+
|
|
1312
|
+
def check(self):
|
|
1313
|
+
"""
|
|
1314
|
+
Make sure all of the riggings are less than or equal to the
|
|
1315
|
+
vacancy number.
|
|
1316
|
+
|
|
1317
|
+
TESTS::
|
|
1318
|
+
|
|
1319
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
|
|
1320
|
+
sage: elt = RC(partition_list=[[1], [1], [], []])
|
|
1321
|
+
sage: elt.check()
|
|
1322
|
+
"""
|
|
1323
|
+
for partition in self:
|
|
1324
|
+
for i, vac_num in enumerate(partition.vacancy_numbers):
|
|
1325
|
+
if vac_num < partition.rigging[i]:
|
|
1326
|
+
raise ValueError("rigging can be at most the vacancy number")
|
|
1327
|
+
|
|
1328
|
+
def e(self, a):
|
|
1329
|
+
r"""
|
|
1330
|
+
Return the action of the crystal operator `e_a` on ``self``.
|
|
1331
|
+
|
|
1332
|
+
For the classical operators, this implements the method defined
|
|
1333
|
+
in [CrysStructSchilling06]_. For `e_0`, this converts the class to
|
|
1334
|
+
a tensor product of KR tableaux and does the corresponding `e_0`
|
|
1335
|
+
and pulls back.
|
|
1336
|
+
|
|
1337
|
+
.. TODO::
|
|
1338
|
+
|
|
1339
|
+
Implement `e_0` without appealing to tensor product of
|
|
1340
|
+
KR tableaux.
|
|
1341
|
+
|
|
1342
|
+
INPUT:
|
|
1343
|
+
|
|
1344
|
+
- ``a`` -- the index of the partition to remove a box
|
|
1345
|
+
|
|
1346
|
+
OUTPUT: the resulting rigged configuration element
|
|
1347
|
+
|
|
1348
|
+
EXAMPLES::
|
|
1349
|
+
|
|
1350
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
|
|
1351
|
+
sage: elt = RC(partition_list=[[1], [1], [1], [1]])
|
|
1352
|
+
sage: elt.e(3)
|
|
1353
|
+
sage: elt.e(1)
|
|
1354
|
+
<BLANKLINE>
|
|
1355
|
+
(/)
|
|
1356
|
+
<BLANKLINE>
|
|
1357
|
+
0[ ]0
|
|
1358
|
+
<BLANKLINE>
|
|
1359
|
+
0[ ]0
|
|
1360
|
+
<BLANKLINE>
|
|
1361
|
+
-1[ ]-1
|
|
1362
|
+
<BLANKLINE>
|
|
1363
|
+
"""
|
|
1364
|
+
if a not in self.parent()._cartan_type.index_set():
|
|
1365
|
+
raise ValueError("{} is not in the index set".format(a))
|
|
1366
|
+
if a == self.parent()._cartan_type.special_node():
|
|
1367
|
+
try:
|
|
1368
|
+
ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().e(a)
|
|
1369
|
+
if ret is None:
|
|
1370
|
+
return None
|
|
1371
|
+
return ret.to_rigged_configuration()
|
|
1372
|
+
except NotImplementedError:
|
|
1373
|
+
# We haven't implemented the bijection yet, so return None
|
|
1374
|
+
# This is to make sure we can at least view it as a classical
|
|
1375
|
+
# crystal if there is no bijection.
|
|
1376
|
+
return None
|
|
1377
|
+
|
|
1378
|
+
return RiggedConfigurationElement.e(self, a)
|
|
1379
|
+
|
|
1380
|
+
def f(self, a):
|
|
1381
|
+
r"""
|
|
1382
|
+
Return the action of the crystal operator `f_a` on ``self``.
|
|
1383
|
+
|
|
1384
|
+
For the classical operators, this implements the method defined
|
|
1385
|
+
in [CrysStructSchilling06]_. For `f_0`, this converts the class to
|
|
1386
|
+
a tensor product of KR tableaux and does the corresponding `f_0`
|
|
1387
|
+
and pulls back.
|
|
1388
|
+
|
|
1389
|
+
.. TODO::
|
|
1390
|
+
|
|
1391
|
+
Implement `f_0` without appealing to tensor product of
|
|
1392
|
+
KR tableaux.
|
|
1393
|
+
|
|
1394
|
+
INPUT:
|
|
1395
|
+
|
|
1396
|
+
- ``a`` -- the index of the partition to add a box
|
|
1397
|
+
|
|
1398
|
+
OUTPUT: the resulting rigged configuration element
|
|
1399
|
+
|
|
1400
|
+
EXAMPLES::
|
|
1401
|
+
|
|
1402
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2,1]])
|
|
1403
|
+
sage: elt = RC(partition_list=[[1], [1], [1], [1]])
|
|
1404
|
+
sage: elt.f(1)
|
|
1405
|
+
sage: elt.f(2)
|
|
1406
|
+
<BLANKLINE>
|
|
1407
|
+
0[ ]0
|
|
1408
|
+
<BLANKLINE>
|
|
1409
|
+
-1[ ]-1
|
|
1410
|
+
-1[ ]-1
|
|
1411
|
+
<BLANKLINE>
|
|
1412
|
+
1[ ]1
|
|
1413
|
+
<BLANKLINE>
|
|
1414
|
+
-1[ ]-1
|
|
1415
|
+
<BLANKLINE>
|
|
1416
|
+
"""
|
|
1417
|
+
ct = self.parent()._cartan_type
|
|
1418
|
+
if a not in ct.index_set():
|
|
1419
|
+
raise ValueError("{} is not in the index set".format(a))
|
|
1420
|
+
if a == ct.special_node():
|
|
1421
|
+
try:
|
|
1422
|
+
ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().f(a)
|
|
1423
|
+
if ret is None:
|
|
1424
|
+
return None
|
|
1425
|
+
return ret.to_rigged_configuration()
|
|
1426
|
+
except NotImplementedError:
|
|
1427
|
+
# We haven't implemented the bijection yet, so return None
|
|
1428
|
+
# This is to make sure we can at least view it as a classical
|
|
1429
|
+
# crystal if there is no bijection.
|
|
1430
|
+
return None
|
|
1431
|
+
|
|
1432
|
+
if not self.phi(a):
|
|
1433
|
+
return None
|
|
1434
|
+
|
|
1435
|
+
return RiggedConfigurationElement.f(self, a)
|
|
1436
|
+
|
|
1437
|
+
def epsilon(self, a):
|
|
1438
|
+
r"""
|
|
1439
|
+
Return `\varepsilon_a` of ``self``.
|
|
1440
|
+
|
|
1441
|
+
EXAMPLES::
|
|
1442
|
+
|
|
1443
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
1444
|
+
sage: I = RC.index_set()
|
|
1445
|
+
sage: matrix([[mg.epsilon(i) for i in I] for mg in RC.module_generators])
|
|
1446
|
+
[4 0 0 0 0]
|
|
1447
|
+
[3 0 0 0 0]
|
|
1448
|
+
[2 0 0 0 0]
|
|
1449
|
+
"""
|
|
1450
|
+
if a == self.parent()._cartan_type.special_node():
|
|
1451
|
+
return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().epsilon(a)
|
|
1452
|
+
return RiggedConfigurationElement.epsilon(self, a)
|
|
1453
|
+
|
|
1454
|
+
def phi(self, a):
|
|
1455
|
+
r"""
|
|
1456
|
+
Return `\varphi_a` of ``self``.
|
|
1457
|
+
|
|
1458
|
+
EXAMPLES::
|
|
1459
|
+
|
|
1460
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
1461
|
+
sage: I = RC.index_set()
|
|
1462
|
+
sage: matrix([[mg.phi(i) for i in I] for mg in RC.module_generators])
|
|
1463
|
+
[0 0 2 0 0]
|
|
1464
|
+
[1 0 1 0 0]
|
|
1465
|
+
[2 0 0 0 0]
|
|
1466
|
+
"""
|
|
1467
|
+
if a == self.parent()._cartan_type.special_node():
|
|
1468
|
+
return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().phi(a)
|
|
1469
|
+
return RiggedConfigurationElement.phi(self, a)
|
|
1470
|
+
|
|
1471
|
+
def weight(self):
|
|
1472
|
+
"""
|
|
1473
|
+
Return the weight of ``self``.
|
|
1474
|
+
|
|
1475
|
+
EXAMPLES::
|
|
1476
|
+
|
|
1477
|
+
sage: RC = RiggedConfigurations(['E', 6, 1], [[2,2]])
|
|
1478
|
+
sage: [x.weight() for x in RC.module_generators]
|
|
1479
|
+
[-4*Lambda[0] + 2*Lambda[2], -2*Lambda[0] + Lambda[2], 0]
|
|
1480
|
+
sage: KR = crystals.KirillovReshetikhin(['E',6,1], 2,2)
|
|
1481
|
+
sage: [x.weight() for x in KR.module_generators] # long time
|
|
1482
|
+
[0, -2*Lambda[0] + Lambda[2], -4*Lambda[0] + 2*Lambda[2]]
|
|
1483
|
+
|
|
1484
|
+
sage: RC = RiggedConfigurations(['D', 6, 1], [[4,2]])
|
|
1485
|
+
sage: [x.weight() for x in RC.module_generators]
|
|
1486
|
+
[-4*Lambda[0] + 2*Lambda[4], -4*Lambda[0] + Lambda[2] + Lambda[4],
|
|
1487
|
+
-2*Lambda[0] + Lambda[4], -4*Lambda[0] + 2*Lambda[2],
|
|
1488
|
+
-2*Lambda[0] + Lambda[2], 0]
|
|
1489
|
+
"""
|
|
1490
|
+
WLR = self.parent().weight_lattice_realization()
|
|
1491
|
+
La = WLR.fundamental_weights()
|
|
1492
|
+
cl_index = self.parent()._rc_index
|
|
1493
|
+
wt = WLR.sum((self.phi(i) - self.epsilon(i)) * La[i] for i in cl_index)
|
|
1494
|
+
return -wt.level() * La[0] + wt
|
|
1495
|
+
|
|
1496
|
+
@cached_method
|
|
1497
|
+
def classical_weight(self):
|
|
1498
|
+
r"""
|
|
1499
|
+
Return the classical weight of ``self``.
|
|
1500
|
+
|
|
1501
|
+
The classical weight `\Lambda` of a rigged configuration is
|
|
1502
|
+
|
|
1503
|
+
.. MATH::
|
|
1504
|
+
|
|
1505
|
+
\Lambda = \sum_{a \in \overline{I}} \sum_{i > 0}
|
|
1506
|
+
i L_i^{(a)} \Lambda_a - \sum_{a \in \overline{I}} \sum_{i > 0}
|
|
1507
|
+
i m_i^{(a)} \alpha_a.
|
|
1508
|
+
|
|
1509
|
+
EXAMPLES::
|
|
1510
|
+
|
|
1511
|
+
sage: RC = RiggedConfigurations(['D',4,1], [[2,2]])
|
|
1512
|
+
sage: elt = RC(partition_list=[[2],[2,1],[1],[1]])
|
|
1513
|
+
sage: elt.classical_weight()
|
|
1514
|
+
(0, 1, 1, 0)
|
|
1515
|
+
|
|
1516
|
+
This agrees with the corresponding classical weight as KR tableaux::
|
|
1517
|
+
|
|
1518
|
+
sage: krt = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); krt
|
|
1519
|
+
[[2, 1], [3, -1]]
|
|
1520
|
+
sage: krt.classical_weight() == elt.classical_weight()
|
|
1521
|
+
True
|
|
1522
|
+
|
|
1523
|
+
TESTS:
|
|
1524
|
+
|
|
1525
|
+
We check the classical weights agree in an entire crystal::
|
|
1526
|
+
|
|
1527
|
+
sage: RC = RiggedConfigurations(['A',2,1], [[2,1], [1,1]])
|
|
1528
|
+
sage: for x in RC:
|
|
1529
|
+
....: y = x.to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
1530
|
+
....: assert x.classical_weight() == y.classical_weight()
|
|
1531
|
+
"""
|
|
1532
|
+
F = self.cartan_type().classical().root_system()
|
|
1533
|
+
if F.ambient_space() is None:
|
|
1534
|
+
WLR = F.weight_lattice()
|
|
1535
|
+
else:
|
|
1536
|
+
WLR = F.ambient_space()
|
|
1537
|
+
La = WLR.fundamental_weights()
|
|
1538
|
+
wt = WLR.sum(La[r] * s for r,s in self.parent().dims)
|
|
1539
|
+
|
|
1540
|
+
alpha = WLR.simple_roots()
|
|
1541
|
+
rc_index = self.parent()._rc_index
|
|
1542
|
+
for a, nu in enumerate(self):
|
|
1543
|
+
wt -= sum(nu) * alpha[rc_index[a]]
|
|
1544
|
+
return wt
|
|
1545
|
+
|
|
1546
|
+
def to_tensor_product_of_kirillov_reshetikhin_tableaux(self, display_steps=False, build_graph=False):
|
|
1547
|
+
r"""
|
|
1548
|
+
Perform the bijection from this rigged configuration to a tensor
|
|
1549
|
+
product of Kirillov-Reshetikhin tableaux given in [RigConBijection]_
|
|
1550
|
+
for single boxes and with [BijectionLRT]_ and [BijectionDn]_ for
|
|
1551
|
+
multiple columns and rows.
|
|
1552
|
+
|
|
1553
|
+
.. NOTE::
|
|
1554
|
+
|
|
1555
|
+
This is only proven to be a bijection in types `A_n^{(1)}`
|
|
1556
|
+
and `D_n^{(1)}`, as well as `\bigotimes_i B^{r_i,1}` and
|
|
1557
|
+
`\bigotimes_i B^{1,s_i}` for general affine types.
|
|
1558
|
+
|
|
1559
|
+
INPUT:
|
|
1560
|
+
|
|
1561
|
+
- ``display_steps`` -- boolean (default: ``False``); indicates whether
|
|
1562
|
+
to print each step in the algorithm
|
|
1563
|
+
- ``build_graph`` -- boolean (default: ``False``); indicates whether
|
|
1564
|
+
to construct and return a graph of the bijection whose
|
|
1565
|
+
vertices are rigged configurations obtained at each step and edges
|
|
1566
|
+
are labeled by either the return value of `\delta` or the
|
|
1567
|
+
doubling/halving map
|
|
1568
|
+
|
|
1569
|
+
OUTPUT:
|
|
1570
|
+
|
|
1571
|
+
- The tensor product of KR tableaux element corresponding to this
|
|
1572
|
+
rigged configuration.
|
|
1573
|
+
|
|
1574
|
+
EXAMPLES::
|
|
1575
|
+
|
|
1576
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
1577
|
+
sage: RC(partition_list=[[2], [2,2], [2], [2]]).to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
1578
|
+
[[3, 3], [5, 5]]
|
|
1579
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
1580
|
+
sage: elt = RC(partition_list=[[2], [2,2], [1], [1]])
|
|
1581
|
+
sage: tp_krt = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); tp_krt
|
|
1582
|
+
[[2, 3], [3, -2]]
|
|
1583
|
+
|
|
1584
|
+
This is invertible by calling
|
|
1585
|
+
:meth:`~sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element.TensorProductOfKirillovReshetikhinTableauxElement.to_rigged_configuration()`::
|
|
1586
|
+
|
|
1587
|
+
sage: ret = tp_krt.to_rigged_configuration(); ret
|
|
1588
|
+
<BLANKLINE>
|
|
1589
|
+
0[ ][ ]0
|
|
1590
|
+
<BLANKLINE>
|
|
1591
|
+
-2[ ][ ]-2
|
|
1592
|
+
-2[ ][ ]-2
|
|
1593
|
+
<BLANKLINE>
|
|
1594
|
+
0[ ]0
|
|
1595
|
+
<BLANKLINE>
|
|
1596
|
+
0[ ]0
|
|
1597
|
+
<BLANKLINE>
|
|
1598
|
+
sage: elt == ret
|
|
1599
|
+
True
|
|
1600
|
+
|
|
1601
|
+
To view the steps of the bijection in the output, run with
|
|
1602
|
+
the ``display_steps=True`` option::
|
|
1603
|
+
|
|
1604
|
+
sage: elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(True)
|
|
1605
|
+
====================
|
|
1606
|
+
...
|
|
1607
|
+
====================
|
|
1608
|
+
<BLANKLINE>
|
|
1609
|
+
0[ ]0
|
|
1610
|
+
<BLANKLINE>
|
|
1611
|
+
-2[ ][ ]-2
|
|
1612
|
+
0[ ]0
|
|
1613
|
+
<BLANKLINE>
|
|
1614
|
+
0[ ]0
|
|
1615
|
+
<BLANKLINE>
|
|
1616
|
+
0[ ]0
|
|
1617
|
+
<BLANKLINE>
|
|
1618
|
+
--------------------
|
|
1619
|
+
[[3, 2]]
|
|
1620
|
+
--------------------
|
|
1621
|
+
...
|
|
1622
|
+
[[2, 3], [3, -2]]
|
|
1623
|
+
|
|
1624
|
+
We can also construct and display a graph of the bijection
|
|
1625
|
+
as follows::
|
|
1626
|
+
|
|
1627
|
+
sage: ret, G = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(build_graph=True)
|
|
1628
|
+
sage: view(G) # not tested
|
|
1629
|
+
"""
|
|
1630
|
+
from sage.combinat.rigged_configurations.bijection import RCToKRTBijection
|
|
1631
|
+
bij = RCToKRTBijection(self)
|
|
1632
|
+
ret = bij.run(display_steps, build_graph)
|
|
1633
|
+
if build_graph:
|
|
1634
|
+
return (ret, bij._graph)
|
|
1635
|
+
return ret
|
|
1636
|
+
|
|
1637
|
+
def to_tensor_product_of_kirillov_reshetikhin_crystals(self, display_steps=False, build_graph=False):
|
|
1638
|
+
r"""
|
|
1639
|
+
Return the corresponding tensor product of Kirillov-Reshetikhin
|
|
1640
|
+
crystals.
|
|
1641
|
+
|
|
1642
|
+
This is a composition of the map to a tensor product of KR tableaux,
|
|
1643
|
+
and then to a tensor product of KR crystals.
|
|
1644
|
+
|
|
1645
|
+
INPUT:
|
|
1646
|
+
|
|
1647
|
+
- ``display_steps`` -- boolean (default: ``False``); indicates whether
|
|
1648
|
+
to print each step in the algorithm
|
|
1649
|
+
- ``build_graph`` -- boolean (default: ``False``); indicates whether
|
|
1650
|
+
to construct and return a graph of the bijection whose
|
|
1651
|
+
vertices are rigged configurations obtained at each step and edges
|
|
1652
|
+
are labeled by either the return value of `\delta` or the
|
|
1653
|
+
doubling/halving map
|
|
1654
|
+
|
|
1655
|
+
EXAMPLES::
|
|
1656
|
+
|
|
1657
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2]])
|
|
1658
|
+
sage: elt = RC(partition_list=[[2], [2,2], [1], [1]])
|
|
1659
|
+
sage: krc = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(); krc
|
|
1660
|
+
[[[2, 3], [3, -2]]]
|
|
1661
|
+
|
|
1662
|
+
We can recover the rigged configuration::
|
|
1663
|
+
|
|
1664
|
+
sage: ret = RC(krc); ret
|
|
1665
|
+
<BLANKLINE>
|
|
1666
|
+
0[ ][ ]0
|
|
1667
|
+
<BLANKLINE>
|
|
1668
|
+
-2[ ][ ]-2
|
|
1669
|
+
-2[ ][ ]-2
|
|
1670
|
+
<BLANKLINE>
|
|
1671
|
+
0[ ]0
|
|
1672
|
+
<BLANKLINE>
|
|
1673
|
+
0[ ]0
|
|
1674
|
+
<BLANKLINE>
|
|
1675
|
+
sage: elt == ret
|
|
1676
|
+
True
|
|
1677
|
+
|
|
1678
|
+
We can also construct and display a graph of the bijection
|
|
1679
|
+
as follows::
|
|
1680
|
+
|
|
1681
|
+
sage: ret, G = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(build_graph=True)
|
|
1682
|
+
sage: view(G) # not tested
|
|
1683
|
+
"""
|
|
1684
|
+
if build_graph:
|
|
1685
|
+
kr_tab, G = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps, build_graph)
|
|
1686
|
+
return (kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals(), G)
|
|
1687
|
+
kr_tab = self.to_tensor_product_of_kirillov_reshetikhin_tableaux(display_steps)
|
|
1688
|
+
return kr_tab.to_tensor_product_of_kirillov_reshetikhin_crystals()
|
|
1689
|
+
|
|
1690
|
+
# TODO: Move the morphisms to a lazy attribute of RiggedConfigurations
|
|
1691
|
+
# once #15463 is done
|
|
1692
|
+
def left_split(self):
|
|
1693
|
+
r"""
|
|
1694
|
+
Return the image of ``self`` under the left column splitting
|
|
1695
|
+
map `\beta`.
|
|
1696
|
+
|
|
1697
|
+
Consider the map `\beta : RC(B^{r,s} \otimes B) \to RC(B^{r,1}
|
|
1698
|
+
\otimes B^{r,s-1} \otimes B)` for `s > 1` which is a natural classical
|
|
1699
|
+
crystal injection. On rigged configurations, the map `\beta` does
|
|
1700
|
+
nothing (except possibly changing the vacancy numbers).
|
|
1701
|
+
|
|
1702
|
+
EXAMPLES::
|
|
1703
|
+
|
|
1704
|
+
sage: RC = RiggedConfigurations(['C',4,1], [[3,3]])
|
|
1705
|
+
sage: mg = RC.module_generators[-1]
|
|
1706
|
+
sage: ascii_art(mg)
|
|
1707
|
+
0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1708
|
+
0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1709
|
+
0[ ][ ]0 0[ ]0
|
|
1710
|
+
sage: ascii_art(mg.left_split())
|
|
1711
|
+
0[ ][ ]0 0[ ][ ]0 1[ ][ ]0 0[ ]0
|
|
1712
|
+
0[ ][ ]0 1[ ][ ]0 0[ ]0
|
|
1713
|
+
1[ ][ ]0 0[ ]0
|
|
1714
|
+
"""
|
|
1715
|
+
P = self.parent()
|
|
1716
|
+
if P.dims[0][1] == 1:
|
|
1717
|
+
raise ValueError("cannot split a single column")
|
|
1718
|
+
r,s = P.dims[0]
|
|
1719
|
+
B = [[r,1], [r,s-1]]
|
|
1720
|
+
B.extend(P.dims[1:])
|
|
1721
|
+
from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
|
|
1722
|
+
RC = RiggedConfigurations(P._cartan_type, B)
|
|
1723
|
+
return RC(*[x._clone() for x in self]) # Make a deep copy
|
|
1724
|
+
|
|
1725
|
+
def right_split(self):
|
|
1726
|
+
r"""
|
|
1727
|
+
Return the image of ``self`` under the right column splitting
|
|
1728
|
+
map `\beta^*`.
|
|
1729
|
+
|
|
1730
|
+
Let `\theta` denote the
|
|
1731
|
+
:meth:`complement rigging map<complement_rigging>` which reverses
|
|
1732
|
+
the tensor factors and `\beta` denote the
|
|
1733
|
+
:meth:`left splitting map<left_split>`, we define the right
|
|
1734
|
+
splitting map by `\beta^* := \theta \circ \beta \circ \theta`.
|
|
1735
|
+
|
|
1736
|
+
EXAMPLES::
|
|
1737
|
+
|
|
1738
|
+
sage: RC = RiggedConfigurations(['C',4,1], [[3,3]])
|
|
1739
|
+
sage: mg = RC.module_generators[-1]
|
|
1740
|
+
sage: ascii_art(mg)
|
|
1741
|
+
0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1742
|
+
0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1743
|
+
0[ ][ ]0 0[ ]0
|
|
1744
|
+
sage: ascii_art(mg.right_split())
|
|
1745
|
+
0[ ][ ]0 0[ ][ ]0 1[ ][ ]1 0[ ]0
|
|
1746
|
+
0[ ][ ]0 1[ ][ ]1 0[ ]0
|
|
1747
|
+
1[ ][ ]1 0[ ]0
|
|
1748
|
+
|
|
1749
|
+
sage: RC = RiggedConfigurations(['D',4,1], [[2,2],[1,2]])
|
|
1750
|
+
sage: elt = RC(partition_list=[[3,1], [2,2,1], [2,1], [2]])
|
|
1751
|
+
sage: ascii_art(elt)
|
|
1752
|
+
-1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1
|
|
1753
|
+
0[ ]0 0[ ][ ]0 -1[ ]-1
|
|
1754
|
+
0[ ]0
|
|
1755
|
+
sage: ascii_art(elt.right_split())
|
|
1756
|
+
-1[ ][ ][ ]-1 0[ ][ ]0 -1[ ][ ]-1 1[ ][ ]1
|
|
1757
|
+
1[ ]0 0[ ][ ]0 -1[ ]-1
|
|
1758
|
+
0[ ]0
|
|
1759
|
+
|
|
1760
|
+
We check that the bijection commutes with the right splitting map::
|
|
1761
|
+
|
|
1762
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[1,1], [2,2]])
|
|
1763
|
+
sage: all(rc.right_split().to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
1764
|
+
....: == rc.to_tensor_product_of_kirillov_reshetikhin_tableaux().right_split() for rc in RC)
|
|
1765
|
+
True
|
|
1766
|
+
"""
|
|
1767
|
+
return self.complement_rigging(True).left_split().complement_rigging(True)
|
|
1768
|
+
|
|
1769
|
+
def left_box(self, return_b=False):
|
|
1770
|
+
r"""
|
|
1771
|
+
Return the image of ``self`` under the left box removal map `\delta`.
|
|
1772
|
+
|
|
1773
|
+
The map `\delta : RC(B^{r,1} \otimes B) \to RC(B^{r-1,1}
|
|
1774
|
+
\otimes B)` (if `r = 1`, then we remove the left-most factor) is the
|
|
1775
|
+
basic map in the bijection `\Phi` between rigged configurations and
|
|
1776
|
+
tensor products of Kirillov-Reshetikhin tableaux. For more
|
|
1777
|
+
information, see
|
|
1778
|
+
:meth:`to_tensor_product_of_kirillov_reshetikhin_tableaux()`.
|
|
1779
|
+
We can extend `\delta` when the left-most factor is not a single
|
|
1780
|
+
column by precomposing with a :meth:`left_split()`.
|
|
1781
|
+
|
|
1782
|
+
.. NOTE::
|
|
1783
|
+
|
|
1784
|
+
Due to the special nature of the bijection for the spinor cases in
|
|
1785
|
+
types `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`, this map is
|
|
1786
|
+
not defined in these cases.
|
|
1787
|
+
|
|
1788
|
+
INPUT:
|
|
1789
|
+
|
|
1790
|
+
- ``return_b`` -- boolean (default: ``False``); whether to return the
|
|
1791
|
+
resulting letter from `\delta`
|
|
1792
|
+
|
|
1793
|
+
OUTPUT:
|
|
1794
|
+
|
|
1795
|
+
The resulting rigged configuration or if ``return_b`` is ``True``,
|
|
1796
|
+
then a tuple of the resulting rigged configuration and the letter.
|
|
1797
|
+
|
|
1798
|
+
EXAMPLES::
|
|
1799
|
+
|
|
1800
|
+
sage: RC = RiggedConfigurations(['C',4,1], [[3,2]])
|
|
1801
|
+
sage: mg = RC.module_generators[-1]
|
|
1802
|
+
sage: ascii_art(mg)
|
|
1803
|
+
0[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1804
|
+
0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1805
|
+
0[ ][ ]0 0[ ]0
|
|
1806
|
+
sage: ascii_art(mg.left_box())
|
|
1807
|
+
0[ ]0 0[ ][ ]0 0[ ][ ]0 0[ ]0
|
|
1808
|
+
0[ ]0 0[ ][ ]0 0[ ]0
|
|
1809
|
+
sage: x,b = mg.left_box(True)
|
|
1810
|
+
sage: b
|
|
1811
|
+
-1
|
|
1812
|
+
sage: b.parent()
|
|
1813
|
+
The crystal of letters for type ['C', 4]
|
|
1814
|
+
"""
|
|
1815
|
+
# Don't do spinor cases
|
|
1816
|
+
P = self.parent()
|
|
1817
|
+
ct = P.cartan_type()
|
|
1818
|
+
if ct.type() == 'D':
|
|
1819
|
+
if P.dims[0][0] >= ct.rank() - 2:
|
|
1820
|
+
raise ValueError("only for non-spinor cases")
|
|
1821
|
+
elif ct.type() == 'B' or ct.dual().type() == 'B':
|
|
1822
|
+
if P.dims[0][0] == ct.rank() - 1:
|
|
1823
|
+
raise ValueError("only for non-spinor cases")
|
|
1824
|
+
|
|
1825
|
+
from sage.combinat.rigged_configurations.bijection import RCToKRTBijection
|
|
1826
|
+
rc = self
|
|
1827
|
+
if P.dims[0][1] != 1:
|
|
1828
|
+
rc = self.left_split()
|
|
1829
|
+
bij = RCToKRTBijection(rc)
|
|
1830
|
+
ht = bij.cur_dims[0][0]
|
|
1831
|
+
bij.cur_dims[0][0] = bij._next_index(ht)
|
|
1832
|
+
b = bij.next_state(ht)
|
|
1833
|
+
if bij.cur_dims[0][0] == 0:
|
|
1834
|
+
bij.cur_dims.pop(0)
|
|
1835
|
+
from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
|
|
1836
|
+
RC = RiggedConfigurations(ct, bij.cur_dims)
|
|
1837
|
+
rc = RC(*bij.cur_partitions)
|
|
1838
|
+
if return_b:
|
|
1839
|
+
from sage.combinat.crystals.letters import CrystalOfLetters
|
|
1840
|
+
L = CrystalOfLetters(self.parent()._cartan_type.classical())
|
|
1841
|
+
return (rc, L(b))
|
|
1842
|
+
return rc
|
|
1843
|
+
|
|
1844
|
+
delta = left_box
|
|
1845
|
+
|
|
1846
|
+
def left_column_box(self):
|
|
1847
|
+
r"""
|
|
1848
|
+
Return the image of ``self`` under the left column box splitting
|
|
1849
|
+
map `\gamma`.
|
|
1850
|
+
|
|
1851
|
+
Consider the map `\gamma : RC(B^{r,1} \otimes B) \to RC(B^{1,1}
|
|
1852
|
+
\otimes B^{r-1,1} \otimes B)` for `r > 1`, which is a natural strict
|
|
1853
|
+
classical crystal injection. On rigged configurations, the map
|
|
1854
|
+
`\gamma` adds a singular string of length `1` to `\nu^{(a)}`.
|
|
1855
|
+
|
|
1856
|
+
We can extend `\gamma` when the left-most factor is not a single
|
|
1857
|
+
column by precomposing with a :meth:`left_split()`.
|
|
1858
|
+
|
|
1859
|
+
EXAMPLES::
|
|
1860
|
+
|
|
1861
|
+
sage: RC = RiggedConfigurations(['C',3,1], [[3,1], [2,1]])
|
|
1862
|
+
sage: mg = RC.module_generators[-1]
|
|
1863
|
+
sage: ascii_art(mg)
|
|
1864
|
+
0[ ]0 0[ ][ ]0 0[ ]0
|
|
1865
|
+
0[ ]0 0[ ]0
|
|
1866
|
+
sage: ascii_art(mg.left_column_box())
|
|
1867
|
+
0[ ]0 0[ ][ ]0 0[ ]0
|
|
1868
|
+
0[ ]0 0[ ]0 0[ ]0
|
|
1869
|
+
0[ ]0
|
|
1870
|
+
|
|
1871
|
+
sage: RC = RiggedConfigurations(['C',3,1], [[2,1], [1,1], [3,1]])
|
|
1872
|
+
sage: mg = RC.module_generators[7]
|
|
1873
|
+
sage: ascii_art(mg)
|
|
1874
|
+
1[ ]0 0[ ][ ]0 0[ ]0
|
|
1875
|
+
0[ ]0 0[ ]0
|
|
1876
|
+
sage: ascii_art(mg.left_column_box())
|
|
1877
|
+
1[ ]1 0[ ][ ]0 0[ ]0
|
|
1878
|
+
1[ ]0 0[ ]0 0[ ]0
|
|
1879
|
+
"""
|
|
1880
|
+
P = self.parent()
|
|
1881
|
+
r = P.dims[0][0]
|
|
1882
|
+
if r == 1:
|
|
1883
|
+
raise ValueError("cannot split a single box")
|
|
1884
|
+
ct = P.cartan_type()
|
|
1885
|
+
if ct.type() == 'D':
|
|
1886
|
+
if P.dims[0][0] >= ct.rank() - 2:
|
|
1887
|
+
raise ValueError("only for non-spinor cases")
|
|
1888
|
+
elif ct.type() == 'B' or ct.dual().type() == 'B':
|
|
1889
|
+
if P.dims[0][0] == ct.rank() - 1:
|
|
1890
|
+
raise ValueError("only for non-spinor cases")
|
|
1891
|
+
|
|
1892
|
+
if P.dims[0][1] > 1:
|
|
1893
|
+
return self.left_split().left_column_box()
|
|
1894
|
+
|
|
1895
|
+
B = [[1,1], [r-1,1]]
|
|
1896
|
+
B.extend(P.dims[1:])
|
|
1897
|
+
from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
|
|
1898
|
+
RC = RiggedConfigurations(P._cartan_type, B)
|
|
1899
|
+
parts = [x._clone() for x in self] # Make a deep copy
|
|
1900
|
+
for nu in parts[:r-1]:
|
|
1901
|
+
nu._list.append(1)
|
|
1902
|
+
for a, nu in enumerate(parts[:r-1]):
|
|
1903
|
+
vac_num = RC._calc_vacancy_number(parts, a, 1)
|
|
1904
|
+
i = nu._list.index(1)
|
|
1905
|
+
nu.vacancy_numbers.insert(i, vac_num)
|
|
1906
|
+
nu.rigging.insert(i, vac_num)
|
|
1907
|
+
return RC(*parts)
|
|
1908
|
+
|
|
1909
|
+
def right_column_box(self):
|
|
1910
|
+
r"""
|
|
1911
|
+
Return the image of ``self`` under the right column box splitting
|
|
1912
|
+
map `\gamma^*`.
|
|
1913
|
+
|
|
1914
|
+
Consider the map `\gamma^* : RC(B \otimes B^{r,1}) \to RC(B \otimes
|
|
1915
|
+
B^{r-1,1} \otimes B^{1,1})` for `r > 1`, which is a natural strict
|
|
1916
|
+
classical crystal injection. On rigged configurations, the map
|
|
1917
|
+
`\gamma` adds a string of length `1` with rigging 0 to `\nu^{(a)}`
|
|
1918
|
+
for all `a < r` to a classically highest weight element and extended
|
|
1919
|
+
as a classical crystal morphism.
|
|
1920
|
+
|
|
1921
|
+
We can extend `\gamma^*` when the right-most factor is not a single
|
|
1922
|
+
column by precomposing with a :meth:`right_split()`.
|
|
1923
|
+
|
|
1924
|
+
EXAMPLES::
|
|
1925
|
+
|
|
1926
|
+
sage: RC = RiggedConfigurations(['C',3,1], [[2,1], [1,1], [3,1]])
|
|
1927
|
+
sage: mg = RC.module_generators[7]
|
|
1928
|
+
sage: ascii_art(mg)
|
|
1929
|
+
1[ ]0 0[ ][ ]0 0[ ]0
|
|
1930
|
+
0[ ]0 0[ ]0
|
|
1931
|
+
sage: ascii_art(mg.right_column_box())
|
|
1932
|
+
1[ ]0 0[ ][ ]0 0[ ]0
|
|
1933
|
+
1[ ]0 0[ ]0 0[ ]0
|
|
1934
|
+
0[ ]0
|
|
1935
|
+
"""
|
|
1936
|
+
P = self.parent()
|
|
1937
|
+
r = P.dims[-1][0]
|
|
1938
|
+
if r == 1:
|
|
1939
|
+
raise ValueError("cannot split a single box")
|
|
1940
|
+
ct = P.cartan_type()
|
|
1941
|
+
if ct.type() == 'D':
|
|
1942
|
+
if P.dims[-1][0] >= ct.rank() - 2:
|
|
1943
|
+
raise ValueError("only for non-spinor cases")
|
|
1944
|
+
elif ct.type() == 'B' or ct.dual().type() == 'B':
|
|
1945
|
+
if P.dims[-1][0] == ct.rank() - 1:
|
|
1946
|
+
raise ValueError("only for non-spinor cases")
|
|
1947
|
+
|
|
1948
|
+
if P.dims[-1][1] > 1:
|
|
1949
|
+
return self.right_split().right_column_box()
|
|
1950
|
+
|
|
1951
|
+
rc, e_string = self.to_highest_weight(P._rc_index)
|
|
1952
|
+
|
|
1953
|
+
B = P.dims[:-1] + ([r-1,1], [1,1])
|
|
1954
|
+
from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
|
|
1955
|
+
RC = RiggedConfigurations(P._cartan_type, B)
|
|
1956
|
+
parts = [x._clone() for x in rc] # Make a deep copy
|
|
1957
|
+
for nu in parts[:r-1]:
|
|
1958
|
+
nu._list.append(1)
|
|
1959
|
+
for a, nu in enumerate(parts[:r-1]):
|
|
1960
|
+
vac_num = RC._calc_vacancy_number(parts, a, -1)
|
|
1961
|
+
nu.vacancy_numbers.append(vac_num)
|
|
1962
|
+
nu.rigging.append(0)
|
|
1963
|
+
return RC(*parts).f_string(reversed(e_string))
|
|
1964
|
+
|
|
1965
|
+
def complement_rigging(self, reverse_factors=False):
|
|
1966
|
+
r"""
|
|
1967
|
+
Apply the complement rigging morphism `\theta` to ``self``.
|
|
1968
|
+
|
|
1969
|
+
Consider a highest weight rigged configuration `(\nu, J)`, the
|
|
1970
|
+
complement rigging morphism `\theta : RC(L) \to RC(L)` is given by
|
|
1971
|
+
sending `(\nu, J) \mapsto (\nu, J')`, where `J'` is obtained by
|
|
1972
|
+
taking the coriggings `x' = p_i^{(a)} - x`, and then extending as
|
|
1973
|
+
a crystal morphism. (The name comes from taking the complement
|
|
1974
|
+
partition for the riggings in a `m_i^{(a)} \times p_i^{(a)}` box.)
|
|
1975
|
+
|
|
1976
|
+
INPUT:
|
|
1977
|
+
|
|
1978
|
+
- ``reverse_factors`` -- boolean (default: ``False``); if ``True``, then this
|
|
1979
|
+
returns an element in `RC(B')` where `B'` is the tensor factors
|
|
1980
|
+
of ``self`` in reverse order
|
|
1981
|
+
|
|
1982
|
+
EXAMPLES::
|
|
1983
|
+
|
|
1984
|
+
sage: RC = RiggedConfigurations(['D',4,1], [[1,1],[2,2]])
|
|
1985
|
+
sage: mg = RC.module_generators[-1]
|
|
1986
|
+
sage: ascii_art(mg)
|
|
1987
|
+
1[ ][ ]1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0
|
|
1988
|
+
0[ ][ ]0
|
|
1989
|
+
sage: ascii_art(mg.complement_rigging())
|
|
1990
|
+
1[ ][ ]0 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0
|
|
1991
|
+
0[ ][ ]0
|
|
1992
|
+
|
|
1993
|
+
sage: lw = mg.to_lowest_weight([1,2,3,4])[0]
|
|
1994
|
+
sage: ascii_art(lw)
|
|
1995
|
+
-1[ ][ ]-1 0[ ][ ]0 0[ ][ ]0 0[ ][ ]0
|
|
1996
|
+
-1[ ]-1 0[ ][ ]0 0[ ]0 0[ ]0
|
|
1997
|
+
-1[ ]-1 0[ ]0
|
|
1998
|
+
0[ ]0
|
|
1999
|
+
sage: ascii_art(lw.complement_rigging())
|
|
2000
|
+
-1[ ][ ][ ]-1 0[ ][ ][ ]0 0[ ][ ][ ]0 0[ ][ ][ ]0
|
|
2001
|
+
-1[ ]-1 0[ ][ ][ ]0
|
|
2002
|
+
sage: lw.complement_rigging() == mg.complement_rigging().to_lowest_weight([1,2,3,4])[0]
|
|
2003
|
+
True
|
|
2004
|
+
|
|
2005
|
+
sage: mg.complement_rigging(True).parent()
|
|
2006
|
+
Rigged configurations of type ['D', 4, 1] and factor(s) ((2, 2), (1, 1))
|
|
2007
|
+
|
|
2008
|
+
We check that the Lusztig involution (under the modification of also
|
|
2009
|
+
mapping to the highest weight element) intertwines with the
|
|
2010
|
+
complement map `\theta` (that reverses the tensor factors)
|
|
2011
|
+
under the bijection `\Phi`::
|
|
2012
|
+
|
|
2013
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 2], [2, 1], [1, 2]])
|
|
2014
|
+
sage: for mg in RC.module_generators: # long time
|
|
2015
|
+
....: y = mg.to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
2016
|
+
....: hw = y.lusztig_involution().to_highest_weight([1,2,3,4])[0]
|
|
2017
|
+
....: c = mg.complement_rigging(True)
|
|
2018
|
+
....: hwc = c.to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
2019
|
+
....: assert hw == hwc
|
|
2020
|
+
|
|
2021
|
+
TESTS:
|
|
2022
|
+
|
|
2023
|
+
We check that :issue:`18898` is fixed::
|
|
2024
|
+
|
|
2025
|
+
sage: RC = RiggedConfigurations(['D',4,1], [[2,1], [2,1], [2,3]])
|
|
2026
|
+
sage: x = RC(partition_list=[[1], [1,1], [1], [1]], rigging_list=[[0], [2,1], [0], [0]])
|
|
2027
|
+
sage: ascii_art(x)
|
|
2028
|
+
0[ ]0 2[ ]2 0[ ]0 0[ ]0
|
|
2029
|
+
2[ ]1
|
|
2030
|
+
sage: ascii_art(x.complement_rigging())
|
|
2031
|
+
0[ ]0 2[ ]1 0[ ]0 0[ ]0
|
|
2032
|
+
2[ ]0
|
|
2033
|
+
"""
|
|
2034
|
+
P = self.parent()
|
|
2035
|
+
if reverse_factors:
|
|
2036
|
+
from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
|
|
2037
|
+
P = RiggedConfigurations(P._cartan_type, reversed(P.dims))
|
|
2038
|
+
|
|
2039
|
+
mg, e_str = self.to_highest_weight(P._rc_index)
|
|
2040
|
+
nu = []
|
|
2041
|
+
rig = []
|
|
2042
|
+
for a,p in enumerate(mg):
|
|
2043
|
+
nu.append(list(p))
|
|
2044
|
+
vac_nums = p.vacancy_numbers
|
|
2045
|
+
riggings = [vac - p.rigging[i] for i,vac in enumerate(vac_nums)]
|
|
2046
|
+
block = 0
|
|
2047
|
+
for j,i in enumerate(p):
|
|
2048
|
+
if p[block] != i:
|
|
2049
|
+
riggings[block:j] = sorted(riggings[block:j], reverse=True)
|
|
2050
|
+
block = j
|
|
2051
|
+
riggings[block:] = sorted(riggings[block:], reverse=True)
|
|
2052
|
+
rig.append(riggings)
|
|
2053
|
+
|
|
2054
|
+
rc = P(partition_list=nu, rigging_list=rig)
|
|
2055
|
+
return rc.f_string(reversed(e_str))
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
class KRRCSimplyLacedElement(KRRiggedConfigurationElement):
|
|
2059
|
+
r"""
|
|
2060
|
+
`U_q^{\prime}(\mathfrak{g})` rigged configurations in simply-laced types.
|
|
2061
|
+
|
|
2062
|
+
TESTS::
|
|
2063
|
+
|
|
2064
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [2,1], [1,1]])
|
|
2065
|
+
sage: elt = RC(partition_list=[[1], [1], []]); elt
|
|
2066
|
+
<BLANKLINE>
|
|
2067
|
+
0[ ]0
|
|
2068
|
+
<BLANKLINE>
|
|
2069
|
+
0[ ]0
|
|
2070
|
+
<BLANKLINE>
|
|
2071
|
+
(/)
|
|
2072
|
+
<BLANKLINE>
|
|
2073
|
+
sage: TestSuite(elt).run()
|
|
2074
|
+
"""
|
|
2075
|
+
@cached_method
|
|
2076
|
+
def cocharge(self):
|
|
2077
|
+
r"""
|
|
2078
|
+
Compute the cocharge statistic of ``self``.
|
|
2079
|
+
|
|
2080
|
+
Computes the cocharge statistic [CrysStructSchilling06]_ on this
|
|
2081
|
+
rigged configuration `(\nu, J)`. The cocharge statistic is defined as:
|
|
2082
|
+
|
|
2083
|
+
.. MATH::
|
|
2084
|
+
|
|
2085
|
+
cc(\nu, J) = \frac{1}{2} \sum_{a, b \in I_0}
|
|
2086
|
+
\sum_{j,k > 0} \left( \alpha_a \mid \alpha_b \right)
|
|
2087
|
+
\min(j, k) m_j^{(a)} m_k^{(b)}
|
|
2088
|
+
+ \sum_{a \in I} \sum_{i > 0} \left\lvert J^{(a, i)} \right\rvert.
|
|
2089
|
+
|
|
2090
|
+
EXAMPLES::
|
|
2091
|
+
|
|
2092
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [2,1], [1,1]])
|
|
2093
|
+
sage: RC(partition_list=[[1], [1], []]).cocharge()
|
|
2094
|
+
1
|
|
2095
|
+
"""
|
|
2096
|
+
cc = 0
|
|
2097
|
+
rigging_sum = 0
|
|
2098
|
+
for a, p in enumerate(self):
|
|
2099
|
+
for pos, i in enumerate(p._list):
|
|
2100
|
+
# Add the rigging
|
|
2101
|
+
rigging_sum += p.rigging[pos]
|
|
2102
|
+
# Add the L matrix contribution
|
|
2103
|
+
for dim in self.parent().dims:
|
|
2104
|
+
if dim[0] == a + 1:
|
|
2105
|
+
cc += min(dim[1], i)
|
|
2106
|
+
# Subtract the vacancy number
|
|
2107
|
+
cc -= p.vacancy_numbers[pos]
|
|
2108
|
+
return cc // 2 + rigging_sum
|
|
2109
|
+
|
|
2110
|
+
cc = cocharge
|
|
2111
|
+
|
|
2112
|
+
@cached_method
|
|
2113
|
+
def charge(self):
|
|
2114
|
+
r"""
|
|
2115
|
+
Compute the charge statistic of ``self``.
|
|
2116
|
+
|
|
2117
|
+
Let `B` denote a set of rigged configurations. The *charge* `c` of
|
|
2118
|
+
a rigged configuration `b` is computed as
|
|
2119
|
+
|
|
2120
|
+
.. MATH::
|
|
2121
|
+
|
|
2122
|
+
c(b) = \max(cc(b) \mid b \in B) - cc(b).
|
|
2123
|
+
|
|
2124
|
+
EXAMPLES::
|
|
2125
|
+
|
|
2126
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [2,1], [1,1]])
|
|
2127
|
+
sage: RC(partition_list=[[],[],[]]).charge()
|
|
2128
|
+
2
|
|
2129
|
+
sage: RC(partition_list=[[1], [1], []]).charge()
|
|
2130
|
+
1
|
|
2131
|
+
"""
|
|
2132
|
+
B = self.parent()
|
|
2133
|
+
if not hasattr(B, "_max_charge"):
|
|
2134
|
+
B._max_charge = max(b.cocharge() for b in B.module_generators)
|
|
2135
|
+
return B._max_charge - self.cocharge()
|
|
2136
|
+
|
|
2137
|
+
|
|
2138
|
+
class KRRCNonSimplyLacedElement(KRRiggedConfigurationElement, RCNonSimplyLacedElement):
|
|
2139
|
+
r"""
|
|
2140
|
+
`U_q^{\prime}(\mathfrak{g})` rigged configurations in non-simply-laced
|
|
2141
|
+
types.
|
|
2142
|
+
|
|
2143
|
+
TESTS::
|
|
2144
|
+
|
|
2145
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
|
|
2146
|
+
sage: elt = RC(partition_list=[[3],[2]]); elt
|
|
2147
|
+
<BLANKLINE>
|
|
2148
|
+
0[ ][ ][ ]0
|
|
2149
|
+
<BLANKLINE>
|
|
2150
|
+
0[ ][ ]0
|
|
2151
|
+
sage: TestSuite(elt).run()
|
|
2152
|
+
"""
|
|
2153
|
+
|
|
2154
|
+
def e(self, a):
|
|
2155
|
+
r"""
|
|
2156
|
+
Return the action of `e_a` on ``self``.
|
|
2157
|
+
|
|
2158
|
+
This works by lifting into the virtual configuration, then applying
|
|
2159
|
+
|
|
2160
|
+
.. MATH::
|
|
2161
|
+
|
|
2162
|
+
e^v_a = \prod_{j \in \iota(a)} \hat{e}_j^{\gamma_j}
|
|
2163
|
+
|
|
2164
|
+
and pulling back.
|
|
2165
|
+
|
|
2166
|
+
EXAMPLES::
|
|
2167
|
+
|
|
2168
|
+
sage: RC = RiggedConfigurations(['A',6,2], [[1,1]]*7)
|
|
2169
|
+
sage: elt = RC(partition_list=[[1]*5,[2,1,1],[3,2]])
|
|
2170
|
+
sage: elt.e(3)
|
|
2171
|
+
<BLANKLINE>
|
|
2172
|
+
0[ ]0
|
|
2173
|
+
0[ ]0
|
|
2174
|
+
0[ ]0
|
|
2175
|
+
0[ ]0
|
|
2176
|
+
0[ ]0
|
|
2177
|
+
<BLANKLINE>
|
|
2178
|
+
0[ ][ ]0
|
|
2179
|
+
1[ ]1
|
|
2180
|
+
1[ ]1
|
|
2181
|
+
<BLANKLINE>
|
|
2182
|
+
1[ ][ ]1
|
|
2183
|
+
1[ ]0
|
|
2184
|
+
<BLANKLINE>
|
|
2185
|
+
"""
|
|
2186
|
+
if a == self.parent()._cartan_type.special_node():
|
|
2187
|
+
try:
|
|
2188
|
+
ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().e(a)
|
|
2189
|
+
if ret is None:
|
|
2190
|
+
return None
|
|
2191
|
+
return ret.to_rigged_configuration()
|
|
2192
|
+
except (NotImplementedError, TypeError):
|
|
2193
|
+
# We haven't implemented the bijection yet, so try by lifting
|
|
2194
|
+
# to the simply-laced case
|
|
2195
|
+
return RCNonSimplyLacedElement.e(self, a)
|
|
2196
|
+
|
|
2197
|
+
if not self.epsilon(a):
|
|
2198
|
+
return None
|
|
2199
|
+
return RCNonSimplyLacedElement.e(self, a)
|
|
2200
|
+
|
|
2201
|
+
def f(self, a):
|
|
2202
|
+
r"""
|
|
2203
|
+
Return the action of `f_a` on ``self``.
|
|
2204
|
+
|
|
2205
|
+
This works by lifting into the virtual configuration, then applying
|
|
2206
|
+
|
|
2207
|
+
.. MATH::
|
|
2208
|
+
|
|
2209
|
+
f^v_a = \prod_{j \in \iota(a)} \hat{f}_j^{\gamma_j}
|
|
2210
|
+
|
|
2211
|
+
and pulling back.
|
|
2212
|
+
|
|
2213
|
+
EXAMPLES::
|
|
2214
|
+
|
|
2215
|
+
sage: RC = RiggedConfigurations(['A',6,2], [[1,1]]*7)
|
|
2216
|
+
sage: elt = RC(partition_list=[[1]*5,[2,1,1],[2,1]], rigging_list=[[0]*5,[0,1,1],[1,0]])
|
|
2217
|
+
sage: elt.f(3)
|
|
2218
|
+
<BLANKLINE>
|
|
2219
|
+
0[ ]0
|
|
2220
|
+
0[ ]0
|
|
2221
|
+
0[ ]0
|
|
2222
|
+
0[ ]0
|
|
2223
|
+
0[ ]0
|
|
2224
|
+
<BLANKLINE>
|
|
2225
|
+
1[ ][ ]1
|
|
2226
|
+
1[ ]1
|
|
2227
|
+
1[ ]1
|
|
2228
|
+
<BLANKLINE>
|
|
2229
|
+
-1[ ][ ][ ]-1
|
|
2230
|
+
0[ ][ ]0
|
|
2231
|
+
<BLANKLINE>
|
|
2232
|
+
"""
|
|
2233
|
+
if a == self.parent()._cartan_type.special_node():
|
|
2234
|
+
try:
|
|
2235
|
+
ret = self.to_tensor_product_of_kirillov_reshetikhin_tableaux().f(a)
|
|
2236
|
+
if ret is None:
|
|
2237
|
+
return None
|
|
2238
|
+
return ret.to_rigged_configuration()
|
|
2239
|
+
except (NotImplementedError, TypeError):
|
|
2240
|
+
# We haven't implemented the bijection yet, so try by lifting
|
|
2241
|
+
# to the simply-laced case
|
|
2242
|
+
return RCNonSimplyLacedElement.f(self, a)
|
|
2243
|
+
|
|
2244
|
+
if not self.phi(a):
|
|
2245
|
+
return None
|
|
2246
|
+
return RCNonSimplyLacedElement.f(self, a)
|
|
2247
|
+
|
|
2248
|
+
@cached_method
|
|
2249
|
+
def cocharge(self):
|
|
2250
|
+
r"""
|
|
2251
|
+
Compute the cocharge statistic.
|
|
2252
|
+
|
|
2253
|
+
Computes the cocharge statistic [OSS03]_ on this
|
|
2254
|
+
rigged configuration `(\nu, J)` by computing the cocharge as a virtual
|
|
2255
|
+
rigged configuration `(\hat{\nu}, \hat{J})` and then using the
|
|
2256
|
+
identity `cc(\hat{\nu}, \hat{J}) = \gamma_0 cc(\nu, J)`.
|
|
2257
|
+
|
|
2258
|
+
EXAMPLES::
|
|
2259
|
+
|
|
2260
|
+
sage: RC = RiggedConfigurations(['C', 3, 1], [[2,1], [1,1]])
|
|
2261
|
+
sage: RC(partition_list=[[1,1],[2,1],[1,1]]).cocharge()
|
|
2262
|
+
1
|
|
2263
|
+
"""
|
|
2264
|
+
# return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0]
|
|
2265
|
+
vct = self.parent()._folded_ct
|
|
2266
|
+
cc = ZZ.zero()
|
|
2267
|
+
rigging_sum = ZZ.zero()
|
|
2268
|
+
sigma = vct.folding_orbit()
|
|
2269
|
+
gamma = vct.scaling_factors()
|
|
2270
|
+
for a, p in enumerate(self):
|
|
2271
|
+
t_check = len(sigma[a + 1]) * gamma[a+1] // gamma[0]
|
|
2272
|
+
for pos, i in enumerate(p._list):
|
|
2273
|
+
# Add the rigging
|
|
2274
|
+
rigging_sum += t_check * p.rigging[pos]
|
|
2275
|
+
# Add the L matrix contribution
|
|
2276
|
+
for dim in self.parent().dims:
|
|
2277
|
+
if dim[0] == a + 1:
|
|
2278
|
+
cc += t_check * min(dim[1], i)
|
|
2279
|
+
# Subtract the vacancy number
|
|
2280
|
+
cc -= t_check * p.vacancy_numbers[pos]
|
|
2281
|
+
return cc // 2 + rigging_sum
|
|
2282
|
+
|
|
2283
|
+
cc = cocharge
|
|
2284
|
+
|
|
2285
|
+
|
|
2286
|
+
class KRRCTypeA2DualElement(KRRCNonSimplyLacedElement):
|
|
2287
|
+
r"""
|
|
2288
|
+
`U_q^{\prime}(\mathfrak{g})` rigged configurations in type
|
|
2289
|
+
`A_{2n}^{(2)\dagger}`.
|
|
2290
|
+
"""
|
|
2291
|
+
|
|
2292
|
+
def epsilon(self, a):
|
|
2293
|
+
r"""
|
|
2294
|
+
Return the value of `\varepsilon_a` of ``self``.
|
|
2295
|
+
|
|
2296
|
+
Here we need to modify the usual definition by
|
|
2297
|
+
`\varepsilon_n^{\prime} := 2 \varepsilon_n`.
|
|
2298
|
+
|
|
2299
|
+
EXAMPLES::
|
|
2300
|
+
|
|
2301
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1], [2,2]])
|
|
2302
|
+
sage: def epsilon(x, i):
|
|
2303
|
+
....: x = x.e(i)
|
|
2304
|
+
....: eps = 0
|
|
2305
|
+
....: while x is not None:
|
|
2306
|
+
....: x = x.e(i)
|
|
2307
|
+
....: eps = eps + 1
|
|
2308
|
+
....: return eps
|
|
2309
|
+
sage: all(epsilon(rc, 2) == rc.epsilon(2) for rc in RC)
|
|
2310
|
+
True
|
|
2311
|
+
"""
|
|
2312
|
+
if a == self.parent()._cartan_type.special_node():
|
|
2313
|
+
return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().epsilon(a)
|
|
2314
|
+
|
|
2315
|
+
a = self.parent()._rc_index_inverse[a]
|
|
2316
|
+
if not self[a]:
|
|
2317
|
+
epsilon = 0
|
|
2318
|
+
else:
|
|
2319
|
+
epsilon = -min(0, *self[a].rigging)
|
|
2320
|
+
n = len(self.parent()._rc_index)
|
|
2321
|
+
if a == n-1: # -1 for indexing
|
|
2322
|
+
epsilon *= 2
|
|
2323
|
+
return Integer(epsilon)
|
|
2324
|
+
|
|
2325
|
+
def phi(self, a):
|
|
2326
|
+
r"""
|
|
2327
|
+
Return the value of `\varphi_a` of ``self``.
|
|
2328
|
+
|
|
2329
|
+
Here we need to modify the usual definition by
|
|
2330
|
+
`\varphi_n^{\prime} := 2 \varphi_n`.
|
|
2331
|
+
|
|
2332
|
+
EXAMPLES::
|
|
2333
|
+
|
|
2334
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1], [2,2]])
|
|
2335
|
+
sage: def phi(x, i):
|
|
2336
|
+
....: x = x.f(i)
|
|
2337
|
+
....: ph = 0
|
|
2338
|
+
....: while x is not None:
|
|
2339
|
+
....: x = x.f(i)
|
|
2340
|
+
....: ph = ph + 1
|
|
2341
|
+
....: return ph
|
|
2342
|
+
sage: all(phi(rc, 2) == rc.phi(2) for rc in RC)
|
|
2343
|
+
True
|
|
2344
|
+
"""
|
|
2345
|
+
if a == self.parent()._cartan_type.special_node():
|
|
2346
|
+
return self.to_tensor_product_of_kirillov_reshetikhin_tableaux().phi(a)
|
|
2347
|
+
|
|
2348
|
+
a = self.parent()._rc_index_inverse[a]
|
|
2349
|
+
p_inf = self.parent()._calc_vacancy_number(self, a, float("inf"))
|
|
2350
|
+
if not self[a]:
|
|
2351
|
+
phi = p_inf
|
|
2352
|
+
else:
|
|
2353
|
+
phi = p_inf - min(0, *self[a].rigging)
|
|
2354
|
+
n = len(self.parent()._rc_index)
|
|
2355
|
+
if a == n-1: # -1 for indexing
|
|
2356
|
+
phi *= 2
|
|
2357
|
+
return Integer(phi)
|
|
2358
|
+
|
|
2359
|
+
@cached_method
|
|
2360
|
+
def cocharge(self):
|
|
2361
|
+
r"""
|
|
2362
|
+
Compute the cocharge statistic.
|
|
2363
|
+
|
|
2364
|
+
Computes the cocharge statistic [RigConBijection]_ on this
|
|
2365
|
+
rigged configuration `(\nu, J)`. The cocharge statistic is
|
|
2366
|
+
computed as:
|
|
2367
|
+
|
|
2368
|
+
.. MATH::
|
|
2369
|
+
|
|
2370
|
+
cc(\nu, J) = \frac{1}{2} \sum_{a \in I_0} \sum_{i > 0}
|
|
2371
|
+
t_a^{\vee} m_i^{(a)} \left( \sum_{j > 0} \min(i, j) L_j^{(a)}
|
|
2372
|
+
- p_i^{(a)} \right) + \sum_{a \in I} t_a^{\vee} \sum_{i > 0}
|
|
2373
|
+
\left\lvert J^{(a, i)} \right\rvert.
|
|
2374
|
+
|
|
2375
|
+
EXAMPLES::
|
|
2376
|
+
|
|
2377
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1],[2,2]])
|
|
2378
|
+
sage: sc = RC.cartan_type().as_folding().scaling_factors()
|
|
2379
|
+
sage: all(mg.cocharge() * sc[0] == mg.to_virtual_configuration().cocharge()
|
|
2380
|
+
....: for mg in RC.module_generators)
|
|
2381
|
+
True
|
|
2382
|
+
"""
|
|
2383
|
+
# return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0]
|
|
2384
|
+
cc = ZZ.zero()
|
|
2385
|
+
rigging_sum = ZZ.zero()
|
|
2386
|
+
# vct = self.parent()._folded_ct
|
|
2387
|
+
# sigma = vct.folding_orbit()
|
|
2388
|
+
# gammatilde = list(vct.scaling_factors())
|
|
2389
|
+
# gammatilde[-1] = 2
|
|
2390
|
+
for a, p in enumerate(self):
|
|
2391
|
+
t_check = 1 # == len(sigma[a+1]) * gammatilde[a+1] / gammatilde[0]
|
|
2392
|
+
for pos, i in enumerate(p._list):
|
|
2393
|
+
# Add the rigging
|
|
2394
|
+
rigging_sum += t_check * p.rigging[pos]
|
|
2395
|
+
# Add the L matrix contribution
|
|
2396
|
+
for dim in self.parent().dims:
|
|
2397
|
+
if dim[0] == a + 1:
|
|
2398
|
+
cc += t_check * min(dim[1], i)
|
|
2399
|
+
# Subtract the vacancy number
|
|
2400
|
+
cc -= t_check * p.vacancy_numbers[pos]
|
|
2401
|
+
return cc / ZZ(2) + rigging_sum
|
|
2402
|
+
|
|
2403
|
+
cc = cocharge
|