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,1918 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.graphs sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Rigged configurations
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Travis Scrimshaw (2010-09-26): initial version
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
# Copyright (C) 2010-2012 Travis Scrimshaw <tscrim@ucdavis.edu>
|
|
13
|
+
#
|
|
14
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
15
|
+
#
|
|
16
|
+
# This code is distributed in the hope that it will be useful,
|
|
17
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
19
|
+
# General Public License for more details.
|
|
20
|
+
#
|
|
21
|
+
# The full text of the GPL is available at:
|
|
22
|
+
#
|
|
23
|
+
# https://www.gnu.org/licenses/
|
|
24
|
+
# ****************************************************************************
|
|
25
|
+
|
|
26
|
+
import itertools
|
|
27
|
+
|
|
28
|
+
from sage.misc.cachefunc import cached_method
|
|
29
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
30
|
+
from sage.structure.global_options import GlobalOptions
|
|
31
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
32
|
+
from sage.structure.parent import Parent
|
|
33
|
+
from sage.combinat.misc import IterableFunctionCall
|
|
34
|
+
import sage.combinat.tableau as tableau
|
|
35
|
+
from sage.rings.rational_field import QQ
|
|
36
|
+
from sage.categories.loop_crystals import KirillovReshetikhinCrystals
|
|
37
|
+
from sage.combinat.root_system.cartan_type import CartanType
|
|
38
|
+
from sage.combinat.rigged_configurations.kleber_tree import KleberTree, VirtualKleberTree
|
|
39
|
+
from sage.combinat.rigged_configurations.rigged_configuration_element import (
|
|
40
|
+
RiggedConfigurationElement, KRRCSimplyLacedElement, KRRCNonSimplyLacedElement,
|
|
41
|
+
KRRCTypeA2DualElement)
|
|
42
|
+
from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Used in the KR crystals catalog so that there is a common interface
|
|
46
|
+
def KirillovReshetikhinCrystal(cartan_type, r, s):
|
|
47
|
+
r"""
|
|
48
|
+
Return the KR crystal `B^{r,s}` using
|
|
49
|
+
:class:`rigged configurations <RiggedConfigurations>`.
|
|
50
|
+
|
|
51
|
+
This is the rigged configuration `RC(B^{r,s})` or `RC(L)` with
|
|
52
|
+
`L = (L_i^{(a)})` and `L_i^{(a)} = \delta_{a,r} \delta_{i,s}`.
|
|
53
|
+
|
|
54
|
+
EXAMPLES::
|
|
55
|
+
|
|
56
|
+
sage: K1 = crystals.kirillov_reshetikhin.RiggedConfigurations(['A',6,2], 2, 1)
|
|
57
|
+
sage: K2 = crystals.kirillov_reshetikhin.LSPaths(['A',6,2], 2, 1)
|
|
58
|
+
sage: K1.digraph().is_isomorphic(K2.digraph(), edge_labels=True)
|
|
59
|
+
True
|
|
60
|
+
|
|
61
|
+
TESTS:
|
|
62
|
+
|
|
63
|
+
We explicitly import and check we get the same crystal::
|
|
64
|
+
|
|
65
|
+
sage: from sage.combinat.rigged_configurations.rigged_configurations import KirillovReshetikhinCrystal
|
|
66
|
+
sage: K1 = crystals.kirillov_reshetikhin.RiggedConfigurations(['A',6,2], 2, 1)
|
|
67
|
+
sage: K1 is KirillovReshetikhinCrystal(['A',6,2], 2, 1)
|
|
68
|
+
True
|
|
69
|
+
"""
|
|
70
|
+
return RiggedConfigurations(cartan_type, [[r, s]])
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Note on implementation, this class is used for simply-laced types only
|
|
74
|
+
class RiggedConfigurations(UniqueRepresentation, Parent):
|
|
75
|
+
r"""
|
|
76
|
+
Rigged configurations as `U_q^{\prime}(\mathfrak{g})`-crystals.
|
|
77
|
+
|
|
78
|
+
Let `\overline{I}` denote the classical index set associated to the Cartan
|
|
79
|
+
type of the rigged configurations. A rigged configuration of multiplicity
|
|
80
|
+
array `L_i^{(a)}` and dominant weight `\Lambda` is a sequence of partitions
|
|
81
|
+
`\{ \nu^{(a)} \mid a \in \overline{I} \}` such that
|
|
82
|
+
|
|
83
|
+
.. MATH::
|
|
84
|
+
|
|
85
|
+
\sum_{\overline{I} \times \ZZ_{>0}} i m_i^{(a)} \alpha_a
|
|
86
|
+
= \sum_{\overline{I} \times \ZZ_{>0}} i L_i^{(a)} \Lambda_a
|
|
87
|
+
- \Lambda
|
|
88
|
+
|
|
89
|
+
where `\alpha_a` is a simple root, `\Lambda_a` is a fundamental weight,
|
|
90
|
+
and `m_i^{(a)}` is the number of rows of length `i` in the partition
|
|
91
|
+
`\nu^{(a)}`.
|
|
92
|
+
|
|
93
|
+
Each partition `\nu^{(a)}`, in the sequence also comes with a sequence of
|
|
94
|
+
statistics `p_i^{(a)}` called *vacancy numbers* and a weakly decreasing
|
|
95
|
+
sequence `J_i^{(a)}` of length `m_i^{(a)}` called *riggings*.
|
|
96
|
+
Vacancy numbers are computed based upon the partitions and `L_i^{(a)}`,
|
|
97
|
+
and the riggings must satisfy `\max J_i^{(a)} \leq p_i^{(a)}`. We call
|
|
98
|
+
such a partition a *rigged partition*. For more, see
|
|
99
|
+
[RigConBijection]_ [CrysStructSchilling06]_ [BijectionLRT]_.
|
|
100
|
+
|
|
101
|
+
Rigged configurations form combinatorial objects first introduced by
|
|
102
|
+
Kerov, Kirillov and Reshetikhin that arose from studies of statistical
|
|
103
|
+
mechanical models using the Bethe Ansatz. They are sequences of rigged
|
|
104
|
+
partitions. A rigged partition is a partition together with a label
|
|
105
|
+
associated to each part that satisfy certain constraints. The labels
|
|
106
|
+
are also called riggings.
|
|
107
|
+
|
|
108
|
+
Rigged configurations exist for all affine Kac-Moody Lie algebras. See
|
|
109
|
+
for example [HKOTT2002]_. In Sage they are specified by providing a Cartan
|
|
110
|
+
type and a list of rectangular shapes `B`. The list of all (highest
|
|
111
|
+
weight) rigged configurations for given `B` is computed via the (virtual)
|
|
112
|
+
Kleber algorithm (see also
|
|
113
|
+
:class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree` and
|
|
114
|
+
:class:`~sage.combinat.rigged_configurations.kleber_tree.VirtualKleberTree`).
|
|
115
|
+
|
|
116
|
+
Rigged configurations in simply-laced types all admit a classical crystal
|
|
117
|
+
structure [CrysStructSchilling06]_. For non-simply-laced types, the
|
|
118
|
+
crystal is given by using virtual rigged configurations [OSS03]_. The
|
|
119
|
+
highest weight rigged configurations are those where all riggings are
|
|
120
|
+
nonnegative. The list of all rigged configurations is computed from the
|
|
121
|
+
highest weight ones using the crystal operators.
|
|
122
|
+
|
|
123
|
+
Rigged configurations are conjecturally in bijection with
|
|
124
|
+
:class:`~sage.combinat.rigged_configurations.tensor_product_kr_tableaux.TensorProductOfKirillovReshetikhinTableaux`
|
|
125
|
+
of non-exceptional affine types where the list `B` corresponds to the
|
|
126
|
+
tensor factors `B^{r,s}`. The bijection has been proven in types `A_n^{(1)}`
|
|
127
|
+
and `D_n^{(1)}` and when the only nonzero entries of `L_i^{(a)}` are either
|
|
128
|
+
only `L_1^{(a)}` or only `L_i^{(1)}` (corresponding to single columns or
|
|
129
|
+
rows respectively) [RigConBijection]_, [BijectionLRT]_, [BijectionDn]_.
|
|
130
|
+
|
|
131
|
+
KR crystals are implemented in Sage, see
|
|
132
|
+
:func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`,
|
|
133
|
+
however, in the bijection with rigged configurations a different
|
|
134
|
+
realization of the elements in the crystal are obtained, which are
|
|
135
|
+
coined KR tableaux, see
|
|
136
|
+
:class:`~sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableaux`.
|
|
137
|
+
For more details see [OSS2011]_.
|
|
138
|
+
|
|
139
|
+
.. NOTE::
|
|
140
|
+
|
|
141
|
+
All non-simply-laced rigged configurations have not been proven to
|
|
142
|
+
give rise to aligned virtual crystals (i.e. have the correct crystal
|
|
143
|
+
structure or isomorphic as affine crystals to the tensor product of
|
|
144
|
+
KR tableaux).
|
|
145
|
+
|
|
146
|
+
INPUT:
|
|
147
|
+
|
|
148
|
+
- ``cartan_type`` -- a Cartan type
|
|
149
|
+
|
|
150
|
+
- ``B`` -- list of positive integer tuples `(r,s)` corresponding to the
|
|
151
|
+
tensor factors in the bijection with tensor product of
|
|
152
|
+
Kirillov-Reshetikhin tableaux or equivalently the sequence of width `s`
|
|
153
|
+
and height `r` rectangles
|
|
154
|
+
|
|
155
|
+
REFERENCES:
|
|
156
|
+
|
|
157
|
+
.. [HKOTT2002] \G. Hatayama, A. Kuniba, M. Okado, T. Takagi, Z. Tsuboi.
|
|
158
|
+
Paths, Crystals and Fermionic Formulae.
|
|
159
|
+
Prog. Math. Phys. **23** (2002) Pages 205-272.
|
|
160
|
+
|
|
161
|
+
.. [CrysStructSchilling06] Anne Schilling.
|
|
162
|
+
Crystal structure on rigged configurations.
|
|
163
|
+
International Mathematics Research Notices.
|
|
164
|
+
Volume 2006. (2006) Article ID 97376. Pages 1-27.
|
|
165
|
+
|
|
166
|
+
.. [RigConBijection] Masato Okado, Anne Schilling, Mark Shimozono.
|
|
167
|
+
A crystal to rigged configuration bijection for non-exceptional affine
|
|
168
|
+
algebras.
|
|
169
|
+
Algebraic Combinatorics and Quantum Groups.
|
|
170
|
+
Edited by N. Jing. World Scientific. (2003) Pages 85-124.
|
|
171
|
+
|
|
172
|
+
.. [BijectionDn] Anne Schilling.
|
|
173
|
+
A bijection between type `D_n^{(1)}` crystals and rigged configurations.
|
|
174
|
+
J. Algebra. **285** (2005) 292-334
|
|
175
|
+
|
|
176
|
+
.. [BijectionLRT] Anatol N. Kirillov, Anne Schilling, Mark Shimozono.
|
|
177
|
+
A bijection between Littlewood-Richardson tableaux and rigged
|
|
178
|
+
configurations.
|
|
179
|
+
Selecta Mathematica (N.S.). **8** (2002) Pages 67-135.
|
|
180
|
+
(:mathscinet:`MR1890195`).
|
|
181
|
+
|
|
182
|
+
EXAMPLES::
|
|
183
|
+
|
|
184
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2], [1, 1]])
|
|
185
|
+
sage: RC
|
|
186
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((3, 2), (1, 2), (1, 1))
|
|
187
|
+
|
|
188
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1]]); RC
|
|
189
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 1),)
|
|
190
|
+
sage: RC.cardinality()
|
|
191
|
+
6
|
|
192
|
+
sage: len(RC.list()) == RC.cardinality()
|
|
193
|
+
True
|
|
194
|
+
sage: RC.list() # random
|
|
195
|
+
[
|
|
196
|
+
<BLANKLINE>
|
|
197
|
+
0[ ]0
|
|
198
|
+
(/) (/) (/) -1[ ]-1 -1[ ]-1
|
|
199
|
+
-1[ ]-1
|
|
200
|
+
(/) -1[ ]-1 0[ ]0 0[ ]0 1[ ]1 -1[ ]-1
|
|
201
|
+
<BLANKLINE>
|
|
202
|
+
(/) (/) -1[ ]-1 (/) -1[ ]-1 0[ ]0
|
|
203
|
+
, , , , ,
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
A rigged configuration element with all riggings equal to the vacancy
|
|
207
|
+
numbers can be created as follows::
|
|
208
|
+
|
|
209
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]]); RC
|
|
210
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((3, 2), (2, 1), (1, 1), (1, 1))
|
|
211
|
+
sage: elt = RC(partition_list=[[1],[],[]]); elt
|
|
212
|
+
<BLANKLINE>
|
|
213
|
+
0[ ]0
|
|
214
|
+
<BLANKLINE>
|
|
215
|
+
(/)
|
|
216
|
+
<BLANKLINE>
|
|
217
|
+
(/)
|
|
218
|
+
<BLANKLINE>
|
|
219
|
+
|
|
220
|
+
If on the other hand we also want to specify the riggings, this can be
|
|
221
|
+
achieved as follows::
|
|
222
|
+
|
|
223
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2], [1, 1]])
|
|
224
|
+
sage: RC(partition_list=[[2],[2],[2]])
|
|
225
|
+
<BLANKLINE>
|
|
226
|
+
1[ ][ ]1
|
|
227
|
+
<BLANKLINE>
|
|
228
|
+
0[ ][ ]0
|
|
229
|
+
<BLANKLINE>
|
|
230
|
+
0[ ][ ]0
|
|
231
|
+
sage: RC(partition_list=[[2],[2],[2]], rigging_list=[[0],[0],[0]])
|
|
232
|
+
<BLANKLINE>
|
|
233
|
+
1[ ][ ]0
|
|
234
|
+
<BLANKLINE>
|
|
235
|
+
0[ ][ ]0
|
|
236
|
+
<BLANKLINE>
|
|
237
|
+
0[ ][ ]0
|
|
238
|
+
|
|
239
|
+
A larger example::
|
|
240
|
+
|
|
241
|
+
sage: RC = RiggedConfigurations(['D', 7, 1], [[3,3],[5,2],[4,3],[2,3],[4,4],[3,1],[1,4],[2,2]])
|
|
242
|
+
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]],
|
|
243
|
+
....: 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]])
|
|
244
|
+
sage: elt
|
|
245
|
+
<BLANKLINE>
|
|
246
|
+
3[ ][ ]2
|
|
247
|
+
<BLANKLINE>
|
|
248
|
+
1[ ][ ][ ]1
|
|
249
|
+
2[ ][ ]0
|
|
250
|
+
1[ ]0
|
|
251
|
+
<BLANKLINE>
|
|
252
|
+
4[ ][ ]4
|
|
253
|
+
4[ ][ ]1
|
|
254
|
+
3[ ]2
|
|
255
|
+
3[ ]1
|
|
256
|
+
<BLANKLINE>
|
|
257
|
+
2[ ][ ]1
|
|
258
|
+
2[ ][ ]0
|
|
259
|
+
0[ ]0
|
|
260
|
+
0[ ]0
|
|
261
|
+
0[ ]0
|
|
262
|
+
0[ ]0
|
|
263
|
+
<BLANKLINE>
|
|
264
|
+
0[ ][ ][ ]0
|
|
265
|
+
2[ ][ ]1
|
|
266
|
+
0[ ]0
|
|
267
|
+
0[ ]0
|
|
268
|
+
0[ ]0
|
|
269
|
+
0[ ]0
|
|
270
|
+
<BLANKLINE>
|
|
271
|
+
0[ ][ ]0
|
|
272
|
+
0[ ]0
|
|
273
|
+
0[ ]0
|
|
274
|
+
<BLANKLINE>
|
|
275
|
+
0[ ][ ]0
|
|
276
|
+
0[ ][ ]0
|
|
277
|
+
<BLANKLINE>
|
|
278
|
+
|
|
279
|
+
To obtain the KR tableau under the bijection between rigged configurations
|
|
280
|
+
and KR tableaux, we can type the following. This example was checked
|
|
281
|
+
against Reiho Sakamoto's Mathematica program on rigged configurations::
|
|
282
|
+
|
|
283
|
+
sage: output = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); output
|
|
284
|
+
[[1, 1, 1], [2, 3, 3], [3, 4, -5]] (X) [[1, 1], [2, 2], [3, 3], [5, -6], [6, -5]] (X)
|
|
285
|
+
[[1, 1, 2], [2, 2, 3], [3, 3, 7], [4, 4, -7]] (X) [[1, 1, 1], [2, 2, 2]] (X)
|
|
286
|
+
[[1, 1, 1, 3], [2, 2, 3, 4], [3, 3, 4, 5], [4, 4, 5, 6]] (X) [[1], [2], [3]] (X) [[1, 1, 1, 1]] (X) [[1, 1], [2, 2]]
|
|
287
|
+
sage: elt.to_tensor_product_of_kirillov_reshetikhin_tableaux().to_rigged_configuration() == elt
|
|
288
|
+
True
|
|
289
|
+
sage: output.to_rigged_configuration().to_tensor_product_of_kirillov_reshetikhin_tableaux() == output
|
|
290
|
+
True
|
|
291
|
+
|
|
292
|
+
We can also convert between rigged configurations and tensor products of
|
|
293
|
+
KR crystals::
|
|
294
|
+
|
|
295
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 1]])
|
|
296
|
+
sage: elt = RC(partition_list=[[1],[1,1],[1],[1]])
|
|
297
|
+
sage: tp_krc = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(); tp_krc
|
|
298
|
+
[[]]
|
|
299
|
+
sage: ret = RC(tp_krc)
|
|
300
|
+
sage: ret == elt
|
|
301
|
+
True
|
|
302
|
+
|
|
303
|
+
::
|
|
304
|
+
|
|
305
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[4,1], [3,3]])
|
|
306
|
+
sage: KR1 = crystals.KirillovReshetikhin(['D', 4, 1], 4, 1)
|
|
307
|
+
sage: KR2 = crystals.KirillovReshetikhin(['D', 4, 1], 3, 3)
|
|
308
|
+
sage: T = crystals.TensorProduct(KR1, KR2)
|
|
309
|
+
sage: t = T[1]; t
|
|
310
|
+
[[++++, []], [+++-, [[1], [2], [4], [-4]]]]
|
|
311
|
+
sage: ret = RC(t)
|
|
312
|
+
sage: ret.to_tensor_product_of_kirillov_reshetikhin_crystals()
|
|
313
|
+
[[++++, []], [+++-, [[1], [2], [4], [-4]]]]
|
|
314
|
+
|
|
315
|
+
TESTS::
|
|
316
|
+
|
|
317
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]])
|
|
318
|
+
sage: len(RC.module_generators)
|
|
319
|
+
17
|
|
320
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[1, 1]])
|
|
321
|
+
sage: RC.cardinality()
|
|
322
|
+
8
|
|
323
|
+
|
|
324
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 1]])
|
|
325
|
+
sage: c = RC.cardinality(); c
|
|
326
|
+
29
|
|
327
|
+
sage: K = crystals.KirillovReshetikhin(['D',4,1],2,1)
|
|
328
|
+
sage: K.cardinality() == c
|
|
329
|
+
True
|
|
330
|
+
"""
|
|
331
|
+
@staticmethod
|
|
332
|
+
def __classcall_private__(cls, cartan_type, B):
|
|
333
|
+
r"""
|
|
334
|
+
Normalize the input arguments to ensure unique representation.
|
|
335
|
+
|
|
336
|
+
EXAMPLES::
|
|
337
|
+
|
|
338
|
+
sage: RC1 = RiggedConfigurations(CartanType(['A',3,1]), [[2,2]])
|
|
339
|
+
sage: RC2 = RiggedConfigurations(['A',3,1], [(2,2)])
|
|
340
|
+
sage: RC3 = RiggedConfigurations(['A',3,1], ((2,2),))
|
|
341
|
+
sage: RC2 is RC1, RC3 is RC1
|
|
342
|
+
(True, True)
|
|
343
|
+
"""
|
|
344
|
+
cartan_type = CartanType(cartan_type)
|
|
345
|
+
if not cartan_type.is_affine():
|
|
346
|
+
raise ValueError("The Cartan type must be affine")
|
|
347
|
+
|
|
348
|
+
# Standardize B input into a tuple of tuples
|
|
349
|
+
B = tuple(tuple(factor) for factor in B)
|
|
350
|
+
if not B:
|
|
351
|
+
raise ValueError("must contain at least one factor")
|
|
352
|
+
|
|
353
|
+
if cartan_type.type() == 'BC': # Type `A_{2n}^{(2)}`
|
|
354
|
+
return RCTypeA2Even(cartan_type, B)
|
|
355
|
+
if cartan_type.dual().type() == 'BC': # Type 'A_{2n}^{(2)\dagger`
|
|
356
|
+
return RCTypeA2Dual(cartan_type, B)
|
|
357
|
+
# We check the classical type to account for A^{(1)}_1 which is not
|
|
358
|
+
# a virtual rigged configuration.
|
|
359
|
+
if not cartan_type.classical().is_simply_laced():
|
|
360
|
+
return RCNonSimplyLaced(cartan_type, B)
|
|
361
|
+
|
|
362
|
+
return super().__classcall__(cls, cartan_type, B)
|
|
363
|
+
|
|
364
|
+
def __init__(self, cartan_type, B):
|
|
365
|
+
r"""
|
|
366
|
+
Initialize the RiggedConfigurations class.
|
|
367
|
+
|
|
368
|
+
EXAMPLES::
|
|
369
|
+
|
|
370
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3,1], [1,2]])
|
|
371
|
+
sage: TestSuite(RC).run() # long time
|
|
372
|
+
sage: RC = RiggedConfigurations(['A',1,1], [[1,1], [1,1]])
|
|
373
|
+
sage: TestSuite(RC).run()
|
|
374
|
+
sage: RC = RiggedConfigurations(['A',2,1], [[1,1], [2,1]])
|
|
375
|
+
sage: TestSuite(RC).run()
|
|
376
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2,1], [1,1]])
|
|
377
|
+
sage: TestSuite(RC).run() # long time
|
|
378
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[3,1]])
|
|
379
|
+
sage: TestSuite(RC).run() # long time
|
|
380
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[4,2]])
|
|
381
|
+
sage: TestSuite(RC).run() # long time
|
|
382
|
+
"""
|
|
383
|
+
self._cartan_type = cartan_type
|
|
384
|
+
self.dims = B
|
|
385
|
+
cl = cartan_type.classical()
|
|
386
|
+
self._rc_index = cl.index_set()
|
|
387
|
+
self._rc_index_inverse = {i: ii for ii,i in enumerate(self._rc_index)}
|
|
388
|
+
# We store the Cartan matrix for the vacancy number calculations for speed
|
|
389
|
+
self._cartan_matrix = cl.cartan_matrix()
|
|
390
|
+
Parent.__init__(self, category=KirillovReshetikhinCrystals().TensorProducts())
|
|
391
|
+
|
|
392
|
+
# add options to class
|
|
393
|
+
class options(GlobalOptions):
|
|
394
|
+
r"""
|
|
395
|
+
Set and display the options for rigged configurations.
|
|
396
|
+
If no parameters are set, then the function returns a copy of
|
|
397
|
+
the options dictionary.
|
|
398
|
+
|
|
399
|
+
The ``options`` to partitions can be accessed as the method
|
|
400
|
+
:obj:`RiggedConfigurations.options` of
|
|
401
|
+
:class:`RiggedConfigurations`.
|
|
402
|
+
|
|
403
|
+
@OPTIONS@
|
|
404
|
+
|
|
405
|
+
EXAMPLES::
|
|
406
|
+
|
|
407
|
+
sage: RC = RiggedConfigurations(['A',3,1], [[2,2],[1,1],[1,1]])
|
|
408
|
+
sage: elt = RC(partition_list=[[3,1], [3], [1]])
|
|
409
|
+
sage: elt
|
|
410
|
+
<BLANKLINE>
|
|
411
|
+
-3[ ][ ][ ]-3
|
|
412
|
+
-1[ ]-1
|
|
413
|
+
<BLANKLINE>
|
|
414
|
+
1[ ][ ][ ]1
|
|
415
|
+
<BLANKLINE>
|
|
416
|
+
-1[ ]-1
|
|
417
|
+
<BLANKLINE>
|
|
418
|
+
sage: RiggedConfigurations.options(display='horizontal', convention='french')
|
|
419
|
+
sage: elt
|
|
420
|
+
-1[ ]-1 1[ ][ ][ ]1 -1[ ]-1
|
|
421
|
+
-3[ ][ ][ ]-3
|
|
422
|
+
|
|
423
|
+
Changing the ``convention`` for rigged configurations also changes the
|
|
424
|
+
``convention`` option for tableaux and vice versa::
|
|
425
|
+
|
|
426
|
+
sage: T = Tableau([[1,2,3],[4,5]])
|
|
427
|
+
sage: T.pp()
|
|
428
|
+
4 5
|
|
429
|
+
1 2 3
|
|
430
|
+
sage: Tableaux.options.convention="english"
|
|
431
|
+
sage: elt
|
|
432
|
+
-3[ ][ ][ ]-3 1[ ][ ][ ]1 -1[ ]-1
|
|
433
|
+
-1[ ]-1
|
|
434
|
+
sage: T.pp()
|
|
435
|
+
1 2 3
|
|
436
|
+
4 5
|
|
437
|
+
sage: RiggedConfigurations.options._reset()
|
|
438
|
+
"""
|
|
439
|
+
NAME = 'RiggedConfigurations'
|
|
440
|
+
module = 'sage.combinat.rigged_configurations.rigged_configurations'
|
|
441
|
+
display = dict(default='vertical',
|
|
442
|
+
description='Specifies how rigged configurations should be printed',
|
|
443
|
+
values=dict(vertical='displayed vertically',
|
|
444
|
+
horizontal='displayed horizontally'),
|
|
445
|
+
case_sensitive=False)
|
|
446
|
+
element_ascii_art = dict(default=True,
|
|
447
|
+
description='display using the repr option ``element_ascii_art``',
|
|
448
|
+
checker=lambda x: isinstance(x, bool))
|
|
449
|
+
half_width_boxes_type_B = dict(default=True,
|
|
450
|
+
description='display the last rigged partition in affine type B as half width boxes',
|
|
451
|
+
checker=lambda x: isinstance(x, bool))
|
|
452
|
+
convention = dict(link_to=(tableau.Tableaux.options,'convention'))
|
|
453
|
+
notation = dict(alt_name='convention')
|
|
454
|
+
|
|
455
|
+
def _repr_(self):
|
|
456
|
+
"""
|
|
457
|
+
Return a string representation of ``self``.
|
|
458
|
+
|
|
459
|
+
EXAMPLES::
|
|
460
|
+
|
|
461
|
+
sage: RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2], [1, 1]])
|
|
462
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((3, 2), (1, 2), (1, 1))
|
|
463
|
+
"""
|
|
464
|
+
return "Rigged configurations of type {} and factor(s) {}".format(self._cartan_type, self.dims)
|
|
465
|
+
|
|
466
|
+
def _repr_option(self, key):
|
|
467
|
+
"""
|
|
468
|
+
Metadata about the :meth:`_repr_` output.
|
|
469
|
+
|
|
470
|
+
See :meth:`sage.structure.parent._repr_option` for details.
|
|
471
|
+
|
|
472
|
+
EXAMPLES::
|
|
473
|
+
|
|
474
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1]])
|
|
475
|
+
sage: RC._repr_option('element_ascii_art')
|
|
476
|
+
True
|
|
477
|
+
"""
|
|
478
|
+
if key == 'element_ascii_art':
|
|
479
|
+
return self.options.element_ascii_art
|
|
480
|
+
return super()._repr_option(key)
|
|
481
|
+
|
|
482
|
+
def __iter__(self):
|
|
483
|
+
"""
|
|
484
|
+
Iterate over ``self``.
|
|
485
|
+
|
|
486
|
+
EXAMPLES::
|
|
487
|
+
|
|
488
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1], [1,1]])
|
|
489
|
+
sage: L = [x for x in RC]
|
|
490
|
+
sage: len(L)
|
|
491
|
+
24
|
|
492
|
+
"""
|
|
493
|
+
index_set = self._rc_index
|
|
494
|
+
from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet
|
|
495
|
+
return RecursivelyEnumeratedSet(self.module_generators,
|
|
496
|
+
lambda x: [x.f(i) for i in index_set],
|
|
497
|
+
structure='graded').breadth_first_search_iterator()
|
|
498
|
+
|
|
499
|
+
@lazy_attribute
|
|
500
|
+
def module_generators(self):
|
|
501
|
+
r"""
|
|
502
|
+
Module generators for this set of rigged configurations.
|
|
503
|
+
|
|
504
|
+
Iterate over the highest weight rigged configurations by moving
|
|
505
|
+
through the
|
|
506
|
+
:class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree`
|
|
507
|
+
and then setting appropriate values of the partitions.
|
|
508
|
+
|
|
509
|
+
EXAMPLES::
|
|
510
|
+
|
|
511
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[2,1]])
|
|
512
|
+
sage: for x in RC.module_generators: x
|
|
513
|
+
<BLANKLINE>
|
|
514
|
+
(/)
|
|
515
|
+
<BLANKLINE>
|
|
516
|
+
(/)
|
|
517
|
+
<BLANKLINE>
|
|
518
|
+
(/)
|
|
519
|
+
<BLANKLINE>
|
|
520
|
+
(/)
|
|
521
|
+
<BLANKLINE>
|
|
522
|
+
<BLANKLINE>
|
|
523
|
+
0[ ]0
|
|
524
|
+
<BLANKLINE>
|
|
525
|
+
0[ ]0
|
|
526
|
+
0[ ]0
|
|
527
|
+
<BLANKLINE>
|
|
528
|
+
0[ ]0
|
|
529
|
+
<BLANKLINE>
|
|
530
|
+
0[ ]0
|
|
531
|
+
<BLANKLINE>
|
|
532
|
+
|
|
533
|
+
TESTS:
|
|
534
|
+
|
|
535
|
+
We check that this works with relabelled Cartan types (:issue:`16876`)::
|
|
536
|
+
|
|
537
|
+
sage: ct = CartanType(['A',3,1]).relabel(lambda x: x+2)
|
|
538
|
+
sage: RC = RiggedConfigurations(ct, [[4,1],[5,1]])
|
|
539
|
+
sage: len(RC.module_generators)
|
|
540
|
+
2
|
|
541
|
+
sage: ct = CartanType(['A',3,1]).relabel(lambda x: (x+2) % 4)
|
|
542
|
+
sage: RC = RiggedConfigurations(ct, [[0,1],[1,1]])
|
|
543
|
+
sage: len(RC.module_generators)
|
|
544
|
+
2
|
|
545
|
+
"""
|
|
546
|
+
module_gens = []
|
|
547
|
+
n = len(self._rc_index)
|
|
548
|
+
|
|
549
|
+
for tree_node in self.kleber_tree():
|
|
550
|
+
shapes = []
|
|
551
|
+
cur = tree_node
|
|
552
|
+
path_lambda = [cur.up_root.to_vector()] # Build the lambda values
|
|
553
|
+
# Note that these are not same lambda as in the paper,
|
|
554
|
+
# but a less computational version.
|
|
555
|
+
while cur.parent_node is not None:
|
|
556
|
+
path_lambda.insert(0, (cur.parent_node.up_root - cur.up_root).to_vector())
|
|
557
|
+
cur = cur.parent_node
|
|
558
|
+
|
|
559
|
+
for a in range(n):
|
|
560
|
+
shapes.append([])
|
|
561
|
+
for i, cur_lambda in enumerate(path_lambda):
|
|
562
|
+
for j in range(cur_lambda[a]):
|
|
563
|
+
shapes[-1].insert(0, i)
|
|
564
|
+
|
|
565
|
+
# Start with a base to calculate the vacancy numbers
|
|
566
|
+
# Make a copy just to be safe
|
|
567
|
+
base = self.element_class(self, partition_list=shapes[:])
|
|
568
|
+
|
|
569
|
+
# Build out the blocks for the partition values
|
|
570
|
+
vac_nums = []
|
|
571
|
+
blocks = []
|
|
572
|
+
L = []
|
|
573
|
+
|
|
574
|
+
for partition in base:
|
|
575
|
+
vac_nums.append(partition.vacancy_numbers)
|
|
576
|
+
blocks.append([[]])
|
|
577
|
+
|
|
578
|
+
# If the partition is empty, there's nothing to do
|
|
579
|
+
if not partition._list:
|
|
580
|
+
L.append([[]])
|
|
581
|
+
continue
|
|
582
|
+
|
|
583
|
+
# Setup the first block
|
|
584
|
+
block_len = partition[0]
|
|
585
|
+
for i, rowLen in enumerate(partition):
|
|
586
|
+
# If we've gone to a different sized block, then update the
|
|
587
|
+
# values which change when moving to a new block size
|
|
588
|
+
if block_len != rowLen:
|
|
589
|
+
blocks[-1].append([])
|
|
590
|
+
block_len = rowLen
|
|
591
|
+
|
|
592
|
+
blocks[-1][-1].append(partition.vacancy_numbers[i])
|
|
593
|
+
|
|
594
|
+
L2 = []
|
|
595
|
+
for block in blocks[-1]:
|
|
596
|
+
L2.append(IterableFunctionCall(self._block_iterator, block))
|
|
597
|
+
L.append(itertools.product(*L2))
|
|
598
|
+
|
|
599
|
+
C = itertools.product(*L)
|
|
600
|
+
for curBlocks in C:
|
|
601
|
+
module_gens.append( self.element_class(self, KT_constructor=[shapes[:],
|
|
602
|
+
self._blocks_to_values(curBlocks[:]),
|
|
603
|
+
vac_nums[:]]) )
|
|
604
|
+
|
|
605
|
+
return tuple(module_gens)
|
|
606
|
+
|
|
607
|
+
def _block_iterator(self, container):
|
|
608
|
+
r"""
|
|
609
|
+
Iterate over all possible riggings for a particular block.
|
|
610
|
+
|
|
611
|
+
Helper iterator which iterates over all possible partitions contained
|
|
612
|
+
within the container.
|
|
613
|
+
|
|
614
|
+
INPUT:
|
|
615
|
+
|
|
616
|
+
- ``container`` -- list of widths of the rows of the container
|
|
617
|
+
|
|
618
|
+
TESTS::
|
|
619
|
+
|
|
620
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
621
|
+
sage: for x in RC._block_iterator([]): x
|
|
622
|
+
[]
|
|
623
|
+
sage: for x in RC._block_iterator([2,3]): x
|
|
624
|
+
[0, 0]
|
|
625
|
+
[1, 0]
|
|
626
|
+
[1, 1]
|
|
627
|
+
[2, 0]
|
|
628
|
+
[2, 1]
|
|
629
|
+
[2, 2]
|
|
630
|
+
"""
|
|
631
|
+
if not container:
|
|
632
|
+
yield []
|
|
633
|
+
return
|
|
634
|
+
|
|
635
|
+
pos = 0
|
|
636
|
+
length = len(container)
|
|
637
|
+
ret_part = [-1] * length
|
|
638
|
+
while pos >= 0:
|
|
639
|
+
ret_part[pos] += 1
|
|
640
|
+
|
|
641
|
+
if ret_part[pos] > container[pos] or (pos != 0 and ret_part[pos] > ret_part[pos - 1]):
|
|
642
|
+
ret_part[pos] = -1
|
|
643
|
+
pos -= 1
|
|
644
|
+
else:
|
|
645
|
+
pos += 1
|
|
646
|
+
|
|
647
|
+
if pos == length:
|
|
648
|
+
yield ret_part[:]
|
|
649
|
+
pos -= 1
|
|
650
|
+
|
|
651
|
+
def _blocks_to_values(self, blocks):
|
|
652
|
+
r"""
|
|
653
|
+
Convert an array of blocks into a list of partition values.
|
|
654
|
+
|
|
655
|
+
INPUT:
|
|
656
|
+
|
|
657
|
+
- ``blocks`` -- the (2-dim) array blocks of the partition values
|
|
658
|
+
|
|
659
|
+
TESTS::
|
|
660
|
+
|
|
661
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
662
|
+
sage: RC._blocks_to_values([[[2, 1]]])
|
|
663
|
+
[[2, 1]]
|
|
664
|
+
"""
|
|
665
|
+
values = []
|
|
666
|
+
for part_block in blocks:
|
|
667
|
+
if not part_block:
|
|
668
|
+
values.append([])
|
|
669
|
+
else:
|
|
670
|
+
values.append(part_block[0][:]) # Need to make a copy
|
|
671
|
+
for block in part_block[1:]:
|
|
672
|
+
values[-1].extend(block)
|
|
673
|
+
return values
|
|
674
|
+
|
|
675
|
+
def classically_highest_weight_vectors(self):
|
|
676
|
+
"""
|
|
677
|
+
Return the classically highest weight elements of ``self``.
|
|
678
|
+
|
|
679
|
+
TESTS::
|
|
680
|
+
|
|
681
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
|
|
682
|
+
sage: ascii_art(RC.classically_highest_weight_vectors())
|
|
683
|
+
( (/) (/) (/) (/) )
|
|
684
|
+
"""
|
|
685
|
+
return self.module_generators
|
|
686
|
+
|
|
687
|
+
def _element_constructor_(self, *lst, **options):
|
|
688
|
+
"""
|
|
689
|
+
Construct a ``RiggedConfigurationElement``.
|
|
690
|
+
|
|
691
|
+
Typically the user should not call this method since it does not check
|
|
692
|
+
if it is a valid configuration. Instead the user should use the
|
|
693
|
+
iterator methods.
|
|
694
|
+
|
|
695
|
+
EXAMPLES::
|
|
696
|
+
|
|
697
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
|
|
698
|
+
sage: RC(partition_list=[[1], [1], [], []], rigging_list=[[-1], [0], [], []])
|
|
699
|
+
<BLANKLINE>
|
|
700
|
+
-1[ ]-1
|
|
701
|
+
<BLANKLINE>
|
|
702
|
+
0[ ]0
|
|
703
|
+
<BLANKLINE>
|
|
704
|
+
(/)
|
|
705
|
+
<BLANKLINE>
|
|
706
|
+
(/)
|
|
707
|
+
<BLANKLINE>
|
|
708
|
+
|
|
709
|
+
TESTS::
|
|
710
|
+
|
|
711
|
+
sage: KT = crystals.TensorProductOfKirillovReshetikhinTableaux(['C',2,1], [[2,4],[1,2]])
|
|
712
|
+
sage: t = KT(pathlist=[[2,1,2,1,-2,2,-1,-2],[2,-2]])
|
|
713
|
+
sage: rc = t.to_rigged_configuration(); rc
|
|
714
|
+
<BLANKLINE>
|
|
715
|
+
-1[ ][ ][ ]-1
|
|
716
|
+
0[ ][ ]0
|
|
717
|
+
<BLANKLINE>
|
|
718
|
+
-1[ ][ ]-1
|
|
719
|
+
-1[ ]-1
|
|
720
|
+
-1[ ]-1
|
|
721
|
+
<BLANKLINE>
|
|
722
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[2,4]])
|
|
723
|
+
sage: RC(rc)
|
|
724
|
+
<BLANKLINE>
|
|
725
|
+
-1[ ][ ][ ]-1
|
|
726
|
+
0[ ][ ]0
|
|
727
|
+
<BLANKLINE>
|
|
728
|
+
-1[ ][ ]-1
|
|
729
|
+
-1[ ]-1
|
|
730
|
+
-1[ ]-1
|
|
731
|
+
<BLANKLINE>
|
|
732
|
+
|
|
733
|
+
TESTS:
|
|
734
|
+
|
|
735
|
+
Check that :issue:`17054` is fixed::
|
|
736
|
+
|
|
737
|
+
sage: B = crystals.infinity.RiggedConfigurations(['A',2])
|
|
738
|
+
sage: RC = RiggedConfigurations(['A',2,1], [[1,1]]*4 + [[2,1]]*4)
|
|
739
|
+
sage: x = B.an_element().f_string([2,2,1,1,2,1,2,1])
|
|
740
|
+
sage: ascii_art(x)
|
|
741
|
+
-4[ ][ ][ ][ ]-4 -4[ ][ ][ ][ ]0
|
|
742
|
+
sage: ascii_art(RC(x))
|
|
743
|
+
0[ ][ ][ ][ ]-4 0[ ][ ][ ][ ]0
|
|
744
|
+
sage: x == B.an_element().f_string([2,2,1,1,2,1,2,1])
|
|
745
|
+
True
|
|
746
|
+
"""
|
|
747
|
+
if not lst:
|
|
748
|
+
return self.element_class(self, [], **options)
|
|
749
|
+
|
|
750
|
+
from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element import TensorProductOfKirillovReshetikhinTableauxElement
|
|
751
|
+
if isinstance(lst[0], TensorProductOfKirillovReshetikhinTableauxElement):
|
|
752
|
+
if self != lst[0].parent().rigged_configurations():
|
|
753
|
+
raise ValueError("incorrect bijection image")
|
|
754
|
+
return lst[0].to_rigged_configuration()
|
|
755
|
+
|
|
756
|
+
from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
|
|
757
|
+
if isinstance(lst[0], TensorProductOfRegularCrystalsElement):
|
|
758
|
+
lst = lst[0]
|
|
759
|
+
from sage.combinat.crystals.kirillov_reshetikhin import KirillovReshetikhinGenericCrystalElement
|
|
760
|
+
if isinstance(lst[0], KirillovReshetikhinGenericCrystalElement):
|
|
761
|
+
KRT = self.tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
762
|
+
krt_elt = KRT(*[x.to_kirillov_reshetikhin_tableau() for x in lst])
|
|
763
|
+
return krt_elt.to_rigged_configuration()
|
|
764
|
+
|
|
765
|
+
if isinstance(lst[0], (list, tuple)):
|
|
766
|
+
lst = lst[0]
|
|
767
|
+
|
|
768
|
+
if isinstance(lst[0], RiggedPartition):
|
|
769
|
+
lst = [p._clone() for p in lst] # Make a deep copy
|
|
770
|
+
elif isinstance(lst[0], RiggedConfigurationElement):
|
|
771
|
+
lst = [p._clone() for p in lst[0]] # Make a deep copy
|
|
772
|
+
|
|
773
|
+
return self.element_class(self, list(lst), **options)
|
|
774
|
+
|
|
775
|
+
def _calc_vacancy_number(self, partitions, a, i, **options):
|
|
776
|
+
r"""
|
|
777
|
+
Calculate the vacancy number `p_i^{(a)}` in ``self``.
|
|
778
|
+
|
|
779
|
+
This assumes that `\gamma_a = 1` for all `a` and `(\alpha_a \mid
|
|
780
|
+
\alpha_b ) = A_{ab}`.
|
|
781
|
+
|
|
782
|
+
INPUT:
|
|
783
|
+
|
|
784
|
+
- ``partitions`` -- the list of rigged partitions we are using
|
|
785
|
+
|
|
786
|
+
- ``a`` -- the rigged partition index
|
|
787
|
+
|
|
788
|
+
- ``i`` -- the row length
|
|
789
|
+
|
|
790
|
+
TESTS::
|
|
791
|
+
|
|
792
|
+
sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
|
|
793
|
+
sage: elt = RC(partition_list=[[1], [1], [], []])
|
|
794
|
+
sage: RC._calc_vacancy_number(elt.nu(), 1, 1)
|
|
795
|
+
0
|
|
796
|
+
"""
|
|
797
|
+
vac_num = 0
|
|
798
|
+
if "B" in options:
|
|
799
|
+
for tab in options["B"]:
|
|
800
|
+
if len(tab) == self._rc_index[a]:
|
|
801
|
+
vac_num += min(i, len(tab[0]))
|
|
802
|
+
elif "L" in options:
|
|
803
|
+
L = options["L"]
|
|
804
|
+
if a in L:
|
|
805
|
+
for kvp in L[a].items():
|
|
806
|
+
vac_num += min(kvp[0], i) * kvp[1]
|
|
807
|
+
elif "dims" in options:
|
|
808
|
+
for dim in options["dims"]:
|
|
809
|
+
if dim[0] == self._rc_index[a]:
|
|
810
|
+
vac_num += min(dim[1], i)
|
|
811
|
+
else:
|
|
812
|
+
for dim in self.dims:
|
|
813
|
+
if dim[0] == self._rc_index[a]:
|
|
814
|
+
vac_num += min(dim[1], i)
|
|
815
|
+
|
|
816
|
+
if i == float('inf'):
|
|
817
|
+
vac_num -= sum(self._cartan_matrix[a,b] * sum(nu)
|
|
818
|
+
for b,nu in enumerate(partitions))
|
|
819
|
+
else:
|
|
820
|
+
vac_num -= sum(self._cartan_matrix[a,b] * nu.get_num_cells_to_column(i)
|
|
821
|
+
for b,nu in enumerate(partitions))
|
|
822
|
+
|
|
823
|
+
return vac_num
|
|
824
|
+
|
|
825
|
+
def kleber_tree(self):
|
|
826
|
+
r"""
|
|
827
|
+
Return the underlying Kleber tree used to generate all highest
|
|
828
|
+
weight rigged configurations.
|
|
829
|
+
|
|
830
|
+
EXAMPLES::
|
|
831
|
+
|
|
832
|
+
sage: RC = RiggedConfigurations(['A',3,1], [[1,1], [2,1]])
|
|
833
|
+
sage: RC.kleber_tree()
|
|
834
|
+
Kleber tree of Cartan type ['A', 3, 1] and B = ((1, 1), (2, 1))
|
|
835
|
+
"""
|
|
836
|
+
return KleberTree(self._cartan_type, self.dims)
|
|
837
|
+
|
|
838
|
+
@cached_method
|
|
839
|
+
def tensor_product_of_kirillov_reshetikhin_tableaux(self):
|
|
840
|
+
"""
|
|
841
|
+
Return the corresponding tensor product of Kirillov-Reshetikhin
|
|
842
|
+
tableaux.
|
|
843
|
+
|
|
844
|
+
EXAMPLES::
|
|
845
|
+
|
|
846
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2]])
|
|
847
|
+
sage: RC.tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
848
|
+
Tensor product of Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and factor(s) ((3, 2), (1, 2))
|
|
849
|
+
"""
|
|
850
|
+
from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import TensorProductOfKirillovReshetikhinTableaux
|
|
851
|
+
return TensorProductOfKirillovReshetikhinTableaux(self._cartan_type, self.dims)
|
|
852
|
+
|
|
853
|
+
@cached_method
|
|
854
|
+
def tensor_product_of_kirillov_reshetikhin_crystals(self):
|
|
855
|
+
"""
|
|
856
|
+
Return the corresponding tensor product of Kirillov-Reshetikhin
|
|
857
|
+
crystals.
|
|
858
|
+
|
|
859
|
+
EXAMPLES::
|
|
860
|
+
|
|
861
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3,1],[2,2]])
|
|
862
|
+
sage: RC.tensor_product_of_kirillov_reshetikhin_crystals()
|
|
863
|
+
Full tensor product of the crystals
|
|
864
|
+
[Kirillov-Reshetikhin crystal of type ['A', 3, 1] with (r,s)=(3,1),
|
|
865
|
+
Kirillov-Reshetikhin crystal of type ['A', 3, 1] with (r,s)=(2,2)]
|
|
866
|
+
"""
|
|
867
|
+
return self.tensor_product_of_kirillov_reshetikhin_tableaux().tensor_product_of_kirillov_reshetikhin_crystals()
|
|
868
|
+
|
|
869
|
+
def fermionic_formula(self, q=None, only_highest_weight=False, weight=None):
|
|
870
|
+
r"""
|
|
871
|
+
Return the fermionic formula associated to ``self``.
|
|
872
|
+
|
|
873
|
+
Given a set of rigged configurations `RC(\lambda, L)`, the fermionic
|
|
874
|
+
formula is defined as:
|
|
875
|
+
|
|
876
|
+
.. MATH::
|
|
877
|
+
|
|
878
|
+
M(\lambda, L; q) = \sum_{(\nu,J)} q^{cc(\nu, J)}
|
|
879
|
+
|
|
880
|
+
where we sum over all (classically highest weight) rigged
|
|
881
|
+
configurations of weight `\lambda` where `cc` is the
|
|
882
|
+
:meth:`cocharge statistic
|
|
883
|
+
<sage.combinat.rigged_configurations.rigged_configuration_element.RiggedConfigurationElement.cc>`.
|
|
884
|
+
This is known to reduce to
|
|
885
|
+
|
|
886
|
+
.. MATH::
|
|
887
|
+
|
|
888
|
+
M(\lambda, L; q) = \sum_{\nu} q^{cc(\nu)} \prod_{(a,i) \in
|
|
889
|
+
I \times \ZZ} \begin{bmatrix} p_i^{(a)} + m_i^{(a)} \\ m_i^{(a)}
|
|
890
|
+
\end{bmatrix}_q.
|
|
891
|
+
|
|
892
|
+
The generating function of `M(\lambda, L; q)` in the weight algebra
|
|
893
|
+
subsumes all fermionic formulas:
|
|
894
|
+
|
|
895
|
+
.. MATH::
|
|
896
|
+
|
|
897
|
+
M(L; q) = \sum_{\lambda \in P} M(\lambda, L; q) \lambda.
|
|
898
|
+
|
|
899
|
+
This is conjecturally equal to the
|
|
900
|
+
:meth:`one dimensional configuration sum
|
|
901
|
+
<sage.combinat.crystals.tensor_product.CrystalOfWords.one_dimensional_configuration_sum>`
|
|
902
|
+
of the corresponding tensor product of Kirillov-Reshetikhin crystals, see [HKOTT2002]_.
|
|
903
|
+
This has been proven in general for type `A_n^{(1)}` [BijectionLRT]_,
|
|
904
|
+
single factors `B^{r,s}` in type `D_n^{(1)}` [OSS2011]_ with the result
|
|
905
|
+
from [Sakamoto13]_, as well as for a tensor product of single columns
|
|
906
|
+
[OSS2003]_, [BijectionDn]_ or a tensor product of single rows [OSS03]_
|
|
907
|
+
for all non-exceptional types.
|
|
908
|
+
|
|
909
|
+
INPUT:
|
|
910
|
+
|
|
911
|
+
- ``q`` -- the variable `q`
|
|
912
|
+
- ``only_highest_weight`` -- use only the classically highest weight
|
|
913
|
+
rigged configurations
|
|
914
|
+
- ``weight`` -- return the fermionic formula `M(\lambda, L; q)` where
|
|
915
|
+
`\lambda` is the classical weight ``weight``
|
|
916
|
+
|
|
917
|
+
REFERENCES:
|
|
918
|
+
|
|
919
|
+
.. [OSS2003] Masato Okado, Anne Schilling, and Mark Shimozono.
|
|
920
|
+
Virtual crystals and fermionic formulas of type `D_{n+1}^{(2)}`,
|
|
921
|
+
`A_{2n}^{(2)}`, and `C_n^{(1)}`. Representation Theory. **7** (2003)
|
|
922
|
+
:arxiv:`math.QA/0105017`.
|
|
923
|
+
|
|
924
|
+
.. [Sakamoto13] Reiho Sakamoto.
|
|
925
|
+
Rigged configurations and Kashiwara operators.
|
|
926
|
+
(2013) :arxiv:`1302.4562v1`.
|
|
927
|
+
|
|
928
|
+
EXAMPLES::
|
|
929
|
+
|
|
930
|
+
sage: RC = RiggedConfigurations(['A', 2, 1], [[1,1], [1,1]])
|
|
931
|
+
sage: RC.fermionic_formula()
|
|
932
|
+
B[-2*Lambda[1] + 2*Lambda[2]] + (q+1)*B[-Lambda[1]]
|
|
933
|
+
+ (q+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]]
|
|
934
|
+
+ B[-2*Lambda[2]] + (q+1)*B[Lambda[2]]
|
|
935
|
+
sage: t = QQ['t'].gen(0)
|
|
936
|
+
sage: RC.fermionic_formula(t)
|
|
937
|
+
B[-2*Lambda[1] + 2*Lambda[2]] + (t+1)*B[-Lambda[1]]
|
|
938
|
+
+ (t+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]]
|
|
939
|
+
+ B[-2*Lambda[2]] + (t+1)*B[Lambda[2]]
|
|
940
|
+
sage: La = RC.weight_lattice_realization().classical().fundamental_weights()
|
|
941
|
+
sage: RC.fermionic_formula(weight=La[2])
|
|
942
|
+
q + 1
|
|
943
|
+
sage: RC.fermionic_formula(only_highest_weight=True, weight=La[2])
|
|
944
|
+
q
|
|
945
|
+
|
|
946
|
+
Only using the highest weight elements on other types::
|
|
947
|
+
|
|
948
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[3,1], [2,2]])
|
|
949
|
+
sage: RC.fermionic_formula(only_highest_weight=True)
|
|
950
|
+
q*B[Lambda[1] + Lambda[2]] + B[2*Lambda[2] + Lambda[3]]
|
|
951
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[3,1], [4,1], [2,1]])
|
|
952
|
+
sage: RC.fermionic_formula(only_highest_weight=True)
|
|
953
|
+
(q^4+q^3+q^2)*B[Lambda[1]] + (q^2+q)*B[Lambda[1] + Lambda[2]]
|
|
954
|
+
+ q*B[Lambda[1] + 2*Lambda[3]] + q*B[Lambda[1] + 2*Lambda[4]]
|
|
955
|
+
+ B[Lambda[2] + Lambda[3] + Lambda[4]] + (q^3+2*q^2+q)*B[Lambda[3] + Lambda[4]]
|
|
956
|
+
sage: RC = RiggedConfigurations(['E', 6, 1], [[2,2]])
|
|
957
|
+
sage: RC.fermionic_formula(only_highest_weight=True)
|
|
958
|
+
q^2*B[0] + q*B[Lambda[2]] + B[2*Lambda[2]]
|
|
959
|
+
sage: RC = RiggedConfigurations(['B', 3, 1], [[3,1], [2,2]])
|
|
960
|
+
sage: RC.fermionic_formula(only_highest_weight=True) # long time
|
|
961
|
+
q*B[Lambda[1] + Lambda[2] + Lambda[3]] + q^2*B[Lambda[1]
|
|
962
|
+
+ Lambda[3]] + (q^2+q)*B[Lambda[2] + Lambda[3]] + B[2*Lambda[2]
|
|
963
|
+
+ Lambda[3]] + (q^3+q^2)*B[Lambda[3]]
|
|
964
|
+
sage: RC = RiggedConfigurations(['C', 3, 1], [[3,1], [2,2]])
|
|
965
|
+
sage: RC.fermionic_formula(only_highest_weight=True) # long time
|
|
966
|
+
(q^3+q^2)*B[Lambda[1] + Lambda[2]] + q*B[Lambda[1] + 2*Lambda[2]]
|
|
967
|
+
+ (q^2+q)*B[2*Lambda[1] + Lambda[3]] + B[2*Lambda[2] + Lambda[3]]
|
|
968
|
+
+ (q^4+q^3+q^2)*B[Lambda[3]]
|
|
969
|
+
sage: RC = RiggedConfigurations(['D', 4, 2], [[3,1], [2,2]])
|
|
970
|
+
sage: RC.fermionic_formula(only_highest_weight=True) # long time
|
|
971
|
+
(q^2+q)*B[Lambda[1] + Lambda[2] + Lambda[3]] + (q^5+2*q^4+q^3)*B[Lambda[1]
|
|
972
|
+
+ Lambda[3]] + (q^3+q^2)*B[2*Lambda[1] + Lambda[3]] + (q^4+q^3+q^2)*B[Lambda[2]
|
|
973
|
+
+ Lambda[3]] + B[2*Lambda[2] + Lambda[3]] + (q^6+q^5+q^4)*B[Lambda[3]]
|
|
974
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1],[2,2]])
|
|
975
|
+
sage: RC.fermionic_formula(only_highest_weight=True)
|
|
976
|
+
(q^3+q^2)*B[Lambda[1]] + (q^2+q)*B[Lambda[1] + 2*Lambda[2]]
|
|
977
|
+
+ B[Lambda[1] + 4*Lambda[2]] + q*B[3*Lambda[1]] + q*B[4*Lambda[2]]
|
|
978
|
+
|
|
979
|
+
TESTS::
|
|
980
|
+
|
|
981
|
+
sage: RC = RiggedConfigurations(['A', 2, 1], [[1,1], [1,1]])
|
|
982
|
+
sage: KR = RC.tensor_product_of_kirillov_reshetikhin_crystals()
|
|
983
|
+
sage: RC.fermionic_formula() == KR.one_dimensional_configuration_sum()
|
|
984
|
+
True
|
|
985
|
+
sage: KT = RC.tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
986
|
+
sage: RC.fermionic_formula() == KT.one_dimensional_configuration_sum()
|
|
987
|
+
True
|
|
988
|
+
sage: RC = RiggedConfigurations(['C', 2, 1], [[2,1], [2,1]])
|
|
989
|
+
sage: KR = RC.tensor_product_of_kirillov_reshetikhin_crystals()
|
|
990
|
+
sage: RC.fermionic_formula() == KR.one_dimensional_configuration_sum() # long time
|
|
991
|
+
True
|
|
992
|
+
sage: t = QQ['t'].gen(0)
|
|
993
|
+
sage: RC = RiggedConfigurations(['D', 4, 1], [[1,1], [2,1]])
|
|
994
|
+
sage: KR = RC.tensor_product_of_kirillov_reshetikhin_crystals()
|
|
995
|
+
sage: RC.fermionic_formula(t) == KR.one_dimensional_configuration_sum(t) # long time
|
|
996
|
+
True
|
|
997
|
+
"""
|
|
998
|
+
if q is None:
|
|
999
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
1000
|
+
q = PolynomialRing(QQ, 'q').gen(0)
|
|
1001
|
+
|
|
1002
|
+
if only_highest_weight:
|
|
1003
|
+
L = self.module_generators
|
|
1004
|
+
else:
|
|
1005
|
+
L = self
|
|
1006
|
+
|
|
1007
|
+
P = q.parent()
|
|
1008
|
+
WLR = self.weight_lattice_realization().classical()
|
|
1009
|
+
|
|
1010
|
+
if weight is not None:
|
|
1011
|
+
weight = WLR(weight)
|
|
1012
|
+
return P.sum(q**x.cc() for x in L if WLR(x.weight()) == weight)
|
|
1013
|
+
|
|
1014
|
+
B = WLR.algebra(P)
|
|
1015
|
+
return B.sum(q**x.cc() * B(WLR(x.weight())) for x in L)
|
|
1016
|
+
|
|
1017
|
+
def _test_bijection(self, **options):
|
|
1018
|
+
r"""
|
|
1019
|
+
Test function to make sure that the bijection between rigged
|
|
1020
|
+
configurations and Kirillov-Reshetikhin tableaux is correct.
|
|
1021
|
+
|
|
1022
|
+
EXAMPLES::
|
|
1023
|
+
|
|
1024
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1],[1,1]])
|
|
1025
|
+
sage: RC._test_bijection()
|
|
1026
|
+
"""
|
|
1027
|
+
tester = self._tester(**options)
|
|
1028
|
+
rejects = []
|
|
1029
|
+
for x in self:
|
|
1030
|
+
y = x.to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
1031
|
+
z = y.to_rigged_configuration()
|
|
1032
|
+
if z != x:
|
|
1033
|
+
rejects.append((x, z))
|
|
1034
|
+
|
|
1035
|
+
tester.assertEqual(len(rejects), 0, "Bijection is not correct: {}".format(rejects))
|
|
1036
|
+
if rejects:
|
|
1037
|
+
return rejects
|
|
1038
|
+
|
|
1039
|
+
def tensor(self, *crystals, **options):
|
|
1040
|
+
"""
|
|
1041
|
+
Return the tensor product of ``self`` with ``crystals``.
|
|
1042
|
+
|
|
1043
|
+
If ``crystals`` is a list of rigged configurations of the same
|
|
1044
|
+
Cartan type, then this returns a new :class:`RiggedConfigurations`.
|
|
1045
|
+
|
|
1046
|
+
EXAMPLES::
|
|
1047
|
+
|
|
1048
|
+
sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1],[1,3]])
|
|
1049
|
+
sage: RC2 = RiggedConfigurations(['A', 3, 1], [[1,1], [3,3]])
|
|
1050
|
+
sage: RC.tensor(RC2, RC2)
|
|
1051
|
+
Rigged configurations of type ['A', 3, 1]
|
|
1052
|
+
and factor(s) ((2, 1), (1, 3), (1, 1), (3, 3), (1, 1), (3, 3))
|
|
1053
|
+
|
|
1054
|
+
sage: K = crystals.KirillovReshetikhin(['A', 3, 1], 2, 2, model='KR')
|
|
1055
|
+
sage: RC.tensor(K)
|
|
1056
|
+
Full tensor product of the crystals
|
|
1057
|
+
[Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 1), (1, 3)),
|
|
1058
|
+
Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and shape (2, 2)]
|
|
1059
|
+
"""
|
|
1060
|
+
ct = self._cartan_type
|
|
1061
|
+
if all(isinstance(B, RiggedConfigurations) and B.cartan_type() == ct for B in crystals):
|
|
1062
|
+
dims = self.dims
|
|
1063
|
+
for B in crystals:
|
|
1064
|
+
dims += B.dims
|
|
1065
|
+
return RiggedConfigurations(ct, dims)
|
|
1066
|
+
return super().tensor(*crystals, **options)
|
|
1067
|
+
|
|
1068
|
+
Element = KRRCSimplyLacedElement
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
class RCNonSimplyLaced(RiggedConfigurations):
|
|
1072
|
+
r"""
|
|
1073
|
+
Rigged configurations in non-simply-laced types.
|
|
1074
|
+
|
|
1075
|
+
These are rigged configurations which lift to virtual rigged configurations
|
|
1076
|
+
in a simply-laced type.
|
|
1077
|
+
|
|
1078
|
+
For more on rigged configurations, see :class:`RiggedConfigurations`.
|
|
1079
|
+
"""
|
|
1080
|
+
@staticmethod
|
|
1081
|
+
def __classcall_private__(cls, cartan_type, B):
|
|
1082
|
+
r"""
|
|
1083
|
+
Normalize the input arguments to ensure unique representation.
|
|
1084
|
+
|
|
1085
|
+
EXAMPLES::
|
|
1086
|
+
|
|
1087
|
+
sage: RC1 = RiggedConfigurations(CartanType(['A',4,2]), [[2,2]])
|
|
1088
|
+
sage: RC2 = RiggedConfigurations(['A',4,2], [(2,2)])
|
|
1089
|
+
sage: RC3 = RiggedConfigurations(['BC',2,2], ((2,2),))
|
|
1090
|
+
sage: RC2 is RC1, RC3 is RC1
|
|
1091
|
+
(True, True)
|
|
1092
|
+
"""
|
|
1093
|
+
cartan_type = CartanType(cartan_type)
|
|
1094
|
+
|
|
1095
|
+
# Standardize B input into a tuple of tuples
|
|
1096
|
+
B = tuple(map(tuple, B))
|
|
1097
|
+
return super().__classcall__(cls, cartan_type, B)
|
|
1098
|
+
|
|
1099
|
+
def __init__(self, cartan_type, dims):
|
|
1100
|
+
"""
|
|
1101
|
+
Initialize ``self``.
|
|
1102
|
+
|
|
1103
|
+
EXAMPLES::
|
|
1104
|
+
|
|
1105
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,1]])
|
|
1106
|
+
sage: TestSuite(RC).run()
|
|
1107
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[2,1]])
|
|
1108
|
+
sage: TestSuite(RC).run() # long time
|
|
1109
|
+
sage: RC = RiggedConfigurations(['B',3,1], [[3,1],[1,1]])
|
|
1110
|
+
sage: TestSuite(RC).run() # long time
|
|
1111
|
+
sage: RC = RiggedConfigurations(['D',4,2], [[2,1]])
|
|
1112
|
+
sage: TestSuite(RC).run() # long time
|
|
1113
|
+
sage: RC = RiggedConfigurations(['A',5,2], [[2,1]])
|
|
1114
|
+
sage: TestSuite(RC).run() # long time
|
|
1115
|
+
"""
|
|
1116
|
+
self._folded_ct = cartan_type.as_folding()
|
|
1117
|
+
RiggedConfigurations.__init__(self, cartan_type, dims)
|
|
1118
|
+
|
|
1119
|
+
def _calc_vacancy_number(self, partitions, a, i, **options):
|
|
1120
|
+
r"""
|
|
1121
|
+
Calculate the vacancy number `p_i^{(a)}` in ``self``.
|
|
1122
|
+
|
|
1123
|
+
INPUT:
|
|
1124
|
+
|
|
1125
|
+
- ``partitions`` -- the list of rigged partitions we are using
|
|
1126
|
+
|
|
1127
|
+
- ``a`` -- the rigged partition index
|
|
1128
|
+
|
|
1129
|
+
- ``i`` -- the row length
|
|
1130
|
+
|
|
1131
|
+
TESTS::
|
|
1132
|
+
|
|
1133
|
+
sage: RC = RiggedConfigurations(['C', 4, 1], [[2, 1]])
|
|
1134
|
+
sage: elt = RC(partition_list=[[1], [2], [2], [1]])
|
|
1135
|
+
sage: RC._calc_vacancy_number(elt.nu(), 1, 2)
|
|
1136
|
+
0
|
|
1137
|
+
"""
|
|
1138
|
+
vac_num = 0
|
|
1139
|
+
if "B" in options:
|
|
1140
|
+
for tab in options["B"]:
|
|
1141
|
+
if len(tab) == self._rc_index[a]:
|
|
1142
|
+
vac_num += min(i, len(tab[0]))
|
|
1143
|
+
elif "L" in options:
|
|
1144
|
+
L = options["L"]
|
|
1145
|
+
if a in L:
|
|
1146
|
+
for kvp in L[a].items():
|
|
1147
|
+
vac_num += min(kvp[0], i) * kvp[1]
|
|
1148
|
+
elif "dims" in options:
|
|
1149
|
+
for dim in options["dims"]:
|
|
1150
|
+
if dim[0] == self._rc_index[a]:
|
|
1151
|
+
vac_num += min(dim[1], i)
|
|
1152
|
+
else:
|
|
1153
|
+
for dim in self.dims:
|
|
1154
|
+
if dim[0] == self._rc_index[a]:
|
|
1155
|
+
vac_num += min(dim[1], i)
|
|
1156
|
+
|
|
1157
|
+
if i == float('inf'):
|
|
1158
|
+
vac_num -= sum(self._cartan_matrix[a,b] * sum(nu)
|
|
1159
|
+
for b,nu in enumerate(partitions))
|
|
1160
|
+
else:
|
|
1161
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1162
|
+
vac_num -= sum(self._cartan_matrix[a,b]
|
|
1163
|
+
* nu.get_num_cells_to_column(gamma[a+1]*i, gamma[b+1])
|
|
1164
|
+
// gamma[b+1]
|
|
1165
|
+
for b,nu in enumerate(partitions))
|
|
1166
|
+
|
|
1167
|
+
return vac_num
|
|
1168
|
+
|
|
1169
|
+
@lazy_attribute
|
|
1170
|
+
def module_generators(self):
|
|
1171
|
+
r"""
|
|
1172
|
+
Module generators for this set of rigged configurations.
|
|
1173
|
+
|
|
1174
|
+
Iterate over the highest weight rigged configurations by moving
|
|
1175
|
+
through the
|
|
1176
|
+
:class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree`
|
|
1177
|
+
and then setting appropriate values of the partitions.
|
|
1178
|
+
|
|
1179
|
+
EXAMPLES::
|
|
1180
|
+
|
|
1181
|
+
sage: RC = RiggedConfigurations(['C', 3, 1], [[1,2]])
|
|
1182
|
+
sage: for x in RC.module_generators: x
|
|
1183
|
+
<BLANKLINE>
|
|
1184
|
+
(/)
|
|
1185
|
+
<BLANKLINE>
|
|
1186
|
+
(/)
|
|
1187
|
+
<BLANKLINE>
|
|
1188
|
+
(/)
|
|
1189
|
+
<BLANKLINE>
|
|
1190
|
+
<BLANKLINE>
|
|
1191
|
+
0[ ][ ]0
|
|
1192
|
+
<BLANKLINE>
|
|
1193
|
+
0[ ][ ]0
|
|
1194
|
+
<BLANKLINE>
|
|
1195
|
+
0[ ]0
|
|
1196
|
+
<BLANKLINE>
|
|
1197
|
+
|
|
1198
|
+
sage: RC = RiggedConfigurations(['D',4,3], [[1,1]])
|
|
1199
|
+
sage: RC.module_generators
|
|
1200
|
+
(
|
|
1201
|
+
<BLANKLINE>
|
|
1202
|
+
0[ ]0
|
|
1203
|
+
(/) 0[ ]0
|
|
1204
|
+
<BLANKLINE>
|
|
1205
|
+
(/) 0[ ]0
|
|
1206
|
+
,
|
|
1207
|
+
)
|
|
1208
|
+
"""
|
|
1209
|
+
module_gens = []
|
|
1210
|
+
vec_len = len(self.kleber_tree().root.up_root.to_vector())
|
|
1211
|
+
|
|
1212
|
+
for tree_node in self.kleber_tree():
|
|
1213
|
+
shapes = []
|
|
1214
|
+
cur = tree_node
|
|
1215
|
+
path_lambda = [cur.up_root.to_vector()] # Build the lambda values
|
|
1216
|
+
# Note that these are not same lambda as in the paper,
|
|
1217
|
+
# but a less computational version.
|
|
1218
|
+
while cur.parent_node is not None:
|
|
1219
|
+
path_lambda.insert(0, (cur.parent_node.up_root - cur.up_root).to_vector())
|
|
1220
|
+
cur = cur.parent_node
|
|
1221
|
+
|
|
1222
|
+
for a in range(vec_len):
|
|
1223
|
+
shapes.append([])
|
|
1224
|
+
for i, cur_lambda in enumerate(path_lambda):
|
|
1225
|
+
for j in range(cur_lambda[a]):
|
|
1226
|
+
shapes[-1].insert(0, i)
|
|
1227
|
+
|
|
1228
|
+
# Convert from the virtual rigged configuration
|
|
1229
|
+
# As a special case, we do not need to do anything for type `A_{2n}^{(2)}`
|
|
1230
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1231
|
+
vindex = self.virtual._rc_index
|
|
1232
|
+
shapes = [shapes[vindex.index(sigma[a][0])] for a in self._rc_index]
|
|
1233
|
+
if self._cartan_type.type() != 'BC':
|
|
1234
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1235
|
+
for a,shape in enumerate(shapes):
|
|
1236
|
+
for i in range(len(shape)):
|
|
1237
|
+
shape[i] = shape[i] // gamma[self._rc_index[a]]
|
|
1238
|
+
|
|
1239
|
+
# Start with a base to calculate the vacancy numbers
|
|
1240
|
+
# Make a copy just to be safe
|
|
1241
|
+
base = self.element_class(self, partition_list=shapes[:])
|
|
1242
|
+
|
|
1243
|
+
# Build out the blocks for the partition values
|
|
1244
|
+
vac_nums = []
|
|
1245
|
+
blocks = []
|
|
1246
|
+
L = []
|
|
1247
|
+
|
|
1248
|
+
for partition in base:
|
|
1249
|
+
vac_nums.append(partition.vacancy_numbers)
|
|
1250
|
+
blocks.append([[]])
|
|
1251
|
+
|
|
1252
|
+
# If the partition is empty, there's nothing to do
|
|
1253
|
+
if not partition._list:
|
|
1254
|
+
L.append([[]])
|
|
1255
|
+
continue
|
|
1256
|
+
|
|
1257
|
+
# Setup the first block
|
|
1258
|
+
block_len = partition[0]
|
|
1259
|
+
for i, rowLen in enumerate(partition):
|
|
1260
|
+
# If we've gone to a different sized block, then update the
|
|
1261
|
+
# values which change when moving to a new block size
|
|
1262
|
+
if block_len != rowLen:
|
|
1263
|
+
blocks[-1].append([])
|
|
1264
|
+
block_len = rowLen
|
|
1265
|
+
|
|
1266
|
+
blocks[-1][-1].append(partition.vacancy_numbers[i])
|
|
1267
|
+
|
|
1268
|
+
L2 = []
|
|
1269
|
+
for block in blocks[-1]:
|
|
1270
|
+
L2.append(IterableFunctionCall(self._block_iterator, block))
|
|
1271
|
+
L.append(itertools.product(*L2))
|
|
1272
|
+
|
|
1273
|
+
C = itertools.product(*L)
|
|
1274
|
+
for cur_blocks in C:
|
|
1275
|
+
module_gens.append( self.element_class(self, KT_constructor=[shapes[:],
|
|
1276
|
+
self._blocks_to_values(cur_blocks[:]), vac_nums[:]]) )
|
|
1277
|
+
|
|
1278
|
+
return tuple(module_gens)
|
|
1279
|
+
|
|
1280
|
+
def kleber_tree(self):
|
|
1281
|
+
r"""
|
|
1282
|
+
Return the underlying (virtual) Kleber tree used to generate all
|
|
1283
|
+
highest weight rigged configurations.
|
|
1284
|
+
|
|
1285
|
+
EXAMPLES::
|
|
1286
|
+
|
|
1287
|
+
sage: RC = RiggedConfigurations(['C',3,1], [[1,1], [2,1]])
|
|
1288
|
+
sage: RC.kleber_tree()
|
|
1289
|
+
Virtual Kleber tree of Cartan type ['C', 3, 1] and B = ((1, 1), (2, 1))
|
|
1290
|
+
"""
|
|
1291
|
+
return VirtualKleberTree(self._cartan_type, self.dims)
|
|
1292
|
+
|
|
1293
|
+
@lazy_attribute
|
|
1294
|
+
def virtual(self):
|
|
1295
|
+
"""
|
|
1296
|
+
Return the corresponding virtual crystal.
|
|
1297
|
+
|
|
1298
|
+
EXAMPLES::
|
|
1299
|
+
|
|
1300
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
|
|
1301
|
+
sage: RC
|
|
1302
|
+
Rigged configurations of type ['C', 2, 1] and factor(s) ((1, 2), (1, 1), (2, 1))
|
|
1303
|
+
sage: RC.virtual
|
|
1304
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 2))
|
|
1305
|
+
"""
|
|
1306
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1307
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1308
|
+
virtual_dims = []
|
|
1309
|
+
for r,s in self.dims:
|
|
1310
|
+
for a in sigma[r]:
|
|
1311
|
+
virtual_dims.append([a, s*gamma[r]])
|
|
1312
|
+
return RiggedConfigurations(self._folded_ct._folding, virtual_dims)
|
|
1313
|
+
|
|
1314
|
+
def to_virtual(self, rc):
|
|
1315
|
+
"""
|
|
1316
|
+
Convert ``rc`` into a rigged configuration in the virtual crystal.
|
|
1317
|
+
|
|
1318
|
+
INPUT:
|
|
1319
|
+
|
|
1320
|
+
- ``rc`` -- a rigged configuration element
|
|
1321
|
+
|
|
1322
|
+
EXAMPLES::
|
|
1323
|
+
|
|
1324
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
|
|
1325
|
+
sage: elt = RC(partition_list=[[3],[2]]); elt
|
|
1326
|
+
<BLANKLINE>
|
|
1327
|
+
0[ ][ ][ ]0
|
|
1328
|
+
<BLANKLINE>
|
|
1329
|
+
0[ ][ ]0
|
|
1330
|
+
sage: velt = RC.to_virtual(elt); velt
|
|
1331
|
+
<BLANKLINE>
|
|
1332
|
+
0[ ][ ][ ]0
|
|
1333
|
+
<BLANKLINE>
|
|
1334
|
+
0[ ][ ][ ][ ]0
|
|
1335
|
+
<BLANKLINE>
|
|
1336
|
+
0[ ][ ][ ]0
|
|
1337
|
+
sage: velt.parent()
|
|
1338
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 2))
|
|
1339
|
+
"""
|
|
1340
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1341
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1342
|
+
n = len(self.virtual._rc_index)
|
|
1343
|
+
# +/- 1 for indexing
|
|
1344
|
+
partitions = [None] * n
|
|
1345
|
+
for a,rp in enumerate(rc):
|
|
1346
|
+
g = gamma[a+1]
|
|
1347
|
+
for i in sigma[a+1]:
|
|
1348
|
+
partitions[i-1] = RiggedPartition([row_len*g for row_len in rp._list],
|
|
1349
|
+
[rig_val*g for rig_val in rp.rigging],
|
|
1350
|
+
[vac_num*g for vac_num in rp.vacancy_numbers])
|
|
1351
|
+
return self.virtual.element_class(self.virtual, partitions, use_vacancy_numbers=True)
|
|
1352
|
+
|
|
1353
|
+
def from_virtual(self, vrc):
|
|
1354
|
+
"""
|
|
1355
|
+
Convert ``vrc`` in the virtual crystal into a rigged configuration of
|
|
1356
|
+
the original Cartan type.
|
|
1357
|
+
|
|
1358
|
+
INPUT:
|
|
1359
|
+
|
|
1360
|
+
- ``vrc`` -- a virtual rigged configuration
|
|
1361
|
+
|
|
1362
|
+
EXAMPLES::
|
|
1363
|
+
|
|
1364
|
+
sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
|
|
1365
|
+
sage: elt = RC(partition_list=[[3],[2]])
|
|
1366
|
+
sage: vrc_elt = RC.to_virtual(elt)
|
|
1367
|
+
sage: ret = RC.from_virtual(vrc_elt); ret
|
|
1368
|
+
<BLANKLINE>
|
|
1369
|
+
0[ ][ ][ ]0
|
|
1370
|
+
<BLANKLINE>
|
|
1371
|
+
0[ ][ ]0
|
|
1372
|
+
sage: ret == elt
|
|
1373
|
+
True
|
|
1374
|
+
"""
|
|
1375
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1376
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1377
|
+
n = len(self._rc_index)
|
|
1378
|
+
partitions = [None] * n
|
|
1379
|
+
# +/- 1 for indexing
|
|
1380
|
+
for a in range(n):
|
|
1381
|
+
rp = vrc[sigma[a+1][0] - 1]
|
|
1382
|
+
g = gamma[a+1]
|
|
1383
|
+
partitions[a] = RiggedPartition([row_len//g for row_len in rp._list],
|
|
1384
|
+
[rig_val//g for rig_val in rp.rigging],
|
|
1385
|
+
[vac_val//g for vac_val in rp.vacancy_numbers])
|
|
1386
|
+
return self.element_class(self, partitions, use_vacancy_numbers=True)
|
|
1387
|
+
|
|
1388
|
+
def _test_virtual_vacancy_numbers(self, **options):
|
|
1389
|
+
"""
|
|
1390
|
+
Test to make sure that the vacancy numbers obtained from the virtual
|
|
1391
|
+
rigged configuration agree with the explicit computation of the
|
|
1392
|
+
vacancy numbers done here.
|
|
1393
|
+
|
|
1394
|
+
EXAMPLES::
|
|
1395
|
+
|
|
1396
|
+
sage: RC = RiggedConfigurations(['B', 3, 1], [[2,1]])
|
|
1397
|
+
sage: RC._test_virtual_vacancy_numbers()
|
|
1398
|
+
"""
|
|
1399
|
+
tester = self._tester(**options)
|
|
1400
|
+
for x in self:
|
|
1401
|
+
parts_list = [p._list[:] for p in x]
|
|
1402
|
+
elt = self.element_class(self, partition_list=parts_list)
|
|
1403
|
+
for i, p in enumerate(elt):
|
|
1404
|
+
for j, vac_num in enumerate(p.vacancy_numbers):
|
|
1405
|
+
tester.assertEqual(vac_num, x[i].vacancy_numbers[j],
|
|
1406
|
+
"Incorrect vacancy number: {}\nComputed: {}\nFor: {}".format(
|
|
1407
|
+
x[i].vacancy_numbers[j], vac_num, x))
|
|
1408
|
+
|
|
1409
|
+
Element = KRRCNonSimplyLacedElement
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
class RCTypeA2Even(RCNonSimplyLaced):
|
|
1413
|
+
"""
|
|
1414
|
+
Rigged configurations for type `A_{2n}^{(2)}`.
|
|
1415
|
+
|
|
1416
|
+
For more on rigged configurations, see :class:`RiggedConfigurations`.
|
|
1417
|
+
|
|
1418
|
+
EXAMPLES::
|
|
1419
|
+
|
|
1420
|
+
sage: RC = RiggedConfigurations(['A',4,2], [[2,1], [1,2]])
|
|
1421
|
+
sage: RC.cardinality()
|
|
1422
|
+
150
|
|
1423
|
+
sage: RC = RiggedConfigurations(['A',2,2], [[1,1]])
|
|
1424
|
+
sage: RC.cardinality()
|
|
1425
|
+
3
|
|
1426
|
+
sage: RC = RiggedConfigurations(['A',2,2], [[1,2],[1,1]])
|
|
1427
|
+
sage: TestSuite(RC).run() # long time
|
|
1428
|
+
sage: RC = RiggedConfigurations(['A',4,2], [[2,1]])
|
|
1429
|
+
sage: TestSuite(RC).run() # long time
|
|
1430
|
+
"""
|
|
1431
|
+
|
|
1432
|
+
def cardinality(self):
|
|
1433
|
+
"""
|
|
1434
|
+
Return the cardinality of ``self``.
|
|
1435
|
+
|
|
1436
|
+
EXAMPLES::
|
|
1437
|
+
|
|
1438
|
+
sage: RC = RiggedConfigurations(['A',4,2], [[1,1], [2,2]])
|
|
1439
|
+
sage: RC.cardinality()
|
|
1440
|
+
250
|
|
1441
|
+
"""
|
|
1442
|
+
return self.tensor_product_of_kirillov_reshetikhin_tableaux().cardinality()
|
|
1443
|
+
|
|
1444
|
+
@lazy_attribute
|
|
1445
|
+
def virtual(self):
|
|
1446
|
+
"""
|
|
1447
|
+
Return the corresponding virtual crystal.
|
|
1448
|
+
|
|
1449
|
+
EXAMPLES::
|
|
1450
|
+
|
|
1451
|
+
sage: RC = RiggedConfigurations(['A',4,2], [[1,2],[1,1],[2,1]])
|
|
1452
|
+
sage: RC
|
|
1453
|
+
Rigged configurations of type ['BC', 2, 2] and factor(s) ((1, 2), (1, 1), (2, 1))
|
|
1454
|
+
sage: RC.virtual
|
|
1455
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 1), (2, 1))
|
|
1456
|
+
"""
|
|
1457
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1458
|
+
n = len(sigma) - 1
|
|
1459
|
+
virtual_dims = []
|
|
1460
|
+
for r,s in self.dims:
|
|
1461
|
+
if r == n:
|
|
1462
|
+
virtual_dims.extend([[n, s], [n, s]])
|
|
1463
|
+
else:
|
|
1464
|
+
for a in sigma[r]:
|
|
1465
|
+
virtual_dims.append([a, s])
|
|
1466
|
+
return RiggedConfigurations(self._folded_ct._folding, virtual_dims)
|
|
1467
|
+
|
|
1468
|
+
def _calc_vacancy_number(self, partitions, a, i, **options):
|
|
1469
|
+
r"""
|
|
1470
|
+
Calculate the vacancy number `p_i^{(a)}` in ``self``.
|
|
1471
|
+
|
|
1472
|
+
This is a special implementation for type `A_{2n}^{(2)}`.
|
|
1473
|
+
|
|
1474
|
+
INPUT:
|
|
1475
|
+
|
|
1476
|
+
- ``partitions`` -- the list of rigged partitions we are using
|
|
1477
|
+
|
|
1478
|
+
- ``a`` -- the rigged partition index
|
|
1479
|
+
|
|
1480
|
+
- ``i`` -- the row length
|
|
1481
|
+
|
|
1482
|
+
TESTS::
|
|
1483
|
+
|
|
1484
|
+
sage: RC = RiggedConfigurations(['A', 4, 2], [[2, 1]])
|
|
1485
|
+
sage: elt = RC(partition_list=[[1], [2]])
|
|
1486
|
+
sage: RC._calc_vacancy_number(elt.nu(), 1, 2)
|
|
1487
|
+
0
|
|
1488
|
+
"""
|
|
1489
|
+
vac_num = 0
|
|
1490
|
+
if "B" in options:
|
|
1491
|
+
for tab in options["B"]:
|
|
1492
|
+
if len(tab) == self._rc_index[a]:
|
|
1493
|
+
vac_num += min(i, len(tab[0]))
|
|
1494
|
+
elif "L" in options:
|
|
1495
|
+
L = options["L"]
|
|
1496
|
+
if a in L:
|
|
1497
|
+
for kvp in L[a].items():
|
|
1498
|
+
vac_num += min(kvp[0], i) * kvp[1]
|
|
1499
|
+
elif "dims" in options:
|
|
1500
|
+
for dim in options["dims"]:
|
|
1501
|
+
if dim[0] == self._rc_index[a]:
|
|
1502
|
+
vac_num += min(dim[1], i)
|
|
1503
|
+
else:
|
|
1504
|
+
for dim in self.dims:
|
|
1505
|
+
if dim[0] == self._rc_index[a]:
|
|
1506
|
+
vac_num += min(dim[1], i)
|
|
1507
|
+
|
|
1508
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1509
|
+
if i == float('inf'):
|
|
1510
|
+
vac_num -= sum(self._cartan_matrix[a,b] * sum(nu) // gamma[b+1]
|
|
1511
|
+
for b, nu in enumerate(partitions))
|
|
1512
|
+
else:
|
|
1513
|
+
vac_num -= sum(self._cartan_matrix[a,b] * nu.get_num_cells_to_column(i) // gamma[b+1]
|
|
1514
|
+
for b, nu in enumerate(partitions))
|
|
1515
|
+
|
|
1516
|
+
return vac_num
|
|
1517
|
+
|
|
1518
|
+
def to_virtual(self, rc):
|
|
1519
|
+
"""
|
|
1520
|
+
Convert ``rc`` into a rigged configuration in the virtual crystal.
|
|
1521
|
+
|
|
1522
|
+
INPUT:
|
|
1523
|
+
|
|
1524
|
+
- ``rc`` -- a rigged configuration element
|
|
1525
|
+
|
|
1526
|
+
EXAMPLES::
|
|
1527
|
+
|
|
1528
|
+
sage: RC = RiggedConfigurations(['A',4,2], [[2,2]])
|
|
1529
|
+
sage: elt = RC(partition_list=[[1],[1]]); elt
|
|
1530
|
+
<BLANKLINE>
|
|
1531
|
+
-1[ ]-1
|
|
1532
|
+
<BLANKLINE>
|
|
1533
|
+
1[ ]1
|
|
1534
|
+
<BLANKLINE>
|
|
1535
|
+
sage: velt = RC.to_virtual(elt); velt
|
|
1536
|
+
<BLANKLINE>
|
|
1537
|
+
-1[ ]-1
|
|
1538
|
+
<BLANKLINE>
|
|
1539
|
+
2[ ]2
|
|
1540
|
+
<BLANKLINE>
|
|
1541
|
+
-1[ ]-1
|
|
1542
|
+
<BLANKLINE>
|
|
1543
|
+
sage: velt.parent()
|
|
1544
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 2), (2, 2))
|
|
1545
|
+
"""
|
|
1546
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1547
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1548
|
+
n = len(self.virtual._rc_index)
|
|
1549
|
+
partitions = [None] * n
|
|
1550
|
+
for a,rp in enumerate(rc):
|
|
1551
|
+
g = gamma[a+1]
|
|
1552
|
+
for i in sigma[a+1]:
|
|
1553
|
+
partitions[i-1] = RiggedPartition(list(rp._list),
|
|
1554
|
+
[rig_val*g for rig_val in rp.rigging],
|
|
1555
|
+
[vac_num*g for vac_num in rp.vacancy_numbers])
|
|
1556
|
+
return self.virtual.element_class(self.virtual, partitions, use_vacancy_numbers=True)
|
|
1557
|
+
|
|
1558
|
+
def from_virtual(self, vrc):
|
|
1559
|
+
"""
|
|
1560
|
+
Convert ``vrc`` in the virtual crystal into a rigged configuration of
|
|
1561
|
+
the original Cartan type.
|
|
1562
|
+
|
|
1563
|
+
INPUT:
|
|
1564
|
+
|
|
1565
|
+
- ``vrc`` -- a virtual rigged configuration element
|
|
1566
|
+
|
|
1567
|
+
EXAMPLES::
|
|
1568
|
+
|
|
1569
|
+
sage: RC = RiggedConfigurations(['A',4,2], [[2,2]])
|
|
1570
|
+
sage: elt = RC(partition_list=[[1],[1]])
|
|
1571
|
+
sage: velt = RC.to_virtual(elt)
|
|
1572
|
+
sage: ret = RC.from_virtual(velt); ret
|
|
1573
|
+
<BLANKLINE>
|
|
1574
|
+
-1[ ]-1
|
|
1575
|
+
<BLANKLINE>
|
|
1576
|
+
1[ ]1
|
|
1577
|
+
<BLANKLINE>
|
|
1578
|
+
sage: ret == elt
|
|
1579
|
+
True
|
|
1580
|
+
"""
|
|
1581
|
+
gamma = self._folded_ct.scaling_factors()
|
|
1582
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1583
|
+
n = len(self._rc_index)
|
|
1584
|
+
partitions = [None] * n
|
|
1585
|
+
# +/- 1 for indexing
|
|
1586
|
+
for a in range(n):
|
|
1587
|
+
rp = vrc[sigma[a+1][0] - 1]
|
|
1588
|
+
g = gamma[a+1]
|
|
1589
|
+
partitions[a] = RiggedPartition(list(rp._list),
|
|
1590
|
+
[rig_val//g for rig_val in rp.rigging],
|
|
1591
|
+
[vac_val//g for vac_val in rp.vacancy_numbers])
|
|
1592
|
+
return self.element_class(self, partitions, use_vacancy_numbers=True)
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
class RCTypeA2Dual(RCTypeA2Even):
|
|
1596
|
+
r"""
|
|
1597
|
+
Rigged configurations of type `A_{2n}^{(2)\dagger}`.
|
|
1598
|
+
|
|
1599
|
+
For more on rigged configurations, see :class:`RiggedConfigurations`.
|
|
1600
|
+
|
|
1601
|
+
EXAMPLES::
|
|
1602
|
+
|
|
1603
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,2],[1,1],[2,1]])
|
|
1604
|
+
sage: RC
|
|
1605
|
+
Rigged configurations of type ['BC', 2, 2]^* and factor(s) ((1, 2), (1, 1), (2, 1))
|
|
1606
|
+
sage: RC.cardinality()
|
|
1607
|
+
750
|
|
1608
|
+
sage: RC.virtual
|
|
1609
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 1), (2, 1))
|
|
1610
|
+
sage: RC = RiggedConfigurations(CartanType(['A',2,2]).dual(), [[1,1]])
|
|
1611
|
+
sage: RC.cardinality()
|
|
1612
|
+
3
|
|
1613
|
+
sage: RC = RiggedConfigurations(CartanType(['A',2,2]).dual(), [[1,2],[1,1]])
|
|
1614
|
+
sage: TestSuite(RC).run() # long time
|
|
1615
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[2,1]])
|
|
1616
|
+
sage: TestSuite(RC).run() # long time
|
|
1617
|
+
"""
|
|
1618
|
+
|
|
1619
|
+
def _calc_vacancy_number(self, partitions, a, i, **options):
|
|
1620
|
+
r"""
|
|
1621
|
+
Calculate the vacancy number `p_i^{(a)}` in ``self``. A special case
|
|
1622
|
+
is needed for the `n`-th partition for type `A_{2n}^{(2)\dagger}`.
|
|
1623
|
+
|
|
1624
|
+
INPUT:
|
|
1625
|
+
|
|
1626
|
+
- ``partitions`` -- the list of rigged partitions we are using
|
|
1627
|
+
|
|
1628
|
+
- ``a`` -- the rigged partition index
|
|
1629
|
+
|
|
1630
|
+
- ``i`` -- the row length
|
|
1631
|
+
|
|
1632
|
+
TESTS::
|
|
1633
|
+
|
|
1634
|
+
sage: RC = RiggedConfigurations(CartanType(['A', 6, 2]).dual(), [[2,1]])
|
|
1635
|
+
sage: elt = RC(partition_list=[[1], [2], [2]])
|
|
1636
|
+
sage: RC._calc_vacancy_number(elt.nu(), 0, 1)
|
|
1637
|
+
-1
|
|
1638
|
+
"""
|
|
1639
|
+
if a != len(self._rc_index) - 1:
|
|
1640
|
+
return RCTypeA2Even._calc_vacancy_number(self, partitions, a, i, **options)
|
|
1641
|
+
|
|
1642
|
+
vac_num = 0
|
|
1643
|
+
if "B" in options:
|
|
1644
|
+
for tab in options["B"]:
|
|
1645
|
+
if len(tab) == self._rc_index[a]:
|
|
1646
|
+
vac_num += min(i, len(tab[0]))
|
|
1647
|
+
elif "L" in options:
|
|
1648
|
+
L = options["L"]
|
|
1649
|
+
if a in L:
|
|
1650
|
+
for kvp in L[a].items():
|
|
1651
|
+
vac_num += min(kvp[0], i) * kvp[1]
|
|
1652
|
+
elif "dims" in options:
|
|
1653
|
+
for dim in options["dims"]:
|
|
1654
|
+
if dim[0] == self._rc_index[a]:
|
|
1655
|
+
vac_num += min(dim[1], i)
|
|
1656
|
+
else:
|
|
1657
|
+
for dim in self.dims:
|
|
1658
|
+
if dim[0] == self._rc_index[a]:
|
|
1659
|
+
vac_num += min(dim[1], i)
|
|
1660
|
+
|
|
1661
|
+
if i == float('inf'):
|
|
1662
|
+
vac_num -= sum(self._cartan_matrix[a,b] * sum(nu) / 2
|
|
1663
|
+
for b,nu in enumerate(partitions))
|
|
1664
|
+
else:
|
|
1665
|
+
vac_num -= sum(self._cartan_matrix[a,b] * nu.get_num_cells_to_column(i) / 2
|
|
1666
|
+
for b,nu in enumerate(partitions))
|
|
1667
|
+
|
|
1668
|
+
return vac_num
|
|
1669
|
+
|
|
1670
|
+
@lazy_attribute
|
|
1671
|
+
def module_generators(self):
|
|
1672
|
+
r"""
|
|
1673
|
+
Module generators for rigged configurations of type
|
|
1674
|
+
`A_{2n}^{(2)\dagger}`.
|
|
1675
|
+
|
|
1676
|
+
Iterate over the highest weight rigged configurations by moving
|
|
1677
|
+
through the
|
|
1678
|
+
:class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree`
|
|
1679
|
+
and then setting appropriate values of the partitions. This also
|
|
1680
|
+
skips rigged configurations where `P_i^{(n)} < 1` when `i` is odd.
|
|
1681
|
+
|
|
1682
|
+
EXAMPLES::
|
|
1683
|
+
|
|
1684
|
+
sage: RC = RiggedConfigurations(CartanType(['A', 4, 2]).dual(), [[1,1]])
|
|
1685
|
+
sage: for x in RC.module_generators: x
|
|
1686
|
+
<BLANKLINE>
|
|
1687
|
+
(/)
|
|
1688
|
+
<BLANKLINE>
|
|
1689
|
+
(/)
|
|
1690
|
+
<BLANKLINE>
|
|
1691
|
+
"""
|
|
1692
|
+
module_gens = []
|
|
1693
|
+
# This is for the non-simply-laced types
|
|
1694
|
+
vec_len = len(self.kleber_tree().root.up_root.to_vector())
|
|
1695
|
+
|
|
1696
|
+
for tree_node in self.kleber_tree():
|
|
1697
|
+
shapes = []
|
|
1698
|
+
cur = tree_node
|
|
1699
|
+
path_lambda = [cur.up_root.to_vector()] # Build the lambda values
|
|
1700
|
+
# Note that these are not same lambda as in the paper,
|
|
1701
|
+
# but a less computational version.
|
|
1702
|
+
while cur.parent_node is not None:
|
|
1703
|
+
path_lambda.insert(0, (cur.parent_node.up_root - cur.up_root).to_vector())
|
|
1704
|
+
cur = cur.parent_node
|
|
1705
|
+
|
|
1706
|
+
for a in range(vec_len):
|
|
1707
|
+
shapes.append([])
|
|
1708
|
+
for i, cur_lambda in enumerate(path_lambda):
|
|
1709
|
+
for j in range(cur_lambda[a]):
|
|
1710
|
+
shapes[-1].insert(0, i)
|
|
1711
|
+
|
|
1712
|
+
# We are not simply-laced, so convert from the virtual rigged configuration
|
|
1713
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1714
|
+
vindex = self.virtual._rc_index
|
|
1715
|
+
shapes = [shapes[vindex.index(sigma[a][0])] for a in self._rc_index]
|
|
1716
|
+
# Nothing more to do since gamma[i] == 1 for all i >= 1
|
|
1717
|
+
|
|
1718
|
+
# Start with a base to calculate the vacancy numbers
|
|
1719
|
+
# Make a copy just to be safe
|
|
1720
|
+
base = self.element_class(self, partition_list=shapes[:])
|
|
1721
|
+
|
|
1722
|
+
# Check the special condition of odd rows in the n-th partition
|
|
1723
|
+
invalid_RC = False
|
|
1724
|
+
for i in range(len(base[-1]._list)):
|
|
1725
|
+
if base[-1]._list[i] % 2 == 1 and base[-1].vacancy_numbers[i] < 1:
|
|
1726
|
+
invalid_RC = True
|
|
1727
|
+
break
|
|
1728
|
+
# If it is invalid, skip it
|
|
1729
|
+
if invalid_RC:
|
|
1730
|
+
continue
|
|
1731
|
+
|
|
1732
|
+
# Build out the blocks for the partition values
|
|
1733
|
+
vac_nums = []
|
|
1734
|
+
blocks = []
|
|
1735
|
+
L = []
|
|
1736
|
+
|
|
1737
|
+
for partition in base[:-1]:
|
|
1738
|
+
vac_nums.append(partition.vacancy_numbers)
|
|
1739
|
+
blocks.append([[]])
|
|
1740
|
+
|
|
1741
|
+
# If the partition is empty, there's nothing to do
|
|
1742
|
+
if len(partition) <= 0:
|
|
1743
|
+
L.append([[]])
|
|
1744
|
+
continue
|
|
1745
|
+
|
|
1746
|
+
# Setup the first block
|
|
1747
|
+
block_len = partition[0]
|
|
1748
|
+
for i, row_len in enumerate(partition):
|
|
1749
|
+
# If we've gone to a different sized block, then update the
|
|
1750
|
+
# values which change when moving to a new block size
|
|
1751
|
+
if block_len != row_len:
|
|
1752
|
+
blocks[-1].append([])
|
|
1753
|
+
block_len = row_len
|
|
1754
|
+
|
|
1755
|
+
blocks[-1][-1].append(partition.vacancy_numbers[i])
|
|
1756
|
+
|
|
1757
|
+
L2 = []
|
|
1758
|
+
for block in blocks[-1]:
|
|
1759
|
+
L2.append(IterableFunctionCall(self._block_iterator, block))
|
|
1760
|
+
L.append(itertools.product(*L2))
|
|
1761
|
+
|
|
1762
|
+
# Special case for the final tableau
|
|
1763
|
+
partition = base[-1]
|
|
1764
|
+
vac_nums.append(partition.vacancy_numbers)
|
|
1765
|
+
|
|
1766
|
+
# If the partition is empty, there's nothing to do
|
|
1767
|
+
if len(partition) <= 0:
|
|
1768
|
+
L.append([[]])
|
|
1769
|
+
else:
|
|
1770
|
+
# Setup the first block
|
|
1771
|
+
block_len = partition[0]
|
|
1772
|
+
blocks = [[]]
|
|
1773
|
+
odd_block = []
|
|
1774
|
+
for i, row_len in enumerate(partition):
|
|
1775
|
+
# If we've gone to a different sized block, then update the
|
|
1776
|
+
# values which change when moving to a new block size
|
|
1777
|
+
if block_len != row_len:
|
|
1778
|
+
blocks.append([])
|
|
1779
|
+
odd_block.append(block_len % 2 == 1)
|
|
1780
|
+
block_len = row_len
|
|
1781
|
+
|
|
1782
|
+
blocks[-1].append(partition.vacancy_numbers[i])
|
|
1783
|
+
odd_block.append(block_len % 2 == 1)
|
|
1784
|
+
|
|
1785
|
+
L2 = []
|
|
1786
|
+
for i, block in enumerate(blocks):
|
|
1787
|
+
if odd_block[i]:
|
|
1788
|
+
L2.append(IterableFunctionCall(self._block_iterator_n_odd, block))
|
|
1789
|
+
else:
|
|
1790
|
+
L2.append(IterableFunctionCall(self._block_iterator, block))
|
|
1791
|
+
L.append(itertools.product(*L2))
|
|
1792
|
+
|
|
1793
|
+
C = itertools.product(*L)
|
|
1794
|
+
for curBlocks in C:
|
|
1795
|
+
module_gens.append( self.element_class(self, KT_constructor=[shapes[:],
|
|
1796
|
+
self._blocks_to_values(curBlocks[:]), vac_nums[:]]) )
|
|
1797
|
+
|
|
1798
|
+
return tuple(module_gens)
|
|
1799
|
+
|
|
1800
|
+
def _block_iterator_n_odd(self, container):
|
|
1801
|
+
r"""
|
|
1802
|
+
Iterate over all possible riggings for a block of odd length in the
|
|
1803
|
+
`n`-th rigged partition for type `A_{2n}^{(2)\dagger}`.
|
|
1804
|
+
|
|
1805
|
+
Helper iterator which iterates over all possible partitions of
|
|
1806
|
+
`\frac{2k+1}{2}` sizes contained within the container.
|
|
1807
|
+
|
|
1808
|
+
INPUT:
|
|
1809
|
+
|
|
1810
|
+
- ``container`` -- list the widths of the rows of the container
|
|
1811
|
+
|
|
1812
|
+
TESTS::
|
|
1813
|
+
|
|
1814
|
+
sage: RC = RiggedConfigurations(CartanType(['A', 4, 2]).dual(), [[2, 2]])
|
|
1815
|
+
sage: for x in RC._block_iterator_n_odd([]): x
|
|
1816
|
+
[]
|
|
1817
|
+
sage: for x in RC._block_iterator_n_odd([2,2]): x
|
|
1818
|
+
[1/2, 1/2]
|
|
1819
|
+
[3/2, 1/2]
|
|
1820
|
+
[3/2, 3/2]
|
|
1821
|
+
"""
|
|
1822
|
+
if len(container) == 0:
|
|
1823
|
+
yield []
|
|
1824
|
+
return
|
|
1825
|
+
|
|
1826
|
+
pos = 0
|
|
1827
|
+
length = len(container)
|
|
1828
|
+
ret_part = [-1] * length
|
|
1829
|
+
while pos >= 0:
|
|
1830
|
+
ret_part[pos] += 2
|
|
1831
|
+
|
|
1832
|
+
if ret_part[pos] > container[pos]*2 or (pos != 0 and ret_part[pos] > ret_part[pos - 1]):
|
|
1833
|
+
ret_part[pos] = -1
|
|
1834
|
+
pos -= 1
|
|
1835
|
+
else:
|
|
1836
|
+
pos += 1
|
|
1837
|
+
|
|
1838
|
+
if pos == length:
|
|
1839
|
+
yield [QQ(n) / QQ(2) for n in ret_part]
|
|
1840
|
+
pos -= 1
|
|
1841
|
+
|
|
1842
|
+
def to_virtual(self, rc):
|
|
1843
|
+
"""
|
|
1844
|
+
Convert ``rc`` into a rigged configuration in the virtual crystal.
|
|
1845
|
+
|
|
1846
|
+
INPUT:
|
|
1847
|
+
|
|
1848
|
+
- ``rc`` -- a rigged configuration element
|
|
1849
|
+
|
|
1850
|
+
EXAMPLES::
|
|
1851
|
+
|
|
1852
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[2,2]])
|
|
1853
|
+
sage: elt = RC(partition_list=[[1],[1]]); elt
|
|
1854
|
+
<BLANKLINE>
|
|
1855
|
+
-1[ ]-1
|
|
1856
|
+
<BLANKLINE>
|
|
1857
|
+
1[ ]1
|
|
1858
|
+
<BLANKLINE>
|
|
1859
|
+
sage: velt = RC.to_virtual(elt); velt
|
|
1860
|
+
<BLANKLINE>
|
|
1861
|
+
-1[ ]-1
|
|
1862
|
+
<BLANKLINE>
|
|
1863
|
+
2[ ]2
|
|
1864
|
+
<BLANKLINE>
|
|
1865
|
+
-1[ ]-1
|
|
1866
|
+
<BLANKLINE>
|
|
1867
|
+
sage: velt.parent()
|
|
1868
|
+
Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 2), (2, 2))
|
|
1869
|
+
"""
|
|
1870
|
+
gammatilde = list(self._folded_ct.scaling_factors())
|
|
1871
|
+
gammatilde[-1] = 2
|
|
1872
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1873
|
+
n = len(self.virtual._rc_index)
|
|
1874
|
+
partitions = [None] * n
|
|
1875
|
+
for a,rp in enumerate(rc):
|
|
1876
|
+
g = gammatilde[a+1]
|
|
1877
|
+
for i in sigma[a+1]:
|
|
1878
|
+
partitions[i-1] = RiggedPartition(list(rp._list),
|
|
1879
|
+
[rig_val*g for rig_val in rp.rigging])
|
|
1880
|
+
return self.virtual.element_class(self.virtual, partitions)
|
|
1881
|
+
|
|
1882
|
+
def from_virtual(self, vrc):
|
|
1883
|
+
"""
|
|
1884
|
+
Convert ``vrc`` in the virtual crystal into a rigged configuration of
|
|
1885
|
+
the original Cartan type.
|
|
1886
|
+
|
|
1887
|
+
INPUT:
|
|
1888
|
+
|
|
1889
|
+
- ``vrc`` -- a virtual rigged configuration element
|
|
1890
|
+
|
|
1891
|
+
EXAMPLES::
|
|
1892
|
+
|
|
1893
|
+
sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[2,2]])
|
|
1894
|
+
sage: elt = RC(partition_list=[[1],[1]])
|
|
1895
|
+
sage: velt = RC.to_virtual(elt)
|
|
1896
|
+
sage: ret = RC.from_virtual(velt); ret
|
|
1897
|
+
<BLANKLINE>
|
|
1898
|
+
-1[ ]-1
|
|
1899
|
+
<BLANKLINE>
|
|
1900
|
+
1[ ]1
|
|
1901
|
+
<BLANKLINE>
|
|
1902
|
+
sage: ret == elt
|
|
1903
|
+
True
|
|
1904
|
+
"""
|
|
1905
|
+
gammatilde = list(self._folded_ct.scaling_factors())
|
|
1906
|
+
gammatilde[-1] = QQ(2)
|
|
1907
|
+
sigma = self._folded_ct.folding_orbit()
|
|
1908
|
+
n = len(self._rc_index)
|
|
1909
|
+
partitions = [None] * n
|
|
1910
|
+
# +/- 1 for indexing
|
|
1911
|
+
for a in range(n):
|
|
1912
|
+
rp = vrc[sigma[a+1][0] - 1]
|
|
1913
|
+
g = gammatilde[a+1]
|
|
1914
|
+
partitions[a] = RiggedPartition(list(rp._list),
|
|
1915
|
+
[rig_val/g for rig_val in rp.rigging])
|
|
1916
|
+
return self.element_class(self, partitions)
|
|
1917
|
+
|
|
1918
|
+
Element = KRRCTypeA2DualElement
|