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,866 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
r"""
|
|
3
|
+
The Hillman-Grassl correspondence
|
|
4
|
+
|
|
5
|
+
This module implements weak reverse plane partitions and four
|
|
6
|
+
correspondences on them: the Hillman-Grassl correspondence and
|
|
7
|
+
its inverse, as well as the Sulzgruber correspondence and its
|
|
8
|
+
inverse (the Pak correspondence).
|
|
9
|
+
|
|
10
|
+
Fix a partition `\lambda`
|
|
11
|
+
(see :meth:`~sage.combinat.partition.Partition`).
|
|
12
|
+
We draw all partitions and tableaux in English notation.
|
|
13
|
+
|
|
14
|
+
A `\lambda`-*array* will mean a tableau of shape `\lambda` whose
|
|
15
|
+
entries are nonnegative integers. (No conditions on the order of
|
|
16
|
+
these entries are made. Note that `0` is allowed.)
|
|
17
|
+
|
|
18
|
+
A *weak reverse plane partition of shape* `\lambda` (short:
|
|
19
|
+
`\lambda`-*rpp*) will mean a `\lambda`-array whose entries weakly
|
|
20
|
+
increase along each row and weakly increase along each column.
|
|
21
|
+
(The name "weak reverse plane partition" comes from Stanley in
|
|
22
|
+
[EnumComb2]_ Section 7.22; other authors -- such as Pak
|
|
23
|
+
[Sulzgr2017]_, or Hillman and Grassl in [HilGra1976]_ -- just
|
|
24
|
+
call it a reverse plane partition.)
|
|
25
|
+
|
|
26
|
+
The Hillman-Grassl correspondence is a bijection from the
|
|
27
|
+
set of `\lambda`-arrays to the set of `\lambda`-rpps.
|
|
28
|
+
For its definition, see
|
|
29
|
+
:meth:`~sage.combinat.tableau.Tableau.hillman_grassl`;
|
|
30
|
+
for its inverse, see
|
|
31
|
+
:meth:`~sage.combinat.hillman_grassl.WeakReversePlanePartition.hillman_grassl_inverse`.
|
|
32
|
+
|
|
33
|
+
The Sulzgruber correspondence `\Phi_\lambda` and the Pak
|
|
34
|
+
correspondence `\xi_\lambda` are two further mutually
|
|
35
|
+
inverse bijections between the set of
|
|
36
|
+
`\lambda`-arrays and the set of `\lambda`-rpps.
|
|
37
|
+
They appear (sometimes with different definitions, but
|
|
38
|
+
defining the same maps) in [Pak2002]_, [Hopkins2017]_ and
|
|
39
|
+
[Sulzgr2017]_. For their definitions, see
|
|
40
|
+
:meth:`~sage.combinat.tableau.Tableau.sulzgruber_correspondence` and
|
|
41
|
+
:meth:`~sage.combinat.hillman_grassl.WeakReversePlanePartition.pak_correspondence`.
|
|
42
|
+
|
|
43
|
+
EXAMPLES:
|
|
44
|
+
|
|
45
|
+
We construct a `\lambda`-rpp for `\lambda = (3, 3, 1)`
|
|
46
|
+
(note that `\lambda` needs not be specified explicitly)::
|
|
47
|
+
|
|
48
|
+
sage: p = WeakReversePlanePartition([[0, 1, 3], [2, 4, 4], [3]])
|
|
49
|
+
sage: p.parent()
|
|
50
|
+
Weak Reverse Plane Partitions
|
|
51
|
+
|
|
52
|
+
(This is the example in Section 7.22 of [EnumComb2]_.)
|
|
53
|
+
|
|
54
|
+
Next, we apply the inverse of the Hillman-Grassl correspondence
|
|
55
|
+
to it::
|
|
56
|
+
|
|
57
|
+
sage: HGp = p.hillman_grassl_inverse(); HGp
|
|
58
|
+
[[1, 2, 0], [1, 0, 1], [1]]
|
|
59
|
+
sage: HGp.parent()
|
|
60
|
+
Tableaux
|
|
61
|
+
|
|
62
|
+
This is a `\lambda`-array, encoded as a tableau. We can
|
|
63
|
+
recover our original `\lambda`-rpp from it using the
|
|
64
|
+
Hillman-Grassl correspondence::
|
|
65
|
+
|
|
66
|
+
sage: HGp.hillman_grassl() == p
|
|
67
|
+
True
|
|
68
|
+
|
|
69
|
+
We can also apply the Pak correspondence to our rpp::
|
|
70
|
+
|
|
71
|
+
sage: Pp = p.pak_correspondence(); Pp
|
|
72
|
+
[[2, 0, 1], [0, 2, 0], [1]]
|
|
73
|
+
sage: Pp.parent()
|
|
74
|
+
Tableaux
|
|
75
|
+
|
|
76
|
+
This is undone by the Sulzgruber correspondence::
|
|
77
|
+
|
|
78
|
+
sage: Pp.sulzgruber_correspondence() == p
|
|
79
|
+
True
|
|
80
|
+
|
|
81
|
+
These four correspondences can also be accessed as standalone
|
|
82
|
+
functions (:meth:`hillman_grassl_inverse`, :meth:`hillman_grassl`,
|
|
83
|
+
:meth:`pak_correspondence` and :meth:`sulzgruber_correspondence`)
|
|
84
|
+
that transform lists of lists into lists of lists;
|
|
85
|
+
this may be more efficient. For example, the above computation
|
|
86
|
+
of ``HGp`` can also be obtained as follows::
|
|
87
|
+
|
|
88
|
+
sage: from sage.combinat.hillman_grassl import hillman_grassl_inverse
|
|
89
|
+
sage: HGp_bare = hillman_grassl_inverse([[0, 1, 3], [2, 4, 4], [3]])
|
|
90
|
+
sage: HGp_bare
|
|
91
|
+
[[1, 2, 0], [1, 0, 1], [1]]
|
|
92
|
+
sage: isinstance(HGp_bare, list)
|
|
93
|
+
True
|
|
94
|
+
|
|
95
|
+
REFERENCES:
|
|
96
|
+
|
|
97
|
+
- [Gans1981]_
|
|
98
|
+
- [HilGra1976]_
|
|
99
|
+
- [EnumComb2]_
|
|
100
|
+
- [Pak2002]_
|
|
101
|
+
- [Sulzgr2017]_
|
|
102
|
+
- [Hopkins2017]_
|
|
103
|
+
|
|
104
|
+
AUTHORS:
|
|
105
|
+
|
|
106
|
+
- Darij Grinberg and Tom Roby (2018): Initial implementation
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
# ****************************************************************************
|
|
110
|
+
# Copyright (C) 2018 Darij Grinberg <darijgrinberg@gmail.com>,
|
|
111
|
+
# 2018 Tom Roby <tomrobyuconn@gmail.com>
|
|
112
|
+
#
|
|
113
|
+
# This program is free software: you can redistribute it and/or modify
|
|
114
|
+
# it under the terms of the GNU General Public License as published by
|
|
115
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
116
|
+
# (at your option) any later version.
|
|
117
|
+
# https://www.gnu.org/licenses/
|
|
118
|
+
# ****************************************************************************
|
|
119
|
+
|
|
120
|
+
from sage.combinat.tableau import Tableau, Tableaux
|
|
121
|
+
from sage.categories.sets_cat import Sets
|
|
122
|
+
from sage.combinat.combinatorial_map import combinatorial_map
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class WeakReversePlanePartition(Tableau):
|
|
126
|
+
r"""
|
|
127
|
+
A weak reverse plane partition (short: rpp).
|
|
128
|
+
|
|
129
|
+
A weak reverse plane partition is a tableau with nonnegative
|
|
130
|
+
entries that are weakly increasing in each row and weakly
|
|
131
|
+
increasing in each column.
|
|
132
|
+
|
|
133
|
+
EXAMPLES::
|
|
134
|
+
|
|
135
|
+
sage: x = WeakReversePlanePartition([[0, 1, 1], [0, 1, 3], [1, 2, 2], [1, 2, 3], [2]]); x
|
|
136
|
+
[[0, 1, 1], [0, 1, 3], [1, 2, 2], [1, 2, 3], [2]]
|
|
137
|
+
sage: x.pp()
|
|
138
|
+
0 1 1
|
|
139
|
+
0 1 3
|
|
140
|
+
1 2 2
|
|
141
|
+
1 2 3
|
|
142
|
+
2
|
|
143
|
+
sage: x.shape()
|
|
144
|
+
[3, 3, 3, 3, 1]
|
|
145
|
+
"""
|
|
146
|
+
@staticmethod
|
|
147
|
+
def __classcall_private__(cls, r):
|
|
148
|
+
r"""
|
|
149
|
+
Return an rpp object.
|
|
150
|
+
|
|
151
|
+
EXAMPLES::
|
|
152
|
+
|
|
153
|
+
sage: WeakReversePlanePartition([[1, 2], [1, 3], [1]])
|
|
154
|
+
[[1, 2], [1, 3], [1]]
|
|
155
|
+
|
|
156
|
+
TESTS::
|
|
157
|
+
|
|
158
|
+
sage: a1 = [[1, 2], [1, 3], [1]]
|
|
159
|
+
sage: a2 = [(1, 2), (1, 3), (1,)]
|
|
160
|
+
sage: A1 = WeakReversePlanePartition(a1)
|
|
161
|
+
sage: A2 = WeakReversePlanePartition(a2)
|
|
162
|
+
sage: A3 = WeakReversePlanePartition(A1)
|
|
163
|
+
sage: A4 = Tableau(A1)
|
|
164
|
+
sage: A1 == A2 == A3 == A4
|
|
165
|
+
True
|
|
166
|
+
"""
|
|
167
|
+
try:
|
|
168
|
+
r = list(map(tuple, r))
|
|
169
|
+
except TypeError:
|
|
170
|
+
raise TypeError("r must be a list of positive integers")
|
|
171
|
+
return WeakReversePlanePartitions()(r)
|
|
172
|
+
|
|
173
|
+
def __init__(self, parent, t):
|
|
174
|
+
"""
|
|
175
|
+
Initialize ``self``.
|
|
176
|
+
|
|
177
|
+
EXAMPLES::
|
|
178
|
+
|
|
179
|
+
sage: R = WeakReversePlanePartition([[0, 1, 2], [0, 2]])
|
|
180
|
+
sage: TestSuite(R).run()
|
|
181
|
+
"""
|
|
182
|
+
if not isinstance(t, Tableau):
|
|
183
|
+
t = [list(row) for row in t]
|
|
184
|
+
else:
|
|
185
|
+
t = list(t)
|
|
186
|
+
|
|
187
|
+
Tableau.__init__(self, parent, t)
|
|
188
|
+
|
|
189
|
+
@combinatorial_map(order=2, name='conjugate')
|
|
190
|
+
def conjugate(self):
|
|
191
|
+
"""
|
|
192
|
+
Return the conjugate of ``self``.
|
|
193
|
+
|
|
194
|
+
EXAMPLES::
|
|
195
|
+
|
|
196
|
+
sage: c = WeakReversePlanePartition([[1,1],[1,3],[2]]).conjugate(); c
|
|
197
|
+
[[1, 1, 2], [1, 3]]
|
|
198
|
+
sage: c.parent()
|
|
199
|
+
Weak Reverse Plane Partitions
|
|
200
|
+
"""
|
|
201
|
+
C = super().conjugate()
|
|
202
|
+
return WeakReversePlanePartition(C)
|
|
203
|
+
|
|
204
|
+
def hillman_grassl_inverse(self):
|
|
205
|
+
r"""
|
|
206
|
+
Return the image of the `\lambda`-rpp ``self`` under the
|
|
207
|
+
inverse of the Hillman-Grassl correspondence (as a
|
|
208
|
+
:class:`~sage.combinat.tableau.Tableau`).
|
|
209
|
+
|
|
210
|
+
Fix a partition `\lambda`
|
|
211
|
+
(see :meth:`~sage.combinat.partition.Partition`).
|
|
212
|
+
We draw all partitions and tableaux in English notation.
|
|
213
|
+
|
|
214
|
+
A `\lambda`-*array* will mean a tableau of shape `\lambda` whose
|
|
215
|
+
entries are nonnegative integers. (No conditions on the order of
|
|
216
|
+
these entries are made. Note that `0` is allowed.)
|
|
217
|
+
|
|
218
|
+
A *weak reverse plane partition of shape* `\lambda` (short:
|
|
219
|
+
`\lambda`-*rpp*) will mean a `\lambda`-array whose entries weakly
|
|
220
|
+
increase along each row and weakly increase along each column.
|
|
221
|
+
|
|
222
|
+
The inverse `H^{-1}` of the Hillman-Grassl correspondence (see
|
|
223
|
+
(:meth:`~sage.combinat.tableau.Tableau.hillman_grassl` for the
|
|
224
|
+
latter) sends a `\lambda`-rpp `\pi` to a `\lambda`-array
|
|
225
|
+
`H^{-1}(\pi)` constructed recursively as follows:
|
|
226
|
+
|
|
227
|
+
* If all entries of `\pi` are `0`, then `H^{-1}(\pi) = \pi`.
|
|
228
|
+
|
|
229
|
+
* Otherwise, let `s` be the index of the leftmost column of `\pi`
|
|
230
|
+
containing a nonzero entry. Write the `\lambda`-array `M`
|
|
231
|
+
as `(m_{i, j})`.
|
|
232
|
+
|
|
233
|
+
* Define a sequence `((i_1, j_1), (i_2, j_2), \ldots,
|
|
234
|
+
(i_n, j_n))` of boxes in the diagram of `\lambda` (actually a
|
|
235
|
+
lattice path made of northward and eastward steps) as follows:
|
|
236
|
+
Let `(i_1, j_1)` be the bottommost box in the `s`-th column
|
|
237
|
+
of `\pi`.
|
|
238
|
+
If `(i_k, j_k)` is defined for some `k \geq 1`, then
|
|
239
|
+
`(i_{k+1}, j_{k+1})` is constructed as follows:
|
|
240
|
+
If `q_{i_k - 1, j_k}` is well-defined and equals `q_{i_k, j_k}`,
|
|
241
|
+
then we set `(i_{k+1}, j_{k+1}) = (i_k - 1, j_k)`. Otherwise,
|
|
242
|
+
we set `(i_{k+1}, j_{k+1}) = (i_k, j_k + 1)` if this is still
|
|
243
|
+
a box of `\lambda`. Otherwise, the sequence ends here.
|
|
244
|
+
|
|
245
|
+
* Let `\pi'` be the `\lambda`-rpp obtained from `\pi` by
|
|
246
|
+
subtracting `1` from the `(i_k, j_k)`-th entry of `\pi` for each
|
|
247
|
+
`k \in \{1, 2, \ldots, n\}`.
|
|
248
|
+
|
|
249
|
+
* Let `N'` be the image `H^{-1}(\pi')` (which is already
|
|
250
|
+
constructed by recursion).
|
|
251
|
+
Then, `H^{-1}(\pi)` is obtained from `N'` by adding `1` to the
|
|
252
|
+
`(i_n, s)`-th entry of `N'`.
|
|
253
|
+
|
|
254
|
+
This construction appears in [HilGra1976]_ Section 6 (where
|
|
255
|
+
`\lambda`-arrays are re-encoded as sequences of "hook number
|
|
256
|
+
multiplicities") and [EnumComb2]_ Section 7.22.
|
|
257
|
+
|
|
258
|
+
.. SEEALSO::
|
|
259
|
+
|
|
260
|
+
:meth:`~sage.combinat.hillman_grassl.hillman_grassl_inverse`
|
|
261
|
+
for the inverse of the Hillman-Grassl correspondence as a
|
|
262
|
+
standalone function.
|
|
263
|
+
|
|
264
|
+
:meth:`~sage.combinat.tableau.Tableau.hillman_grassl`
|
|
265
|
+
for the inverse map.
|
|
266
|
+
|
|
267
|
+
EXAMPLES::
|
|
268
|
+
|
|
269
|
+
sage: a = WeakReversePlanePartition([[2, 2, 4], [2, 3, 4], [3, 5]])
|
|
270
|
+
sage: a.hillman_grassl_inverse()
|
|
271
|
+
[[2, 1, 1], [0, 2, 0], [1, 1]]
|
|
272
|
+
sage: b = WeakReversePlanePartition([[1, 1, 2, 2], [1, 1, 2, 2], [2, 2, 3, 3], [2, 2, 3, 3]])
|
|
273
|
+
sage: B = b.hillman_grassl_inverse(); B
|
|
274
|
+
[[1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1]]
|
|
275
|
+
sage: b.parent(), B.parent()
|
|
276
|
+
(Weak Reverse Plane Partitions, Tableaux)
|
|
277
|
+
|
|
278
|
+
Applying the inverse of the Hillman-Grassl correspondence
|
|
279
|
+
to the transpose of a `\lambda`-rpp `M` yields the same
|
|
280
|
+
result as applying it to `M` and then transposing the
|
|
281
|
+
result ([Gans1981]_ Corollary 3.4)::
|
|
282
|
+
|
|
283
|
+
sage: a = WeakReversePlanePartition([[1,3,5],[2,4]])
|
|
284
|
+
sage: aic = a.hillman_grassl_inverse().conjugate()
|
|
285
|
+
sage: aic == a.conjugate().hillman_grassl_inverse()
|
|
286
|
+
True
|
|
287
|
+
"""
|
|
288
|
+
return Tableau(hillman_grassl_inverse(list(self)))
|
|
289
|
+
|
|
290
|
+
def pak_correspondence(self):
|
|
291
|
+
r"""
|
|
292
|
+
Return the image of the `\lambda`-rpp ``self`` under the Pak
|
|
293
|
+
correspondence (as a :class:`~sage.combinat.tableau.Tableau`).
|
|
294
|
+
|
|
295
|
+
See :mod:`~sage.combinat.hillman_grassl`.
|
|
296
|
+
|
|
297
|
+
The Pak correspondence is the map `\xi_\lambda`
|
|
298
|
+
from [Sulzgr2017]_ Section 7, and is the map
|
|
299
|
+
`\xi_\lambda` from [Pak2002]_ Section 4.
|
|
300
|
+
It is the inverse of the Sulzgruber correspondence
|
|
301
|
+
(:meth:`sulzgruber_correspondence`).
|
|
302
|
+
The following description of the Pak correspondence follows
|
|
303
|
+
[Hopkins2017]_ (which denotes it by `\mathcal{RSK}^{-1}`):
|
|
304
|
+
|
|
305
|
+
Fix a partition `\lambda`
|
|
306
|
+
(see :meth:`~sage.combinat.partition.Partition`).
|
|
307
|
+
We draw all partitions and tableaux in English notation.
|
|
308
|
+
|
|
309
|
+
A `\lambda`-*array* will mean a tableau of shape `\lambda` whose
|
|
310
|
+
entries are nonnegative integers. (No conditions on the order of
|
|
311
|
+
these entries are made. Note that `0` is allowed.)
|
|
312
|
+
|
|
313
|
+
A *weak reverse plane partition of shape* `\lambda` (short:
|
|
314
|
+
`\lambda`-*rpp*) will mean a `\lambda`-array whose entries weakly
|
|
315
|
+
increase along each row and weakly increase along each column.
|
|
316
|
+
|
|
317
|
+
We shall also use the following notation:
|
|
318
|
+
If `(u, v)` is a cell of `\lambda`, and if `\pi` is a
|
|
319
|
+
`\lambda`-rpp, then:
|
|
320
|
+
|
|
321
|
+
* the *lower bound* of `\pi` at `(u, v)` (denoted by
|
|
322
|
+
`\pi_{<(u, v)}`) is defined to be
|
|
323
|
+
`\max \{ \pi_{u-1, v} , \pi_{u, v-1} \}`
|
|
324
|
+
(where `\pi_{0, v}` and `\pi_{u, 0}` are understood to
|
|
325
|
+
mean `0`).
|
|
326
|
+
|
|
327
|
+
* the *upper bound* of `\pi` at `(u, v)` (denoted by
|
|
328
|
+
`\pi_{>(u, v)}`) is defined to be
|
|
329
|
+
`\min \{ \pi_{u+1, v} , \pi_{u, v+1} \}`
|
|
330
|
+
(where `\pi_{i, j}` is understood to mean `+ \infty`
|
|
331
|
+
if `(i, j)` is not in `\lambda`; thus, the upper
|
|
332
|
+
bound at a corner cell is `+ \infty`).
|
|
333
|
+
|
|
334
|
+
* *toggling* `\pi` at `(u, v)` means replacing the entry
|
|
335
|
+
`\pi_{u, v}` of `\pi` at `(u, v)` by
|
|
336
|
+
`\pi_{<(u, v)} + \pi_{>(u, v)} - \pi_{u, v}`
|
|
337
|
+
(this is well-defined as long as `(u, v)` is not a
|
|
338
|
+
corner of `\lambda`).
|
|
339
|
+
|
|
340
|
+
Note that every `\lambda`-rpp `\pi` and every cell
|
|
341
|
+
`(u, v)` of `\lambda` satisfy
|
|
342
|
+
`\pi_{<(u, v)} \leq \pi_{u, v} \leq \pi_{>(u, v)}`.
|
|
343
|
+
Note that toggling a `\lambda`-rpp (at a cell that is not
|
|
344
|
+
a corner) always results in a `\lambda`-rpp. Also,
|
|
345
|
+
toggling is an involution).
|
|
346
|
+
|
|
347
|
+
Note also that the lower bound of `\pi` at `(u, v)` is
|
|
348
|
+
defined (and finite) even when `(u, v)` is not a cell of
|
|
349
|
+
`\lambda`, as long as both `(u-1, v)` and `(u, v-1)` are
|
|
350
|
+
cells of `\lambda`.
|
|
351
|
+
|
|
352
|
+
The Pak correspondence `\Phi_\lambda` sends a `\lambda`-array
|
|
353
|
+
`M = (m_{i, j})` to a `\lambda`-rpp `\Phi_\lambda(M)`. It
|
|
354
|
+
is defined by recursion on `\lambda` (that is, we assume that
|
|
355
|
+
`\Phi_\mu` is already defined for every partition `\mu`
|
|
356
|
+
smaller than `\lambda`), and its definition proceeds as
|
|
357
|
+
follows:
|
|
358
|
+
|
|
359
|
+
* If `\lambda = \varnothing`, then `\Phi_\lambda` is the
|
|
360
|
+
obvious bijection sending the only `\varnothing`-array
|
|
361
|
+
to the only `\varnothing`-rpp.
|
|
362
|
+
|
|
363
|
+
* Pick any corner `c = (i, j)` of `\lambda`, and let `\mu`
|
|
364
|
+
be the result of removing this corner `c` from the partition
|
|
365
|
+
`\lambda`. (The exact choice of `c` is immaterial.)
|
|
366
|
+
|
|
367
|
+
* Let `M'` be what remains of `M` when the corner cell `c`
|
|
368
|
+
is removed.
|
|
369
|
+
|
|
370
|
+
* Let `\pi' = \Phi_\mu(M')`.
|
|
371
|
+
|
|
372
|
+
* For each positive integer `k` such that `(i-k, j-k)` is a
|
|
373
|
+
cell of `\lambda`, toggle `\pi'` at `(i-k, j-k)`.
|
|
374
|
+
(All these togglings commute, so the order in which they
|
|
375
|
+
are made is immaterial.)
|
|
376
|
+
|
|
377
|
+
* Extend the `\mu`-rpp `\pi'` to a `\lambda`-rpp `\pi` by
|
|
378
|
+
adding the cell `c` and writing the number
|
|
379
|
+
`m_{i, j} - \pi'_{<(i, j)}` into this cell.
|
|
380
|
+
|
|
381
|
+
* Set `\Phi_\lambda(M) = \pi`.
|
|
382
|
+
|
|
383
|
+
.. SEEALSO::
|
|
384
|
+
|
|
385
|
+
:meth:`~sage.combinat.hillman_grassl.pak_correspondence`
|
|
386
|
+
for the Pak correspondence as a standalone function.
|
|
387
|
+
|
|
388
|
+
:meth:`~sage.combinat.tableau.Tableau.sulzgruber_correspondence`
|
|
389
|
+
for the inverse map.
|
|
390
|
+
|
|
391
|
+
EXAMPLES::
|
|
392
|
+
|
|
393
|
+
sage: a = WeakReversePlanePartition([[1, 2, 3], [1, 2, 3], [2, 4, 4]])
|
|
394
|
+
sage: A = a.pak_correspondence(); A
|
|
395
|
+
[[1, 0, 2], [0, 2, 0], [1, 1, 0]]
|
|
396
|
+
sage: a.parent(), A.parent()
|
|
397
|
+
(Weak Reverse Plane Partitions, Tableaux)
|
|
398
|
+
|
|
399
|
+
Applying the Pak correspondence to the transpose of a
|
|
400
|
+
`\lambda`-rpp `M` yields the same result as applying it to
|
|
401
|
+
`M` and then transposing the result::
|
|
402
|
+
|
|
403
|
+
sage: a = WeakReversePlanePartition([[1,3,5],[2,4]])
|
|
404
|
+
sage: acc = a.pak_correspondence().conjugate()
|
|
405
|
+
sage: acc == a.conjugate().pak_correspondence()
|
|
406
|
+
True
|
|
407
|
+
"""
|
|
408
|
+
return Tableau(pak_correspondence(list(self)))
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
class WeakReversePlanePartitions(Tableaux):
|
|
412
|
+
r"""
|
|
413
|
+
The set of all weak reverse plane partitions.
|
|
414
|
+
"""
|
|
415
|
+
@staticmethod
|
|
416
|
+
def __classcall_private__(cls, shape=None, **kwds):
|
|
417
|
+
"""
|
|
418
|
+
Normalize input to ensure a unique representation and
|
|
419
|
+
return the correct class based on input.
|
|
420
|
+
|
|
421
|
+
The ``shape`` parameter is currently not implemented.
|
|
422
|
+
|
|
423
|
+
EXAMPLES::
|
|
424
|
+
|
|
425
|
+
sage: S1 = WeakReversePlanePartitions()
|
|
426
|
+
sage: S2 = WeakReversePlanePartitions()
|
|
427
|
+
sage: S1 is S2
|
|
428
|
+
True
|
|
429
|
+
|
|
430
|
+
sage: S1 = WeakReversePlanePartitions([4, 2, 2, 1]) # not tested (not implemented)
|
|
431
|
+
sage: S2 = WeakReversePlanePartitions((4, 2, 2, 1)) # not tested (not implemented)
|
|
432
|
+
sage: S1 is S2 # not tested (not implemented)
|
|
433
|
+
True
|
|
434
|
+
"""
|
|
435
|
+
if shape is not None:
|
|
436
|
+
raise NotImplementedError("shape cannot be specified")
|
|
437
|
+
# from sage.combinat.partition import Partition
|
|
438
|
+
# return RibbonShapedTableaux_shape(Partition(shape))
|
|
439
|
+
|
|
440
|
+
return super().__classcall__(cls, **kwds)
|
|
441
|
+
|
|
442
|
+
def __init__(self):
|
|
443
|
+
"""
|
|
444
|
+
Initialize ``self``.
|
|
445
|
+
|
|
446
|
+
EXAMPLES::
|
|
447
|
+
|
|
448
|
+
sage: S = WeakReversePlanePartitions()
|
|
449
|
+
sage: TestSuite(S).run()
|
|
450
|
+
"""
|
|
451
|
+
Tableaux.__init__(self, category=Sets())
|
|
452
|
+
|
|
453
|
+
def _repr_(self):
|
|
454
|
+
"""
|
|
455
|
+
TESTS::
|
|
456
|
+
|
|
457
|
+
sage: WeakReversePlanePartitions()
|
|
458
|
+
Weak Reverse Plane Partitions
|
|
459
|
+
"""
|
|
460
|
+
return "Weak Reverse Plane Partitions"
|
|
461
|
+
|
|
462
|
+
Element = WeakReversePlanePartition
|
|
463
|
+
|
|
464
|
+
def _an_element_(self):
|
|
465
|
+
r"""
|
|
466
|
+
Return a particular element of the class.
|
|
467
|
+
|
|
468
|
+
TESTS::
|
|
469
|
+
|
|
470
|
+
sage: T = WeakReversePlanePartitions()
|
|
471
|
+
sage: T.an_element()
|
|
472
|
+
[[0, 0, 1, 2], [0, 1, 1], [0], [2]]
|
|
473
|
+
"""
|
|
474
|
+
return self.element_class(self, [[0, 0, 1, 2], [0, 1, 1], [0], [2]])
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def transpose(M):
|
|
478
|
+
r"""
|
|
479
|
+
Return the transpose of a `\lambda`-array.
|
|
480
|
+
|
|
481
|
+
The transpose of a `\lambda`-array `(m_{i, j})` is the
|
|
482
|
+
`\lambda^t`-array `(m_{j, i})`
|
|
483
|
+
(where `\lambda^t` is the conjugate of the partition
|
|
484
|
+
`\lambda`).
|
|
485
|
+
|
|
486
|
+
EXAMPLES::
|
|
487
|
+
|
|
488
|
+
sage: from sage.combinat.hillman_grassl import transpose
|
|
489
|
+
sage: transpose([[1, 2, 3], [4, 5]])
|
|
490
|
+
[[1, 4], [2, 5], [3]]
|
|
491
|
+
sage: transpose([[5, 0, 3], [4, 1, 0], [7]])
|
|
492
|
+
[[5, 4, 7], [0, 1], [3, 0]]
|
|
493
|
+
|
|
494
|
+
TESTS::
|
|
495
|
+
|
|
496
|
+
sage: transpose(((2, 1), (3,)))
|
|
497
|
+
[[2, 3], [1]]
|
|
498
|
+
sage: transpose([])
|
|
499
|
+
[]
|
|
500
|
+
sage: transpose(WeakReversePlanePartition([[1, 2, 3], [4, 5]]))
|
|
501
|
+
[[1, 4], [2, 5], [3]]
|
|
502
|
+
sage: transpose(WeakReversePlanePartition([]))
|
|
503
|
+
[]
|
|
504
|
+
"""
|
|
505
|
+
if not M: # empty array
|
|
506
|
+
return []
|
|
507
|
+
l = len(M[0])
|
|
508
|
+
res = []
|
|
509
|
+
for j in range(l):
|
|
510
|
+
lj = []
|
|
511
|
+
for r in M:
|
|
512
|
+
if len(r) <= j:
|
|
513
|
+
break
|
|
514
|
+
lj.append(r[j])
|
|
515
|
+
res.append(lj)
|
|
516
|
+
return res
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def hillman_grassl(M):
|
|
520
|
+
r"""
|
|
521
|
+
Return the image of the `\lambda`-array ``M``
|
|
522
|
+
under the Hillman-Grassl correspondence.
|
|
523
|
+
|
|
524
|
+
The Hillman-Grassl correspondence is a bijection
|
|
525
|
+
between the tableaux with nonnegative entries
|
|
526
|
+
(otherwise arbitrary) and the weak reverse plane
|
|
527
|
+
partitions with nonnegative entries.
|
|
528
|
+
This bijection preserves the shape of the
|
|
529
|
+
tableau. See :mod:`~sage.combinat.hillman_grassl`.
|
|
530
|
+
|
|
531
|
+
See :meth:`~sage.combinat.tableau.Tableau.hillman_grassl`
|
|
532
|
+
for a description of this map.
|
|
533
|
+
|
|
534
|
+
.. SEEALSO::
|
|
535
|
+
|
|
536
|
+
:meth:`hillman_grassl_inverse`
|
|
537
|
+
|
|
538
|
+
EXAMPLES::
|
|
539
|
+
|
|
540
|
+
sage: from sage.combinat.hillman_grassl import hillman_grassl
|
|
541
|
+
sage: hillman_grassl([[2, 1, 1], [0, 2, 0], [1, 1]])
|
|
542
|
+
[[2, 2, 4], [2, 3, 4], [3, 5]]
|
|
543
|
+
sage: hillman_grassl([[1, 2, 0], [1, 0, 1], [1]])
|
|
544
|
+
[[0, 1, 3], [2, 4, 4], [3]]
|
|
545
|
+
sage: hillman_grassl([])
|
|
546
|
+
[]
|
|
547
|
+
sage: hillman_grassl([[3, 1, 2]])
|
|
548
|
+
[[3, 4, 6]]
|
|
549
|
+
sage: hillman_grassl([[2, 2, 0], [1, 1, 1], [1]])
|
|
550
|
+
[[1, 2, 4], [3, 5, 5], [4]]
|
|
551
|
+
sage: hillman_grassl([[1, 1, 1, 1]]*3)
|
|
552
|
+
[[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
|
|
553
|
+
|
|
554
|
+
TESTS::
|
|
555
|
+
|
|
556
|
+
sage: hillman_grassl(((2, 2, 0), (1, 1, 1), (1,)))
|
|
557
|
+
[[1, 2, 4], [3, 5, 5], [4]]
|
|
558
|
+
"""
|
|
559
|
+
lam = [len(row) for row in M]
|
|
560
|
+
l = len(lam)
|
|
561
|
+
Mt = transpose(M)
|
|
562
|
+
# We won't touch M from now on; we'll only modify Mt
|
|
563
|
+
# in place.
|
|
564
|
+
hook_mults = []
|
|
565
|
+
for j, col_j in enumerate(Mt):
|
|
566
|
+
col_j_hook_mults = []
|
|
567
|
+
for r, entry in enumerate(col_j):
|
|
568
|
+
if entry != 0:
|
|
569
|
+
col_j_hook_mults += [(r, j)] * entry
|
|
570
|
+
hook_mults += reversed(col_j_hook_mults)
|
|
571
|
+
res = [[0] * rowlen for rowlen in lam]
|
|
572
|
+
for (r, s) in reversed(hook_mults):
|
|
573
|
+
i = r
|
|
574
|
+
j = lam[r] - 1
|
|
575
|
+
while True:
|
|
576
|
+
old = res[i][j]
|
|
577
|
+
res[i][j] += 1
|
|
578
|
+
if i + 1 != l and j < lam[i + 1] and old == res[i + 1][j]:
|
|
579
|
+
i += 1
|
|
580
|
+
else:
|
|
581
|
+
if j == s:
|
|
582
|
+
break
|
|
583
|
+
j -= 1
|
|
584
|
+
return res
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def hillman_grassl_inverse(M):
|
|
588
|
+
r"""
|
|
589
|
+
Return the image of the `\lambda`-rpp ``M`` under the
|
|
590
|
+
inverse of the Hillman-Grassl correspondence.
|
|
591
|
+
|
|
592
|
+
See :mod:`~sage.combinat.hillman_grassl`.
|
|
593
|
+
|
|
594
|
+
See
|
|
595
|
+
:meth:`~sage.combinat.hillman_grassl.WeakReversePlanePartition.hillman_grassl_inverse`
|
|
596
|
+
for a description of this map.
|
|
597
|
+
|
|
598
|
+
.. SEEALSO::
|
|
599
|
+
|
|
600
|
+
:meth:`hillman_grassl`
|
|
601
|
+
|
|
602
|
+
EXAMPLES::
|
|
603
|
+
|
|
604
|
+
sage: from sage.combinat.hillman_grassl import hillman_grassl_inverse
|
|
605
|
+
sage: hillman_grassl_inverse([[2, 2, 4], [2, 3, 4], [3, 5]])
|
|
606
|
+
[[2, 1, 1], [0, 2, 0], [1, 1]]
|
|
607
|
+
sage: hillman_grassl_inverse([[0, 1, 3], [2, 4, 4], [3]])
|
|
608
|
+
[[1, 2, 0], [1, 0, 1], [1]]
|
|
609
|
+
|
|
610
|
+
Applying the inverse of the Hillman-Grassl correspondence
|
|
611
|
+
to the transpose of a `\lambda`-rpp `M` yields the same
|
|
612
|
+
result as applying it to `M` and then transposing the
|
|
613
|
+
result ([Gans1981]_ Corollary 3.4)::
|
|
614
|
+
|
|
615
|
+
sage: hillman_grassl_inverse([[1,3,5],[2,4]])
|
|
616
|
+
[[1, 2, 2], [1, 1]]
|
|
617
|
+
sage: hillman_grassl_inverse([[1,2],[3,4],[5]])
|
|
618
|
+
[[1, 1], [2, 1], [2]]
|
|
619
|
+
sage: hillman_grassl_inverse([[1, 2, 3], [1, 2, 3], [2, 4, 4]])
|
|
620
|
+
[[1, 2, 0], [0, 1, 1], [1, 0, 1]]
|
|
621
|
+
sage: hillman_grassl_inverse([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]])
|
|
622
|
+
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
|
|
623
|
+
|
|
624
|
+
TESTS::
|
|
625
|
+
|
|
626
|
+
sage: a = [[3], [4], [6]]
|
|
627
|
+
sage: hillman_grassl_inverse(a)
|
|
628
|
+
[[3], [1], [2]]
|
|
629
|
+
sage: a
|
|
630
|
+
[[3], [4], [6]]
|
|
631
|
+
|
|
632
|
+
sage: hillman_grassl_inverse(((1,2),(3,4),(5,)))
|
|
633
|
+
[[1, 1], [2, 1], [2]]
|
|
634
|
+
"""
|
|
635
|
+
lam = [len(row) for row in M]
|
|
636
|
+
res = [[0] * rowlen for rowlen in lam]
|
|
637
|
+
Mt = transpose(M)
|
|
638
|
+
# We won't touch M from now on; we'll only modify Mt
|
|
639
|
+
# in place.
|
|
640
|
+
while True:
|
|
641
|
+
for j, col_j in enumerate(Mt):
|
|
642
|
+
if all(entry == 0 for entry in col_j):
|
|
643
|
+
continue
|
|
644
|
+
else:
|
|
645
|
+
break
|
|
646
|
+
else: # all entries of Mt are 0.
|
|
647
|
+
break
|
|
648
|
+
# Now, j is the index of the leftmost nonzero column of
|
|
649
|
+
# the array.
|
|
650
|
+
s = j
|
|
651
|
+
i = len(col_j) - 1 # We already have j = s.
|
|
652
|
+
while True:
|
|
653
|
+
old = col_j[i]
|
|
654
|
+
col_j[i] -= 1
|
|
655
|
+
if i > 0 and old == col_j[i - 1]:
|
|
656
|
+
i -= 1
|
|
657
|
+
else:
|
|
658
|
+
j += 1
|
|
659
|
+
if j == lam[i]:
|
|
660
|
+
break
|
|
661
|
+
col_j = Mt[j]
|
|
662
|
+
res[i][s] += 1
|
|
663
|
+
return res
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
def sulzgruber_correspondence(M):
|
|
667
|
+
r"""
|
|
668
|
+
Return the image of a `\lambda`-array ``M``
|
|
669
|
+
under the Sulzgruber correspondence.
|
|
670
|
+
|
|
671
|
+
The Sulzgruber correspondence is the map `\Phi_\lambda`
|
|
672
|
+
from [Sulzgr2017]_ Section 7, and is the map
|
|
673
|
+
`\xi_\lambda^{-1}` from [Pak2002]_ Section 5.
|
|
674
|
+
It is denoted by `\mathcal{RSK}` in [Hopkins2017]_.
|
|
675
|
+
It is the inverse of the Pak correspondence
|
|
676
|
+
(:meth:`pak_correspondence`).
|
|
677
|
+
|
|
678
|
+
See :meth:`~sage.combinat.tableau.Tableau.sulzgruber_correspondence`
|
|
679
|
+
for a description of this map.
|
|
680
|
+
|
|
681
|
+
EXAMPLES::
|
|
682
|
+
|
|
683
|
+
sage: from sage.combinat.hillman_grassl import sulzgruber_correspondence
|
|
684
|
+
sage: sulzgruber_correspondence([[1, 0, 2], [0, 2, 0], [1, 1, 0]])
|
|
685
|
+
[[1, 2, 3], [1, 2, 3], [2, 4, 4]]
|
|
686
|
+
sage: sulzgruber_correspondence([[1, 1, 2], [0, 1, 0], [3, 0, 0]])
|
|
687
|
+
[[1, 1, 4], [2, 3, 4], [4, 4, 4]]
|
|
688
|
+
sage: sulzgruber_correspondence([[1, 0, 2], [0, 2, 0], [1, 1]])
|
|
689
|
+
[[0, 2, 3], [1, 3, 3], [2, 4]]
|
|
690
|
+
sage: sulzgruber_correspondence([[0, 2, 2], [1, 1], [2]])
|
|
691
|
+
[[1, 2, 4], [1, 3], [3]]
|
|
692
|
+
sage: sulzgruber_correspondence([[1, 1, 1, 1]]*3)
|
|
693
|
+
[[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
|
|
694
|
+
|
|
695
|
+
The Sulzgruber correspondence can actually be
|
|
696
|
+
extended (by the same definition) to arrays
|
|
697
|
+
of nonnegative reals rather than nonnegative
|
|
698
|
+
integers. This implementation supports this::
|
|
699
|
+
|
|
700
|
+
sage: sulzgruber_correspondence([[1/2, 0, 1], [0, 1, 0], [1/2, 1/2]])
|
|
701
|
+
[[0, 1, 3/2], [1/2, 3/2, 3/2], [1, 2]]
|
|
702
|
+
|
|
703
|
+
TESTS::
|
|
704
|
+
|
|
705
|
+
sage: sulzgruber_correspondence([])
|
|
706
|
+
[]
|
|
707
|
+
sage: sulzgruber_correspondence(((0, 2, 2), (1, 1), (2,)))
|
|
708
|
+
[[1, 2, 4], [1, 3], [3]]
|
|
709
|
+
"""
|
|
710
|
+
lam = [len(row) for row in M]
|
|
711
|
+
l = len(lam)
|
|
712
|
+
if l == 0:
|
|
713
|
+
return []
|
|
714
|
+
# Finding a corner of lam...
|
|
715
|
+
lam_0 = lam[0]
|
|
716
|
+
for i, lam_i in enumerate(lam):
|
|
717
|
+
if lam_i != lam_0:
|
|
718
|
+
i -= 1
|
|
719
|
+
break
|
|
720
|
+
j = lam_0 - 1
|
|
721
|
+
# Now, i is the index of the last row of ``M`` that
|
|
722
|
+
# has the same length as the first row; hence, (i, j)
|
|
723
|
+
# is a corner of lam.
|
|
724
|
+
x = M[i][j]
|
|
725
|
+
N = [list(row) for row in M]
|
|
726
|
+
|
|
727
|
+
# remove the corner (i, j):
|
|
728
|
+
N[i].pop()
|
|
729
|
+
if not N[i]:
|
|
730
|
+
N.pop()
|
|
731
|
+
|
|
732
|
+
N = sulzgruber_correspondence(N)
|
|
733
|
+
|
|
734
|
+
# toggling and inserting the new entry:
|
|
735
|
+
for k in range(min(i, j) + 1):
|
|
736
|
+
u = i - k
|
|
737
|
+
v = j - k
|
|
738
|
+
if u > 0 and v > 0:
|
|
739
|
+
lower_bound = max(N[u - 1][v], N[u][v - 1])
|
|
740
|
+
elif u > 0:
|
|
741
|
+
lower_bound = N[u - 1][v]
|
|
742
|
+
elif v > 0:
|
|
743
|
+
lower_bound = N[u][v - 1]
|
|
744
|
+
else:
|
|
745
|
+
lower_bound = 0
|
|
746
|
+
if k > 0:
|
|
747
|
+
val = N[u][v]
|
|
748
|
+
upper_bound = min(N[u + 1][v], N[u][v + 1])
|
|
749
|
+
N[u][v] = lower_bound + upper_bound - val
|
|
750
|
+
else:
|
|
751
|
+
if len(N) <= u:
|
|
752
|
+
N.append([])
|
|
753
|
+
N[u].append(lower_bound + x)
|
|
754
|
+
|
|
755
|
+
return N
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
def pak_correspondence(M, copy=True):
|
|
759
|
+
r"""
|
|
760
|
+
Return the image of a `\lambda`-rpp ``M``
|
|
761
|
+
under the Pak correspondence.
|
|
762
|
+
|
|
763
|
+
The Pak correspondence is the map `\xi_\lambda`
|
|
764
|
+
from [Sulzgr2017]_ Section 7, and is the map
|
|
765
|
+
`\xi_\lambda` from [Pak2002]_ Section 4.
|
|
766
|
+
It is the inverse of the Sulzgruber correspondence
|
|
767
|
+
(:meth:`sulzgruber_correspondence`).
|
|
768
|
+
|
|
769
|
+
See
|
|
770
|
+
:meth:`~sage.combinat.hillman_grassl.WeakReversePlanePartition.pak_correspondence`
|
|
771
|
+
for a description of this map.
|
|
772
|
+
|
|
773
|
+
INPUT:
|
|
774
|
+
|
|
775
|
+
- ``copy`` -- boolean (default: ``True``); if set to ``False``, the
|
|
776
|
+
algorithm will mutate the input (but be more efficient)
|
|
777
|
+
|
|
778
|
+
EXAMPLES::
|
|
779
|
+
|
|
780
|
+
sage: from sage.combinat.hillman_grassl import pak_correspondence
|
|
781
|
+
sage: pak_correspondence([[1, 2, 3], [1, 2, 3], [2, 4, 4]])
|
|
782
|
+
[[1, 0, 2], [0, 2, 0], [1, 1, 0]]
|
|
783
|
+
sage: pak_correspondence([[1, 1, 4], [2, 3, 4], [4, 4, 4]])
|
|
784
|
+
[[1, 1, 2], [0, 1, 0], [3, 0, 0]]
|
|
785
|
+
sage: pak_correspondence([[0, 2, 3], [1, 3, 3], [2, 4]])
|
|
786
|
+
[[1, 0, 2], [0, 2, 0], [1, 1]]
|
|
787
|
+
sage: pak_correspondence([[1, 2, 4], [1, 3], [3]])
|
|
788
|
+
[[0, 2, 2], [1, 1], [2]]
|
|
789
|
+
sage: pak_correspondence([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]])
|
|
790
|
+
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
|
|
791
|
+
|
|
792
|
+
The Pak correspondence can actually be
|
|
793
|
+
extended (by the same definition) to "rpps"
|
|
794
|
+
of nonnegative reals rather than nonnegative
|
|
795
|
+
integers. This implementation supports this::
|
|
796
|
+
|
|
797
|
+
sage: pak_correspondence([[0, 1, 3/2], [1/2, 3/2, 3/2], [1, 2]])
|
|
798
|
+
[[1/2, 0, 1], [0, 1, 0], [1/2, 1/2]]
|
|
799
|
+
|
|
800
|
+
TESTS::
|
|
801
|
+
|
|
802
|
+
sage: pak_correspondence([])
|
|
803
|
+
[]
|
|
804
|
+
sage: pak_correspondence(((1, 2, 4), (1, 3), (3,)))
|
|
805
|
+
[[0, 2, 2], [1, 1], [2]]
|
|
806
|
+
|
|
807
|
+
sage: a = [[0, 2, 3], [1, 3, 3], [2, 4]]
|
|
808
|
+
sage: pak_correspondence(a)
|
|
809
|
+
[[1, 0, 2], [0, 2, 0], [1, 1]]
|
|
810
|
+
sage: a
|
|
811
|
+
[[0, 2, 3], [1, 3, 3], [2, 4]]
|
|
812
|
+
sage: pak_correspondence(a, copy=False)
|
|
813
|
+
[[1, 0, 2], [0, 2, 0], [1, 1]]
|
|
814
|
+
sage: a
|
|
815
|
+
[]
|
|
816
|
+
"""
|
|
817
|
+
if not M:
|
|
818
|
+
return []
|
|
819
|
+
lam = [len(row) for row in M]
|
|
820
|
+
# Finding a corner of lam...
|
|
821
|
+
lam_0 = lam[0]
|
|
822
|
+
for i, lam_i in enumerate(lam):
|
|
823
|
+
if lam_i != lam_0:
|
|
824
|
+
i -= 1
|
|
825
|
+
break
|
|
826
|
+
j = lam_0 - 1
|
|
827
|
+
# Now, i is the index of the last row of ``M`` that
|
|
828
|
+
# has the same length as the first row; hence, (i, j)
|
|
829
|
+
# is a corner of lam.
|
|
830
|
+
x = M[i][j]
|
|
831
|
+
|
|
832
|
+
if copy:
|
|
833
|
+
N = [list(row) for row in M]
|
|
834
|
+
# make a deep copy of M to avoid vandalizing M
|
|
835
|
+
else:
|
|
836
|
+
N = M
|
|
837
|
+
|
|
838
|
+
# toggling and obtaining x (the corner entry of the output):
|
|
839
|
+
for k in range(min(i, j) + 1):
|
|
840
|
+
u = i - k
|
|
841
|
+
v = j - k
|
|
842
|
+
if u > 0 and v > 0:
|
|
843
|
+
lower_bound = max(N[u - 1][v], N[u][v - 1])
|
|
844
|
+
elif u > 0:
|
|
845
|
+
lower_bound = N[u - 1][v]
|
|
846
|
+
elif v > 0:
|
|
847
|
+
lower_bound = N[u][v - 1]
|
|
848
|
+
else:
|
|
849
|
+
lower_bound = 0
|
|
850
|
+
if k > 0:
|
|
851
|
+
val = N[u][v]
|
|
852
|
+
upper_bound = min(N[u + 1][v], N[u][v + 1])
|
|
853
|
+
N[u][v] = lower_bound + upper_bound - val
|
|
854
|
+
else:
|
|
855
|
+
x -= lower_bound
|
|
856
|
+
|
|
857
|
+
# remove the corner (i, j):
|
|
858
|
+
N[i].pop()
|
|
859
|
+
if not N[i]:
|
|
860
|
+
N.pop()
|
|
861
|
+
|
|
862
|
+
N = pak_correspondence(N, copy=False)
|
|
863
|
+
if len(N) <= i:
|
|
864
|
+
N.append([])
|
|
865
|
+
N[i].append(x)
|
|
866
|
+
return N
|