passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.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/DELVEWHEEL +2 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +401 -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-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
- passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +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 +44 -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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +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.cp314t-win_amd64.pyd +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
|
@@ -0,0 +1,900 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.graphs sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Bijection classes for type `B_n^{(1)}`
|
|
5
|
+
|
|
6
|
+
Part of the (internal) classes which runs the bijection between rigged
|
|
7
|
+
configurations and KR tableaux of type `B_n^{(1)}`.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Travis Scrimshaw (2012-12-21): Initial version
|
|
12
|
+
|
|
13
|
+
TESTS::
|
|
14
|
+
|
|
15
|
+
sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2,1]])
|
|
16
|
+
sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB
|
|
17
|
+
sage: bijection = KRTToRCBijectionTypeB(KRT(pathlist=[[-1,2]]))
|
|
18
|
+
sage: TestSuite(bijection).run()
|
|
19
|
+
sage: RC = RiggedConfigurations(['B', 3, 1], [[2, 1]])
|
|
20
|
+
sage: from sage.combinat.rigged_configurations.bij_type_B import RCToKRTBijectionTypeB
|
|
21
|
+
sage: bijection = RCToKRTBijectionTypeB(RC(partition_list=[[],[],[]]))
|
|
22
|
+
sage: TestSuite(bijection).run()
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# ****************************************************************************
|
|
26
|
+
# Copyright (C) 2012 Travis Scrimshaw <tscrim@ucdavis.edu>
|
|
27
|
+
#
|
|
28
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
29
|
+
#
|
|
30
|
+
# This code is distributed in the hope that it will be useful,
|
|
31
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
32
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
33
|
+
# General Public License for more details.
|
|
34
|
+
#
|
|
35
|
+
# The full text of the GPL is available at:
|
|
36
|
+
#
|
|
37
|
+
# https://www.gnu.org/licenses/
|
|
38
|
+
# ****************************************************************************
|
|
39
|
+
|
|
40
|
+
from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA
|
|
41
|
+
from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC
|
|
42
|
+
from sage.combinat.rigged_configurations.bij_type_C import RCToKRTBijectionTypeC
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class KRTToRCBijectionTypeB(KRTToRCBijectionTypeC):
|
|
46
|
+
r"""
|
|
47
|
+
Specific implementation of the bijection from KR tableaux to rigged
|
|
48
|
+
configurations for type `B_n^{(1)}`.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def run(self, verbose=False):
|
|
52
|
+
"""
|
|
53
|
+
Run the bijection from a tensor product of KR tableaux to a rigged
|
|
54
|
+
configuration.
|
|
55
|
+
|
|
56
|
+
INPUT:
|
|
57
|
+
|
|
58
|
+
- ``tp_krt`` -- a tensor product of KR tableaux
|
|
59
|
+
|
|
60
|
+
- ``verbose`` -- (default: ``False``) display each step in the
|
|
61
|
+
bijection
|
|
62
|
+
|
|
63
|
+
EXAMPLES::
|
|
64
|
+
|
|
65
|
+
sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB
|
|
66
|
+
sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2, 1]])
|
|
67
|
+
sage: KRTToRCBijectionTypeB(KRT(pathlist=[[0,3]])).run()
|
|
68
|
+
<BLANKLINE>
|
|
69
|
+
0[ ]0
|
|
70
|
+
<BLANKLINE>
|
|
71
|
+
-1[ ]-1
|
|
72
|
+
-1[ ]-1
|
|
73
|
+
<BLANKLINE>
|
|
74
|
+
0[]0
|
|
75
|
+
<BLANKLINE>
|
|
76
|
+
sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[3, 1]])
|
|
77
|
+
sage: KRTToRCBijectionTypeB(KRT(pathlist=[[-2,3,1]])).run()
|
|
78
|
+
<BLANKLINE>
|
|
79
|
+
(/)
|
|
80
|
+
<BLANKLINE>
|
|
81
|
+
-1[ ]-1
|
|
82
|
+
<BLANKLINE>
|
|
83
|
+
0[]0
|
|
84
|
+
<BLANKLINE>
|
|
85
|
+
|
|
86
|
+
TESTS:
|
|
87
|
+
|
|
88
|
+
Check that :issue:`19384` is fixed::
|
|
89
|
+
|
|
90
|
+
sage: RC = RiggedConfigurations(['B',3,1], [[3,1],[3,1]])
|
|
91
|
+
sage: RC._test_bijection()
|
|
92
|
+
sage: RC = RiggedConfigurations(['B',3,1], [[1,1],[3,1],[1,1]])
|
|
93
|
+
sage: RC._test_bijection()
|
|
94
|
+
"""
|
|
95
|
+
if verbose:
|
|
96
|
+
from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \
|
|
97
|
+
import TensorProductOfKirillovReshetikhinTableauxElement
|
|
98
|
+
|
|
99
|
+
for cur_crystal in reversed(self.tp_krt):
|
|
100
|
+
r = cur_crystal.parent().r()
|
|
101
|
+
|
|
102
|
+
# Check if it is a spinor
|
|
103
|
+
if r == self.n:
|
|
104
|
+
# Perform the spinor bijection by converting to type A_{2n-1}^{(2)}
|
|
105
|
+
# doing the bijection there and pulling back
|
|
106
|
+
from sage.combinat.rigged_configurations.bij_type_A2_odd import KRTToRCBijectionTypeA2Odd
|
|
107
|
+
from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import TensorProductOfKirillovReshetikhinTableaux
|
|
108
|
+
from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition
|
|
109
|
+
|
|
110
|
+
if verbose:
|
|
111
|
+
print("====================")
|
|
112
|
+
if len(self.cur_path) == 0:
|
|
113
|
+
print(repr([])) # Special case for displaying when the rightmost factor is a spinor
|
|
114
|
+
else:
|
|
115
|
+
print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path)))
|
|
116
|
+
print("--------------------")
|
|
117
|
+
print(repr(self.ret_rig_con))
|
|
118
|
+
print("--------------------\n")
|
|
119
|
+
print("Applying doubling map")
|
|
120
|
+
|
|
121
|
+
# Convert to a type A_{2n-1}^{(2)} RC
|
|
122
|
+
dims = self.cur_dims[:]
|
|
123
|
+
dims.insert(0, [r, cur_crystal.parent().s()])
|
|
124
|
+
KRT = TensorProductOfKirillovReshetikhinTableaux(['A', 2*self.n-1, 2], dims)
|
|
125
|
+
# Convert the n-th partition into a regular rigged partition
|
|
126
|
+
self.ret_rig_con[-1] = RiggedPartition(self.ret_rig_con[-1]._list,
|
|
127
|
+
self.ret_rig_con[-1].rigging,
|
|
128
|
+
self.ret_rig_con[-1].vacancy_numbers)
|
|
129
|
+
# Placeholder element
|
|
130
|
+
elt = KRT(*[C.module_generators[0] for C in KRT.crystals])
|
|
131
|
+
bij = KRTToRCBijectionTypeA2Odd(elt)
|
|
132
|
+
bij.ret_rig_con = KRT.rigged_configurations()(*self.ret_rig_con, use_vacancy_numbers=True)
|
|
133
|
+
bij.cur_path = self.cur_path
|
|
134
|
+
bij.cur_dims = self.cur_dims
|
|
135
|
+
for i in range(len(self.cur_dims)):
|
|
136
|
+
if bij.cur_dims[i][0] != self.n:
|
|
137
|
+
bij.cur_dims[i][1] *= 2
|
|
138
|
+
for i in range(self.n-1):
|
|
139
|
+
for j in range(len(bij.ret_rig_con[i])):
|
|
140
|
+
bij.ret_rig_con[i]._list[j] *= 2
|
|
141
|
+
bij.ret_rig_con[i].rigging[j] *= 2
|
|
142
|
+
bij.ret_rig_con[i].vacancy_numbers[j] *= 2
|
|
143
|
+
|
|
144
|
+
# Perform the type A_{2n-1}^{(2)} bijection
|
|
145
|
+
r = cur_crystal.parent().r()
|
|
146
|
+
# Iterate through the columns
|
|
147
|
+
for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))):
|
|
148
|
+
bij.cur_path.insert(0, []) # Prepend an empty list
|
|
149
|
+
bij.cur_dims.insert(0, [0, 1])
|
|
150
|
+
|
|
151
|
+
# Note that we do not need to worry about iterating over columns
|
|
152
|
+
# (see previous note about the data structure).
|
|
153
|
+
for letter in reversed(cur_column):
|
|
154
|
+
bij.cur_dims[0][0] += 1
|
|
155
|
+
val = letter.value # Convert from a CrystalOfLetter to an Integer
|
|
156
|
+
|
|
157
|
+
if verbose:
|
|
158
|
+
print("====================")
|
|
159
|
+
print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), bij.cur_path)))
|
|
160
|
+
print("--------------------")
|
|
161
|
+
print(repr(bij.ret_rig_con))
|
|
162
|
+
print("--------------------\n")
|
|
163
|
+
|
|
164
|
+
# Build the next state
|
|
165
|
+
bij.cur_path[0].insert(0, [letter]) # Prepend the value
|
|
166
|
+
bij.next_state(val)
|
|
167
|
+
|
|
168
|
+
# If we've split off a column, we need to merge the current column
|
|
169
|
+
# to the current crystal tableau
|
|
170
|
+
if col_number > 0:
|
|
171
|
+
for i, letter_singleton in enumerate(self.cur_path[0]):
|
|
172
|
+
bij.cur_path[1][i].insert(0, letter_singleton[0])
|
|
173
|
+
bij.cur_dims[1][1] += 1
|
|
174
|
+
bij.cur_path.pop(0)
|
|
175
|
+
bij.cur_dims.pop(0)
|
|
176
|
+
|
|
177
|
+
# And perform the inverse column splitting map on the RC
|
|
178
|
+
for a in range(self.n):
|
|
179
|
+
bij._update_vacancy_nums(a)
|
|
180
|
+
|
|
181
|
+
if verbose:
|
|
182
|
+
print("====================")
|
|
183
|
+
print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), bij.cur_path)))
|
|
184
|
+
print("--------------------")
|
|
185
|
+
print(repr(bij.ret_rig_con))
|
|
186
|
+
print("--------------------\n")
|
|
187
|
+
print("Applying halving map")
|
|
188
|
+
|
|
189
|
+
# Convert back to a type B_n^{(1)}
|
|
190
|
+
for i in range(len(self.cur_dims)):
|
|
191
|
+
if bij.cur_dims[i][0] != self.n:
|
|
192
|
+
bij.cur_dims[i][1] //= 2
|
|
193
|
+
for i in range(self.n-1):
|
|
194
|
+
for j in range(len(bij.ret_rig_con[i])):
|
|
195
|
+
bij.ret_rig_con[i]._list[j] //= 2
|
|
196
|
+
bij.ret_rig_con[i].rigging[j] //= 2
|
|
197
|
+
bij.ret_rig_con[i].vacancy_numbers[j] //= 2
|
|
198
|
+
self.ret_rig_con = self.tp_krt.parent().rigged_configurations()(*bij.ret_rig_con, use_vacancy_numbers=True)
|
|
199
|
+
# Make it mutable so we don't have to keep making copies, at the
|
|
200
|
+
# end of the bijection, we will make it immutable again
|
|
201
|
+
self.ret_rig_con._set_mutable()
|
|
202
|
+
else:
|
|
203
|
+
# Perform the regular type B_n^{(1)} bijection
|
|
204
|
+
# Iterate through the columns
|
|
205
|
+
for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))):
|
|
206
|
+
self.cur_path.insert(0, []) # Prepend an empty list
|
|
207
|
+
self.cur_dims.insert(0, [0, 1])
|
|
208
|
+
|
|
209
|
+
# Note that we do not need to worry about iterating over columns
|
|
210
|
+
# (see previous note about the data structure).
|
|
211
|
+
for letter in reversed(cur_column):
|
|
212
|
+
self.cur_dims[0][0] += 1
|
|
213
|
+
val = letter.value # Convert from a CrystalOfLetter to an Integer
|
|
214
|
+
|
|
215
|
+
if verbose:
|
|
216
|
+
print("====================")
|
|
217
|
+
print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path)))
|
|
218
|
+
print("--------------------")
|
|
219
|
+
print(repr(self.ret_rig_con))
|
|
220
|
+
print("--------------------\n")
|
|
221
|
+
|
|
222
|
+
# Build the next state
|
|
223
|
+
self.cur_path[0].insert(0, [letter]) # Prepend the value
|
|
224
|
+
self.next_state(val)
|
|
225
|
+
|
|
226
|
+
# If we've split off a column, we need to merge the current column
|
|
227
|
+
# to the current crystal tableau
|
|
228
|
+
if col_number > 0:
|
|
229
|
+
if verbose:
|
|
230
|
+
print("====================")
|
|
231
|
+
print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path)))
|
|
232
|
+
print("--------------------")
|
|
233
|
+
print(repr(self.ret_rig_con))
|
|
234
|
+
print("--------------------\n")
|
|
235
|
+
print("Applying column merge")
|
|
236
|
+
|
|
237
|
+
for i, letter_singleton in enumerate(self.cur_path[0]):
|
|
238
|
+
self.cur_path[1][i].insert(0, letter_singleton[0])
|
|
239
|
+
self.cur_dims[1][1] += 1
|
|
240
|
+
self.cur_path.pop(0)
|
|
241
|
+
self.cur_dims.pop(0)
|
|
242
|
+
|
|
243
|
+
# And perform the inverse column splitting map on the RC
|
|
244
|
+
for a in range(self.n):
|
|
245
|
+
self._update_vacancy_nums(a)
|
|
246
|
+
self.ret_rig_con.set_immutable() # Return it to immutable
|
|
247
|
+
return self.ret_rig_con
|
|
248
|
+
|
|
249
|
+
def next_state(self, val):
|
|
250
|
+
r"""
|
|
251
|
+
Build the next state for type `B_n^{(1)}`.
|
|
252
|
+
|
|
253
|
+
TESTS::
|
|
254
|
+
|
|
255
|
+
sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['B', 3, 1], [[2,1]])
|
|
256
|
+
sage: from sage.combinat.rigged_configurations.bij_type_B import KRTToRCBijectionTypeB
|
|
257
|
+
sage: bijection = KRTToRCBijectionTypeB(KRT(pathlist=[[-1,2]]))
|
|
258
|
+
sage: bijection.cur_path.insert(0, [])
|
|
259
|
+
sage: bijection.cur_dims.insert(0, [0, 1])
|
|
260
|
+
sage: bijection.cur_path[0].insert(0, [3])
|
|
261
|
+
sage: bijection.next_state(3)
|
|
262
|
+
"""
|
|
263
|
+
n = self.n
|
|
264
|
+
tableau_height = len(self.cur_path[0]) - 1
|
|
265
|
+
|
|
266
|
+
# If it is a regular value, we follow the A_n rules
|
|
267
|
+
if val > 0:
|
|
268
|
+
KRTToRCBijectionTypeA.next_state(self, val)
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
pos_val = -val
|
|
272
|
+
|
|
273
|
+
# Special case for 0
|
|
274
|
+
if pos_val == 0:
|
|
275
|
+
if len(self.ret_rig_con[pos_val - 1]) > 0:
|
|
276
|
+
max_width = self.ret_rig_con[n-1][0]
|
|
277
|
+
else:
|
|
278
|
+
max_width = 1
|
|
279
|
+
max_width = self.ret_rig_con[n-1].insert_cell(max_width)
|
|
280
|
+
width_n = max_width + 1
|
|
281
|
+
max_width = max_width // 2
|
|
282
|
+
|
|
283
|
+
# Check to see if we need to make the new string quasi-singular
|
|
284
|
+
if tableau_height != n-1:
|
|
285
|
+
max_width = self.ret_rig_con[n-2].insert_cell(max_width)
|
|
286
|
+
else:
|
|
287
|
+
max_width = -1
|
|
288
|
+
self._update_vacancy_nums(n - 1)
|
|
289
|
+
self._update_partition_values(n - 1)
|
|
290
|
+
|
|
291
|
+
# Check if we need to make the new string at n quasi-singular
|
|
292
|
+
p = self.ret_rig_con[n-1]
|
|
293
|
+
num_rows = len(p)
|
|
294
|
+
# Note that max width is 1 less than the corresponding string length
|
|
295
|
+
if max_width*2 + 1 != width_n:
|
|
296
|
+
for i in range(num_rows):
|
|
297
|
+
if p._list[i] == width_n:
|
|
298
|
+
j = i+1
|
|
299
|
+
while j < num_rows and p._list[j] == width_n \
|
|
300
|
+
and p.vacancy_numbers[j] == p.rigging[j]:
|
|
301
|
+
j += 1
|
|
302
|
+
p.rigging[j-1] -= 1
|
|
303
|
+
break
|
|
304
|
+
|
|
305
|
+
# Follow regular A_n rules
|
|
306
|
+
for a in reversed(range(tableau_height, n-2)):
|
|
307
|
+
max_width = self.ret_rig_con[a].insert_cell(max_width)
|
|
308
|
+
self._update_vacancy_nums(a + 1)
|
|
309
|
+
self._update_partition_values(a + 1)
|
|
310
|
+
self._update_vacancy_nums(tableau_height)
|
|
311
|
+
self._update_partition_values(tableau_height)
|
|
312
|
+
if tableau_height > 0:
|
|
313
|
+
self._update_vacancy_nums(tableau_height-1)
|
|
314
|
+
self._update_partition_values(tableau_height-1)
|
|
315
|
+
return
|
|
316
|
+
|
|
317
|
+
# Always add a cell to the first singular value in the first
|
|
318
|
+
# tableau we are updating.
|
|
319
|
+
if len(self.ret_rig_con[pos_val - 1]) > 0:
|
|
320
|
+
max_width = self.ret_rig_con[pos_val - 1][0] + 1
|
|
321
|
+
else:
|
|
322
|
+
max_width = 0
|
|
323
|
+
|
|
324
|
+
# Add cells similar to type A_n but we move to the right until n
|
|
325
|
+
for a in range(pos_val - 1, n - 1):
|
|
326
|
+
max_width = self.ret_rig_con[a].insert_cell(max_width)
|
|
327
|
+
|
|
328
|
+
# Handle the special behavior at n
|
|
329
|
+
if pos_val != n:
|
|
330
|
+
max_width = max_width * 2
|
|
331
|
+
|
|
332
|
+
# Find either the quasi-singular string and the next largest singular,
|
|
333
|
+
# the largest singular string if smaller than the max width
|
|
334
|
+
# or the two largest singular strings
|
|
335
|
+
singular_max_width = False
|
|
336
|
+
case_QS = False
|
|
337
|
+
# Note, case_QS and singular_max_width will never both be True
|
|
338
|
+
p = self.ret_rig_con[n-1]
|
|
339
|
+
num_rows = len(p)
|
|
340
|
+
width_n = 0
|
|
341
|
+
for i in range(num_rows + 1):
|
|
342
|
+
if i == num_rows:
|
|
343
|
+
if case_QS:
|
|
344
|
+
# If we are in case (QS), we will be adding a box
|
|
345
|
+
p._list.append(1)
|
|
346
|
+
p.vacancy_numbers.append(None)
|
|
347
|
+
p.rigging.append(None)
|
|
348
|
+
width_n = 1
|
|
349
|
+
max_width = 0
|
|
350
|
+
elif not singular_max_width:
|
|
351
|
+
# If we have not found a (quasi)singular string, we must add 2 boxes
|
|
352
|
+
# Go through our partition until we find a length of greater than 2
|
|
353
|
+
j = len(p._list) - 1
|
|
354
|
+
while j >= 0 and p._list[j] <= 2:
|
|
355
|
+
j -= 1
|
|
356
|
+
p._list.insert(j+1, 2)
|
|
357
|
+
p.vacancy_numbers.insert(j+1, None)
|
|
358
|
+
p.rigging.insert(j+1, None)
|
|
359
|
+
max_width = 0
|
|
360
|
+
break
|
|
361
|
+
elif p.vacancy_numbers[i] == p.rigging[i]:
|
|
362
|
+
if p._list[i] < max_width:
|
|
363
|
+
if singular_max_width:
|
|
364
|
+
width_n = p._list[i]
|
|
365
|
+
break
|
|
366
|
+
|
|
367
|
+
max_width = p._list[i]
|
|
368
|
+
if case_QS:
|
|
369
|
+
p._list[i] += 1
|
|
370
|
+
p.rigging[i] = None
|
|
371
|
+
width_n = max_width + 1
|
|
372
|
+
else:
|
|
373
|
+
# Add 2 boxes
|
|
374
|
+
j = i - 1
|
|
375
|
+
while j >= 0 and p._list[j] <= max_width + 2:
|
|
376
|
+
p.rigging[j+1] = p.rigging[j] # Shuffle it along
|
|
377
|
+
j -= 1
|
|
378
|
+
p._list.pop(i)
|
|
379
|
+
p._list.insert(j+1, max_width + 2)
|
|
380
|
+
p.rigging[j+1] = None
|
|
381
|
+
break
|
|
382
|
+
|
|
383
|
+
if p._list[i] == max_width and not singular_max_width:
|
|
384
|
+
p._list[i] += 1 # We always at least add a box to the first singular value
|
|
385
|
+
p.rigging[i] = None
|
|
386
|
+
if case_QS:
|
|
387
|
+
width_n = p._list[i]
|
|
388
|
+
break
|
|
389
|
+
singular_max_width = True
|
|
390
|
+
elif p._list[i] == max_width + 1 and not case_QS:
|
|
391
|
+
# If we can't add 2 boxes, we must be in case (QS)
|
|
392
|
+
p._list[i] += 1
|
|
393
|
+
p.rigging[i] = None
|
|
394
|
+
width_n = max_width
|
|
395
|
+
case_QS = True
|
|
396
|
+
elif p.vacancy_numbers[i] - 1 == p.rigging[i] and not case_QS and not singular_max_width and p._list[i] <= max_width:
|
|
397
|
+
case_QS = True
|
|
398
|
+
max_width = p._list[i]
|
|
399
|
+
p._list[i] += 1
|
|
400
|
+
p.rigging[i] = None
|
|
401
|
+
|
|
402
|
+
if singular_max_width:
|
|
403
|
+
# There are 2 possibilities, case (S) and case (QS), we might need
|
|
404
|
+
# to attempt both
|
|
405
|
+
# Make a *deep* copy of the element
|
|
406
|
+
cp = self.ret_rig_con.__copy__()
|
|
407
|
+
for i, rp in enumerate(cp):
|
|
408
|
+
cp[i] = rp._clone()
|
|
409
|
+
# We attempt case (S) first
|
|
410
|
+
self._insert_cell_case_S(p)
|
|
411
|
+
|
|
412
|
+
max_width = max_width // 2
|
|
413
|
+
|
|
414
|
+
# We need to do the next partition in order to determine the step at n
|
|
415
|
+
if tableau_height != n-1:
|
|
416
|
+
max_width = self.ret_rig_con[n-2].insert_cell(max_width)
|
|
417
|
+
else:
|
|
418
|
+
max_width = -1
|
|
419
|
+
|
|
420
|
+
self._update_vacancy_nums(n - 1)
|
|
421
|
+
self._update_partition_values(n - 1)
|
|
422
|
+
|
|
423
|
+
# If we need to make the smaller added string quasisingular
|
|
424
|
+
# Note that max width is 1 less than the corresponding string length
|
|
425
|
+
if case_QS and max_width*2 + 1 != width_n:
|
|
426
|
+
for i in range(num_rows):
|
|
427
|
+
if p._list[i] == width_n:
|
|
428
|
+
j = i+1
|
|
429
|
+
while j < num_rows and p._list[j] == width_n \
|
|
430
|
+
and p.vacancy_numbers[j] == p.rigging[j]:
|
|
431
|
+
j += 1
|
|
432
|
+
p.rigging[j-1] -= 1
|
|
433
|
+
break
|
|
434
|
+
|
|
435
|
+
# Continue back following the regular A_n rules
|
|
436
|
+
for a in reversed(range(tableau_height, n - 2)):
|
|
437
|
+
max_width = self.ret_rig_con[a].insert_cell(max_width)
|
|
438
|
+
self._update_vacancy_nums(a + 1)
|
|
439
|
+
self._update_partition_values(a + 1)
|
|
440
|
+
|
|
441
|
+
# Update the final rigged partitions
|
|
442
|
+
if tableau_height < n:
|
|
443
|
+
self._update_vacancy_nums(tableau_height)
|
|
444
|
+
self._update_partition_values(tableau_height)
|
|
445
|
+
|
|
446
|
+
assert pos_val > 0
|
|
447
|
+
if pos_val <= tableau_height:
|
|
448
|
+
for a in range(pos_val-1, tableau_height):
|
|
449
|
+
self._update_vacancy_nums(a)
|
|
450
|
+
self._update_partition_values(a)
|
|
451
|
+
if pos_val > 1:
|
|
452
|
+
self._update_vacancy_nums(pos_val - 2)
|
|
453
|
+
self._update_partition_values(pos_val - 2)
|
|
454
|
+
elif tableau_height > 0:
|
|
455
|
+
self._update_vacancy_nums(tableau_height - 1)
|
|
456
|
+
self._update_partition_values(tableau_height - 1)
|
|
457
|
+
|
|
458
|
+
if singular_max_width:
|
|
459
|
+
try:
|
|
460
|
+
self.ret_rig_con.check()
|
|
461
|
+
except Exception:
|
|
462
|
+
self.other_outcome(cp, pos_val, width_n)
|
|
463
|
+
|
|
464
|
+
def other_outcome(self, rc, pos_val, width_n):
|
|
465
|
+
r"""
|
|
466
|
+
Do the other case `(QS)` possibility.
|
|
467
|
+
|
|
468
|
+
This arises from the ambiguity when we found a singular string at the
|
|
469
|
+
max width in `\nu^{(n)}`. We had first attempted case `(S)`, and if
|
|
470
|
+
that resulted in an invalid rigged configuration, we now
|
|
471
|
+
finish the bijection using case `(QS)`.
|
|
472
|
+
|
|
473
|
+
EXAMPLES::
|
|
474
|
+
|
|
475
|
+
sage: RC = RiggedConfigurations(['B',3,1], [[2,1],[1,2]])
|
|
476
|
+
sage: rc = RC(partition_list=[[2,1], [2,1,1], [5,1]])
|
|
477
|
+
sage: t = rc.to_tensor_product_of_kirillov_reshetikhin_tableaux()
|
|
478
|
+
sage: t.to_rigged_configuration() == rc # indirect doctest
|
|
479
|
+
True
|
|
480
|
+
"""
|
|
481
|
+
n = self.n
|
|
482
|
+
tableau_height = len(self.cur_path[0]) - 1
|
|
483
|
+
self.ret_rig_con = rc
|
|
484
|
+
|
|
485
|
+
# We need to do the next partition in order to determine the step at n
|
|
486
|
+
max_width = self.ret_rig_con[n-2].insert_cell(width_n // 2)
|
|
487
|
+
|
|
488
|
+
# We now attempt case (QS)
|
|
489
|
+
case_QS = False
|
|
490
|
+
p = self.ret_rig_con[n-1]
|
|
491
|
+
num_rows = len(p)
|
|
492
|
+
for i in range(len(p._list)):
|
|
493
|
+
if p._list[i] == width_n:
|
|
494
|
+
p._list[i] += 1
|
|
495
|
+
p.rigging[i] = None
|
|
496
|
+
case_QS = True
|
|
497
|
+
break
|
|
498
|
+
if not case_QS: # we have not added a box yet
|
|
499
|
+
p._list.append(1)
|
|
500
|
+
p.rigging.append(None)
|
|
501
|
+
p.vacancy_numbers.append(None)
|
|
502
|
+
case_QS = True
|
|
503
|
+
width_n += 1
|
|
504
|
+
|
|
505
|
+
self._update_vacancy_nums(n - 1)
|
|
506
|
+
self._update_partition_values(n - 1)
|
|
507
|
+
|
|
508
|
+
# If we need to make the smaller added string quasisingular
|
|
509
|
+
# Note that max width is 1 less than the corresponding string length
|
|
510
|
+
if case_QS and max_width*2 + 1 != width_n:
|
|
511
|
+
for i in range(num_rows):
|
|
512
|
+
if p._list[i] == width_n:
|
|
513
|
+
j = i+1
|
|
514
|
+
while j < num_rows and p._list[j] == width_n \
|
|
515
|
+
and p.vacancy_numbers[j] == p.rigging[j]:
|
|
516
|
+
j += 1
|
|
517
|
+
p.rigging[j-1] -= 1
|
|
518
|
+
break
|
|
519
|
+
|
|
520
|
+
# Continue back following the regular A_n rules
|
|
521
|
+
for a in reversed(range(tableau_height, n - 2)):
|
|
522
|
+
max_width = self.ret_rig_con[a].insert_cell(max_width)
|
|
523
|
+
self._update_vacancy_nums(a + 1)
|
|
524
|
+
self._update_partition_values(a + 1)
|
|
525
|
+
|
|
526
|
+
# Update the final rigged partitions
|
|
527
|
+
if tableau_height < n:
|
|
528
|
+
self._update_vacancy_nums(tableau_height)
|
|
529
|
+
self._update_partition_values(tableau_height)
|
|
530
|
+
|
|
531
|
+
assert pos_val > 0
|
|
532
|
+
if pos_val <= tableau_height:
|
|
533
|
+
for a in range(pos_val-1, tableau_height):
|
|
534
|
+
self._update_vacancy_nums(a)
|
|
535
|
+
self._update_partition_values(a)
|
|
536
|
+
if pos_val > 1:
|
|
537
|
+
self._update_vacancy_nums(pos_val - 2)
|
|
538
|
+
self._update_partition_values(pos_val - 2)
|
|
539
|
+
elif tableau_height > 0:
|
|
540
|
+
self._update_vacancy_nums(tableau_height - 1)
|
|
541
|
+
self._update_partition_values(tableau_height - 1)
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
class RCToKRTBijectionTypeB(RCToKRTBijectionTypeC):
|
|
545
|
+
r"""
|
|
546
|
+
Specific implementation of the bijection from rigged configurations to
|
|
547
|
+
tensor products of KR tableaux for type `B_n^{(1)}`.
|
|
548
|
+
"""
|
|
549
|
+
|
|
550
|
+
def run(self, verbose=False, build_graph=False):
|
|
551
|
+
"""
|
|
552
|
+
Run the bijection from rigged configurations to tensor product of KR
|
|
553
|
+
tableaux for type `B_n^{(1)}`.
|
|
554
|
+
|
|
555
|
+
INPUT:
|
|
556
|
+
|
|
557
|
+
- ``verbose`` -- boolean (default: ``False``); display each step in the
|
|
558
|
+
bijection
|
|
559
|
+
- ``build_graph`` -- boolean (default: ``False``); build the graph of each
|
|
560
|
+
step of the bijection
|
|
561
|
+
|
|
562
|
+
EXAMPLES::
|
|
563
|
+
|
|
564
|
+
sage: RC = RiggedConfigurations(['B', 3, 1], [[2, 1]])
|
|
565
|
+
sage: from sage.combinat.rigged_configurations.bij_type_B import RCToKRTBijectionTypeB
|
|
566
|
+
sage: RCToKRTBijectionTypeB(RC(partition_list=[[1],[1,1],[1]])).run()
|
|
567
|
+
[[3], [0]]
|
|
568
|
+
|
|
569
|
+
sage: RC = RiggedConfigurations(['B', 3, 1], [[3, 1]])
|
|
570
|
+
sage: x = RC(partition_list=[[],[1],[1]])
|
|
571
|
+
sage: RCToKRTBijectionTypeB(x).run()
|
|
572
|
+
[[1], [3], [-2]]
|
|
573
|
+
sage: bij = RCToKRTBijectionTypeB(x)
|
|
574
|
+
sage: bij.run(build_graph=True)
|
|
575
|
+
[[1], [3], [-2]]
|
|
576
|
+
sage: bij._graph
|
|
577
|
+
Digraph on 6 vertices
|
|
578
|
+
"""
|
|
579
|
+
from sage.combinat.crystals.letters import CrystalOfLetters
|
|
580
|
+
letters = CrystalOfLetters(self.rigged_con.parent()._cartan_type.classical())
|
|
581
|
+
|
|
582
|
+
# This is technically bad, but because the first thing we do is append
|
|
583
|
+
# an empty list to ret_crystal_path, we correct this. We do it this
|
|
584
|
+
# way so that we do not have to remove an empty list after the
|
|
585
|
+
# bijection has been performed.
|
|
586
|
+
ret_crystal_path = []
|
|
587
|
+
|
|
588
|
+
for dim in self.rigged_con.parent().dims:
|
|
589
|
+
ret_crystal_path.append([])
|
|
590
|
+
|
|
591
|
+
# Check to see if we are a spinor
|
|
592
|
+
if dim[0] == self.n:
|
|
593
|
+
# Perform the spinor bijection by converting to type A_{2n-1}^{(2)}
|
|
594
|
+
# doing the bijection there and pulling back
|
|
595
|
+
|
|
596
|
+
from sage.combinat.rigged_configurations.bij_type_A2_odd import RCToKRTBijectionTypeA2Odd
|
|
597
|
+
from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
|
|
598
|
+
from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition, RiggedPartitionTypeB
|
|
599
|
+
|
|
600
|
+
# Convert to a type A_{2n-1}^{(2)} RC
|
|
601
|
+
RC = RiggedConfigurations(['A', 2*self.n-1, 2], self.cur_dims)
|
|
602
|
+
if verbose:
|
|
603
|
+
print("====================")
|
|
604
|
+
print(repr(RC(*self.cur_partitions, use_vacancy_numbers=True)))
|
|
605
|
+
print("--------------------")
|
|
606
|
+
print(ret_crystal_path)
|
|
607
|
+
print("--------------------\n")
|
|
608
|
+
print("Applying doubling map\n")
|
|
609
|
+
# Convert the n-th partition into a regular rigged partition
|
|
610
|
+
self.cur_partitions[-1] = RiggedPartition(self.cur_partitions[-1]._list,
|
|
611
|
+
self.cur_partitions[-1].rigging,
|
|
612
|
+
self.cur_partitions[-1].vacancy_numbers)
|
|
613
|
+
|
|
614
|
+
bij = RCToKRTBijectionTypeA2Odd(RC(*self.cur_partitions, use_vacancy_numbers=True))
|
|
615
|
+
for i in range(len(self.cur_dims)):
|
|
616
|
+
if bij.cur_dims[i][0] != self.n:
|
|
617
|
+
bij.cur_dims[i][1] *= 2
|
|
618
|
+
for i in range(self.n-1):
|
|
619
|
+
for j in range(len(bij.cur_partitions[i])):
|
|
620
|
+
bij.cur_partitions[i]._list[j] *= 2
|
|
621
|
+
bij.cur_partitions[i].rigging[j] *= 2
|
|
622
|
+
bij.cur_partitions[i].vacancy_numbers[j] *= 2
|
|
623
|
+
|
|
624
|
+
if build_graph:
|
|
625
|
+
y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True)
|
|
626
|
+
self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x'])
|
|
627
|
+
|
|
628
|
+
# Perform the type A_{2n-1}^{(2)} bijection
|
|
629
|
+
|
|
630
|
+
# Iterate over each column
|
|
631
|
+
for dummy_var in range(dim[1]):
|
|
632
|
+
# Split off a new column if necessary
|
|
633
|
+
if bij.cur_dims[0][1] > 1:
|
|
634
|
+
bij.cur_dims[0][1] -= 1
|
|
635
|
+
bij.cur_dims.insert(0, [dim[0], 1])
|
|
636
|
+
|
|
637
|
+
# Perform the corresponding splitting map on rigged configurations
|
|
638
|
+
# All it does is update the vacancy numbers on the RC side
|
|
639
|
+
for a in range(self.n):
|
|
640
|
+
bij._update_vacancy_numbers(a)
|
|
641
|
+
|
|
642
|
+
if build_graph:
|
|
643
|
+
y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True)
|
|
644
|
+
self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls'])
|
|
645
|
+
|
|
646
|
+
while bij.cur_dims[0][0]: # > 0:
|
|
647
|
+
if verbose:
|
|
648
|
+
print("====================")
|
|
649
|
+
print(repr(RC(*bij.cur_partitions, use_vacancy_numbers=True)))
|
|
650
|
+
print("--------------------")
|
|
651
|
+
print(ret_crystal_path)
|
|
652
|
+
print("--------------------\n")
|
|
653
|
+
|
|
654
|
+
ht = bij.cur_dims[0][0]
|
|
655
|
+
bij.cur_dims[0][0] = bij._next_index(ht)
|
|
656
|
+
b = bij.next_state(ht)
|
|
657
|
+
# Make sure we have a crystal letter
|
|
658
|
+
ret_crystal_path[-1].append(letters(b)) # Append the rank
|
|
659
|
+
|
|
660
|
+
if build_graph:
|
|
661
|
+
y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True)
|
|
662
|
+
self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)])
|
|
663
|
+
|
|
664
|
+
bij.cur_dims.pop(0) # Pop off the leading column
|
|
665
|
+
|
|
666
|
+
self.cur_dims.pop(0) # Pop off the spin rectangle
|
|
667
|
+
|
|
668
|
+
self.cur_partitions = bij.cur_partitions
|
|
669
|
+
# Convert the n-th partition back into the special type B one
|
|
670
|
+
self.cur_partitions[-1] = RiggedPartitionTypeB(self.cur_partitions[-1])
|
|
671
|
+
|
|
672
|
+
# Convert back to a type B_n^{(1)}
|
|
673
|
+
if verbose:
|
|
674
|
+
print("====================")
|
|
675
|
+
print(repr(self.rigged_con.parent()(*bij.cur_partitions, use_vacancy_numbers=True)))
|
|
676
|
+
print("--------------------")
|
|
677
|
+
print(ret_crystal_path)
|
|
678
|
+
print("--------------------\n")
|
|
679
|
+
print("Applying halving map\n")
|
|
680
|
+
|
|
681
|
+
for i in range(self.n-1):
|
|
682
|
+
for j in range(len(self.cur_partitions[i])):
|
|
683
|
+
self.cur_partitions[i]._list[j] //= 2
|
|
684
|
+
self.cur_partitions[i].rigging[j] //= 2
|
|
685
|
+
self.cur_partitions[i].vacancy_numbers[j] //= 2
|
|
686
|
+
|
|
687
|
+
if build_graph:
|
|
688
|
+
y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True)
|
|
689
|
+
self._graph.append([self._graph[-1][1], (y, len(self._graph)), '1/2x'])
|
|
690
|
+
else:
|
|
691
|
+
# Perform the regular type B_n^{(1)} bijection
|
|
692
|
+
|
|
693
|
+
# Iterate over each column
|
|
694
|
+
for dummy_var in range(dim[1]):
|
|
695
|
+
# Split off a new column if necessary
|
|
696
|
+
if self.cur_dims[0][1] > 1:
|
|
697
|
+
if verbose:
|
|
698
|
+
print("====================")
|
|
699
|
+
print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True)))
|
|
700
|
+
print("--------------------")
|
|
701
|
+
print(ret_crystal_path)
|
|
702
|
+
print("--------------------\n")
|
|
703
|
+
print("Applying column split")
|
|
704
|
+
|
|
705
|
+
self.cur_dims[0][1] -= 1
|
|
706
|
+
self.cur_dims.insert(0, [dim[0], 1])
|
|
707
|
+
|
|
708
|
+
# Perform the corresponding splitting map on rigged configurations
|
|
709
|
+
# All it does is update the vacancy numbers on the RC side
|
|
710
|
+
for a in range(self.n):
|
|
711
|
+
self._update_vacancy_numbers(a)
|
|
712
|
+
|
|
713
|
+
if build_graph:
|
|
714
|
+
y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True)
|
|
715
|
+
self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x'])
|
|
716
|
+
|
|
717
|
+
while self.cur_dims[0][0]: # > 0:
|
|
718
|
+
if verbose:
|
|
719
|
+
print("====================")
|
|
720
|
+
print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True)))
|
|
721
|
+
print("--------------------")
|
|
722
|
+
print(ret_crystal_path)
|
|
723
|
+
print("--------------------\n")
|
|
724
|
+
|
|
725
|
+
self.cur_dims[0][0] -= 1 # This takes care of the indexing
|
|
726
|
+
b = self.next_state(self.cur_dims[0][0])
|
|
727
|
+
|
|
728
|
+
# Make sure we have a crystal letter
|
|
729
|
+
ret_crystal_path[-1].append(letters(b)) # Append the rank
|
|
730
|
+
|
|
731
|
+
if build_graph:
|
|
732
|
+
y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True)
|
|
733
|
+
self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)])
|
|
734
|
+
|
|
735
|
+
self.cur_dims.pop(0) # Pop off the leading column
|
|
736
|
+
|
|
737
|
+
if build_graph:
|
|
738
|
+
self._graph.pop(0) # Remove the dummy at the start
|
|
739
|
+
from sage.graphs.digraph import DiGraph
|
|
740
|
+
from sage.graphs.dot2tex_utils import have_dot2tex
|
|
741
|
+
self._graph = DiGraph(self._graph)
|
|
742
|
+
if have_dot2tex():
|
|
743
|
+
self._graph.set_latex_options(format='dot2tex', edge_labels=True)
|
|
744
|
+
|
|
745
|
+
return self.KRT(pathlist=ret_crystal_path)
|
|
746
|
+
|
|
747
|
+
def next_state(self, height):
|
|
748
|
+
r"""
|
|
749
|
+
Build the next state for type `B_n^{(1)}`.
|
|
750
|
+
|
|
751
|
+
TESTS::
|
|
752
|
+
|
|
753
|
+
sage: RC = RiggedConfigurations(['B', 3, 1], [[2, 1]])
|
|
754
|
+
sage: from sage.combinat.rigged_configurations.bij_type_B import RCToKRTBijectionTypeB
|
|
755
|
+
sage: bijection = RCToKRTBijectionTypeB(RC(partition_list=[[1],[1,1],[1]]))
|
|
756
|
+
sage: bijection.next_state(0)
|
|
757
|
+
0
|
|
758
|
+
"""
|
|
759
|
+
n = self.n
|
|
760
|
+
ell = [None] * (2*n)
|
|
761
|
+
case_S = False
|
|
762
|
+
case_Q = False
|
|
763
|
+
b = None
|
|
764
|
+
|
|
765
|
+
# Calculate the rank and ell values
|
|
766
|
+
|
|
767
|
+
last_size = 0
|
|
768
|
+
for a in range(height, n-1):
|
|
769
|
+
ell[a] = self._find_singular_string(self.cur_partitions[a], last_size)
|
|
770
|
+
|
|
771
|
+
if ell[a] is None:
|
|
772
|
+
b = a + 1
|
|
773
|
+
break
|
|
774
|
+
else:
|
|
775
|
+
last_size = self.cur_partitions[a][ell[a]]
|
|
776
|
+
|
|
777
|
+
# Special case for n
|
|
778
|
+
if b is None:
|
|
779
|
+
last_size = 2 * last_size - 1
|
|
780
|
+
partition = self.cur_partitions[n-1]
|
|
781
|
+
# Modified version of _find_singular_string()
|
|
782
|
+
for i in reversed(range(len(partition))):
|
|
783
|
+
if partition[i] == last_size \
|
|
784
|
+
and partition.vacancy_numbers[i] == partition.rigging[i]:
|
|
785
|
+
case_Q = True
|
|
786
|
+
ell[n-1] = i
|
|
787
|
+
elif partition[i] > last_size:
|
|
788
|
+
if not case_Q and partition.vacancy_numbers[i] - 1 == partition.rigging[i]:
|
|
789
|
+
case_Q = True
|
|
790
|
+
# Check if the block is singular as well
|
|
791
|
+
block_size = partition[i]
|
|
792
|
+
for j in reversed(range(i)):
|
|
793
|
+
if partition[j] != block_size:
|
|
794
|
+
break
|
|
795
|
+
elif partition.vacancy_numbers[j] == partition.rigging[j]:
|
|
796
|
+
case_Q = False
|
|
797
|
+
ell[2*n-1] = j
|
|
798
|
+
last_size = partition[j]
|
|
799
|
+
case_S = True
|
|
800
|
+
break
|
|
801
|
+
if not case_Q: # We found a singular string above the quasi-singular one
|
|
802
|
+
break
|
|
803
|
+
ell[n-1] = i
|
|
804
|
+
last_size = partition[i]
|
|
805
|
+
# Now check for case QS
|
|
806
|
+
elif partition.vacancy_numbers[i] == partition.rigging[i]:
|
|
807
|
+
ell[2*n-1] = i
|
|
808
|
+
last_size = partition[i]
|
|
809
|
+
case_S = True
|
|
810
|
+
break
|
|
811
|
+
|
|
812
|
+
if ell[2*n-1] is None:
|
|
813
|
+
if not case_Q:
|
|
814
|
+
b = n
|
|
815
|
+
else:
|
|
816
|
+
b = 0
|
|
817
|
+
|
|
818
|
+
if b is None:
|
|
819
|
+
# Now go back
|
|
820
|
+
last_size = (last_size + 1) // 2
|
|
821
|
+
for a in reversed(range(n - 1)):
|
|
822
|
+
# Modified form of _find_singular_string
|
|
823
|
+
end = ell[a]
|
|
824
|
+
if a < height:
|
|
825
|
+
end = len(self.cur_partitions[a])
|
|
826
|
+
for i in reversed(range(end)):
|
|
827
|
+
if self.cur_partitions[a][i] >= last_size and \
|
|
828
|
+
self.cur_partitions[a].vacancy_numbers[i] == self.cur_partitions[a].rigging[i]:
|
|
829
|
+
ell[n + a] = i
|
|
830
|
+
break
|
|
831
|
+
|
|
832
|
+
if ell[n + a] is None:
|
|
833
|
+
b = -(a + 2)
|
|
834
|
+
break
|
|
835
|
+
else:
|
|
836
|
+
last_size = self.cur_partitions[a][ell[n + a]]
|
|
837
|
+
|
|
838
|
+
if b is None:
|
|
839
|
+
b = -1
|
|
840
|
+
|
|
841
|
+
# Determine the new rigged configuration by removing boxes from the
|
|
842
|
+
# selected string and then making the new string singular
|
|
843
|
+
|
|
844
|
+
# Determine if we need to make the n-th string quasisingular
|
|
845
|
+
make_quasisingular = case_Q and case_S and \
|
|
846
|
+
(ell[2*n-2] is None
|
|
847
|
+
or self.cur_partitions[n-1][ell[2*n-1]]
|
|
848
|
+
< 2*self.cur_partitions[n-2][ell[2*n-2]])
|
|
849
|
+
|
|
850
|
+
row_num = self.cur_partitions[0].remove_cell(ell[0])
|
|
851
|
+
row_num_bar = self.cur_partitions[0].remove_cell(ell[n])
|
|
852
|
+
for a in range(1, n-1):
|
|
853
|
+
row_num_next = self.cur_partitions[a].remove_cell(ell[a])
|
|
854
|
+
row_num_bar_next = self.cur_partitions[a].remove_cell(ell[n+a])
|
|
855
|
+
|
|
856
|
+
self._update_vacancy_numbers(a - 1)
|
|
857
|
+
if row_num is not None:
|
|
858
|
+
self.cur_partitions[a-1].rigging[row_num] = self.cur_partitions[a-1].vacancy_numbers[row_num]
|
|
859
|
+
if row_num_bar is not None:
|
|
860
|
+
self.cur_partitions[a-1].rigging[row_num_bar] = self.cur_partitions[a-1].vacancy_numbers[row_num_bar]
|
|
861
|
+
row_num = row_num_next
|
|
862
|
+
row_num_bar = row_num_bar_next
|
|
863
|
+
|
|
864
|
+
if case_Q:
|
|
865
|
+
if case_S:
|
|
866
|
+
row_num_next = self.cur_partitions[n-1].remove_cell(ell[n-1])
|
|
867
|
+
row_num_bar_next = self.cur_partitions[n-1].remove_cell(ell[2*n-1])
|
|
868
|
+
else:
|
|
869
|
+
row_num_next = self.cur_partitions[n-1].remove_cell(ell[n-1])
|
|
870
|
+
row_num_bar_next = None
|
|
871
|
+
elif case_S:
|
|
872
|
+
row_num_next = self.cur_partitions[n-1].remove_cell(ell[2*n-1], 2)
|
|
873
|
+
row_num_bar_next = None
|
|
874
|
+
else:
|
|
875
|
+
row_num_next = None
|
|
876
|
+
row_num_bar_next = None
|
|
877
|
+
|
|
878
|
+
self._update_vacancy_numbers(n - 2)
|
|
879
|
+
if row_num is not None:
|
|
880
|
+
self.cur_partitions[n-2].rigging[row_num] = self.cur_partitions[n-2].vacancy_numbers[row_num]
|
|
881
|
+
if row_num_bar is not None:
|
|
882
|
+
self.cur_partitions[n-2].rigging[row_num_bar] = self.cur_partitions[n-2].vacancy_numbers[row_num_bar]
|
|
883
|
+
|
|
884
|
+
self._update_vacancy_numbers(n - 1)
|
|
885
|
+
if row_num_next is not None:
|
|
886
|
+
self.cur_partitions[n-1].rigging[row_num_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_next]
|
|
887
|
+
if row_num_bar_next is not None: # If we enter here, it means case (Q, S) holds
|
|
888
|
+
vac_num = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next]
|
|
889
|
+
self.cur_partitions[n-1].rigging[row_num_bar_next] = vac_num
|
|
890
|
+
if make_quasisingular:
|
|
891
|
+
block_len = self.cur_partitions[n-1][row_num_bar_next]
|
|
892
|
+
j = row_num_bar_next + 1
|
|
893
|
+
length = len(self.cur_partitions[n-1])
|
|
894
|
+
# Find the place for the quasisingular rigging
|
|
895
|
+
while j < length and self.cur_partitions[n-1][j] == block_len \
|
|
896
|
+
and self.cur_partitions[n-1].rigging[j] == vac_num:
|
|
897
|
+
j += 1
|
|
898
|
+
self.cur_partitions[n-1].rigging[j-1] = vac_num - 1
|
|
899
|
+
|
|
900
|
+
return b
|