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,1403 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.groups sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Specht modules
|
|
5
|
+
|
|
6
|
+
.. TODO::
|
|
7
|
+
|
|
8
|
+
Integrate this with the implementations in
|
|
9
|
+
:mod:`sage.modules.with_basis.representation`.
|
|
10
|
+
|
|
11
|
+
AUTHORS:
|
|
12
|
+
|
|
13
|
+
- Travis Scrimshaw (2023-1-22): initial version
|
|
14
|
+
- Travis Scrimshaw (2023-11-23): added simple modules based on code
|
|
15
|
+
from Sacha Goldman
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# ****************************************************************************
|
|
19
|
+
# Copyright (C) 2023 Travis Scrimshaw <tcscrims (at) gmail.com>
|
|
20
|
+
#
|
|
21
|
+
# This program is free software: you can redistribute it and/or modify
|
|
22
|
+
# it under the terms of the GNU General Public License as published by
|
|
23
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
24
|
+
# (at your option) any later version.
|
|
25
|
+
# https://www.gnu.org/licenses/
|
|
26
|
+
# ****************************************************************************
|
|
27
|
+
|
|
28
|
+
from sage.misc.cachefunc import cached_method
|
|
29
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
30
|
+
from sage.combinat.diagram import Diagram
|
|
31
|
+
from sage.combinat.partition import _Partitions
|
|
32
|
+
from sage.combinat.free_module import CombinatorialFreeModule
|
|
33
|
+
from sage.modules.with_basis.representation import Representation_abstract
|
|
34
|
+
from sage.sets.family import Family
|
|
35
|
+
from sage.matrix.constructor import matrix
|
|
36
|
+
from sage.rings.rational_field import QQ
|
|
37
|
+
from sage.modules.with_basis.subquotient import SubmoduleWithBasis, QuotientModuleWithBasis
|
|
38
|
+
from sage.categories.modules_with_basis import ModulesWithBasis
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class SymmetricGroupRepresentation(Representation_abstract):
|
|
42
|
+
"""
|
|
43
|
+
Mixin class for symmetric group (algebra) representations.
|
|
44
|
+
"""
|
|
45
|
+
def __init__(self, SGA):
|
|
46
|
+
"""
|
|
47
|
+
Initialize ``self``.
|
|
48
|
+
|
|
49
|
+
EXAMPLES::
|
|
50
|
+
|
|
51
|
+
sage: SM = Partition([3,1,1]).specht_module(GF(3))
|
|
52
|
+
sage: SM.side()
|
|
53
|
+
'left'
|
|
54
|
+
sage: TestSuite(SM).run()
|
|
55
|
+
"""
|
|
56
|
+
Representation_abstract.__init__(self, SGA.group(), "left", SGA)
|
|
57
|
+
|
|
58
|
+
@cached_method
|
|
59
|
+
def frobenius_image(self):
|
|
60
|
+
r"""
|
|
61
|
+
Return the Frobenius image of ``self``.
|
|
62
|
+
|
|
63
|
+
The Frobenius map is defined as the map to symmetric functions
|
|
64
|
+
|
|
65
|
+
.. MATH::
|
|
66
|
+
|
|
67
|
+
F(\chi) = \frac{1}{n!} \sum_{w \in S_n} \chi(w) p_{\rho(w)},
|
|
68
|
+
|
|
69
|
+
where `\chi` is the character of the `S_n`-module ``self``,
|
|
70
|
+
`p_{\lambda}` is the powersum symmetric function basis element
|
|
71
|
+
indexed by `\lambda`, and `\rho(w)` is the cycle type of `w` as a
|
|
72
|
+
partition. Specifically, this map takes irreducible representations
|
|
73
|
+
indexed by `\lambda` to the Schur function `s_{\lambda}`.
|
|
74
|
+
|
|
75
|
+
EXAMPLES::
|
|
76
|
+
|
|
77
|
+
sage: SM = Partition([2,2,1]).specht_module(QQ)
|
|
78
|
+
sage: SM.frobenius_image()
|
|
79
|
+
s[2, 2, 1]
|
|
80
|
+
sage: SM = Partition([4,1]).specht_module(CyclotomicField(5))
|
|
81
|
+
sage: SM.frobenius_image()
|
|
82
|
+
s[4, 1]
|
|
83
|
+
|
|
84
|
+
We verify the regular representation::
|
|
85
|
+
|
|
86
|
+
sage: from sage.combinat.diagram import Diagram
|
|
87
|
+
sage: D = Diagram([(0,0), (1,1), (2,2), (3,3), (4,4)])
|
|
88
|
+
sage: F = D.specht_module(QQ).frobenius_image(); F
|
|
89
|
+
s[1, 1, 1, 1, 1] + 4*s[2, 1, 1, 1] + 5*s[2, 2, 1]
|
|
90
|
+
+ 6*s[3, 1, 1] + 5*s[3, 2] + 4*s[4, 1] + s[5]
|
|
91
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
92
|
+
sage: F == sum(StandardTableaux(la).cardinality() * s[la]
|
|
93
|
+
....: for la in Partitions(5))
|
|
94
|
+
True
|
|
95
|
+
sage: all(s[la] == la.specht_module(QQ).frobenius_image()
|
|
96
|
+
....: for n in range(1, 5) for la in Partitions(n))
|
|
97
|
+
True
|
|
98
|
+
|
|
99
|
+
sage: D = Diagram([(0,0), (1,1), (1,2), (2,3), (2,4)])
|
|
100
|
+
sage: SM = D.specht_module(QQ)
|
|
101
|
+
sage: SM.frobenius_image()
|
|
102
|
+
s[2, 2, 1] + s[3, 1, 1] + 2*s[3, 2] + 2*s[4, 1] + s[5]
|
|
103
|
+
|
|
104
|
+
An example using the tabloid module::
|
|
105
|
+
|
|
106
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
107
|
+
sage: TM = SGA.tabloid_module([2, 2, 1])
|
|
108
|
+
sage: TM.frobenius_image()
|
|
109
|
+
s[2, 2, 1] + s[3, 1, 1] + 2*s[3, 2] + 2*s[4, 1] + s[5]
|
|
110
|
+
"""
|
|
111
|
+
from sage.combinat.sf.sf import SymmetricFunctions
|
|
112
|
+
p = SymmetricFunctions(QQ).p()
|
|
113
|
+
s = SymmetricFunctions(QQ).s()
|
|
114
|
+
G = self._semigroup
|
|
115
|
+
CCR = [(elt, elt.cycle_type()) for elt in G.conjugacy_classes_representatives()]
|
|
116
|
+
B = self.basis()
|
|
117
|
+
return s(p.sum(QQ(sum((elt * B[k])[k] for k in B.keys())) / la.centralizer_size() * p[la]
|
|
118
|
+
for elt, la in CCR))
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class SpechtModule(SymmetricGroupRepresentation, SubmoduleWithBasis):
|
|
122
|
+
r"""
|
|
123
|
+
A Specht module.
|
|
124
|
+
|
|
125
|
+
Let `S_n` be the symmetric group on `n` letters and `R` be a commutative
|
|
126
|
+
ring. The *Specht module* `S^D` for a diagram `D` is an `S_n`-module
|
|
127
|
+
defined as follows. Let
|
|
128
|
+
|
|
129
|
+
.. MATH::
|
|
130
|
+
|
|
131
|
+
R(D) := \sum_{w \in R_D} w,
|
|
132
|
+
\qquad\qquad
|
|
133
|
+
C(D) := \sum_{w \in C_D} (-1)^w w,
|
|
134
|
+
|
|
135
|
+
where `R_D` (resp. `C_D`) is the row (resp. column) stabilizer of `D`.
|
|
136
|
+
Then, we construct the Specht module `S^D` as the left ideal
|
|
137
|
+
|
|
138
|
+
.. MATH::
|
|
139
|
+
|
|
140
|
+
S^D = R[S_n] C(D) R(D),
|
|
141
|
+
|
|
142
|
+
where `R[S_n]` is the group algebra of `S_n` over `R`.
|
|
143
|
+
|
|
144
|
+
INPUT:
|
|
145
|
+
|
|
146
|
+
- ``SGA`` -- a symmetric group algebra
|
|
147
|
+
- ``D`` -- a diagram
|
|
148
|
+
|
|
149
|
+
EXAMPLES:
|
|
150
|
+
|
|
151
|
+
We begin by constructing all irreducible Specht modules for the symmetric
|
|
152
|
+
group `S_4` and show that they give a full set of irreducible
|
|
153
|
+
representations both by having distinct Frobenius characters and the
|
|
154
|
+
sum of the square of their dimensions is equal to `4!`::
|
|
155
|
+
|
|
156
|
+
sage: SP = [la.specht_module(QQ) for la in Partitions(4)]
|
|
157
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
158
|
+
sage: [s(S.frobenius_image()) for S in SP]
|
|
159
|
+
[s[4], s[3, 1], s[2, 2], s[2, 1, 1], s[1, 1, 1, 1]]
|
|
160
|
+
sage: sum(S.dimension()^2 for S in SP)
|
|
161
|
+
24
|
|
162
|
+
|
|
163
|
+
Next, we compute the Specht module for a more general diagram
|
|
164
|
+
for `S_5` and compute its irreducible decomposition by using
|
|
165
|
+
its Frobenius character::
|
|
166
|
+
|
|
167
|
+
sage: D = [(0,0), (0,1), (1,1), (1,2), (0,3)]
|
|
168
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
169
|
+
sage: SM = SGA.specht_module(D)
|
|
170
|
+
sage: SM.dimension()
|
|
171
|
+
9
|
|
172
|
+
sage: s(SM.frobenius_image())
|
|
173
|
+
s[3, 2] + s[4, 1]
|
|
174
|
+
|
|
175
|
+
This carries a natural (left) action of the symmetric group (algebra)::
|
|
176
|
+
|
|
177
|
+
sage: S5 = SGA.group()
|
|
178
|
+
sage: v = SM.an_element(); v
|
|
179
|
+
2*S[0] + 2*S[1] + 3*S[2]
|
|
180
|
+
sage: S5([2,1,5,3,4]) * v
|
|
181
|
+
3*S[0] + 2*S[1] + 2*S[2]
|
|
182
|
+
sage: x = SGA.an_element(); x
|
|
183
|
+
[1, 2, 3, 4, 5] + 2*[1, 2, 3, 5, 4] + 3*[1, 2, 4, 3, 5] + [5, 1, 2, 3, 4]
|
|
184
|
+
sage: x * v
|
|
185
|
+
15*S[0] + 14*S[1] + 16*S[2] - 7*S[5] + 2*S[6] + 2*S[7]
|
|
186
|
+
|
|
187
|
+
.. SEEALSO::
|
|
188
|
+
|
|
189
|
+
:class:`~sage.combinat.symmetric_group_representations.SpechtRepresentation`
|
|
190
|
+
for an implementation of the representation by matrices.
|
|
191
|
+
"""
|
|
192
|
+
@staticmethod
|
|
193
|
+
def __classcall_private__(cls, SGA, D):
|
|
194
|
+
r"""
|
|
195
|
+
Normalize input to ensure a unique representation.
|
|
196
|
+
|
|
197
|
+
EXAMPLES::
|
|
198
|
+
|
|
199
|
+
sage: from sage.combinat.specht_module import SpechtModule
|
|
200
|
+
sage: from sage.combinat.diagram import Diagram
|
|
201
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 3)
|
|
202
|
+
sage: D = [(0,0), (1,1), (1,2)]
|
|
203
|
+
sage: SM1 = SpechtModule(SGA, D)
|
|
204
|
+
sage: SM2 = SpechtModule(SGA, Diagram(D))
|
|
205
|
+
sage: SM1 is SM2
|
|
206
|
+
True
|
|
207
|
+
sage: SM1 is SpechtModule(SGA, [[1,1], [1,2], [0,0]])
|
|
208
|
+
True
|
|
209
|
+
|
|
210
|
+
sage: SpechtModule(SGA, [[0,0], [1,1]])
|
|
211
|
+
Traceback (most recent call last):
|
|
212
|
+
...
|
|
213
|
+
ValueError: the domain size (=3) does not match the number of boxes (=2) of the diagram
|
|
214
|
+
"""
|
|
215
|
+
if D in _Partitions:
|
|
216
|
+
D = _Partitions(D)
|
|
217
|
+
return TabloidModule(SGA, D).specht_module()
|
|
218
|
+
D = _to_diagram(D)
|
|
219
|
+
D = Diagram(D)
|
|
220
|
+
n = len(D)
|
|
221
|
+
if SGA.group().rank() != n - 1:
|
|
222
|
+
rk = SGA.group().rank() + 1
|
|
223
|
+
raise ValueError(f"the domain size (={rk}) does not match the number of boxes (={n}) of the diagram")
|
|
224
|
+
return super().__classcall__(cls, SGA, D)
|
|
225
|
+
|
|
226
|
+
def __init__(self, SGA, D):
|
|
227
|
+
r"""
|
|
228
|
+
Initialize ``self``.
|
|
229
|
+
|
|
230
|
+
EXAMPLES::
|
|
231
|
+
|
|
232
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
233
|
+
sage: SM = SGA.specht_module([(0,0), (1,1), (1,2), (2,1)])
|
|
234
|
+
sage: TestSuite(SM).run()
|
|
235
|
+
"""
|
|
236
|
+
SymmetricGroupRepresentation.__init__(self, SGA)
|
|
237
|
+
self._diagram = D
|
|
238
|
+
Mod = ModulesWithBasis(SGA.category().base_ring())
|
|
239
|
+
span_set = specht_module_spanning_set(D, SGA)
|
|
240
|
+
support_order = SGA.get_order()
|
|
241
|
+
basis = SGA.echelon_form(span_set, False, order=support_order)
|
|
242
|
+
basis = Family(basis)
|
|
243
|
+
SubmoduleWithBasis.__init__(self, basis, support_order, ambient=SGA,
|
|
244
|
+
unitriangular=False, category=Mod.Subobjects(),
|
|
245
|
+
prefix='S')
|
|
246
|
+
|
|
247
|
+
def _repr_(self):
|
|
248
|
+
r"""
|
|
249
|
+
Return a string representation of ``self``.
|
|
250
|
+
|
|
251
|
+
EXAMPLES::
|
|
252
|
+
|
|
253
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
254
|
+
sage: SGA.specht_module([(0,0), (1,1), (1,2), (2,1)])
|
|
255
|
+
Specht module of [(0, 0), (1, 1), (1, 2), (2, 1)] over Rational Field
|
|
256
|
+
|
|
257
|
+
sage: SGA.specht_module([3, 1])
|
|
258
|
+
Specht module of [3, 1] over Rational Field
|
|
259
|
+
"""
|
|
260
|
+
return f"Specht module of {self._diagram} over {self.base_ring()}"
|
|
261
|
+
|
|
262
|
+
def _latex_(self):
|
|
263
|
+
r"""
|
|
264
|
+
Return a latex representation of ``self``.
|
|
265
|
+
|
|
266
|
+
EXAMPLES::
|
|
267
|
+
|
|
268
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
269
|
+
sage: SM = SGA.specht_module([(0,0), (1,1), (1,2), (2,1)])
|
|
270
|
+
sage: latex(SM)
|
|
271
|
+
S^{{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
272
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{3}{p{0.6ex}}}\cline{1-1}
|
|
273
|
+
\lr{\phantom{x}}&&\\\cline{1-1}\cline{2-2}\cline{3-3}
|
|
274
|
+
&\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{2-2}\cline{3-3}\cline{2-2}
|
|
275
|
+
&\lr{\phantom{x}}&\\\cline{2-2}
|
|
276
|
+
\end{array}$}
|
|
277
|
+
}}
|
|
278
|
+
|
|
279
|
+
sage: SM = SGA.specht_module([3,1])
|
|
280
|
+
sage: latex(SM)
|
|
281
|
+
S^{{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
282
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{3}c}\cline{1-3}
|
|
283
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-3}
|
|
284
|
+
\lr{\phantom{x}}\\\cline{1-1}
|
|
285
|
+
\end{array}$}
|
|
286
|
+
}}
|
|
287
|
+
"""
|
|
288
|
+
from sage.misc.latex import latex
|
|
289
|
+
return f"S^{{{latex(self._diagram)}}}"
|
|
290
|
+
|
|
291
|
+
def _ascii_art_(self):
|
|
292
|
+
r"""
|
|
293
|
+
Return an ascii art representation of ``self``.
|
|
294
|
+
|
|
295
|
+
EXAMPLES::
|
|
296
|
+
|
|
297
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
298
|
+
sage: SM = SGA.specht_module([(0,0), (1,1), (1,2), (2,1)])
|
|
299
|
+
sage: ascii_art(SM)
|
|
300
|
+
O . .
|
|
301
|
+
. O O
|
|
302
|
+
. O .
|
|
303
|
+
S
|
|
304
|
+
|
|
305
|
+
sage: SM = SGA.specht_module([3,1])
|
|
306
|
+
sage: ascii_art(SM)
|
|
307
|
+
***
|
|
308
|
+
*
|
|
309
|
+
S
|
|
310
|
+
"""
|
|
311
|
+
from sage.typeset.ascii_art import ascii_art
|
|
312
|
+
return ascii_art("S", baseline=0) + ascii_art(self._diagram, baseline=-1)
|
|
313
|
+
|
|
314
|
+
def _unicode_art_(self):
|
|
315
|
+
r"""
|
|
316
|
+
Return a unicode art representation of ``self``.
|
|
317
|
+
|
|
318
|
+
EXAMPLES::
|
|
319
|
+
|
|
320
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
321
|
+
sage: SM = SGA.specht_module([(0,0), (1,1), (1,2), (2,1)])
|
|
322
|
+
sage: unicode_art(SM)
|
|
323
|
+
┌─┬─┬─┐
|
|
324
|
+
│X│ │ │
|
|
325
|
+
├─┼─┼─┤
|
|
326
|
+
│ │X│X│
|
|
327
|
+
├─┼─┼─┤
|
|
328
|
+
│ │X│ │
|
|
329
|
+
└─┴─┴─┘
|
|
330
|
+
S
|
|
331
|
+
|
|
332
|
+
sage: SM = SGA.specht_module([3,1])
|
|
333
|
+
sage: unicode_art(SM)
|
|
334
|
+
┌┬┬┐
|
|
335
|
+
├┼┴┘
|
|
336
|
+
└┘
|
|
337
|
+
S
|
|
338
|
+
"""
|
|
339
|
+
from sage.typeset.unicode_art import unicode_art
|
|
340
|
+
return unicode_art("S", baseline=0) + unicode_art(self._diagram, baseline=-1)
|
|
341
|
+
|
|
342
|
+
class Element(SubmoduleWithBasis.Element):
|
|
343
|
+
def _acted_upon_(self, x, self_on_left=False):
|
|
344
|
+
"""
|
|
345
|
+
Return the action of ``x`` on ``self``.
|
|
346
|
+
|
|
347
|
+
INPUT:
|
|
348
|
+
|
|
349
|
+
- ``x`` -- an element of the base ring or can be converted into
|
|
350
|
+
the defining symmetric group algebra
|
|
351
|
+
- ``self_on_left`` -- boolean (default: ``False``); which side
|
|
352
|
+
``self`` is on for the action
|
|
353
|
+
|
|
354
|
+
EXAMPLES::
|
|
355
|
+
|
|
356
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
357
|
+
sage: from sage.combinat.diagram import Diagram
|
|
358
|
+
sage: D = Diagram([(0,0), (1,1), (2,2), (3,3), (4,4)])
|
|
359
|
+
sage: SM = SGA.specht_module(D)
|
|
360
|
+
sage: SGA.an_element() * SM.an_element()
|
|
361
|
+
15*S[0] + 6*S[1] + 9*S[2] + 6*S[3] + 6*S[4] + 2*S[72] + 2*S[96] + 3*S[97]
|
|
362
|
+
|
|
363
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
364
|
+
sage: SM = SGA.specht_module([3,1])
|
|
365
|
+
sage: SGA.an_element() * SM.an_element()
|
|
366
|
+
9*S[[1, 2, 3], [4]] + 17*S[[1, 2, 4], [3]] + 14*S[[1, 3, 4], [2]]
|
|
367
|
+
sage: 4 * SM.an_element()
|
|
368
|
+
12*S[[1, 2, 3], [4]] + 8*S[[1, 2, 4], [3]] + 8*S[[1, 3, 4], [2]]
|
|
369
|
+
|
|
370
|
+
TESTS::
|
|
371
|
+
|
|
372
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
373
|
+
sage: SM = SGA.specht_module([3,1])
|
|
374
|
+
sage: SM.an_element() * SGA.an_element()
|
|
375
|
+
Traceback (most recent call last):
|
|
376
|
+
...
|
|
377
|
+
TypeError: unsupported operand parent(s) for *:
|
|
378
|
+
'Specht module of [3, 1] over Rational Field'
|
|
379
|
+
and 'Symmetric group algebra of order 4 over Rational Field'
|
|
380
|
+
sage: groups.permutation.Dihedral(3).an_element() * SM.an_element()
|
|
381
|
+
Traceback (most recent call last):
|
|
382
|
+
...
|
|
383
|
+
TypeError: unsupported operand parent(s) for *:
|
|
384
|
+
'Dihedral group of order 6 as a permutation group'
|
|
385
|
+
and 'Specht module of [3, 1] over Rational Field'
|
|
386
|
+
"""
|
|
387
|
+
# Check for a scalar first
|
|
388
|
+
ret = super()._acted_upon_(x, self_on_left)
|
|
389
|
+
if ret is not None:
|
|
390
|
+
return ret
|
|
391
|
+
# Check if it is in the symmetric group algebra
|
|
392
|
+
P = self.parent()
|
|
393
|
+
if x in P._semigroup_algebra or x in P._semigroup_algebra.group():
|
|
394
|
+
if self_on_left: # it is only a left module
|
|
395
|
+
return None
|
|
396
|
+
else:
|
|
397
|
+
return P.retract(P._semigroup_algebra(x) * self.lift())
|
|
398
|
+
return None
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class TabloidModule(SymmetricGroupRepresentation, CombinatorialFreeModule):
|
|
402
|
+
r"""
|
|
403
|
+
The vector space of all tabloids of a fixed shape with the natural
|
|
404
|
+
symmetric group action.
|
|
405
|
+
|
|
406
|
+
A *tabloid* is an :class:`OrderedSetPartition` whose underlying set
|
|
407
|
+
is `\{1, \ldots, n\}`. The symmetric group acts by permuting the
|
|
408
|
+
entries of the set. Hence, this is a representation of the symmetric
|
|
409
|
+
group defined over any field.
|
|
410
|
+
|
|
411
|
+
EXAMPLES::
|
|
412
|
+
|
|
413
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
414
|
+
sage: TM = SGA.tabloid_module([2, 2, 1])
|
|
415
|
+
sage: TM.dimension()
|
|
416
|
+
30
|
|
417
|
+
sage: TM.brauer_character()
|
|
418
|
+
(30, 6, 2, 0, 0)
|
|
419
|
+
sage: IM = TM.invariant_module()
|
|
420
|
+
sage: IM.dimension()
|
|
421
|
+
1
|
|
422
|
+
sage: IM.basis()[0].lift() == sum(TM.basis())
|
|
423
|
+
True
|
|
424
|
+
"""
|
|
425
|
+
@staticmethod
|
|
426
|
+
def __classcall_private__(cls, SGA, shape):
|
|
427
|
+
r"""
|
|
428
|
+
Normalize input to ensure a unique representation.
|
|
429
|
+
|
|
430
|
+
EXAMPLES::
|
|
431
|
+
|
|
432
|
+
sage: from sage.combinat.specht_module import TabloidModule
|
|
433
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
434
|
+
sage: TM1 = TabloidModule(SGA, [2, 2, 1])
|
|
435
|
+
sage: TM2 = TabloidModule(SGA, Partition([2, 2, 1]))
|
|
436
|
+
sage: TM1 is TM2
|
|
437
|
+
True
|
|
438
|
+
|
|
439
|
+
sage: TabloidModule(SGA, [3, 2, 1])
|
|
440
|
+
Traceback (most recent call last):
|
|
441
|
+
...
|
|
442
|
+
ValueError: the domain size (=5) does not match the number of boxes (=6) of the diagram
|
|
443
|
+
"""
|
|
444
|
+
shape = _Partitions(shape)
|
|
445
|
+
if SGA.group().rank() != sum(shape) - 1:
|
|
446
|
+
rk = SGA.group().rank() + 1
|
|
447
|
+
n = sum(shape)
|
|
448
|
+
raise ValueError(f"the domain size (={rk}) does not match the number of boxes (={n}) of the diagram")
|
|
449
|
+
return super().__classcall__(cls, SGA, shape)
|
|
450
|
+
|
|
451
|
+
def __init__(self, SGA, shape):
|
|
452
|
+
r"""
|
|
453
|
+
Initialize ``self``.
|
|
454
|
+
|
|
455
|
+
EXAMPLES::
|
|
456
|
+
|
|
457
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
458
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
459
|
+
sage: TestSuite(TM).run()
|
|
460
|
+
"""
|
|
461
|
+
from sage.combinat.set_partition_ordered import OrderedSetPartitions
|
|
462
|
+
from sage.groups.perm_gps.permgroup_named import SymmetricGroup
|
|
463
|
+
self._shape = shape
|
|
464
|
+
n = sum(shape)
|
|
465
|
+
self._symgp = SymmetricGroup(n)
|
|
466
|
+
cat = ModulesWithBasis(SGA.base_ring()).FiniteDimensional()
|
|
467
|
+
tabloids = OrderedSetPartitions(n, shape)
|
|
468
|
+
CombinatorialFreeModule.__init__(self, SGA.base_ring(), tabloids,
|
|
469
|
+
category=cat, prefix='T', bracket='')
|
|
470
|
+
SymmetricGroupRepresentation.__init__(self, SGA)
|
|
471
|
+
|
|
472
|
+
def _repr_(self):
|
|
473
|
+
r"""
|
|
474
|
+
Return a string representation of ``self``.
|
|
475
|
+
|
|
476
|
+
EXAMPLES::
|
|
477
|
+
|
|
478
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
479
|
+
sage: SGA.tabloid_module([2,2,1])
|
|
480
|
+
Tabloid module of [2, 2, 1] over Rational Field
|
|
481
|
+
"""
|
|
482
|
+
return f"Tabloid module of {self._shape} over {self.base_ring()}"
|
|
483
|
+
|
|
484
|
+
def _latex_(self):
|
|
485
|
+
r"""
|
|
486
|
+
Return a latex representation of ``self``.
|
|
487
|
+
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
491
|
+
sage: latex(SGA.tabloid_module([2,2,1]))
|
|
492
|
+
T^{{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
493
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
|
|
494
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-2}
|
|
495
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-2}
|
|
496
|
+
\lr{\phantom{x}}\\\cline{1-1}
|
|
497
|
+
\end{array}$}
|
|
498
|
+
}}
|
|
499
|
+
"""
|
|
500
|
+
from sage.misc.latex import latex
|
|
501
|
+
return "T^{{{}}}".format(latex(self._shape))
|
|
502
|
+
|
|
503
|
+
def _ascii_art_term(self, T):
|
|
504
|
+
r"""
|
|
505
|
+
Return an ascii art representation of the term indexed by ``T``.
|
|
506
|
+
|
|
507
|
+
EXAMPLES::
|
|
508
|
+
|
|
509
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
510
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
511
|
+
sage: ascii_art(TM.an_element()) # indirect doctest
|
|
512
|
+
2*T + 2*T + 3*T
|
|
513
|
+
{1, 2} {1, 2} {1, 2}
|
|
514
|
+
{3, 4} {3, 5} {4, 5}
|
|
515
|
+
{5} {4} {3}
|
|
516
|
+
"""
|
|
517
|
+
# This is basically copied from CombinatorialFreeModule._ascii_art_term
|
|
518
|
+
from sage.typeset.ascii_art import AsciiArt, ascii_art
|
|
519
|
+
pref = AsciiArt([self.prefix()])
|
|
520
|
+
tab = "\n".join("{" + ", ".join(str(val) for val in sorted(row)) + "}" for row in T)
|
|
521
|
+
if not tab:
|
|
522
|
+
tab = '-'
|
|
523
|
+
r = pref * (AsciiArt([" " * len(pref)]) + ascii_art(tab))
|
|
524
|
+
r._baseline = r._h - 1
|
|
525
|
+
return r
|
|
526
|
+
|
|
527
|
+
def _unicode_art_term(self, T):
|
|
528
|
+
r"""
|
|
529
|
+
Return a unicode art representation of the term indexed by ``T``.
|
|
530
|
+
|
|
531
|
+
EXAMPLES::
|
|
532
|
+
|
|
533
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
534
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
535
|
+
sage: unicode_art(TM.an_element()) # indirect doctest
|
|
536
|
+
2*T + 2*T + 3*T
|
|
537
|
+
{1, 2} {1, 2} {1, 2}
|
|
538
|
+
{3, 4} {3, 5} {4, 5}
|
|
539
|
+
{5} {4} {3}
|
|
540
|
+
"""
|
|
541
|
+
from sage.typeset.unicode_art import unicode_art
|
|
542
|
+
r = unicode_art(repr(self._ascii_art_term(T)))
|
|
543
|
+
r._baseline = r._h - 1
|
|
544
|
+
return r
|
|
545
|
+
|
|
546
|
+
def _latex_term(self, T):
|
|
547
|
+
r"""
|
|
548
|
+
Return a latex representation of the term indexed by ``T``.
|
|
549
|
+
|
|
550
|
+
EXAMPLES::
|
|
551
|
+
|
|
552
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
553
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
554
|
+
sage: latex(TM.an_element()) # indirect doctest
|
|
555
|
+
2 T_{{\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}}
|
|
556
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
|
|
557
|
+
\lr{1}&\lr{2}\\\cline{1-2}
|
|
558
|
+
\lr{3}&\lr{4}\\\cline{1-2}
|
|
559
|
+
\lr{5}\\\cline{1-1}
|
|
560
|
+
\end{array}$}
|
|
561
|
+
}} + 2 T_{{\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}}
|
|
562
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
|
|
563
|
+
\lr{1}&\lr{2}\\\cline{1-2}
|
|
564
|
+
\lr{3}&\lr{5}\\\cline{1-2}
|
|
565
|
+
\lr{4}\\\cline{1-1}
|
|
566
|
+
\end{array}$}
|
|
567
|
+
}} + 3 T_{{\def\lr#1{\multicolumn{1}{@{\hspace{.6ex}}c@{\hspace{.6ex}}}{\raisebox{-.3ex}{$#1$}}}
|
|
568
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
|
|
569
|
+
\lr{1}&\lr{2}\\\cline{1-2}
|
|
570
|
+
\lr{4}&\lr{5}\\\cline{1-2}
|
|
571
|
+
\lr{3}\\\cline{1-1}
|
|
572
|
+
\end{array}$}
|
|
573
|
+
}}
|
|
574
|
+
"""
|
|
575
|
+
if not T:
|
|
576
|
+
tab = "\\emptyset"
|
|
577
|
+
else:
|
|
578
|
+
from sage.combinat.output import tex_from_array
|
|
579
|
+
A = list(map(sorted, T))
|
|
580
|
+
tab = str(tex_from_array(A))
|
|
581
|
+
tab = tab.replace("|", "")
|
|
582
|
+
return f"{self.prefix()}_{{{tab}}}"
|
|
583
|
+
|
|
584
|
+
def _symmetric_group_action(self, osp, g):
|
|
585
|
+
r"""
|
|
586
|
+
Return the action of the symmetric group element ``g`` on the
|
|
587
|
+
ordered set partition ``osp``.
|
|
588
|
+
|
|
589
|
+
EXAMPLES::
|
|
590
|
+
|
|
591
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
592
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
593
|
+
sage: osp = TM._indices([[1,4],[3,5],[2]])
|
|
594
|
+
sage: g = SGA.group().an_element(); g
|
|
595
|
+
[5, 1, 2, 3, 4]
|
|
596
|
+
sage: TM._symmetric_group_action(osp, g)
|
|
597
|
+
[{3, 5}, {2, 4}, {1}]
|
|
598
|
+
"""
|
|
599
|
+
P = self._indices
|
|
600
|
+
g = self._symgp(g)
|
|
601
|
+
return P.element_class(P, [[g(val) for val in row] for row in osp], check=False)
|
|
602
|
+
|
|
603
|
+
def specht_module(self):
|
|
604
|
+
r"""
|
|
605
|
+
Return the Specht submodule of ``self``.
|
|
606
|
+
|
|
607
|
+
EXAMPLES::
|
|
608
|
+
|
|
609
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
610
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
611
|
+
sage: TM.specht_module() is SGA.specht_module([2,2,1])
|
|
612
|
+
True
|
|
613
|
+
"""
|
|
614
|
+
return SpechtModuleTableauxBasis(self)
|
|
615
|
+
|
|
616
|
+
def bilinear_form(self, u, v):
|
|
617
|
+
r"""
|
|
618
|
+
Return the natural bilinear form of ``self`` applied to ``u`` and ``v``.
|
|
619
|
+
|
|
620
|
+
The natural bilinear form is given by defining the tabloid basis
|
|
621
|
+
to be orthonormal.
|
|
622
|
+
|
|
623
|
+
EXAMPLES::
|
|
624
|
+
|
|
625
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
626
|
+
sage: TM = SGA.tabloid_module([2,2,1])
|
|
627
|
+
sage: u = TM.an_element(); u
|
|
628
|
+
2*T[{1, 2}, {3, 4}, {5}] + 2*T[{1, 2}, {3, 5}, {4}] + 3*T[{1, 2}, {4, 5}, {3}]
|
|
629
|
+
sage: v = sum(TM.basis())
|
|
630
|
+
sage: TM.bilinear_form(u, v)
|
|
631
|
+
7
|
|
632
|
+
sage: TM.bilinear_form(u, TM.zero())
|
|
633
|
+
0
|
|
634
|
+
"""
|
|
635
|
+
if len(v) < len(u):
|
|
636
|
+
u, v = v, u
|
|
637
|
+
R = self.base_ring()
|
|
638
|
+
return R.sum(c * v[T] for T, c in u)
|
|
639
|
+
|
|
640
|
+
class Element(CombinatorialFreeModule.Element):
|
|
641
|
+
def _acted_upon_(self, x, self_on_left):
|
|
642
|
+
r"""
|
|
643
|
+
Return the action of ``x`` on ``self``.
|
|
644
|
+
|
|
645
|
+
INPUT:
|
|
646
|
+
|
|
647
|
+
- ``x`` -- an element of the base ring or can be converted into
|
|
648
|
+
the defining symmetric group algebra
|
|
649
|
+
- ``self_on_left`` -- boolean (default: ``False``); which side
|
|
650
|
+
``self`` is on for the action
|
|
651
|
+
|
|
652
|
+
EXAMPLES::
|
|
653
|
+
|
|
654
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
655
|
+
sage: SM = SGA.tabloid_module([2,2,1])
|
|
656
|
+
sage: SGA.an_element() * SM.an_element()
|
|
657
|
+
2*T[{1, 5}, {2, 3}, {4}] + 2*T[{1, 5}, {2, 4}, {3}] + 3*T[{1, 5}, {3, 4}, {2}]
|
|
658
|
+
+ 12*T[{1, 2}, {3, 4}, {5}] + 15*T[{1, 2}, {3, 5}, {4}] + 15*T[{1, 2}, {4, 5}, {3}]
|
|
659
|
+
sage: 4 * SM.an_element()
|
|
660
|
+
8*T[{1, 2}, {3, 4}, {5}] + 8*T[{1, 2}, {3, 5}, {4}] + 12*T[{1, 2}, {4, 5}, {3}]
|
|
661
|
+
sage: SM.an_element() * SGA.an_element()
|
|
662
|
+
Traceback (most recent call last):
|
|
663
|
+
...
|
|
664
|
+
TypeError: unsupported operand parent(s) for *:
|
|
665
|
+
'Tabloid module of [2, 2, 1] over Rational Field'
|
|
666
|
+
and 'Symmetric group algebra of order 5 over Rational Field'
|
|
667
|
+
"""
|
|
668
|
+
# first check for the base action
|
|
669
|
+
ret = super()._acted_upon_(x, self_on_left)
|
|
670
|
+
if ret is not None:
|
|
671
|
+
return ret
|
|
672
|
+
|
|
673
|
+
if self_on_left:
|
|
674
|
+
return None
|
|
675
|
+
P = self.parent()
|
|
676
|
+
if x in P._semigroup_algebra:
|
|
677
|
+
return P.linear_combination((perm * self, c) for perm, c in x.monomial_coefficients().items())
|
|
678
|
+
if x in P._semigroup_algebra.indices():
|
|
679
|
+
return P.element_class(P, {P._symmetric_group_action(T, x): c
|
|
680
|
+
for T, c in self._monomial_coefficients.items()})
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
class SpechtModuleTableauxBasis(SpechtModule):
|
|
684
|
+
r"""
|
|
685
|
+
A Specht module of a partition in the classical standard
|
|
686
|
+
tableau basis.
|
|
687
|
+
|
|
688
|
+
This is constructed as a `S_n`-submodule of the :class:`TabloidModule`
|
|
689
|
+
(also referred to as the standard module).
|
|
690
|
+
|
|
691
|
+
.. SEEALSO::
|
|
692
|
+
|
|
693
|
+
- :class:`SpechtModule` for the generic diagram implementation
|
|
694
|
+
constructed as a left ideal of the group algebra
|
|
695
|
+
- :class:`~sage.combinat.symmetric_group_representations.SpechtRepresentation`
|
|
696
|
+
for an implementation of the representation by matrices.
|
|
697
|
+
"""
|
|
698
|
+
def __init__(self, ambient):
|
|
699
|
+
r"""
|
|
700
|
+
Initialize ``self``.
|
|
701
|
+
|
|
702
|
+
EXAMPLES::
|
|
703
|
+
|
|
704
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
705
|
+
sage: SM = SGA.specht_module([2,2,1])
|
|
706
|
+
sage: TestSuite(SM).run()
|
|
707
|
+
"""
|
|
708
|
+
self._diagram = ambient._shape
|
|
709
|
+
SymmetricGroupRepresentation.__init__(self, ambient._semigroup_algebra)
|
|
710
|
+
|
|
711
|
+
ambient_basis = ambient.basis()
|
|
712
|
+
tabloids = ambient_basis.keys()
|
|
713
|
+
support_order = list(tabloids)
|
|
714
|
+
|
|
715
|
+
def elt(T):
|
|
716
|
+
tab = tabloids.element_class(tabloids, list(T), check=False)
|
|
717
|
+
return ambient.sum_of_terms((ambient._symmetric_group_action(tab, sigma), sigma.sign())
|
|
718
|
+
for sigma in T.column_stabilizer())
|
|
719
|
+
|
|
720
|
+
basis = Family({T: elt(T)
|
|
721
|
+
for T in self._diagram.standard_tableaux()})
|
|
722
|
+
cat = ambient.category().Subobjects()
|
|
723
|
+
SubmoduleWithBasis.__init__(self, basis, support_order, ambient=ambient,
|
|
724
|
+
unitriangular=False, category=cat,
|
|
725
|
+
prefix='S', bracket='')
|
|
726
|
+
|
|
727
|
+
@lazy_attribute
|
|
728
|
+
def lift(self):
|
|
729
|
+
r"""
|
|
730
|
+
The lift (embedding) map from ``self`` to the ambient space.
|
|
731
|
+
|
|
732
|
+
EXAMPLES::
|
|
733
|
+
|
|
734
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
735
|
+
sage: SM = SGA.specht_module([3, 1, 1])
|
|
736
|
+
sage: SM.lift
|
|
737
|
+
Generic morphism:
|
|
738
|
+
From: Specht module of [3, 1, 1] over Rational Field
|
|
739
|
+
To: Tabloid module of [3, 1, 1] over Rational Field
|
|
740
|
+
"""
|
|
741
|
+
return self.module_morphism(self.lift_on_basis, codomain=self.ambient())
|
|
742
|
+
|
|
743
|
+
@lazy_attribute
|
|
744
|
+
def retract(self):
|
|
745
|
+
r"""
|
|
746
|
+
The retract map from the ambient space.
|
|
747
|
+
|
|
748
|
+
EXAMPLES::
|
|
749
|
+
|
|
750
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
751
|
+
sage: X = SGA.tabloid_module([2,2,1])
|
|
752
|
+
sage: Y = X.specht_module()
|
|
753
|
+
sage: Y.retract
|
|
754
|
+
Generic morphism:
|
|
755
|
+
From: Tabloid module of [2, 2, 1] over Rational Field
|
|
756
|
+
To: Specht module of [2, 2, 1] over Rational Field
|
|
757
|
+
sage: all(Y.retract(u.lift()) == u for u in Y.basis())
|
|
758
|
+
True
|
|
759
|
+
|
|
760
|
+
sage: Y.retract(X.zero())
|
|
761
|
+
0
|
|
762
|
+
sage: Y.retract(sum(X.basis()))
|
|
763
|
+
Traceback (most recent call last):
|
|
764
|
+
...
|
|
765
|
+
ValueError: ... is not in the image
|
|
766
|
+
"""
|
|
767
|
+
B = self.basis()
|
|
768
|
+
COB = matrix([b.lift().to_vector() for b in B]).T
|
|
769
|
+
P, L, U = COB.LU()
|
|
770
|
+
# Since U is upper triangular, the nonzero entries must be in the
|
|
771
|
+
# upper square portion of the matrix
|
|
772
|
+
n = len(B)
|
|
773
|
+
|
|
774
|
+
Uinv = U.matrix_from_rows(range(n)).inverse()
|
|
775
|
+
# This is a slight abuse as the codomain should be a module
|
|
776
|
+
# with a different
|
|
777
|
+
# S_n action, but we only use it internally, so there is no problem
|
|
778
|
+
PLinv = (P * L).inverse()
|
|
779
|
+
|
|
780
|
+
def retraction(elt):
|
|
781
|
+
vec = PLinv * elt.to_vector(order=self._support_order)
|
|
782
|
+
if not vec:
|
|
783
|
+
return self.zero()
|
|
784
|
+
# vec is now in the image of self under U, which is
|
|
785
|
+
if max(vec.support()) >= n:
|
|
786
|
+
raise ValueError(f"{elt} is not in the image")
|
|
787
|
+
return self._from_dict(dict(zip(B.keys(), Uinv * vec[:n])))
|
|
788
|
+
|
|
789
|
+
return self._ambient.module_morphism(function=retraction, codomain=self)
|
|
790
|
+
|
|
791
|
+
def bilinear_form(self, u, v):
|
|
792
|
+
r"""
|
|
793
|
+
Return the natural bilinear form of ``self`` applied to ``u`` and ``v``.
|
|
794
|
+
|
|
795
|
+
The natural bilinear form is given by the pullback of the natural
|
|
796
|
+
bilinear form on the tabloid module (where the tabloid basis is an
|
|
797
|
+
orthonormal basis).
|
|
798
|
+
|
|
799
|
+
EXAMPLES::
|
|
800
|
+
|
|
801
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
802
|
+
sage: SM = SGA.specht_module([2,2,1])
|
|
803
|
+
sage: u = SM.an_element(); u
|
|
804
|
+
3*S[[1, 2], [3, 5], [4]] + 2*S[[1, 3], [2, 5], [4]] + 2*S[[1, 4], [2, 5], [3]]
|
|
805
|
+
sage: v = sum(SM.basis())
|
|
806
|
+
sage: SM.bilinear_form(u, v)
|
|
807
|
+
140
|
|
808
|
+
"""
|
|
809
|
+
TM = self._ambient
|
|
810
|
+
return TM.bilinear_form(u.lift(), v.lift())
|
|
811
|
+
|
|
812
|
+
@cached_method
|
|
813
|
+
def gram_matrix(self):
|
|
814
|
+
r"""
|
|
815
|
+
Return the Gram matrix of the natural bilinear form of ``self``.
|
|
816
|
+
|
|
817
|
+
EXAMPLES::
|
|
818
|
+
|
|
819
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
820
|
+
sage: SM = SGA.specht_module([2,2,1])
|
|
821
|
+
sage: M = SM.gram_matrix(); M
|
|
822
|
+
[12 4 -4 -4 4]
|
|
823
|
+
[ 4 12 4 4 4]
|
|
824
|
+
[-4 4 12 4 4]
|
|
825
|
+
[-4 4 4 12 4]
|
|
826
|
+
[ 4 4 4 4 12]
|
|
827
|
+
sage: M.det() != 0
|
|
828
|
+
True
|
|
829
|
+
"""
|
|
830
|
+
B = self.basis()
|
|
831
|
+
M = matrix([[self.bilinear_form(b, bp) for bp in B] for b in B])
|
|
832
|
+
M.set_immutable()
|
|
833
|
+
return M
|
|
834
|
+
|
|
835
|
+
def maximal_submodule(self):
|
|
836
|
+
"""
|
|
837
|
+
Return the maximal submodule of ``self``.
|
|
838
|
+
|
|
839
|
+
EXAMPLES::
|
|
840
|
+
|
|
841
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
842
|
+
sage: SM = SGA.specht_module([3,2])
|
|
843
|
+
sage: U = SM.maximal_submodule()
|
|
844
|
+
sage: U.dimension()
|
|
845
|
+
4
|
|
846
|
+
"""
|
|
847
|
+
return MaximalSpechtSubmodule(self)
|
|
848
|
+
|
|
849
|
+
def simple_module(self):
|
|
850
|
+
r"""
|
|
851
|
+
Return the simple (or irreducible) `S_n`-submodule of ``self``.
|
|
852
|
+
|
|
853
|
+
.. SEEALSO::
|
|
854
|
+
|
|
855
|
+
:class:`~sage.combinat.specht_module.SimpleModule`
|
|
856
|
+
|
|
857
|
+
EXAMPLES::
|
|
858
|
+
|
|
859
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
860
|
+
sage: SM = SGA.specht_module([3,2])
|
|
861
|
+
sage: L = SM.simple_module()
|
|
862
|
+
sage: L.dimension()
|
|
863
|
+
1
|
|
864
|
+
|
|
865
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
866
|
+
sage: SM = SGA.specht_module([3,2])
|
|
867
|
+
sage: SM.simple_module() is SM
|
|
868
|
+
True
|
|
869
|
+
"""
|
|
870
|
+
if self.base_ring().characteristic() == 0:
|
|
871
|
+
return self
|
|
872
|
+
return SimpleModule(self)
|
|
873
|
+
|
|
874
|
+
def intrinsic_arrangement(self, base_ring=None):
|
|
875
|
+
r"""
|
|
876
|
+
Return the intrinsic arrangement of ``self``.
|
|
877
|
+
|
|
878
|
+
Consider the Specht module `S^{\lambda}` with `\lambda` a
|
|
879
|
+
(integer) partition of `n` (i.e., `S^{\lambda}` is an `S_n`-module).
|
|
880
|
+
The *intrinsic arrangement* of `S^{\lambda}` is the central hyperplane
|
|
881
|
+
arrangement in `S^{\lambda}` given by the hyperplanes `H_{\alpha}`,
|
|
882
|
+
indexed by a set partition `\alpha` of `\{1, \ldots, n\}` of size
|
|
883
|
+
`\lambda`, defined by
|
|
884
|
+
|
|
885
|
+
.. MATH::
|
|
886
|
+
|
|
887
|
+
H_{\alpha} := \bigoplus_{\tau \in T_{\alpha}} (S^{\lambda})^{\tau},
|
|
888
|
+
|
|
889
|
+
where `T_{\alpha}` is some set of generating transpositions
|
|
890
|
+
of the Young subgroup `S_{\alpha}` and `V^{\tau}` denotes the
|
|
891
|
+
`\tau`-invariant subspace of `V`. (These hyperplanes do not
|
|
892
|
+
depend on the choice of `T_{\alpha}`.)
|
|
893
|
+
|
|
894
|
+
This was introduced in [TVY2020]_ as a generalization of the
|
|
895
|
+
braid arrangement, which is the case when `\lambda = (n-1, 1)`
|
|
896
|
+
(equivalently, for the irreducible representation of `S_n`
|
|
897
|
+
given by the type `A_{n-1}` root system).
|
|
898
|
+
|
|
899
|
+
EXAMPLES::
|
|
900
|
+
|
|
901
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 4)
|
|
902
|
+
sage: SM = SGA.specht_module([2, 1, 1])
|
|
903
|
+
sage: A = SM.intrinsic_arrangement()
|
|
904
|
+
sage: A.hyperplanes()
|
|
905
|
+
(Hyperplane T0 - T1 - 3*T2 + 0,
|
|
906
|
+
Hyperplane T0 - T1 + T2 + 0,
|
|
907
|
+
Hyperplane T0 + 3*T1 + T2 + 0,
|
|
908
|
+
Hyperplane 3*T0 + T1 - T2 + 0)
|
|
909
|
+
sage: A.is_free()
|
|
910
|
+
False
|
|
911
|
+
|
|
912
|
+
We reproduce Example 3 of [TVY2020]_::
|
|
913
|
+
|
|
914
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
915
|
+
sage: for la in Partitions(5):
|
|
916
|
+
....: SM = SGA.specht_module(la)
|
|
917
|
+
....: A = SM.intrinsic_arrangement()
|
|
918
|
+
....: print(la, A.characteristic_polynomial())
|
|
919
|
+
[5] 1
|
|
920
|
+
[4, 1] x^4 - 10*x^3 + 35*x^2 - 50*x + 24
|
|
921
|
+
[3, 2] x^5 - 15*x^4 + 90*x^3 - 260*x^2 + 350*x - 166
|
|
922
|
+
[3, 1, 1] x^6 - 10*x^5 + 45*x^4 - 115*x^3 + 175*x^2 - 147*x + 51
|
|
923
|
+
[2, 2, 1] x^5 - 10*x^4 + 45*x^3 - 105*x^2 + 120*x - 51
|
|
924
|
+
[2, 1, 1, 1] x^4 - 5*x^3 + 10*x^2 - 10*x + 4
|
|
925
|
+
[1, 1, 1, 1, 1] 1
|
|
926
|
+
|
|
927
|
+
sage: A = SGA.specht_module([4, 1]).intrinsic_arrangement()
|
|
928
|
+
sage: A.characteristic_polynomial().factor()
|
|
929
|
+
(x - 4) * (x - 3) * (x - 2) * (x - 1)
|
|
930
|
+
"""
|
|
931
|
+
from sage.geometry.hyperplane_arrangement.arrangement import HyperplaneArrangements
|
|
932
|
+
from sage.combinat.set_partition import SetPartitions
|
|
933
|
+
if base_ring is None:
|
|
934
|
+
base_ring = self.base_ring()
|
|
935
|
+
|
|
936
|
+
if self.dimension() == 1: # corner case
|
|
937
|
+
HA = HyperplaneArrangements(base_ring, 'T')
|
|
938
|
+
return HA()
|
|
939
|
+
|
|
940
|
+
SGA = self._semigroup_algebra
|
|
941
|
+
G = self._semigroup
|
|
942
|
+
|
|
943
|
+
def t(i, j):
|
|
944
|
+
ret = list(range(1, SGA.n + 1))
|
|
945
|
+
ret[i - 1] = j
|
|
946
|
+
ret[j - 1] = i
|
|
947
|
+
return SGA(G(ret))
|
|
948
|
+
|
|
949
|
+
# Construct the hyperplanes
|
|
950
|
+
fixed_spaces = {}
|
|
951
|
+
norms = []
|
|
952
|
+
for alpha in SetPartitions(SGA.n, self._diagram.conjugate()):
|
|
953
|
+
span = []
|
|
954
|
+
for a in alpha:
|
|
955
|
+
a = list(a)
|
|
956
|
+
for i in range(len(a)-1):
|
|
957
|
+
elt = t(a[i], a[i+1])
|
|
958
|
+
if elt not in fixed_spaces:
|
|
959
|
+
fixed_spaces[elt] = self.annihilator_basis([elt - SGA.one()], side='left')
|
|
960
|
+
span.extend(fixed_spaces[elt])
|
|
961
|
+
H = self.echelon_form(span)
|
|
962
|
+
N = matrix([v.to_vector() for v in H]).right_kernel_matrix()
|
|
963
|
+
assert N.nrows() == 1
|
|
964
|
+
norms.append(N[0])
|
|
965
|
+
|
|
966
|
+
# Convert the data to an arrangement
|
|
967
|
+
HA = HyperplaneArrangements(base_ring, tuple([f'T{i}' for i in range(self.dimension())]))
|
|
968
|
+
return HA([[0] + list(N) for N in norms])
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
class MaximalSpechtSubmodule(SymmetricGroupRepresentation, SubmoduleWithBasis):
|
|
972
|
+
r"""
|
|
973
|
+
The maximal submodule `U^{\lambda}` of the Specht module `S^{\lambda}`.
|
|
974
|
+
|
|
975
|
+
ALGORITHM:
|
|
976
|
+
|
|
977
|
+
We construct `U^{\lambda}` as the intersection `S \cap S^{\perp}`,
|
|
978
|
+
where `S^{\perp}` is the orthogonal complement of the Specht module `S`
|
|
979
|
+
inside of the tabloid module `T` (with respect to the natural
|
|
980
|
+
bilinear form on `T`).
|
|
981
|
+
|
|
982
|
+
EXAMPLES::
|
|
983
|
+
|
|
984
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
985
|
+
sage: SM = SGA.specht_module([3,2])
|
|
986
|
+
sage: U = SM.maximal_submodule()
|
|
987
|
+
sage: u = U.an_element(); u
|
|
988
|
+
2*U[0] + 2*U[1]
|
|
989
|
+
sage: [p * u for p in list(SGA.basis())[:4]]
|
|
990
|
+
[2*U[0] + 2*U[1], 2*U[2] + 2*U[3], 2*U[0] + 2*U[1], U[0] + 2*U[2]]
|
|
991
|
+
sage: sum(SGA.basis()) * u
|
|
992
|
+
0
|
|
993
|
+
"""
|
|
994
|
+
def __init__(self, specht_module):
|
|
995
|
+
r"""
|
|
996
|
+
Initialize ``self``.
|
|
997
|
+
|
|
998
|
+
EXAMPLES::
|
|
999
|
+
|
|
1000
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1001
|
+
sage: SM = SGA.specht_module([3,2])
|
|
1002
|
+
sage: U = SM.maximal_submodule()
|
|
1003
|
+
sage: TestSuite(U).run()
|
|
1004
|
+
|
|
1005
|
+
sage: SM = SGA.specht_module([2,1,1,1])
|
|
1006
|
+
sage: SM.maximal_submodule().dimension() == SM.dimension()
|
|
1007
|
+
True
|
|
1008
|
+
|
|
1009
|
+
sage: SGA = SymmetricGroupAlgebra(QQ, 5)
|
|
1010
|
+
sage: SM = SGA.specht_module([3,2])
|
|
1011
|
+
sage: U = SM.maximal_submodule()
|
|
1012
|
+
sage: TestSuite(U).run()
|
|
1013
|
+
sage: U.dimension()
|
|
1014
|
+
0
|
|
1015
|
+
"""
|
|
1016
|
+
SymmetricGroupRepresentation.__init__(self, specht_module._semigroup_algebra)
|
|
1017
|
+
|
|
1018
|
+
p = specht_module.base_ring().characteristic()
|
|
1019
|
+
if p == 0:
|
|
1020
|
+
basis = Family([])
|
|
1021
|
+
else:
|
|
1022
|
+
TM = specht_module._ambient
|
|
1023
|
+
if not TM._shape.is_regular(p):
|
|
1024
|
+
basis = specht_module.basis()
|
|
1025
|
+
else:
|
|
1026
|
+
TV = TM._dense_free_module()
|
|
1027
|
+
SV = TV.submodule(specht_module.lift.matrix().columns())
|
|
1028
|
+
basis = (SV & SV.complement()).basis()
|
|
1029
|
+
basis = [specht_module.retract(TM.from_vector(b)) for b in basis]
|
|
1030
|
+
basis = Family(specht_module.echelon_form(basis))
|
|
1031
|
+
|
|
1032
|
+
unitriangular = all(b.leading_support() == 1 for b in basis)
|
|
1033
|
+
support_order = list(specht_module.basis().keys())
|
|
1034
|
+
cat = specht_module.category().Subobjects()
|
|
1035
|
+
SubmoduleWithBasis.__init__(self, basis, support_order, ambient=specht_module,
|
|
1036
|
+
unitriangular=unitriangular, category=cat,
|
|
1037
|
+
prefix='U')
|
|
1038
|
+
|
|
1039
|
+
def _repr_(self):
|
|
1040
|
+
r"""
|
|
1041
|
+
Return a string representation of ``self``.
|
|
1042
|
+
|
|
1043
|
+
EXAMPLES::
|
|
1044
|
+
|
|
1045
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1046
|
+
sage: SM = SGA.specht_module([3,2])
|
|
1047
|
+
sage: SM.maximal_submodule()
|
|
1048
|
+
Maximal submodule of Specht module of [3, 2] over Finite Field of size 3
|
|
1049
|
+
"""
|
|
1050
|
+
return f"Maximal submodule of {self._ambient}"
|
|
1051
|
+
|
|
1052
|
+
def _latex_(self):
|
|
1053
|
+
r"""
|
|
1054
|
+
Return a latex representation of ``self``.
|
|
1055
|
+
|
|
1056
|
+
EXAMPLES::
|
|
1057
|
+
|
|
1058
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1059
|
+
sage: latex(SGA.specht_module([2,2,1]).maximal_submodule())
|
|
1060
|
+
U^{{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
1061
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
|
|
1062
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-2}
|
|
1063
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-2}
|
|
1064
|
+
\lr{\phantom{x}}\\\cline{1-1}
|
|
1065
|
+
\end{array}$}
|
|
1066
|
+
}}
|
|
1067
|
+
"""
|
|
1068
|
+
from sage.misc.latex import latex
|
|
1069
|
+
return "U^{{{}}}".format(latex(self._ambient._diagram))
|
|
1070
|
+
|
|
1071
|
+
Element = SpechtModule.Element
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
class SimpleModule(SymmetricGroupRepresentation, QuotientModuleWithBasis):
|
|
1075
|
+
r"""
|
|
1076
|
+
The simple `S_n`-module associated with a partition `\lambda`.
|
|
1077
|
+
|
|
1078
|
+
The simple module `D^{\lambda}` is the quotient of the Specht module
|
|
1079
|
+
`S^{\lambda}` by its :class:`maximal submodule <MaximalSpechtSubmodule>`
|
|
1080
|
+
`U^{\lambda}`.
|
|
1081
|
+
|
|
1082
|
+
EXAMPLES::
|
|
1083
|
+
|
|
1084
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1085
|
+
sage: SM = SGA.specht_module([3,1,1])
|
|
1086
|
+
sage: D = SM.simple_module()
|
|
1087
|
+
sage: v = D.an_element(); v
|
|
1088
|
+
2*D[[[1, 3, 5], [2], [4]]] + 2*D[[[1, 4, 5], [2], [3]]]
|
|
1089
|
+
sage: SGA.an_element() * v
|
|
1090
|
+
2*D[[[1, 2, 4], [3], [5]]] + 2*D[[[1, 3, 5], [2], [4]]]
|
|
1091
|
+
|
|
1092
|
+
We give an example on how to construct the decomposition matrix
|
|
1093
|
+
(the Specht modules are a complete set of irreducible projective
|
|
1094
|
+
modules) and the Cartan matrix of a symmetric group algebra::
|
|
1095
|
+
|
|
1096
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 4)
|
|
1097
|
+
sage: BM = matrix(SGA.simple_module(la).brauer_character()
|
|
1098
|
+
....: for la in Partitions(4, regular=3))
|
|
1099
|
+
sage: SBT = matrix(SGA.specht_module(la).brauer_character()
|
|
1100
|
+
....: for la in Partitions(4))
|
|
1101
|
+
sage: D = SBT * ~BM; D
|
|
1102
|
+
[1 0 0 0]
|
|
1103
|
+
[0 1 0 0]
|
|
1104
|
+
[1 0 1 0]
|
|
1105
|
+
[0 0 0 1]
|
|
1106
|
+
[0 0 1 0]
|
|
1107
|
+
sage: D.transpose() * D
|
|
1108
|
+
[2 0 1 0]
|
|
1109
|
+
[0 1 0 0]
|
|
1110
|
+
[1 0 2 0]
|
|
1111
|
+
[0 0 0 1]
|
|
1112
|
+
|
|
1113
|
+
We verify this against the direct computation (up to reindexing the
|
|
1114
|
+
rows and columns)::
|
|
1115
|
+
|
|
1116
|
+
sage: SGA.cartan_invariants_matrix() # long time
|
|
1117
|
+
[1 0 0 0]
|
|
1118
|
+
[0 1 0 0]
|
|
1119
|
+
[0 0 2 1]
|
|
1120
|
+
[0 0 1 2]
|
|
1121
|
+
"""
|
|
1122
|
+
def __init__(self, specht_module):
|
|
1123
|
+
r"""
|
|
1124
|
+
Initialize ``self``.
|
|
1125
|
+
|
|
1126
|
+
EXAMPLES::
|
|
1127
|
+
|
|
1128
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1129
|
+
sage: SM = SGA.specht_module([3,1,1])
|
|
1130
|
+
sage: D = SM.simple_module()
|
|
1131
|
+
sage: TestSuite(D).run()
|
|
1132
|
+
|
|
1133
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1134
|
+
sage: SM = SGA.specht_module([2,1,1,1])
|
|
1135
|
+
sage: SM.simple_module()
|
|
1136
|
+
Traceback (most recent call last):
|
|
1137
|
+
...
|
|
1138
|
+
ValueError: the partition must be 3-regular
|
|
1139
|
+
"""
|
|
1140
|
+
self._diagram = specht_module._diagram
|
|
1141
|
+
p = specht_module.base_ring().characteristic()
|
|
1142
|
+
if not self._diagram.is_regular(p):
|
|
1143
|
+
raise ValueError(f"the partition must be {p}-regular")
|
|
1144
|
+
SymmetricGroupRepresentation.__init__(self, specht_module._semigroup_algebra)
|
|
1145
|
+
cat = specht_module.category()
|
|
1146
|
+
QuotientModuleWithBasis.__init__(self, specht_module.maximal_submodule(), cat, prefix='D')
|
|
1147
|
+
|
|
1148
|
+
def _repr_(self):
|
|
1149
|
+
r"""
|
|
1150
|
+
Return a string representation of ``self``.
|
|
1151
|
+
|
|
1152
|
+
EXAMPLES::
|
|
1153
|
+
|
|
1154
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1155
|
+
sage: SM = SGA.specht_module([3,1,1])
|
|
1156
|
+
sage: SM.simple_module()
|
|
1157
|
+
Simple module of [3, 1, 1] over Finite Field of size 3
|
|
1158
|
+
"""
|
|
1159
|
+
return f"Simple module of {self._diagram} over {self.base_ring()}"
|
|
1160
|
+
|
|
1161
|
+
def _latex_(self):
|
|
1162
|
+
r"""
|
|
1163
|
+
Return a latex representation of ``self``.
|
|
1164
|
+
|
|
1165
|
+
EXAMPLES::
|
|
1166
|
+
|
|
1167
|
+
sage: SGA = SymmetricGroupAlgebra(GF(3), 5)
|
|
1168
|
+
sage: latex(SGA.simple_module([2,2,1]))
|
|
1169
|
+
D^{{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
|
|
1170
|
+
\raisebox{-.6ex}{$\begin{array}[b]{*{2}c}\cline{1-2}
|
|
1171
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-2}
|
|
1172
|
+
\lr{\phantom{x}}&\lr{\phantom{x}}\\\cline{1-2}
|
|
1173
|
+
\lr{\phantom{x}}\\\cline{1-1}
|
|
1174
|
+
\end{array}$}
|
|
1175
|
+
}}
|
|
1176
|
+
"""
|
|
1177
|
+
from sage.misc.latex import latex
|
|
1178
|
+
return "D^{{{}}}".format(latex(self._diagram))
|
|
1179
|
+
|
|
1180
|
+
Element = SpechtModule.Element
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
def _to_diagram(D):
|
|
1184
|
+
r"""
|
|
1185
|
+
Convert ``D`` to a list of cells representing a diagram.
|
|
1186
|
+
|
|
1187
|
+
TESTS::
|
|
1188
|
+
|
|
1189
|
+
sage: from sage.combinat.specht_module import _to_diagram
|
|
1190
|
+
sage: _to_diagram(Partition([3,1,1]))
|
|
1191
|
+
[(0, 0), (0, 1), (0, 2), (1, 0), (2, 0)]
|
|
1192
|
+
sage: _to_diagram(SkewPartition([[5,3,1,1],[2,2,1]]))
|
|
1193
|
+
[(0, 2), (0, 3), (0, 4), (1, 2), (3, 0)]
|
|
1194
|
+
sage: _to_diagram([1,2,0,2])
|
|
1195
|
+
[(0, 0), (1, 0), (1, 1), (3, 0), (3, 1)]
|
|
1196
|
+
sage: _to_diagram(Composition([2,1,3]))
|
|
1197
|
+
[(0, 0), (0, 1), (1, 0), (2, 0), (2, 1), (2, 2)]
|
|
1198
|
+
sage: _to_diagram([(1,2), (2,2)])
|
|
1199
|
+
[(1, 2), (2, 2)]
|
|
1200
|
+
"""
|
|
1201
|
+
from sage.combinat.integer_vector import IntegerVectors
|
|
1202
|
+
from sage.combinat.skew_partition import SkewPartitions
|
|
1203
|
+
if isinstance(D, Diagram):
|
|
1204
|
+
return D
|
|
1205
|
+
if D in _Partitions:
|
|
1206
|
+
return _Partitions(D).cells()
|
|
1207
|
+
if D in SkewPartitions():
|
|
1208
|
+
return SkewPartitions()(D).cells()
|
|
1209
|
+
if D in IntegerVectors():
|
|
1210
|
+
return [(i, j) for i, row in enumerate(D) for j in range(row)]
|
|
1211
|
+
return [tuple(cell) for cell in D]
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
def specht_module_spanning_set(D, SGA=None):
|
|
1215
|
+
r"""
|
|
1216
|
+
Return a spanning set of the Specht module of diagram ``D``.
|
|
1217
|
+
|
|
1218
|
+
INPUT:
|
|
1219
|
+
|
|
1220
|
+
- ``D`` -- list of cells ``(r,c)`` for row ``r`` and column ``c``
|
|
1221
|
+
- ``SGA`` -- (optional) a symmetric group algebra
|
|
1222
|
+
|
|
1223
|
+
EXAMPLES::
|
|
1224
|
+
|
|
1225
|
+
sage: from sage.combinat.specht_module import specht_module_spanning_set
|
|
1226
|
+
sage: specht_module_spanning_set([(0,0), (1,1), (2,2)])
|
|
1227
|
+
([1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1])
|
|
1228
|
+
sage: specht_module_spanning_set([(0,0), (1,1), (2,1)])
|
|
1229
|
+
([1, 2, 3] - [1, 3, 2], -[1, 2, 3] + [1, 3, 2], [2, 1, 3] - [3, 1, 2],
|
|
1230
|
+
[2, 3, 1] - [3, 2, 1], -[2, 1, 3] + [3, 1, 2], -[2, 3, 1] + [3, 2, 1])
|
|
1231
|
+
|
|
1232
|
+
sage: SGA = SymmetricGroup(3).algebra(QQ)
|
|
1233
|
+
sage: specht_module_spanning_set([(0,0), (1,1), (2,1)], SGA)
|
|
1234
|
+
(() - (2,3), -(1,2) + (1,3,2), (1,2,3) - (1,3),
|
|
1235
|
+
-() + (2,3), -(1,2,3) + (1,3), (1,2) - (1,3,2))
|
|
1236
|
+
|
|
1237
|
+
TESTS:
|
|
1238
|
+
|
|
1239
|
+
Verify that diagrams bigger than the rank work::
|
|
1240
|
+
|
|
1241
|
+
sage: specht_module_spanning_set([(0,0), (3,5)])
|
|
1242
|
+
([1, 2], [2, 1])
|
|
1243
|
+
sage: specht_module_spanning_set([(0,0), (5,3)])
|
|
1244
|
+
([1, 2], [2, 1])
|
|
1245
|
+
"""
|
|
1246
|
+
n = len(D)
|
|
1247
|
+
if SGA is None:
|
|
1248
|
+
from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra
|
|
1249
|
+
SGA = SymmetricGroupAlgebra(QQ, n)
|
|
1250
|
+
elif SGA.group().rank() != n - 1:
|
|
1251
|
+
raise ValueError("the rank does not match the size of the diagram")
|
|
1252
|
+
nr = max((c[0] for c in D), default=0) + 1
|
|
1253
|
+
nc = max((c[1] for c in D), default=0) + 1
|
|
1254
|
+
row_diagram = [set() for _ in range(nr)]
|
|
1255
|
+
col_diagram = [set() for _ in range(nc)]
|
|
1256
|
+
for i, cell in enumerate(D):
|
|
1257
|
+
x, y = cell
|
|
1258
|
+
row_diagram[x].add(i)
|
|
1259
|
+
col_diagram[y].add(i)
|
|
1260
|
+
# Construct the row and column stabilizer elements
|
|
1261
|
+
row_stab = SGA.zero()
|
|
1262
|
+
col_stab = SGA.zero()
|
|
1263
|
+
B = SGA.basis()
|
|
1264
|
+
for w in B.keys():
|
|
1265
|
+
# Remember that the permutation w is 1-based
|
|
1266
|
+
row_perm = [set() for _ in range(nr)]
|
|
1267
|
+
col_perm = [set() for _ in range(nc)]
|
|
1268
|
+
for i, cell in enumerate(D):
|
|
1269
|
+
x, y = cell
|
|
1270
|
+
row_perm[x].add(w(i + 1) - 1)
|
|
1271
|
+
col_perm[y].add(w(i + 1) - 1)
|
|
1272
|
+
if row_diagram == row_perm:
|
|
1273
|
+
row_stab += B[w]
|
|
1274
|
+
if col_diagram == col_perm:
|
|
1275
|
+
col_stab += w.sign() * B[w]
|
|
1276
|
+
gen = col_stab * row_stab
|
|
1277
|
+
return tuple([b * gen for b in B])
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
def specht_module_rank(D, base_ring=None):
|
|
1281
|
+
r"""
|
|
1282
|
+
Return the rank of the Specht module of diagram ``D``.
|
|
1283
|
+
|
|
1284
|
+
EXAMPLES::
|
|
1285
|
+
|
|
1286
|
+
sage: from sage.combinat.specht_module import specht_module_rank
|
|
1287
|
+
sage: specht_module_rank([(0,0), (1,1), (2,2)])
|
|
1288
|
+
6
|
|
1289
|
+
"""
|
|
1290
|
+
D = _to_diagram(D)
|
|
1291
|
+
span_set = specht_module_spanning_set(D)
|
|
1292
|
+
if base_ring is None:
|
|
1293
|
+
base_ring = QQ
|
|
1294
|
+
return matrix(base_ring, [v.to_vector() for v in span_set]).rank()
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
def polytabloid(T):
|
|
1298
|
+
r"""
|
|
1299
|
+
Compute the polytabloid element associated to a tableau ``T``.
|
|
1300
|
+
|
|
1301
|
+
For a tableau `T`, the polytabloid associated to `T` is
|
|
1302
|
+
|
|
1303
|
+
.. MATH::
|
|
1304
|
+
|
|
1305
|
+
e_T = \sum_{\sigma \in C_T} (-1)^{\sigma} \{\sigma T\},
|
|
1306
|
+
|
|
1307
|
+
where `\{\}` is the row-equivalence class, i.e. a tabloid,
|
|
1308
|
+
and `C_T` is the column stabilizer of `T`. The sum takes place in
|
|
1309
|
+
the module spanned by tabloids `\{T\}`.
|
|
1310
|
+
|
|
1311
|
+
OUTPUT:
|
|
1312
|
+
|
|
1313
|
+
A ``dict`` whose keys are tabloids represented by tuples of frozensets
|
|
1314
|
+
and whose values are the coefficient.
|
|
1315
|
+
|
|
1316
|
+
EXAMPLES::
|
|
1317
|
+
|
|
1318
|
+
sage: from sage.combinat.specht_module import polytabloid
|
|
1319
|
+
sage: T = StandardTableau([[1,3,4],[2,5]])
|
|
1320
|
+
sage: polytabloid(T)
|
|
1321
|
+
{(frozenset({1, 3, 4}), frozenset({2, 5})): 1,
|
|
1322
|
+
(frozenset({1, 4, 5}), frozenset({2, 3})): -1,
|
|
1323
|
+
(frozenset({2, 3, 4}), frozenset({1, 5})): -1,
|
|
1324
|
+
(frozenset({2, 4, 5}), frozenset({1, 3})): 1}
|
|
1325
|
+
"""
|
|
1326
|
+
e_T = {}
|
|
1327
|
+
C_T = T.column_stabilizer()
|
|
1328
|
+
for perm in C_T:
|
|
1329
|
+
TT = tuple([frozenset(perm(val) for val in row) for row in T])
|
|
1330
|
+
if TT in e_T:
|
|
1331
|
+
e_T[TT] += perm.sign()
|
|
1332
|
+
else:
|
|
1333
|
+
e_T[TT] = perm.sign()
|
|
1334
|
+
return e_T
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
def tabloid_gram_matrix(la, base_ring):
|
|
1338
|
+
r"""
|
|
1339
|
+
Compute the Gram matrix of the bilinear form of a Specht module
|
|
1340
|
+
pulled back from the tabloid module.
|
|
1341
|
+
|
|
1342
|
+
For the module spanned by all tabloids, we define an bilinear form
|
|
1343
|
+
by having the tabloids be an orthonormal basis. We then pull this
|
|
1344
|
+
bilinear form back across the natural injection of the Specht module
|
|
1345
|
+
into the tabloid module.
|
|
1346
|
+
|
|
1347
|
+
EXAMPLES::
|
|
1348
|
+
|
|
1349
|
+
sage: from sage.combinat.specht_module import tabloid_gram_matrix
|
|
1350
|
+
sage: tabloid_gram_matrix([3,2], GF(5))
|
|
1351
|
+
[4 2 2 1 4]
|
|
1352
|
+
[2 4 1 2 1]
|
|
1353
|
+
[2 1 4 2 1]
|
|
1354
|
+
[1 2 2 4 2]
|
|
1355
|
+
[4 1 1 2 4]
|
|
1356
|
+
"""
|
|
1357
|
+
from sage.combinat.tableau import StandardTableaux
|
|
1358
|
+
ST = list(StandardTableaux(la))
|
|
1359
|
+
|
|
1360
|
+
def bilinear_form(p1, p2):
|
|
1361
|
+
if len(p2) < len(p1):
|
|
1362
|
+
p1, p2 = p2, p1
|
|
1363
|
+
return sum(c1 * p2[T1] for T1, c1 in p1.items() if c1 and T1 in p2)
|
|
1364
|
+
|
|
1365
|
+
PT = {T: polytabloid(T) for T in ST}
|
|
1366
|
+
gram_matrix = [[bilinear_form(PT[T1], PT[T2]) for T1 in ST] for T2 in ST]
|
|
1367
|
+
return matrix(base_ring, gram_matrix)
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
def simple_module_rank(la, base_ring):
|
|
1371
|
+
r"""
|
|
1372
|
+
Return the rank of the simple `S_n`-module corresponding to the
|
|
1373
|
+
partition ``la`` of size `n` over ``base_ring``.
|
|
1374
|
+
|
|
1375
|
+
EXAMPLES::
|
|
1376
|
+
|
|
1377
|
+
sage: from sage.combinat.specht_module import simple_module_rank
|
|
1378
|
+
sage: simple_module_rank([3,2,1,1], GF(3))
|
|
1379
|
+
13
|
|
1380
|
+
|
|
1381
|
+
TESTS::
|
|
1382
|
+
|
|
1383
|
+
sage: from sage.combinat.specht_module import simple_module_rank
|
|
1384
|
+
sage: simple_module_rank([1,1,1,1], GF(3))
|
|
1385
|
+
Traceback (most recent call last):
|
|
1386
|
+
...
|
|
1387
|
+
ValueError: the partition [1, 1, 1, 1] is not 3-regular
|
|
1388
|
+
|
|
1389
|
+
sage: from sage.combinat.specht_module import simple_module_rank
|
|
1390
|
+
sage: simple_module_rank([2,1], GF(3)['x'])
|
|
1391
|
+
Traceback (most recent call last):
|
|
1392
|
+
...
|
|
1393
|
+
NotImplementedError: the base must be a field
|
|
1394
|
+
"""
|
|
1395
|
+
from sage.categories.fields import Fields
|
|
1396
|
+
from sage.combinat.partition import Partition
|
|
1397
|
+
if base_ring not in Fields():
|
|
1398
|
+
raise NotImplementedError("the base must be a field")
|
|
1399
|
+
p = base_ring.characteristic()
|
|
1400
|
+
la = Partition(la)
|
|
1401
|
+
if not la.is_regular(p):
|
|
1402
|
+
raise ValueError(f"the partition {la} is not {p}-regular")
|
|
1403
|
+
return tabloid_gram_matrix(la, base_ring).rank()
|