passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_combinat/__init__.py +3 -0
- passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
- passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
- passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
- passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
- passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
- sage/algebras/affine_nil_temperley_lieb.py +263 -0
- sage/algebras/all.py +24 -0
- sage/algebras/all__sagemath_combinat.py +35 -0
- sage/algebras/askey_wilson.py +935 -0
- sage/algebras/associated_graded.py +345 -0
- sage/algebras/cellular_basis.py +350 -0
- sage/algebras/cluster_algebra.py +2766 -0
- sage/algebras/down_up_algebra.py +860 -0
- sage/algebras/free_algebra.py +1698 -0
- sage/algebras/free_algebra_element.py +345 -0
- sage/algebras/free_algebra_quotient.py +405 -0
- sage/algebras/free_algebra_quotient_element.py +295 -0
- sage/algebras/free_zinbiel_algebra.py +885 -0
- sage/algebras/hall_algebra.py +783 -0
- sage/algebras/hecke_algebras/all.py +4 -0
- sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
- sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
- sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
- sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
- sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
- sage/algebras/iwahori_hecke_algebra.py +3095 -0
- sage/algebras/jordan_algebra.py +1773 -0
- sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
- sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
- sage/algebras/lie_conformal_algebras/all.py +18 -0
- sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
- sage/algebras/lie_conformal_algebras/examples.py +43 -0
- sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
- sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
- sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
- sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
- sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
- sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
- sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
- sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
- sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
- sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
- sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
- sage/algebras/nil_coxeter_algebra.py +191 -0
- sage/algebras/q_commuting_polynomials.py +673 -0
- sage/algebras/q_system.py +608 -0
- sage/algebras/quantum_clifford.py +959 -0
- sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
- sage/algebras/quantum_groups/all.py +9 -0
- sage/algebras/quantum_groups/fock_space.py +2219 -0
- sage/algebras/quantum_groups/q_numbers.py +207 -0
- sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
- sage/algebras/quantum_groups/representations.py +591 -0
- sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
- sage/algebras/quantum_oscillator.py +623 -0
- sage/algebras/quaternion_algebra.py +20 -0
- sage/algebras/quaternion_algebra_element.py +55 -0
- sage/algebras/rational_cherednik_algebra.py +525 -0
- sage/algebras/schur_algebra.py +670 -0
- sage/algebras/shuffle_algebra.py +1011 -0
- sage/algebras/splitting_algebra.py +779 -0
- sage/algebras/tensor_algebra.py +709 -0
- sage/algebras/yangian.py +1082 -0
- sage/algebras/yokonuma_hecke_algebra.py +1018 -0
- sage/all__sagemath_combinat.py +35 -0
- sage/combinat/SJT.py +255 -0
- sage/combinat/affine_permutation.py +2405 -0
- sage/combinat/algebraic_combinatorics.py +55 -0
- sage/combinat/all.py +53 -0
- sage/combinat/all__sagemath_combinat.py +195 -0
- sage/combinat/alternating_sign_matrix.py +2063 -0
- sage/combinat/baxter_permutations.py +346 -0
- sage/combinat/bijectionist.py +3220 -0
- sage/combinat/binary_recurrence_sequences.py +1180 -0
- sage/combinat/blob_algebra.py +685 -0
- sage/combinat/catalog_partitions.py +27 -0
- sage/combinat/chas/all.py +23 -0
- sage/combinat/chas/fsym.py +1180 -0
- sage/combinat/chas/wqsym.py +2601 -0
- sage/combinat/cluster_complex.py +326 -0
- sage/combinat/colored_permutations.py +2039 -0
- sage/combinat/colored_permutations_representations.py +964 -0
- sage/combinat/composition_signed.py +142 -0
- sage/combinat/composition_tableau.py +855 -0
- sage/combinat/constellation.py +1729 -0
- sage/combinat/core.py +751 -0
- sage/combinat/counting.py +12 -0
- sage/combinat/crystals/affine.py +742 -0
- sage/combinat/crystals/affine_factorization.py +518 -0
- sage/combinat/crystals/affinization.py +331 -0
- sage/combinat/crystals/alcove_path.py +2013 -0
- sage/combinat/crystals/all.py +22 -0
- sage/combinat/crystals/bkk_crystals.py +141 -0
- sage/combinat/crystals/catalog.py +115 -0
- sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
- sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
- sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
- sage/combinat/crystals/crystals.py +257 -0
- sage/combinat/crystals/direct_sum.py +260 -0
- sage/combinat/crystals/elementary_crystals.py +1251 -0
- sage/combinat/crystals/fast_crystals.py +441 -0
- sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
- sage/combinat/crystals/generalized_young_walls.py +1076 -0
- sage/combinat/crystals/highest_weight_crystals.py +436 -0
- sage/combinat/crystals/induced_structure.py +695 -0
- sage/combinat/crystals/infinity_crystals.py +730 -0
- sage/combinat/crystals/kac_modules.py +863 -0
- sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
- sage/combinat/crystals/kyoto_path_model.py +497 -0
- sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/letters.pxd +79 -0
- sage/combinat/crystals/letters.pyx +3056 -0
- sage/combinat/crystals/littelmann_path.py +1518 -0
- sage/combinat/crystals/monomial_crystals.py +1262 -0
- sage/combinat/crystals/multisegments.py +462 -0
- sage/combinat/crystals/mv_polytopes.py +467 -0
- sage/combinat/crystals/pbw_crystal.py +511 -0
- sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/pbw_datum.pxd +4 -0
- sage/combinat/crystals/pbw_datum.pyx +487 -0
- sage/combinat/crystals/polyhedral_realization.py +372 -0
- sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/spins.pxd +21 -0
- sage/combinat/crystals/spins.pyx +756 -0
- sage/combinat/crystals/star_crystal.py +290 -0
- sage/combinat/crystals/subcrystal.py +464 -0
- sage/combinat/crystals/tensor_product.py +1177 -0
- sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/crystals/tensor_product_element.pxd +35 -0
- sage/combinat/crystals/tensor_product_element.pyx +1870 -0
- sage/combinat/crystals/virtual_crystal.py +420 -0
- sage/combinat/cyclic_sieving_phenomenon.py +204 -0
- sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/debruijn_sequence.pyx +355 -0
- sage/combinat/decorated_permutation.py +270 -0
- sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/degree_sequences.pyx +588 -0
- sage/combinat/derangements.py +527 -0
- sage/combinat/descent_algebra.py +1008 -0
- sage/combinat/diagram.py +1551 -0
- sage/combinat/diagram_algebras.py +5886 -0
- sage/combinat/dyck_word.py +4349 -0
- sage/combinat/e_one_star.py +1623 -0
- sage/combinat/enumerated_sets.py +123 -0
- sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/expnums.pyx +148 -0
- sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/fast_vector_partitions.pyx +346 -0
- sage/combinat/fqsym.py +1977 -0
- sage/combinat/free_dendriform_algebra.py +954 -0
- sage/combinat/free_prelie_algebra.py +1141 -0
- sage/combinat/fully_commutative_elements.py +1077 -0
- sage/combinat/fully_packed_loop.py +1523 -0
- sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
- sage/combinat/gray_codes.py +311 -0
- sage/combinat/grossman_larson_algebras.py +667 -0
- sage/combinat/growth.py +4352 -0
- sage/combinat/hall_polynomial.py +188 -0
- sage/combinat/hillman_grassl.py +866 -0
- sage/combinat/integer_matrices.py +329 -0
- sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
- sage/combinat/k_tableau.py +4564 -0
- sage/combinat/kazhdan_lusztig.py +215 -0
- sage/combinat/key_polynomial.py +885 -0
- sage/combinat/knutson_tao_puzzles.py +2286 -0
- sage/combinat/lr_tableau.py +311 -0
- sage/combinat/matrices/all.py +24 -0
- sage/combinat/matrices/hadamard_matrix.py +3790 -0
- sage/combinat/matrices/latin.py +2912 -0
- sage/combinat/misc.py +401 -0
- sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
- sage/combinat/ncsf_qsym/all.py +21 -0
- sage/combinat/ncsf_qsym/combinatorics.py +317 -0
- sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
- sage/combinat/ncsf_qsym/ncsf.py +5637 -0
- sage/combinat/ncsf_qsym/qsym.py +4053 -0
- sage/combinat/ncsf_qsym/tutorial.py +447 -0
- sage/combinat/ncsym/all.py +21 -0
- sage/combinat/ncsym/bases.py +855 -0
- sage/combinat/ncsym/dual.py +593 -0
- sage/combinat/ncsym/ncsym.py +2076 -0
- sage/combinat/necklace.py +551 -0
- sage/combinat/non_decreasing_parking_function.py +634 -0
- sage/combinat/nu_dyck_word.py +1474 -0
- sage/combinat/output.py +861 -0
- sage/combinat/parallelogram_polyomino.py +4326 -0
- sage/combinat/parking_functions.py +1602 -0
- sage/combinat/partition_algebra.py +1998 -0
- sage/combinat/partition_kleshchev.py +1982 -0
- sage/combinat/partition_shifting_algebras.py +584 -0
- sage/combinat/partition_tuple.py +3114 -0
- sage/combinat/path_tableaux/all.py +13 -0
- sage/combinat/path_tableaux/catalog.py +29 -0
- sage/combinat/path_tableaux/dyck_path.py +380 -0
- sage/combinat/path_tableaux/frieze.py +476 -0
- sage/combinat/path_tableaux/path_tableau.py +728 -0
- sage/combinat/path_tableaux/semistandard.py +510 -0
- sage/combinat/perfect_matching.py +779 -0
- sage/combinat/plane_partition.py +3300 -0
- sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/q_bernoulli.pyx +128 -0
- sage/combinat/quickref.py +81 -0
- sage/combinat/recognizable_series.py +2051 -0
- sage/combinat/regular_sequence.py +4316 -0
- sage/combinat/regular_sequence_bounded.py +543 -0
- sage/combinat/restricted_growth.py +81 -0
- sage/combinat/ribbon.py +20 -0
- sage/combinat/ribbon_shaped_tableau.py +489 -0
- sage/combinat/ribbon_tableau.py +1180 -0
- sage/combinat/rigged_configurations/all.py +46 -0
- sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
- sage/combinat/rigged_configurations/bij_infinity.py +370 -0
- sage/combinat/rigged_configurations/bij_type_A.py +163 -0
- sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
- sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
- sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
- sage/combinat/rigged_configurations/bij_type_B.py +900 -0
- sage/combinat/rigged_configurations/bij_type_C.py +267 -0
- sage/combinat/rigged_configurations/bij_type_D.py +771 -0
- sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
- sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
- sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
- sage/combinat/rigged_configurations/bijection.py +143 -0
- sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
- sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
- sage/combinat/rigged_configurations/rc_crystal.py +461 -0
- sage/combinat/rigged_configurations/rc_infinity.py +540 -0
- sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
- sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
- sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
- sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
- sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
- sage/combinat/rsk.py +3438 -0
- sage/combinat/schubert_polynomial.py +508 -0
- sage/combinat/set_partition.py +3318 -0
- sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/set_partition_iterator.pyx +136 -0
- sage/combinat/set_partition_ordered.py +1590 -0
- sage/combinat/sf/abreu_nigro.py +346 -0
- sage/combinat/sf/all.py +52 -0
- sage/combinat/sf/character.py +576 -0
- sage/combinat/sf/classical.py +319 -0
- sage/combinat/sf/dual.py +996 -0
- sage/combinat/sf/elementary.py +549 -0
- sage/combinat/sf/hall_littlewood.py +1028 -0
- sage/combinat/sf/hecke.py +336 -0
- sage/combinat/sf/homogeneous.py +464 -0
- sage/combinat/sf/jack.py +1428 -0
- sage/combinat/sf/k_dual.py +1458 -0
- sage/combinat/sf/kfpoly.py +447 -0
- sage/combinat/sf/llt.py +789 -0
- sage/combinat/sf/macdonald.py +2019 -0
- sage/combinat/sf/monomial.py +525 -0
- sage/combinat/sf/multiplicative.py +113 -0
- sage/combinat/sf/new_kschur.py +1786 -0
- sage/combinat/sf/ns_macdonald.py +964 -0
- sage/combinat/sf/orthogonal.py +246 -0
- sage/combinat/sf/orthotriang.py +355 -0
- sage/combinat/sf/powersum.py +963 -0
- sage/combinat/sf/schur.py +880 -0
- sage/combinat/sf/sf.py +1653 -0
- sage/combinat/sf/sfa.py +7053 -0
- sage/combinat/sf/symplectic.py +253 -0
- sage/combinat/sf/witt.py +721 -0
- sage/combinat/shifted_primed_tableau.py +2735 -0
- sage/combinat/shuffle.py +830 -0
- sage/combinat/sidon_sets.py +146 -0
- sage/combinat/similarity_class_type.py +1721 -0
- sage/combinat/sine_gordon.py +618 -0
- sage/combinat/six_vertex_model.py +784 -0
- sage/combinat/skew_partition.py +2053 -0
- sage/combinat/skew_tableau.py +2989 -0
- sage/combinat/sloane_functions.py +8935 -0
- sage/combinat/specht_module.py +1403 -0
- sage/combinat/species/all.py +48 -0
- sage/combinat/species/characteristic_species.py +321 -0
- sage/combinat/species/composition_species.py +273 -0
- sage/combinat/species/cycle_species.py +284 -0
- sage/combinat/species/empty_species.py +155 -0
- sage/combinat/species/functorial_composition_species.py +148 -0
- sage/combinat/species/generating_series.py +673 -0
- sage/combinat/species/library.py +148 -0
- sage/combinat/species/linear_order_species.py +169 -0
- sage/combinat/species/misc.py +83 -0
- sage/combinat/species/partition_species.py +290 -0
- sage/combinat/species/permutation_species.py +268 -0
- sage/combinat/species/product_species.py +423 -0
- sage/combinat/species/recursive_species.py +476 -0
- sage/combinat/species/set_species.py +192 -0
- sage/combinat/species/species.py +820 -0
- sage/combinat/species/structure.py +539 -0
- sage/combinat/species/subset_species.py +243 -0
- sage/combinat/species/sum_species.py +225 -0
- sage/combinat/subword.py +564 -0
- sage/combinat/subword_complex.py +2122 -0
- sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/subword_complex_c.pyx +119 -0
- sage/combinat/super_tableau.py +821 -0
- sage/combinat/superpartition.py +1154 -0
- sage/combinat/symmetric_group_algebra.py +3774 -0
- sage/combinat/symmetric_group_representations.py +1830 -0
- sage/combinat/t_sequences.py +877 -0
- sage/combinat/tableau.py +9506 -0
- sage/combinat/tableau_residues.py +860 -0
- sage/combinat/tableau_tuple.py +5353 -0
- sage/combinat/tiling.py +2432 -0
- sage/combinat/triangles_FHM.py +777 -0
- sage/combinat/tutorial.py +1857 -0
- sage/combinat/vector_partition.py +337 -0
- sage/combinat/words/abstract_word.py +1722 -0
- sage/combinat/words/all.py +59 -0
- sage/combinat/words/alphabet.py +268 -0
- sage/combinat/words/finite_word.py +7201 -0
- sage/combinat/words/infinite_word.py +113 -0
- sage/combinat/words/lyndon_word.py +652 -0
- sage/combinat/words/morphic.py +351 -0
- sage/combinat/words/morphism.py +3878 -0
- sage/combinat/words/paths.py +2932 -0
- sage/combinat/words/shuffle_product.py +278 -0
- sage/combinat/words/suffix_trees.py +1873 -0
- sage/combinat/words/word.py +769 -0
- sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_char.pyx +847 -0
- sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/words/word_datatypes.pxd +4 -0
- sage/combinat/words/word_datatypes.pyx +1067 -0
- sage/combinat/words/word_generators.py +2026 -0
- sage/combinat/words/word_infinite_datatypes.py +1218 -0
- sage/combinat/words/word_options.py +99 -0
- sage/combinat/words/words.py +2396 -0
- sage/data_structures/all__sagemath_combinat.py +1 -0
- sage/databases/all__sagemath_combinat.py +13 -0
- sage/databases/findstat.py +4897 -0
- sage/databases/oeis.py +2058 -0
- sage/databases/sloane.py +393 -0
- sage/dynamics/all__sagemath_combinat.py +14 -0
- sage/dynamics/cellular_automata/all.py +7 -0
- sage/dynamics/cellular_automata/catalog.py +34 -0
- sage/dynamics/cellular_automata/elementary.py +612 -0
- sage/dynamics/cellular_automata/glca.py +477 -0
- sage/dynamics/cellular_automata/solitons.py +1463 -0
- sage/dynamics/finite_dynamical_system.py +1249 -0
- sage/dynamics/finite_dynamical_system_catalog.py +382 -0
- sage/games/all.py +7 -0
- sage/games/hexad.py +704 -0
- sage/games/quantumino.py +591 -0
- sage/games/sudoku.py +889 -0
- sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
- sage/games/sudoku_backtrack.pyx +189 -0
- sage/groups/all__sagemath_combinat.py +1 -0
- sage/groups/indexed_free_group.py +489 -0
- sage/libs/all__sagemath_combinat.py +6 -0
- sage/libs/lrcalc/__init__.py +1 -0
- sage/libs/lrcalc/lrcalc.py +525 -0
- sage/libs/symmetrica/__init__.py +7 -0
- sage/libs/symmetrica/all.py +101 -0
- sage/libs/symmetrica/kostka.pxi +168 -0
- sage/libs/symmetrica/part.pxi +193 -0
- sage/libs/symmetrica/plet.pxi +42 -0
- sage/libs/symmetrica/sab.pxi +196 -0
- sage/libs/symmetrica/sb.pxi +332 -0
- sage/libs/symmetrica/sc.pxi +192 -0
- sage/libs/symmetrica/schur.pxi +956 -0
- sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/symmetrica/symmetrica.pxi +1172 -0
- sage/libs/symmetrica/symmetrica.pyx +39 -0
- sage/monoids/all.py +13 -0
- sage/monoids/automatic_semigroup.py +1054 -0
- sage/monoids/free_abelian_monoid.py +315 -0
- sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/monoids/free_abelian_monoid_element.pxd +16 -0
- sage/monoids/free_abelian_monoid_element.pyx +397 -0
- sage/monoids/free_monoid.py +335 -0
- sage/monoids/free_monoid_element.py +431 -0
- sage/monoids/hecke_monoid.py +65 -0
- sage/monoids/string_monoid.py +817 -0
- sage/monoids/string_monoid_element.py +547 -0
- sage/monoids/string_ops.py +143 -0
- sage/monoids/trace_monoid.py +972 -0
- sage/rings/all__sagemath_combinat.py +2 -0
- sage/sat/all.py +4 -0
- sage/sat/boolean_polynomials.py +405 -0
- sage/sat/converters/__init__.py +6 -0
- sage/sat/converters/anf2cnf.py +14 -0
- sage/sat/converters/polybori.py +611 -0
- sage/sat/solvers/__init__.py +5 -0
- sage/sat/solvers/cryptominisat.py +287 -0
- sage/sat/solvers/dimacs.py +783 -0
- sage/sat/solvers/picosat.py +228 -0
- sage/sat/solvers/sat_lp.py +156 -0
- sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
- sage/sat/solvers/satsolver.pxd +3 -0
- sage/sat/solvers/satsolver.pyx +405 -0
|
@@ -0,0 +1,3095 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-combinat
|
|
2
|
+
# sage.doctest: needs sage.combinat sage.graphs sage.modules
|
|
3
|
+
r"""
|
|
4
|
+
Iwahori-Hecke Algebras
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Daniel Bump, Nicolas Thiery (2010): Initial version
|
|
9
|
+
|
|
10
|
+
- Brant Jones, Travis Scrimshaw, Andrew Mathas (2013):
|
|
11
|
+
Moved into the category framework and implemented the
|
|
12
|
+
Kazhdan-Lusztig `C` and `C^{\prime}` bases
|
|
13
|
+
|
|
14
|
+
- Chase Meadors, Tianyuan Xu (2021):
|
|
15
|
+
Implemented direct computation of products in the
|
|
16
|
+
`C^{\prime}` basis using du Cloux's Coxeter3 package
|
|
17
|
+
"""
|
|
18
|
+
# ****************************************************************************
|
|
19
|
+
# Copyright (C) 2013 Brant Jones <brant at math.jmu.edu>
|
|
20
|
+
# Daniel Bump <bump at match.stanford.edu>
|
|
21
|
+
# Nicolas M. Thiery <nthiery at users.sf.net>
|
|
22
|
+
#
|
|
23
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
24
|
+
# https://www.gnu.org/licenses/
|
|
25
|
+
# ****************************************************************************
|
|
26
|
+
|
|
27
|
+
from functools import cmp_to_key
|
|
28
|
+
from sage.misc.abstract_method import abstract_method
|
|
29
|
+
from sage.misc.cachefunc import cached_method
|
|
30
|
+
from sage.misc.bindable_class import BindableClass
|
|
31
|
+
from sage.structure.parent import Parent
|
|
32
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
33
|
+
from sage.categories.realizations import Realizations, Category_realization_of_parent
|
|
34
|
+
from sage.categories.algebras_with_basis import AlgebrasWithBasis
|
|
35
|
+
from sage.categories.finite_dimensional_algebras_with_basis import FiniteDimensionalAlgebrasWithBasis
|
|
36
|
+
from sage.categories.coxeter_groups import CoxeterGroups
|
|
37
|
+
from sage.rings.integer_ring import ZZ
|
|
38
|
+
from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
|
|
39
|
+
from sage.arith.misc import is_square
|
|
40
|
+
from sage.combinat.root_system.coxeter_group import CoxeterGroup
|
|
41
|
+
from sage.sets.family import Family
|
|
42
|
+
from sage.combinat.free_module import CombinatorialFreeModule
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def normalized_laurent_polynomial(R, p):
|
|
46
|
+
r"""
|
|
47
|
+
Return a normalized version of the (Laurent polynomial) ``p`` in the
|
|
48
|
+
ring ``R``.
|
|
49
|
+
|
|
50
|
+
Various ring operations in ``sage`` return an element of the field of
|
|
51
|
+
fractions of the parent ring even though the element is "known" to belong to
|
|
52
|
+
the base ring. This function is a hack to recover from this. This occurs
|
|
53
|
+
somewhat haphazardly with Laurent polynomial rings::
|
|
54
|
+
|
|
55
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
56
|
+
sage: [type(c) for c in (q**-1).coefficients()]
|
|
57
|
+
[<class 'sage.rings.integer.Integer'>]
|
|
58
|
+
|
|
59
|
+
It also happens in any ring when dividing by units::
|
|
60
|
+
|
|
61
|
+
sage: type(3/1)
|
|
62
|
+
<class 'sage.rings.rational.Rational'>
|
|
63
|
+
sage: type(-1/-1)
|
|
64
|
+
<class 'sage.rings.rational.Rational'>
|
|
65
|
+
|
|
66
|
+
This function is a variation on a suggested workaround of Nils Bruin.
|
|
67
|
+
|
|
68
|
+
EXAMPLES::
|
|
69
|
+
|
|
70
|
+
sage: from sage.algebras.iwahori_hecke_algebra import normalized_laurent_polynomial
|
|
71
|
+
sage: type(normalized_laurent_polynomial(ZZ, 3/1))
|
|
72
|
+
<class 'sage.rings.integer.Integer'>
|
|
73
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
74
|
+
sage: [type(c) for c in normalized_laurent_polynomial(R, q**-1).coefficients()]
|
|
75
|
+
[<class 'sage.rings.integer.Integer'>]
|
|
76
|
+
sage: R.<u,v> = LaurentPolynomialRing(ZZ,2)
|
|
77
|
+
sage: p = normalized_laurent_polynomial(R, 2*u**-1*v**-1 + u*v)
|
|
78
|
+
sage: ui = normalized_laurent_polynomial(R, u^-1)
|
|
79
|
+
sage: vi = normalized_laurent_polynomial(R, v^-1)
|
|
80
|
+
sage: p(ui, vi)
|
|
81
|
+
2*u*v + u^-1*v^-1
|
|
82
|
+
sage: q = u+v+ui
|
|
83
|
+
sage: q(ui, vi)
|
|
84
|
+
u + v^-1 + u^-1
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
return R({k: R._base(c) for k, c in p.monomial_coefficients().items()})
|
|
88
|
+
except (AttributeError, TypeError):
|
|
89
|
+
return R(p)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def index_cmp(x, y):
|
|
93
|
+
"""
|
|
94
|
+
Compare two term indices ``x`` and ``y`` by Bruhat order, then by word
|
|
95
|
+
length, and then by the generic comparison.
|
|
96
|
+
|
|
97
|
+
EXAMPLES::
|
|
98
|
+
|
|
99
|
+
sage: from sage.algebras.iwahori_hecke_algebra import index_cmp
|
|
100
|
+
sage: W = WeylGroup(['A',2,1])
|
|
101
|
+
sage: x = W.from_reduced_word([0,1])
|
|
102
|
+
sage: y = W.from_reduced_word([0,2,1])
|
|
103
|
+
sage: x.bruhat_le(y)
|
|
104
|
+
True
|
|
105
|
+
sage: index_cmp(x, y)
|
|
106
|
+
1
|
|
107
|
+
"""
|
|
108
|
+
if x.bruhat_le(y) or x.length() < y.length():
|
|
109
|
+
return 1
|
|
110
|
+
if y.bruhat_le(x) or x.length() > y.length():
|
|
111
|
+
return -1
|
|
112
|
+
# fallback case, in order to define a total order
|
|
113
|
+
if x < y:
|
|
114
|
+
return -1
|
|
115
|
+
if x > y:
|
|
116
|
+
return 1
|
|
117
|
+
return 0
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
sorting_key = cmp_to_key(index_cmp)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class IwahoriHeckeAlgebra(Parent, UniqueRepresentation):
|
|
124
|
+
r"""
|
|
125
|
+
The Iwahori-Hecke algebra of the Coxeter group ``W``
|
|
126
|
+
with the specified parameters.
|
|
127
|
+
|
|
128
|
+
INPUT:
|
|
129
|
+
|
|
130
|
+
- ``W`` -- a Coxeter group or Cartan type
|
|
131
|
+
- ``q1`` -- a parameter
|
|
132
|
+
- ``q2`` -- (default: ``-1``) another parameter
|
|
133
|
+
- ``base_ring`` -- (default: ``q1.parent()``) a ring containing ``q1``
|
|
134
|
+
and ``q2``
|
|
135
|
+
|
|
136
|
+
The Iwahori-Hecke algebra [Iwa1964]_ is a deformation of the group algebra of
|
|
137
|
+
a Weyl group or, more generally, a Coxeter group. These algebras are
|
|
138
|
+
defined by generators and relations and they depend on a deformation
|
|
139
|
+
parameter `q`. Taking `q = 1`, as in the following example, gives a ring
|
|
140
|
+
isomorphic to the group algebra of the corresponding Coxeter group.
|
|
141
|
+
|
|
142
|
+
Let `(W, S)` be a Coxeter system and let `R` be a commutative ring
|
|
143
|
+
containing elements `q_1` and `q_2`. Then the *Iwahori-Hecke algebra*
|
|
144
|
+
`H = H_{q_1,q_2}(W,S)` of `(W,S)` with parameters `q_1` and `q_2` is the
|
|
145
|
+
unital associative algebra with generators `\{T_s \mid s\in S\}` and
|
|
146
|
+
relations:
|
|
147
|
+
|
|
148
|
+
.. MATH::
|
|
149
|
+
|
|
150
|
+
\begin{aligned}
|
|
151
|
+
(T_s - q_1)(T_s - q_2) &= 0\\
|
|
152
|
+
T_r T_s T_r \cdots &= T_s T_r T_s \cdots,
|
|
153
|
+
\end{aligned}
|
|
154
|
+
|
|
155
|
+
where the number of terms on either side of the second relations (the braid
|
|
156
|
+
relations) is the order of `rs` in the Coxeter group `W`, for `r,s \in S`.
|
|
157
|
+
|
|
158
|
+
Iwahori-Hecke algebras are fundamental in many areas of mathematics,
|
|
159
|
+
ranging from the representation theory of Lie groups and quantum groups,
|
|
160
|
+
to knot theory and statistical mechanics. For more information see,
|
|
161
|
+
for example, [KL1979]_, [HKP2010]_, [Jon1987]_ and
|
|
162
|
+
:wikipedia:`Iwahori-Hecke_algebra`.
|
|
163
|
+
|
|
164
|
+
.. RUBRIC:: Bases
|
|
165
|
+
|
|
166
|
+
A reduced expression for an element `w \in W` is any minimal length
|
|
167
|
+
word `w = s_1 \cdots s_k`, with `s_i \in S`. If `w = s_1 \cdots s_k` is a
|
|
168
|
+
reduced expression for `w` then Matsumoto's Monoid Lemma implies that
|
|
169
|
+
`T_w = T_{s_1} \cdots T_{s_k}` depends on `w` and not on the choice of
|
|
170
|
+
reduced expressions. Moreover, `\{ T_w \mid w\in W \}` is a basis for the
|
|
171
|
+
Iwahori-Hecke algebra `H` and
|
|
172
|
+
|
|
173
|
+
.. MATH::
|
|
174
|
+
|
|
175
|
+
T_s T_w = \begin{cases}
|
|
176
|
+
T_{sw}, & \text{if } \ell(sw) = \ell(w)+1,\\
|
|
177
|
+
(q_1+q_2)T_w -q_1q_2 T_{sw}, & \text{if } \ell(sw) = \ell(w)-1.
|
|
178
|
+
\end{cases}
|
|
179
|
+
|
|
180
|
+
The `T`-basis of `H` is implemented for any choice of parameters
|
|
181
|
+
``q_1`` and ``q_2``::
|
|
182
|
+
|
|
183
|
+
sage: R.<u,v> = LaurentPolynomialRing(ZZ,2)
|
|
184
|
+
sage: H = IwahoriHeckeAlgebra('A3', u,v)
|
|
185
|
+
sage: T = H.T()
|
|
186
|
+
sage: T[1]
|
|
187
|
+
T[1]
|
|
188
|
+
sage: T[1,2,1] + T[2]
|
|
189
|
+
T[1,2,1] + T[2]
|
|
190
|
+
sage: T[1] * T[1,2,1]
|
|
191
|
+
(u+v)*T[1,2,1] + (-u*v)*T[2,1]
|
|
192
|
+
sage: T[1]^-1
|
|
193
|
+
(-u^-1*v^-1)*T[1] + (v^-1+u^-1)
|
|
194
|
+
|
|
195
|
+
Working over the Laurent polynomial ring `Z[q^{\pm 1/2}]` Kazhdan and
|
|
196
|
+
Lusztig proved that there exist two distinguished bases
|
|
197
|
+
`\{ C^{\prime}_w \mid w \in W \}` and `\{ C_w \mid w \in W \}` of `H`
|
|
198
|
+
which are uniquely determined by the properties that they are invariant
|
|
199
|
+
under the bar involution on `H` and have triangular transitions matrices
|
|
200
|
+
with polynomial entries of a certain form with the `T`-basis;
|
|
201
|
+
see [KL1979]_ for a precise statement.
|
|
202
|
+
|
|
203
|
+
It turns out that the Kazhdan-Lusztig bases can be defined (by
|
|
204
|
+
specialization) in `H` whenever `-q_1 q_2` is a square in the base ring.
|
|
205
|
+
The Kazhdan-Lusztig bases are implemented inside `H` whenever `-q_1 q_2`
|
|
206
|
+
has a square root::
|
|
207
|
+
|
|
208
|
+
sage: H = IwahoriHeckeAlgebra('A3', u^2, -v^2)
|
|
209
|
+
sage: T = H.T(); Cp = H.Cp(); C = H.C()
|
|
210
|
+
sage: T(Cp[1])
|
|
211
|
+
(u^-1*v^-1)*T[1] + (u^-1*v)
|
|
212
|
+
sage: T(C[1])
|
|
213
|
+
(u^-1*v^-1)*T[1] + (-u*v^-1)
|
|
214
|
+
sage: Cp(C[1])
|
|
215
|
+
Cp[1] + (-u*v^-1-u^-1*v)
|
|
216
|
+
sage: elt = Cp[2]*Cp[3]+C[1]; elt
|
|
217
|
+
Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)
|
|
218
|
+
sage: c = C(elt); c
|
|
219
|
+
C[2,3] + C[1] + (u*v^-1+u^-1*v)*C[3] + (u*v^-1+u^-1*v)*C[2] + (u^2*v^-2+2+u^-2*v^2)
|
|
220
|
+
sage: t = T(c); t
|
|
221
|
+
(u^-2*v^-2)*T[2,3] + (u^-1*v^-1)*T[1] + (u^-2)*T[3] + (u^-2)*T[2] + (-u*v^-1+u^-2*v^2)
|
|
222
|
+
sage: Cp(t)
|
|
223
|
+
Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)
|
|
224
|
+
sage: Cp(c)
|
|
225
|
+
Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)
|
|
226
|
+
|
|
227
|
+
The conversions to and from the Kazhdan-Lusztig bases are done behind the
|
|
228
|
+
scenes whenever the Kazhdan-Lusztig bases are well-defined. Once a suitable
|
|
229
|
+
Iwahori-Hecke algebra is defined they will work without further
|
|
230
|
+
intervention.
|
|
231
|
+
|
|
232
|
+
For example, with the "standard parameters", so that
|
|
233
|
+
`(T_r-q^2)(T_r+1) = 0`::
|
|
234
|
+
|
|
235
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
236
|
+
sage: H = IwahoriHeckeAlgebra('A3', q^2)
|
|
237
|
+
sage: T=H.T(); Cp=H.Cp(); C=H.C()
|
|
238
|
+
sage: C(T[1])
|
|
239
|
+
q*C[1] + q^2
|
|
240
|
+
sage: elt = Cp(T[1,2,1]); elt
|
|
241
|
+
q^3*Cp[1,2,1] - q^2*Cp[2,1] - q^2*Cp[1,2] + q*Cp[1] + q*Cp[2] - 1
|
|
242
|
+
sage: C(elt)
|
|
243
|
+
q^3*C[1,2,1] + q^4*C[2,1] + q^4*C[1,2] + q^5*C[1] + q^5*C[2] + q^6
|
|
244
|
+
|
|
245
|
+
With the "normalized presentation", so that `(T_r-q)(T_r+q^{-1}) = 0`::
|
|
246
|
+
|
|
247
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
248
|
+
sage: H = IwahoriHeckeAlgebra('A3', q, -q^-1)
|
|
249
|
+
sage: T=H.T(); Cp=H.Cp(); C=H.C()
|
|
250
|
+
sage: C(T[1])
|
|
251
|
+
C[1] + q
|
|
252
|
+
sage: elt = Cp(T[1,2,1]); elt
|
|
253
|
+
Cp[1,2,1] - (q^-1)*Cp[2,1] - (q^-1)*Cp[1,2] + (q^-2)*Cp[1] + (q^-2)*Cp[2] - (q^-3)
|
|
254
|
+
sage: C(elt)
|
|
255
|
+
C[1,2,1] + q*C[2,1] + q*C[1,2] + q^2*C[1] + q^2*C[2] + q^3
|
|
256
|
+
|
|
257
|
+
In the group algebra, so that `(T_r-1)(T_r+1) = 0`::
|
|
258
|
+
|
|
259
|
+
sage: H = IwahoriHeckeAlgebra('A3', 1)
|
|
260
|
+
sage: T=H.T(); Cp=H.Cp(); C=H.C()
|
|
261
|
+
sage: C(T[1])
|
|
262
|
+
C[1] + 1
|
|
263
|
+
sage: Cp(T[1,2,1])
|
|
264
|
+
Cp[1,2,1] - Cp[2,1] - Cp[1,2] + Cp[1] + Cp[2] - 1
|
|
265
|
+
sage: C(_)
|
|
266
|
+
C[1,2,1] + C[2,1] + C[1,2] + C[1] + C[2] + 1
|
|
267
|
+
|
|
268
|
+
On the other hand, if the Kazhdan-Lusztig bases are not well-defined (when
|
|
269
|
+
`-q_1 q_2` is not a square), attempting to use the Kazhdan-Lusztig bases
|
|
270
|
+
triggers an error::
|
|
271
|
+
|
|
272
|
+
sage: R.<q>=LaurentPolynomialRing(ZZ)
|
|
273
|
+
sage: H = IwahoriHeckeAlgebra('A3', q)
|
|
274
|
+
sage: C=H.C()
|
|
275
|
+
Traceback (most recent call last):
|
|
276
|
+
...
|
|
277
|
+
ValueError: the Kazhdan-Lusztig bases are defined only when -q_1*q_2 is a square
|
|
278
|
+
|
|
279
|
+
We give an example in affine type::
|
|
280
|
+
|
|
281
|
+
sage: R.<v> = LaurentPolynomialRing(ZZ)
|
|
282
|
+
sage: H = IwahoriHeckeAlgebra(['A',2,1], v^2)
|
|
283
|
+
sage: T=H.T(); Cp=H.Cp(); C=H.C()
|
|
284
|
+
sage: C(T[1,0,2])
|
|
285
|
+
v^3*C[1,0,2] + v^4*C[1,0] + v^4*C[0,2] + v^4*C[1,2]
|
|
286
|
+
+ v^5*C[0] + v^5*C[2] + v^5*C[1] + v^6
|
|
287
|
+
sage: Cp(T[1,0,2])
|
|
288
|
+
v^3*Cp[1,0,2] - v^2*Cp[1,0] - v^2*Cp[0,2] - v^2*Cp[1,2]
|
|
289
|
+
+ v*Cp[0] + v*Cp[2] + v*Cp[1] - 1
|
|
290
|
+
sage: T(C[1,0,2])
|
|
291
|
+
(v^-3)*T[1,0,2] - (v^-1)*T[1,0] - (v^-1)*T[0,2] - (v^-1)*T[1,2]
|
|
292
|
+
+ v*T[0] + v*T[2] + v*T[1] - v^3
|
|
293
|
+
sage: T(Cp[1,0,2])
|
|
294
|
+
(v^-3)*T[1,0,2] + (v^-3)*T[1,0] + (v^-3)*T[0,2] + (v^-3)*T[1,2]
|
|
295
|
+
+ (v^-3)*T[0] + (v^-3)*T[2] + (v^-3)*T[1] + (v^-3)
|
|
296
|
+
|
|
297
|
+
EXAMPLES:
|
|
298
|
+
|
|
299
|
+
We start by creating a Iwahori-Hecke algebra together with the three bases
|
|
300
|
+
for these algebras that are currently supported::
|
|
301
|
+
|
|
302
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
303
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
304
|
+
sage: T = H.T()
|
|
305
|
+
sage: C = H.C()
|
|
306
|
+
sage: Cp = H.Cp()
|
|
307
|
+
|
|
308
|
+
It is also possible to define these three bases quickly using
|
|
309
|
+
the :meth:`inject_shorthands` method.
|
|
310
|
+
|
|
311
|
+
Next we create our generators for the `T`-basis and do some basic
|
|
312
|
+
computations and conversions between the bases::
|
|
313
|
+
|
|
314
|
+
sage: T1,T2,T3 = T.algebra_generators()
|
|
315
|
+
sage: T1 == T[1]
|
|
316
|
+
True
|
|
317
|
+
sage: T1*T2 == T[1,2]
|
|
318
|
+
True
|
|
319
|
+
sage: T1 + T2
|
|
320
|
+
T[1] + T[2]
|
|
321
|
+
sage: T1*T1
|
|
322
|
+
-(1-v^2)*T[1] + v^2
|
|
323
|
+
sage: (T1 + T2)*T3 + T1*T1 - (v + v^-1)*T2
|
|
324
|
+
T[3,1] + T[2,3] - (1-v^2)*T[1] - (v^-1+v)*T[2] + v^2
|
|
325
|
+
sage: Cp(T1)
|
|
326
|
+
v*Cp[1] - 1
|
|
327
|
+
sage: Cp((v^1 - 1)*T1*T2 - T3)
|
|
328
|
+
-(v^2-v^3)*Cp[1,2] + (v-v^2)*Cp[1] - v*Cp[3] + (v-v^2)*Cp[2] + v
|
|
329
|
+
sage: C(T1)
|
|
330
|
+
v*C[1] + v^2
|
|
331
|
+
sage: p = C(T2*T3 - v*T1); p
|
|
332
|
+
v^2*C[2,3] - v^2*C[1] + v^3*C[3] + v^3*C[2] - (v^3-v^4)
|
|
333
|
+
sage: Cp(p)
|
|
334
|
+
v^2*Cp[2,3] - v^2*Cp[1] - v*Cp[3] - v*Cp[2] + (1+v)
|
|
335
|
+
sage: Cp(T2*T3 - v*T1)
|
|
336
|
+
v^2*Cp[2,3] - v^2*Cp[1] - v*Cp[3] - v*Cp[2] + (1+v)
|
|
337
|
+
|
|
338
|
+
In addition to explicitly creating generators, we have two shortcuts to
|
|
339
|
+
basis elements. The first is by using elements of the underlying Coxeter
|
|
340
|
+
group, the other is by using reduced words::
|
|
341
|
+
|
|
342
|
+
sage: s1,s2,s3 = H.coxeter_group().gens()
|
|
343
|
+
sage: T[s1*s2*s1*s3] == T[1,2,1,3]
|
|
344
|
+
True
|
|
345
|
+
sage: T[1,2,1,3] == T1*T2*T1*T3
|
|
346
|
+
True
|
|
347
|
+
|
|
348
|
+
TESTS:
|
|
349
|
+
|
|
350
|
+
We check the defining properties of the bases::
|
|
351
|
+
|
|
352
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
353
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
354
|
+
sage: W = H.coxeter_group()
|
|
355
|
+
sage: T = H.T()
|
|
356
|
+
sage: C = H.C()
|
|
357
|
+
sage: Cp = H.Cp()
|
|
358
|
+
sage: T(Cp[1])
|
|
359
|
+
(v^-1)*T[1] + (v^-1)
|
|
360
|
+
sage: T(C[1])
|
|
361
|
+
(v^-1)*T[1] - v
|
|
362
|
+
sage: C(Cp[1])
|
|
363
|
+
C[1] + (v^-1+v)
|
|
364
|
+
sage: Cp(C[1])
|
|
365
|
+
Cp[1] - (v^-1+v)
|
|
366
|
+
sage: all(C[x] == C[x].bar() for x in W) # long time
|
|
367
|
+
True
|
|
368
|
+
sage: all(Cp[x] == Cp[x].bar() for x in W) # long time
|
|
369
|
+
True
|
|
370
|
+
sage: all(T(C[x]).bar() == T(C[x]) for x in W) # long time
|
|
371
|
+
True
|
|
372
|
+
sage: all(T(Cp[x]).bar() == T(Cp[x]) for x in W) # long time
|
|
373
|
+
True
|
|
374
|
+
sage: KL = KazhdanLusztigPolynomial(W, v)
|
|
375
|
+
sage: term = lambda x,y: (-1)^y.length() * v^(-2*y.length()) * KL.P(y, x).substitute(v=v^-2)*T[y]
|
|
376
|
+
sage: all(T(C[x]) == (-v)^x.length()*sum(term(x,y) for y in W) for x in W) # long time
|
|
377
|
+
True
|
|
378
|
+
sage: all(T(Cp[x]) == v^-x.length()*sum(KL.P(y,x).substitute(v=v^2)*T[y] for y in W) for x in W) # long time
|
|
379
|
+
True
|
|
380
|
+
|
|
381
|
+
We check conversion between the bases for type `B_2` as well as some of
|
|
382
|
+
the defining properties::
|
|
383
|
+
|
|
384
|
+
sage: H = IwahoriHeckeAlgebra(['B',2], v**2)
|
|
385
|
+
sage: W = H.coxeter_group()
|
|
386
|
+
sage: T = H.T()
|
|
387
|
+
sage: C = H.C()
|
|
388
|
+
sage: Cp = H.Cp()
|
|
389
|
+
sage: all(T[x] == T(C(T[x])) for x in W) # long time
|
|
390
|
+
True
|
|
391
|
+
sage: all(T[x] == T(Cp(T[x])) for x in W) # long time
|
|
392
|
+
True
|
|
393
|
+
sage: all(C[x] == C(T(C[x])) for x in W) # long time
|
|
394
|
+
True
|
|
395
|
+
sage: all(C[x] == C(Cp(C[x])) for x in W) # long time
|
|
396
|
+
True
|
|
397
|
+
sage: all(Cp[x] == Cp(T(Cp[x])) for x in W) # long time
|
|
398
|
+
True
|
|
399
|
+
sage: all(Cp[x] == Cp(C(Cp[x])) for x in W) # long time
|
|
400
|
+
True
|
|
401
|
+
sage: all(T(C[x]).bar() == T(C[x]) for x in W) # long time
|
|
402
|
+
True
|
|
403
|
+
sage: all(T(Cp[x]).bar() == T(Cp[x]) for x in W) # long time
|
|
404
|
+
True
|
|
405
|
+
sage: KL = KazhdanLusztigPolynomial(W, v)
|
|
406
|
+
sage: term = lambda x,y: (-1)^y.length() * v^(-2*y.length()) * KL.P(y, x).substitute(v=v^-2)*T[y]
|
|
407
|
+
sage: all(T(C[x]) == (-v)^x.length()*sum(term(x,y) for y in W) for x in W) # long time
|
|
408
|
+
True
|
|
409
|
+
sage: all(T(Cp[x]) == v^-x.length()*sum(KL.P(y,x).substitute(v=v^2)*T[y] for y in W) for x in W) # long time
|
|
410
|
+
True
|
|
411
|
+
|
|
412
|
+
.. TODO::
|
|
413
|
+
|
|
414
|
+
Implement multi-parameter Iwahori-Hecke algebras together with their
|
|
415
|
+
Kazhdan-Lusztig bases. That is, Iwahori-Hecke algebras with (possibly)
|
|
416
|
+
different parameters for each conjugacy class of simple reflections
|
|
417
|
+
in the underlying Coxeter group.
|
|
418
|
+
|
|
419
|
+
.. TODO::
|
|
420
|
+
|
|
421
|
+
When given "generic parameters" we should return the generic
|
|
422
|
+
Iwahori-Hecke algebra with these parameters and allow the user to
|
|
423
|
+
work inside this algebra rather than doing calculations behind the
|
|
424
|
+
scenes in a copy of the generic Iwahori-Hecke algebra. The main
|
|
425
|
+
problem is that it is not clear how to recognise when the
|
|
426
|
+
parameters are "generic".
|
|
427
|
+
"""
|
|
428
|
+
@staticmethod
|
|
429
|
+
def __classcall_private__(cls, W, q1, q2=-1, base_ring=None):
|
|
430
|
+
r"""
|
|
431
|
+
TESTS::
|
|
432
|
+
|
|
433
|
+
sage: H = IwahoriHeckeAlgebra("A2", 1)
|
|
434
|
+
sage: W = CoxeterGroup("A2")
|
|
435
|
+
sage: H.coxeter_group() == W
|
|
436
|
+
True
|
|
437
|
+
sage: H.cartan_type() == CartanType("A2")
|
|
438
|
+
True
|
|
439
|
+
sage: H._q2 == -1
|
|
440
|
+
True
|
|
441
|
+
sage: H2 = IwahoriHeckeAlgebra(W, QQ(1), base_ring=ZZ)
|
|
442
|
+
sage: H is H2
|
|
443
|
+
True
|
|
444
|
+
"""
|
|
445
|
+
if W not in CoxeterGroups():
|
|
446
|
+
W = CoxeterGroup(W)
|
|
447
|
+
if base_ring is None:
|
|
448
|
+
base_ring = q1.parent()
|
|
449
|
+
else:
|
|
450
|
+
q1 = base_ring(q1)
|
|
451
|
+
q2 = base_ring(q2)
|
|
452
|
+
return super().__classcall__(cls, W, q1, q2, base_ring)
|
|
453
|
+
|
|
454
|
+
def __init__(self, W, q1, q2, base_ring):
|
|
455
|
+
r"""
|
|
456
|
+
Initialize and return the two parameter Iwahori-Hecke algebra ``self``.
|
|
457
|
+
|
|
458
|
+
EXAMPLES::
|
|
459
|
+
|
|
460
|
+
sage: R.<q1,q2> = QQ[]
|
|
461
|
+
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2, base_ring=Frac(R))
|
|
462
|
+
sage: TestSuite(H).run()
|
|
463
|
+
"""
|
|
464
|
+
self._W = W
|
|
465
|
+
self._coxeter_type = W.coxeter_type()
|
|
466
|
+
|
|
467
|
+
self._q1 = q1
|
|
468
|
+
self._q2 = q2
|
|
469
|
+
|
|
470
|
+
# Used when multiplying generators: minor speed-up as it avoids the
|
|
471
|
+
# need to constantly add and multiply the parameters when applying the
|
|
472
|
+
# quadratic relation: T^2 = (q1+q2)T - q1*q2
|
|
473
|
+
self._q_sum = q1 + q2
|
|
474
|
+
self._q_prod = -q1 * q2
|
|
475
|
+
|
|
476
|
+
# If -q1*q2 is a square then it makes sense to talk of he Kazhdan-Lusztig
|
|
477
|
+
# basis of the Iwhaori-Hecke algebra. In this case we set
|
|
478
|
+
# self._root=\sqrt{q1*q2}. The Kazhdan-Lusztig bases will be computed in
|
|
479
|
+
# the generic case behind the scenes and then specialized to this # algebra.
|
|
480
|
+
is_Square, root = is_square(self._q_prod, root=True)
|
|
481
|
+
if is_Square:
|
|
482
|
+
# Attach the generic Hecke algebra and the basis change maps
|
|
483
|
+
self._root = root
|
|
484
|
+
self._generic_iwahori_hecke_algebra = IwahoriHeckeAlgebra_nonstandard(W)
|
|
485
|
+
self._shorthands = ['C', 'Cp', 'T']
|
|
486
|
+
else:
|
|
487
|
+
# Can we actually remove the bases C and Cp in this case?
|
|
488
|
+
self._root = None
|
|
489
|
+
self._shorthands = ['T']
|
|
490
|
+
|
|
491
|
+
# if 2 is a unit in the base ring then add th A and B bases
|
|
492
|
+
try:
|
|
493
|
+
base_ring(base_ring.one() / 2)
|
|
494
|
+
self._shorthands.extend(['A', 'B'])
|
|
495
|
+
except (TypeError, ZeroDivisionError):
|
|
496
|
+
pass
|
|
497
|
+
|
|
498
|
+
if W.is_finite():
|
|
499
|
+
self._category = FiniteDimensionalAlgebrasWithBasis(base_ring)
|
|
500
|
+
else:
|
|
501
|
+
self._category = AlgebrasWithBasis(base_ring)
|
|
502
|
+
Parent.__init__(self, base=base_ring, category=self._category.WithRealizations())
|
|
503
|
+
|
|
504
|
+
self._is_generic = False # needed for initialisation of _KLHeckeBasis
|
|
505
|
+
|
|
506
|
+
# The following is used by the bar involution = self._bar_on_coefficients
|
|
507
|
+
try:
|
|
508
|
+
self._inverse_base_ring_generators = {g: self.base_ring()(g) ** -1
|
|
509
|
+
for g in self.base_ring().variable_names()}
|
|
510
|
+
except TypeError:
|
|
511
|
+
self._inverse_base_ring_generators = {}
|
|
512
|
+
|
|
513
|
+
def _repr_(self):
|
|
514
|
+
r"""
|
|
515
|
+
EXAMPLES::
|
|
516
|
+
|
|
517
|
+
sage: R.<q1,q2> = QQ[]
|
|
518
|
+
sage: IwahoriHeckeAlgebra("A2", q1**2, q2**2, base_ring=Frac(R))
|
|
519
|
+
Iwahori-Hecke algebra of type A2 in q1^2,q2^2 over Fraction Field of Multivariate Polynomial Ring in q1, q2 over Rational Field
|
|
520
|
+
"""
|
|
521
|
+
try:
|
|
522
|
+
ct = self._coxeter_type._repr_(compact=True)
|
|
523
|
+
except TypeError:
|
|
524
|
+
ct = repr(self._coxeter_type)
|
|
525
|
+
return "Iwahori-Hecke algebra of type {} in {},{} over {}".format(
|
|
526
|
+
ct, self._q1, self._q2, self.base_ring())
|
|
527
|
+
|
|
528
|
+
def _latex_(self):
|
|
529
|
+
r"""
|
|
530
|
+
Return a latex representation of ``self``.
|
|
531
|
+
|
|
532
|
+
EXAMPLES::
|
|
533
|
+
|
|
534
|
+
sage: R.<q1,q2> = QQ[]
|
|
535
|
+
sage: H = IwahoriHeckeAlgebra("A2", q1**2, q2**2, base_ring=Frac(R))
|
|
536
|
+
sage: latex(H)
|
|
537
|
+
\mathcal{H}_{q_{1}^{2},q_{2}^{2}}\left(A_{2},
|
|
538
|
+
\mathrm{Frac}(\Bold{Q}[q_{1}, q_{2}])\right)
|
|
539
|
+
sage: R.<q> = LaurentPolynomialRing(ZZ)
|
|
540
|
+
sage: H = IwahoriHeckeAlgebra("A2", q)
|
|
541
|
+
sage: latex(H)
|
|
542
|
+
\mathcal{H}_{q,-1}\left(A_{2}, \Bold{Z}[q^{\pm 1}]\right)
|
|
543
|
+
"""
|
|
544
|
+
from sage.misc.latex import latex
|
|
545
|
+
return "\\mathcal{{H}}_{{{},{}}}\\left({}, {}\\right)".format(latex(self._q1),
|
|
546
|
+
latex(self._q2), latex(self._coxeter_type), latex(self.base_ring()))
|
|
547
|
+
|
|
548
|
+
def _bar_on_coefficients(self, c):
|
|
549
|
+
r"""
|
|
550
|
+
Given a Laurent polynomial ``c`` return the Laurent polynomial obtained
|
|
551
|
+
by applying the (generic) bar involution to ``c`` .
|
|
552
|
+
|
|
553
|
+
This is the ring homomorphism of Laurent polynomials in
|
|
554
|
+
`\ZZ[u,u^{-1},v,v^{-1}]` which sends `u` to `u^{-1}` and `v`
|
|
555
|
+
to `v^{-1}`.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: R.<q>=LaurentPolynomialRing(ZZ)
|
|
560
|
+
sage: H = IwahoriHeckeAlgebra("A3",q^2)
|
|
561
|
+
sage: H._bar_on_coefficients(q)
|
|
562
|
+
q^-1
|
|
563
|
+
"""
|
|
564
|
+
return normalized_laurent_polynomial(self._base, c).substitute(**self._inverse_base_ring_generators)
|
|
565
|
+
|
|
566
|
+
def coxeter_type(self):
|
|
567
|
+
r"""
|
|
568
|
+
Return the Coxeter type of ``self``.
|
|
569
|
+
|
|
570
|
+
EXAMPLES::
|
|
571
|
+
|
|
572
|
+
sage: IwahoriHeckeAlgebra("D4", 1).coxeter_type()
|
|
573
|
+
Coxeter type of ['D', 4]
|
|
574
|
+
"""
|
|
575
|
+
return self._coxeter_type
|
|
576
|
+
|
|
577
|
+
def cartan_type(self):
|
|
578
|
+
r"""
|
|
579
|
+
Return the Cartan type of ``self``.
|
|
580
|
+
|
|
581
|
+
EXAMPLES::
|
|
582
|
+
|
|
583
|
+
sage: IwahoriHeckeAlgebra("D4", 1).cartan_type()
|
|
584
|
+
['D', 4]
|
|
585
|
+
"""
|
|
586
|
+
try:
|
|
587
|
+
return self._coxeter_type.cartan_type()
|
|
588
|
+
except AttributeError:
|
|
589
|
+
return None
|
|
590
|
+
|
|
591
|
+
def coxeter_group(self):
|
|
592
|
+
r"""
|
|
593
|
+
Return the Coxeter group of ``self``.
|
|
594
|
+
|
|
595
|
+
EXAMPLES::
|
|
596
|
+
|
|
597
|
+
sage: IwahoriHeckeAlgebra("B2", 1).coxeter_group()
|
|
598
|
+
Finite Coxeter group over Number Field in a with defining polynomial x^2 - 2 with a = 1.414213562373095? with Coxeter matrix:
|
|
599
|
+
[1 4]
|
|
600
|
+
[4 1]
|
|
601
|
+
"""
|
|
602
|
+
return self._W
|
|
603
|
+
|
|
604
|
+
def a_realization(self):
|
|
605
|
+
r"""
|
|
606
|
+
Return a particular realization of ``self`` (the `T`-basis).
|
|
607
|
+
|
|
608
|
+
EXAMPLES::
|
|
609
|
+
|
|
610
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
611
|
+
sage: H.a_realization()
|
|
612
|
+
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the T-basis
|
|
613
|
+
"""
|
|
614
|
+
return self.T()
|
|
615
|
+
|
|
616
|
+
def q1(self):
|
|
617
|
+
"""
|
|
618
|
+
Return the parameter `q_1` of ``self``.
|
|
619
|
+
|
|
620
|
+
EXAMPLES::
|
|
621
|
+
|
|
622
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
623
|
+
sage: H.q1()
|
|
624
|
+
1
|
|
625
|
+
"""
|
|
626
|
+
return self._q1
|
|
627
|
+
|
|
628
|
+
def q2(self):
|
|
629
|
+
"""
|
|
630
|
+
Return the parameter `q_2` of ``self``.
|
|
631
|
+
|
|
632
|
+
EXAMPLES::
|
|
633
|
+
|
|
634
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
635
|
+
sage: H.q2()
|
|
636
|
+
-1
|
|
637
|
+
"""
|
|
638
|
+
return self._q2
|
|
639
|
+
|
|
640
|
+
class _BasesCategory(Category_realization_of_parent):
|
|
641
|
+
r"""
|
|
642
|
+
The category of bases of a Iwahori-Hecke algebra.
|
|
643
|
+
"""
|
|
644
|
+
def __init__(self, base):
|
|
645
|
+
r"""
|
|
646
|
+
Initialize the bases of a Iwahori-Hecke algebra.
|
|
647
|
+
|
|
648
|
+
INPUT:
|
|
649
|
+
|
|
650
|
+
- ``base`` -- a Iwahori-Hecke algebra
|
|
651
|
+
|
|
652
|
+
TESTS::
|
|
653
|
+
|
|
654
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
655
|
+
sage: bases = H._BasesCategory()
|
|
656
|
+
sage: H.T() in bases
|
|
657
|
+
True
|
|
658
|
+
"""
|
|
659
|
+
Category_realization_of_parent.__init__(self, base)
|
|
660
|
+
|
|
661
|
+
def super_categories(self):
|
|
662
|
+
r"""
|
|
663
|
+
The super categories of ``self``.
|
|
664
|
+
|
|
665
|
+
EXAMPLES::
|
|
666
|
+
|
|
667
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
668
|
+
sage: bases = H._BasesCategory()
|
|
669
|
+
sage: bases.super_categories()
|
|
670
|
+
[Category of realizations of Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring,
|
|
671
|
+
Category of finite dimensional algebras with basis over Integer Ring]
|
|
672
|
+
"""
|
|
673
|
+
return [Realizations(self.base()), self.base()._category]
|
|
674
|
+
|
|
675
|
+
def _repr_(self):
|
|
676
|
+
r"""
|
|
677
|
+
Return the representation of ``self``.
|
|
678
|
+
|
|
679
|
+
EXAMPLES::
|
|
680
|
+
|
|
681
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
682
|
+
sage: H._BasesCategory()
|
|
683
|
+
Category of bases of Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring
|
|
684
|
+
"""
|
|
685
|
+
return "Category of bases of %s" % self.base()
|
|
686
|
+
|
|
687
|
+
class ParentMethods:
|
|
688
|
+
r"""
|
|
689
|
+
This class collects code common to all the various bases. In most
|
|
690
|
+
cases, these are just default implementations that will get
|
|
691
|
+
specialized in a basis.
|
|
692
|
+
"""
|
|
693
|
+
def _repr_(self):
|
|
694
|
+
"""
|
|
695
|
+
Text representation of this basis of Iwahori-Hecke algebra.
|
|
696
|
+
|
|
697
|
+
EXAMPLES::
|
|
698
|
+
|
|
699
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
700
|
+
sage: H.T()
|
|
701
|
+
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the T-basis
|
|
702
|
+
sage: H.C()
|
|
703
|
+
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the C-basis
|
|
704
|
+
sage: H.Cp()
|
|
705
|
+
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the Cp-basis
|
|
706
|
+
"""
|
|
707
|
+
return "%s in the %s-basis" % (self.realization_of(),
|
|
708
|
+
self._basis_name)
|
|
709
|
+
|
|
710
|
+
def __getitem__(self, i):
|
|
711
|
+
"""
|
|
712
|
+
Return the basis element indexed by ``i``.
|
|
713
|
+
|
|
714
|
+
INPUT:
|
|
715
|
+
|
|
716
|
+
- ``i`` -- either an element of the Coxeter group or a
|
|
717
|
+
reduced word
|
|
718
|
+
|
|
719
|
+
.. WARNING::
|
|
720
|
+
|
|
721
|
+
If ``i`` is not a reduced expression then the basis element
|
|
722
|
+
indexed by the corresponding element of the algebra is
|
|
723
|
+
returned rather than the corresponding product of the
|
|
724
|
+
generators::
|
|
725
|
+
|
|
726
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
727
|
+
sage: T = IwahoriHeckeAlgebra('A3', v**2).T()
|
|
728
|
+
sage: T[1,1] == T[1] * T[1]
|
|
729
|
+
False
|
|
730
|
+
|
|
731
|
+
EXAMPLES::
|
|
732
|
+
|
|
733
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
734
|
+
sage: T = H.T()
|
|
735
|
+
sage: G = H.coxeter_group()
|
|
736
|
+
sage: T[G.one()]
|
|
737
|
+
1
|
|
738
|
+
sage: T[G.simple_reflection(1)]
|
|
739
|
+
T[1]
|
|
740
|
+
sage: T[G.from_reduced_word([1,2,1])]
|
|
741
|
+
T[1,2,1]
|
|
742
|
+
sage: T[[]]
|
|
743
|
+
1
|
|
744
|
+
sage: T[1]
|
|
745
|
+
T[1]
|
|
746
|
+
sage: T[1,2,1]
|
|
747
|
+
T[1,2,1]
|
|
748
|
+
"""
|
|
749
|
+
W = self.realization_of().coxeter_group()
|
|
750
|
+
if i in ZZ:
|
|
751
|
+
return self(W.simple_reflection(i))
|
|
752
|
+
if i in W:
|
|
753
|
+
return self(i)
|
|
754
|
+
if i == []:
|
|
755
|
+
return self.one()
|
|
756
|
+
return self(W.from_reduced_word(i))
|
|
757
|
+
|
|
758
|
+
def is_field(self, proof=True):
|
|
759
|
+
"""
|
|
760
|
+
Return whether this Iwahori-Hecke algebra is a field.
|
|
761
|
+
|
|
762
|
+
EXAMPLES::
|
|
763
|
+
|
|
764
|
+
sage: T = IwahoriHeckeAlgebra("B2", 1).T()
|
|
765
|
+
sage: T.is_field()
|
|
766
|
+
False
|
|
767
|
+
"""
|
|
768
|
+
return False
|
|
769
|
+
|
|
770
|
+
def is_commutative(self) -> bool:
|
|
771
|
+
"""
|
|
772
|
+
Return whether this Iwahori-Hecke algebra is commutative.
|
|
773
|
+
|
|
774
|
+
EXAMPLES::
|
|
775
|
+
|
|
776
|
+
sage: T = IwahoriHeckeAlgebra("B2", 1).T()
|
|
777
|
+
sage: T.is_commutative()
|
|
778
|
+
False
|
|
779
|
+
"""
|
|
780
|
+
return self.base_ring().is_commutative() \
|
|
781
|
+
and self.realization_of().coxeter_group().is_commutative()
|
|
782
|
+
|
|
783
|
+
@cached_method
|
|
784
|
+
def one_basis(self):
|
|
785
|
+
r"""
|
|
786
|
+
Return the identity element in the Weyl group, as per
|
|
787
|
+
``AlgebrasWithBasis.ParentMethods.one_basis``.
|
|
788
|
+
|
|
789
|
+
EXAMPLES::
|
|
790
|
+
|
|
791
|
+
sage: H = IwahoriHeckeAlgebra("B2", 1)
|
|
792
|
+
sage: H.T().one_basis()
|
|
793
|
+
[1 0]
|
|
794
|
+
[0 1]
|
|
795
|
+
"""
|
|
796
|
+
return self.realization_of().coxeter_group().one()
|
|
797
|
+
|
|
798
|
+
def index_set(self):
|
|
799
|
+
r"""
|
|
800
|
+
Return the index set of ``self``.
|
|
801
|
+
|
|
802
|
+
EXAMPLES::
|
|
803
|
+
|
|
804
|
+
sage: IwahoriHeckeAlgebra("B2", 1).T().index_set()
|
|
805
|
+
(1, 2)
|
|
806
|
+
"""
|
|
807
|
+
return self.realization_of().coxeter_group().index_set()
|
|
808
|
+
|
|
809
|
+
@cached_method
|
|
810
|
+
def algebra_generators(self):
|
|
811
|
+
r"""
|
|
812
|
+
Return the generators.
|
|
813
|
+
|
|
814
|
+
They do not have order two but satisfy a quadratic relation.
|
|
815
|
+
They coincide with the simple reflections in the Coxeter group
|
|
816
|
+
when `q_1 = 1` and `q_2 = -1`. In this special case,
|
|
817
|
+
the Iwahori-Hecke algebra is identified with the group algebra
|
|
818
|
+
of the Coxeter group.
|
|
819
|
+
|
|
820
|
+
EXAMPLES:
|
|
821
|
+
|
|
822
|
+
In the standard basis::
|
|
823
|
+
|
|
824
|
+
sage: R.<q> = QQ[]
|
|
825
|
+
sage: H = IwahoriHeckeAlgebra("A3", q).T()
|
|
826
|
+
sage: T = H.algebra_generators(); T
|
|
827
|
+
Finite family {1: T[1], 2: T[2], 3: T[3]}
|
|
828
|
+
sage: T.list()
|
|
829
|
+
[T[1], T[2], T[3]]
|
|
830
|
+
sage: [T[i] for i in [1,2,3]]
|
|
831
|
+
[T[1], T[2], T[3]]
|
|
832
|
+
sage: T1,T2,T3 = H.algebra_generators()
|
|
833
|
+
sage: T1
|
|
834
|
+
T[1]
|
|
835
|
+
sage: H = IwahoriHeckeAlgebra(['A',2,1], q).T()
|
|
836
|
+
sage: T = H.algebra_generators(); T
|
|
837
|
+
Finite family {0: T[0], 1: T[1], 2: T[2]}
|
|
838
|
+
sage: T.list()
|
|
839
|
+
[T[0], T[1], T[2]]
|
|
840
|
+
sage: [T[i] for i in [0,1,2]]
|
|
841
|
+
[T[0], T[1], T[2]]
|
|
842
|
+
sage: [T0, T1, T2] = H.algebra_generators()
|
|
843
|
+
sage: T0
|
|
844
|
+
T[0]
|
|
845
|
+
|
|
846
|
+
In the Kazhdan-Lusztig basis::
|
|
847
|
+
|
|
848
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
849
|
+
sage: v = R.gen(0)
|
|
850
|
+
sage: H = IwahoriHeckeAlgebra('A5', v**2)
|
|
851
|
+
sage: C = H.C()
|
|
852
|
+
sage: C.algebra_generators()
|
|
853
|
+
Finite family {1: C[1], 2: C[2], 3: C[3], 4: C[4], 5: C[5]}
|
|
854
|
+
sage: C.algebra_generators().list()
|
|
855
|
+
[C[1], C[2], C[3], C[4], C[5]]
|
|
856
|
+
"""
|
|
857
|
+
return self.basis().keys().simple_reflections().map(self.monomial)
|
|
858
|
+
|
|
859
|
+
def algebra_generator(self, i):
|
|
860
|
+
r"""
|
|
861
|
+
Return the `i`-th generator of ``self``.
|
|
862
|
+
|
|
863
|
+
EXAMPLES:
|
|
864
|
+
|
|
865
|
+
In the standard basis::
|
|
866
|
+
|
|
867
|
+
sage: R.<q>=QQ[]
|
|
868
|
+
sage: H = IwahoriHeckeAlgebra("A3", q).T()
|
|
869
|
+
sage: [H.algebra_generator(i) for i in H.index_set()]
|
|
870
|
+
[T[1], T[2], T[3]]
|
|
871
|
+
|
|
872
|
+
In the Kazhdan-Lusztig basis::
|
|
873
|
+
|
|
874
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
875
|
+
sage: v = R.gen(0)
|
|
876
|
+
sage: H = IwahoriHeckeAlgebra('A5', v**2)
|
|
877
|
+
sage: C = H.C()
|
|
878
|
+
sage: [C.algebra_generator(i) for i in H.coxeter_group().index_set()]
|
|
879
|
+
[C[1], C[2], C[3], C[4], C[5]]
|
|
880
|
+
"""
|
|
881
|
+
return self.algebra_generators()[i]
|
|
882
|
+
|
|
883
|
+
@abstract_method(optional=True)
|
|
884
|
+
def bar_on_basis(self, w):
|
|
885
|
+
"""
|
|
886
|
+
Return the bar involution on the basis element of ``self``
|
|
887
|
+
indexed by ``w``.
|
|
888
|
+
|
|
889
|
+
EXAMPLES::
|
|
890
|
+
|
|
891
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
892
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
893
|
+
sage: W = H.coxeter_group()
|
|
894
|
+
sage: s1,s2,s3 = W.simple_reflections()
|
|
895
|
+
sage: Cp = H.Cp()
|
|
896
|
+
sage: Cp.bar_on_basis(s1*s2*s1*s3)
|
|
897
|
+
Cp[1,2,3,1]
|
|
898
|
+
"""
|
|
899
|
+
|
|
900
|
+
@abstract_method(optional=True)
|
|
901
|
+
def hash_involution_on_basis(self, w):
|
|
902
|
+
"""
|
|
903
|
+
Return the bar involution on the basis element of ``self``
|
|
904
|
+
indexed by ``w``.
|
|
905
|
+
|
|
906
|
+
EXAMPLES::
|
|
907
|
+
|
|
908
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
909
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
910
|
+
sage: W = H.coxeter_group()
|
|
911
|
+
sage: s1,s2,s3 = W.simple_reflections()
|
|
912
|
+
sage: Cp = H.Cp()
|
|
913
|
+
sage: C = H.C()
|
|
914
|
+
sage: C(Cp.hash_involution_on_basis(s1*s2*s1*s3))
|
|
915
|
+
C[1,2,3,1]
|
|
916
|
+
"""
|
|
917
|
+
|
|
918
|
+
class ElementMethods:
|
|
919
|
+
def bar(self):
|
|
920
|
+
r"""
|
|
921
|
+
Return the bar involution of ``self``.
|
|
922
|
+
|
|
923
|
+
The bar involution `\overline{\phantom{x}}` is an antilinear
|
|
924
|
+
`\ZZ`-algebra involution defined by the identity on `\ZZ`,
|
|
925
|
+
sending `q^{1/2} \mapsto q^{-1/2}`, and `\overline{T_w} =
|
|
926
|
+
T_{w^{-1}}^{-1}`.
|
|
927
|
+
|
|
928
|
+
REFERENCES:
|
|
929
|
+
|
|
930
|
+
- :wikipedia:`Iwahori-Hecke_algebra#Canonical_basis`
|
|
931
|
+
|
|
932
|
+
EXAMPLES:
|
|
933
|
+
|
|
934
|
+
We first test on a single generator::
|
|
935
|
+
|
|
936
|
+
sage: R.<q> = LaurentPolynomialRing(QQ)
|
|
937
|
+
sage: H = IwahoriHeckeAlgebra('A3', q)
|
|
938
|
+
sage: T = H.T()
|
|
939
|
+
sage: T1,T2,T3 = T.algebra_generators()
|
|
940
|
+
sage: T1.bar()
|
|
941
|
+
(q^-1)*T[1] + (q^-1-1)
|
|
942
|
+
sage: T1.bar().bar() == T1
|
|
943
|
+
True
|
|
944
|
+
|
|
945
|
+
Next on a multiple of generators::
|
|
946
|
+
|
|
947
|
+
sage: b = (T1*T2*T1).bar(); b
|
|
948
|
+
(q^-3)*T[1,2,1] + (q^-3-q^-2)*T[2,1] + (q^-3-q^-2)*T[1,2]
|
|
949
|
+
+ (q^-3-2*q^-2+q^-1)*T[1] + (q^-3-2*q^-2+q^-1)*T[2]
|
|
950
|
+
+ (q^-3-2*q^-2+2*q^-1-1)
|
|
951
|
+
sage: b.bar() == T1*T2*T1
|
|
952
|
+
True
|
|
953
|
+
|
|
954
|
+
A sum::
|
|
955
|
+
|
|
956
|
+
sage: s = T1 + T2
|
|
957
|
+
sage: b = s.bar(); b
|
|
958
|
+
(q^-1)*T[1] + (q^-1)*T[2] + (2*q^-1-2)
|
|
959
|
+
sage: b.bar() == s
|
|
960
|
+
True
|
|
961
|
+
|
|
962
|
+
A more complicated example::
|
|
963
|
+
|
|
964
|
+
sage: p = T1*T2 + (1-q+q^-1)*T3 - q^3*T1*T3
|
|
965
|
+
sage: p.bar()
|
|
966
|
+
-(q^-5)*T[3,1] + (q^-2)*T[1,2]
|
|
967
|
+
- (q^-5-q^-4-q^-2+q^-1)*T[1]
|
|
968
|
+
- (q^-5-q^-4+q^-2-q^-1-1)*T[3]
|
|
969
|
+
+ (q^-2-q^-1)*T[2]
|
|
970
|
+
- (q^-5-2*q^-4+q^-3-1+q)
|
|
971
|
+
sage: p.bar().bar() == p
|
|
972
|
+
True
|
|
973
|
+
|
|
974
|
+
This also works for arbitrary ``q1`` and ``q2``::
|
|
975
|
+
|
|
976
|
+
sage: R.<q1,q2> = LaurentPolynomialRing(QQ)
|
|
977
|
+
sage: H = IwahoriHeckeAlgebra('A3', q1, q2=-q2)
|
|
978
|
+
sage: T = H.T()
|
|
979
|
+
sage: T1,T2,T3 = T.algebra_generators()
|
|
980
|
+
sage: p = T1*T3 + T2
|
|
981
|
+
sage: p.bar()
|
|
982
|
+
(q1^-2*q2^-2)*T[3,1]
|
|
983
|
+
+ (-q1^-1*q2^-2+q1^-2*q2^-1)*T[1]
|
|
984
|
+
+ (-q1^-1*q2^-2+q1^-2*q2^-1)*T[3]
|
|
985
|
+
+ (q1^-1*q2^-1)*T[2]
|
|
986
|
+
+ (-q2^-1+q1^-1+q2^-2-2*q1^-1*q2^-1+q1^-2)
|
|
987
|
+
sage: p.bar().bar() == p
|
|
988
|
+
True
|
|
989
|
+
|
|
990
|
+
Next we have an example in the `C` basis::
|
|
991
|
+
|
|
992
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
993
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
994
|
+
sage: C = H.C()
|
|
995
|
+
sage: p = C[1]*C[3] + C[2]
|
|
996
|
+
sage: p.bar()
|
|
997
|
+
C[3,1] + C[2]
|
|
998
|
+
sage: p.bar().bar() == p
|
|
999
|
+
True
|
|
1000
|
+
|
|
1001
|
+
For the `C^{\prime}` basis as well::
|
|
1002
|
+
|
|
1003
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1004
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1005
|
+
sage: Cp = H.Cp()
|
|
1006
|
+
sage: p = Cp[1]*Cp[3] + Cp[2]
|
|
1007
|
+
sage: p.bar()
|
|
1008
|
+
Cp[3,1] + Cp[2]
|
|
1009
|
+
|
|
1010
|
+
TESTS:
|
|
1011
|
+
|
|
1012
|
+
We check that doing the computations explicitly in the `T`
|
|
1013
|
+
basis gives the same results and with bar invariant
|
|
1014
|
+
coefficients::
|
|
1015
|
+
|
|
1016
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1017
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1018
|
+
sage: Cp = H.Cp()
|
|
1019
|
+
sage: T = H.T()
|
|
1020
|
+
sage: Cp(T(Cp[1,2,1])) == Cp[1,2,1]
|
|
1021
|
+
True
|
|
1022
|
+
sage: p = 4*Cp[1]*Cp[3] + (v^2 + v^-2 - 2)*Cp[2]
|
|
1023
|
+
sage: Cp(T(p).bar()) == p
|
|
1024
|
+
True
|
|
1025
|
+
"""
|
|
1026
|
+
B = self.parent()
|
|
1027
|
+
if B.bar_on_basis is NotImplemented:
|
|
1028
|
+
T = B.realization_of().T()
|
|
1029
|
+
return B(T(self).bar())
|
|
1030
|
+
H = B.realization_of()
|
|
1031
|
+
return sum(H._bar_on_coefficients(c) * B.bar_on_basis(w)
|
|
1032
|
+
for (w, c) in self)
|
|
1033
|
+
|
|
1034
|
+
def hash_involution(self):
|
|
1035
|
+
r"""
|
|
1036
|
+
Return the hash involution of ``self``.
|
|
1037
|
+
|
|
1038
|
+
The hash involution `\alpha` is a `\ZZ`-algebra
|
|
1039
|
+
involution of the Iwahori-Hecke algebra determined by
|
|
1040
|
+
`q^{1/2} \mapsto q^{-1/2}`, and `T_w \mapsto
|
|
1041
|
+
(-q_1 q_2)^{-\ell(w)} T_w`, for `w` an element of the
|
|
1042
|
+
corresponding Coxeter group.
|
|
1043
|
+
|
|
1044
|
+
This map is defined in [KL1979]_ and it is used to
|
|
1045
|
+
change between the `C` and `C^{\prime}` bases because
|
|
1046
|
+
`\alpha(C_w) = (-1)^{\ell(w)} C_w'`.
|
|
1047
|
+
|
|
1048
|
+
EXAMPLES::
|
|
1049
|
+
|
|
1050
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1051
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1052
|
+
sage: T = H.T()
|
|
1053
|
+
sage: T1,T2,T3 = T.algebra_generators()
|
|
1054
|
+
sage: elt = T1.hash_involution(); elt
|
|
1055
|
+
-(v^-2)*T[1]
|
|
1056
|
+
sage: elt.hash_involution()
|
|
1057
|
+
T[1]
|
|
1058
|
+
sage: elt = T1*T2 + (v^3 - v^-1 + 2)*T3*T1*T2*T3
|
|
1059
|
+
sage: elt.hash_involution()
|
|
1060
|
+
(v^-11+2*v^-8-v^-7)*T[1,2,3,2] + (v^-4)*T[1,2]
|
|
1061
|
+
sage: elt.hash_involution().hash_involution() == elt
|
|
1062
|
+
True
|
|
1063
|
+
|
|
1064
|
+
With the Kazhdan-Lusztig `C^{\prime}` basis::
|
|
1065
|
+
|
|
1066
|
+
sage: Cp = H.Cp()
|
|
1067
|
+
sage: p = Cp[1]*Cp[3] + Cp[2]
|
|
1068
|
+
sage: q = p.hash_involution(); q
|
|
1069
|
+
Cp[3,1] - (v^-1+v)*Cp[1] - (v^-1+v)*Cp[3] - Cp[2] + (v^-2+v^-1+2+v+v^2)
|
|
1070
|
+
sage: q.hash_involution() == p
|
|
1071
|
+
True
|
|
1072
|
+
|
|
1073
|
+
With the Kazhdan-Lusztig `C` basis::
|
|
1074
|
+
|
|
1075
|
+
sage: C = H.C()
|
|
1076
|
+
sage: p = C[1]*C[3] + C[2]
|
|
1077
|
+
sage: q = p.hash_involution(); q
|
|
1078
|
+
C[3,1] + (v^-1+v)*C[1] + (v^-1+v)*C[3] - C[2] + (v^-2-v^-1+2-v+v^2)
|
|
1079
|
+
sage: q.hash_involution() == p
|
|
1080
|
+
True
|
|
1081
|
+
"""
|
|
1082
|
+
basis = self.parent()
|
|
1083
|
+
if basis.hash_involution_on_basis is NotImplemented:
|
|
1084
|
+
T = basis.realization_of().T()
|
|
1085
|
+
return basis(T(self).hash_involution())
|
|
1086
|
+
|
|
1087
|
+
H = basis.realization_of()
|
|
1088
|
+
return basis(sum(H._bar_on_coefficients(c) * basis.hash_involution_on_basis(w) for (w, c) in self))
|
|
1089
|
+
|
|
1090
|
+
def goldman_involution(self):
|
|
1091
|
+
r"""
|
|
1092
|
+
Return the Goldman involution of ``self``.
|
|
1093
|
+
|
|
1094
|
+
The Goldman involution is the algebra involution of the
|
|
1095
|
+
Iwahori-Hecke algebra determined by
|
|
1096
|
+
|
|
1097
|
+
.. MATH::
|
|
1098
|
+
|
|
1099
|
+
T_w \mapsto (-q_1 q_2)^{\ell(w)} T_{w^{-1}}^{-1},
|
|
1100
|
+
|
|
1101
|
+
where `w` is
|
|
1102
|
+
an element of the corresponding Coxeter group. The main point
|
|
1103
|
+
here is that `q_1 q_2 T_s^{-1} = -T_s + q_1 + q_2`, for
|
|
1104
|
+
each simple reflection `s`.
|
|
1105
|
+
|
|
1106
|
+
This map is defined in [Iwa1964]_. The *alternating Hecke algebra*
|
|
1107
|
+
is the fixed-point subalgebra the Iwahori-Hecke algebra under
|
|
1108
|
+
this involution.
|
|
1109
|
+
|
|
1110
|
+
EXAMPLES::
|
|
1111
|
+
|
|
1112
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1113
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1114
|
+
sage: T = H.T()
|
|
1115
|
+
sage: T[1].goldman_involution()
|
|
1116
|
+
-T[1] - (1-v^2)
|
|
1117
|
+
sage: T[2].goldman_involution()
|
|
1118
|
+
-T[2] - (1-v^2)
|
|
1119
|
+
sage: T[1,2].goldman_involution()
|
|
1120
|
+
T[1,2] + (1-v^2)*T[1] + (1-v^2)*T[2] + (1-2*v^2+v^4)
|
|
1121
|
+
sage: elt=T[1,2]+ v*T[1]
|
|
1122
|
+
sage: elt.goldman_involution()
|
|
1123
|
+
T[1,2] + (1-v-v^2)*T[1] + (1-v^2)*T[2] + (1-v-2*v^2+v^3+v^4)
|
|
1124
|
+
sage: elt.goldman_involution().goldman_involution() == elt
|
|
1125
|
+
True
|
|
1126
|
+
sage: H.A()(elt).goldman_involution()==elt.goldman_involution()
|
|
1127
|
+
True
|
|
1128
|
+
|
|
1129
|
+
With different parameters::
|
|
1130
|
+
|
|
1131
|
+
sage: H = IwahoriHeckeAlgebra('A3', q1=v, q2=-v^-1)
|
|
1132
|
+
sage: T = H.T()
|
|
1133
|
+
sage: T[1].goldman_involution()
|
|
1134
|
+
-T[1] - (v^-1-v)
|
|
1135
|
+
sage: T[2].goldman_involution()
|
|
1136
|
+
-T[2] - (v^-1-v)
|
|
1137
|
+
sage: T[1,2].goldman_involution()
|
|
1138
|
+
T[1,2] + (v^-1-v)*T[1] + (v^-1-v)*T[2] + (v^-2-2+v^2)
|
|
1139
|
+
sage: elt=T[1,2]+ v*T[1]
|
|
1140
|
+
sage: elt.goldman_involution()
|
|
1141
|
+
T[1,2] + (v^-1-2*v)*T[1] + (v^-1-v)*T[2] + (v^-2-3+2*v^2)
|
|
1142
|
+
sage: elt.goldman_involution().goldman_involution() == elt
|
|
1143
|
+
True
|
|
1144
|
+
sage: H.A()(elt).goldman_involution()==elt.goldman_involution()
|
|
1145
|
+
True
|
|
1146
|
+
|
|
1147
|
+
With the `A` basis::
|
|
1148
|
+
|
|
1149
|
+
sage: A = H.A()
|
|
1150
|
+
sage: p = A[1,3] + A[2]
|
|
1151
|
+
sage: q = p.goldman_involution(); q
|
|
1152
|
+
A[3,1] - A[2]
|
|
1153
|
+
sage: q.goldman_involution() == p
|
|
1154
|
+
True
|
|
1155
|
+
|
|
1156
|
+
TESTS::
|
|
1157
|
+
|
|
1158
|
+
sage: all(h.goldman_involution().goldman_involution() == h for h in T.basis()) # long time
|
|
1159
|
+
True
|
|
1160
|
+
"""
|
|
1161
|
+
basis = self.parent()
|
|
1162
|
+
if hasattr(basis, 'goldman_involution_on_basis'):
|
|
1163
|
+
return basis.sum(c * basis.goldman_involution_on_basis(w) for (w, c) in self)
|
|
1164
|
+
|
|
1165
|
+
T = basis.realization_of().T()
|
|
1166
|
+
return basis(T(self).goldman_involution())
|
|
1167
|
+
|
|
1168
|
+
def specialize_to(self, new_hecke, num_vars=2):
|
|
1169
|
+
r"""
|
|
1170
|
+
Return the element in the Iwahori-Hecke algebra ``new_hecke``
|
|
1171
|
+
with respect to the same basis which is obtained from ``self``
|
|
1172
|
+
by specializing the generic parameters in this algebra to the
|
|
1173
|
+
parameters of ``new_hecke``.
|
|
1174
|
+
|
|
1175
|
+
INPUT:
|
|
1176
|
+
|
|
1177
|
+
- ``new_hecke`` -- the Hecke algebra in specialized parameters
|
|
1178
|
+
- ``num_vars`` -- the number of variables to specialize
|
|
1179
|
+
|
|
1180
|
+
.. WARNING::
|
|
1181
|
+
|
|
1182
|
+
This is not always defined. In particular, the number of
|
|
1183
|
+
generators must match ``num_vars``
|
|
1184
|
+
|
|
1185
|
+
EXAMPLES::
|
|
1186
|
+
|
|
1187
|
+
sage: R.<a,b> = LaurentPolynomialRing(ZZ)
|
|
1188
|
+
sage: H = IwahoriHeckeAlgebra("A3", a^2, -b^2)
|
|
1189
|
+
sage: T = H.T()
|
|
1190
|
+
sage: elt = T[1,2,1] + 3*T[1] - a*b*T[3]
|
|
1191
|
+
sage: S.<q> = LaurentPolynomialRing(ZZ)
|
|
1192
|
+
sage: HS = IwahoriHeckeAlgebra("A3", q^2, -1)
|
|
1193
|
+
sage: selt = elt.specialize_to(HS); selt
|
|
1194
|
+
T[1,2,1] + 3*T[1] + q^2*T[3]
|
|
1195
|
+
sage: GA = IwahoriHeckeAlgebra("A3", 1, -1)
|
|
1196
|
+
sage: elt.specialize_to(GA)
|
|
1197
|
+
T[1,2,1] + 3*T[1] + T[3]
|
|
1198
|
+
|
|
1199
|
+
We need to specify that we are only specializing
|
|
1200
|
+
one argument::
|
|
1201
|
+
|
|
1202
|
+
sage: selt.specialize_to(GA)
|
|
1203
|
+
Traceback (most recent call last):
|
|
1204
|
+
...
|
|
1205
|
+
TypeError: Wrong number of arguments
|
|
1206
|
+
sage: selt.specialize_to(GA, 1)
|
|
1207
|
+
T[1,2,1] + 3*T[1] + T[3]
|
|
1208
|
+
"""
|
|
1209
|
+
q1 = new_hecke._q1
|
|
1210
|
+
q2 = new_hecke._q2
|
|
1211
|
+
new_basis = getattr(new_hecke, self.parent()._basis_name)()
|
|
1212
|
+
|
|
1213
|
+
# is there an easier way than this to convert the
|
|
1214
|
+
# coefficients to the correct base ring for new_hecke?
|
|
1215
|
+
if num_vars == 2:
|
|
1216
|
+
args = (q1, q2)
|
|
1217
|
+
elif num_vars == 1:
|
|
1218
|
+
args = (q1,)
|
|
1219
|
+
else:
|
|
1220
|
+
return new_basis._from_dict({w: new_hecke._base(c)
|
|
1221
|
+
for w, c in self})
|
|
1222
|
+
|
|
1223
|
+
return new_basis._from_dict({w: new_hecke._base(c(args))
|
|
1224
|
+
for w, c in self})
|
|
1225
|
+
|
|
1226
|
+
class _Basis(CombinatorialFreeModule, BindableClass):
|
|
1227
|
+
r"""
|
|
1228
|
+
Technical methods (i.e., not mathematical) that are inherited by each
|
|
1229
|
+
basis of the algebra. These methods cannot be defined in the category.
|
|
1230
|
+
"""
|
|
1231
|
+
def __init__(self, algebra, prefix=None):
|
|
1232
|
+
r"""
|
|
1233
|
+
Initialises a basis class for the Iwahori-Hecke algebra ``algebra``.
|
|
1234
|
+
Optionally, a ``prefix`` can be set which is used when printing the
|
|
1235
|
+
basis elements. The prefix defaults to ``self._basis-name``, which
|
|
1236
|
+
is the name of the basis class.
|
|
1237
|
+
|
|
1238
|
+
EXAMPLES::
|
|
1239
|
+
|
|
1240
|
+
sage: H = IwahoriHeckeAlgebra("G2",1)
|
|
1241
|
+
sage: t = H.T(prefix='t')
|
|
1242
|
+
sage: t[1]
|
|
1243
|
+
t[1]
|
|
1244
|
+
"""
|
|
1245
|
+
if prefix is None:
|
|
1246
|
+
self._prefix = self._basis_name
|
|
1247
|
+
else:
|
|
1248
|
+
self._prefix = prefix
|
|
1249
|
+
|
|
1250
|
+
CombinatorialFreeModule.__init__(self,
|
|
1251
|
+
algebra.base_ring(),
|
|
1252
|
+
algebra._W,
|
|
1253
|
+
category=algebra._BasesCategory(),
|
|
1254
|
+
sorting_key=sorting_key,
|
|
1255
|
+
prefix=self._prefix)
|
|
1256
|
+
|
|
1257
|
+
# This **must** match the name of the class in order for
|
|
1258
|
+
# specialize_to() to work
|
|
1259
|
+
_basis_name = 'B'
|
|
1260
|
+
|
|
1261
|
+
def _repr_term(self, t):
|
|
1262
|
+
r"""
|
|
1263
|
+
Return the string representation of the term indexed by ``t``.
|
|
1264
|
+
|
|
1265
|
+
EXAMPLES::
|
|
1266
|
+
|
|
1267
|
+
sage: R.<q> = QQ[]
|
|
1268
|
+
sage: H = IwahoriHeckeAlgebra("A3", q)
|
|
1269
|
+
sage: W = H.coxeter_group()
|
|
1270
|
+
sage: H.T()._repr_term(W.from_reduced_word([1,2,3]))
|
|
1271
|
+
'T[1,2,3]'
|
|
1272
|
+
"""
|
|
1273
|
+
redword = t.reduced_word()
|
|
1274
|
+
if not redword:
|
|
1275
|
+
return "1"
|
|
1276
|
+
return self._print_options['prefix'] + '[%s]' % ','.join('%d' % i for i in redword)
|
|
1277
|
+
|
|
1278
|
+
def _latex_term(self, t):
|
|
1279
|
+
r"""
|
|
1280
|
+
Return latex for the term indexed by ``t``.
|
|
1281
|
+
|
|
1282
|
+
EXAMPLES::
|
|
1283
|
+
|
|
1284
|
+
sage: R.<v> = QQ[]
|
|
1285
|
+
sage: H = IwahoriHeckeAlgebra("A3", q1=v**2, q2=-1)
|
|
1286
|
+
sage: W = H.coxeter_group()
|
|
1287
|
+
sage: H.T()._latex_term(W.from_reduced_word([1,2,3]))
|
|
1288
|
+
'T_{1}T_{2}T_{3}'
|
|
1289
|
+
"""
|
|
1290
|
+
redword = t.reduced_word()
|
|
1291
|
+
if not redword:
|
|
1292
|
+
return '1'
|
|
1293
|
+
return ''.join("%s_{%d}" % (self._print_options['prefix'], i)
|
|
1294
|
+
for i in redword)
|
|
1295
|
+
|
|
1296
|
+
def product_on_basis(self, w1, w2):
|
|
1297
|
+
r"""
|
|
1298
|
+
Return the product of the two basis elements indexed by ``w1`` and
|
|
1299
|
+
``w2``.
|
|
1300
|
+
|
|
1301
|
+
The computation is actually done by converting to the
|
|
1302
|
+
`T`-basis, multiplying and then converting back.
|
|
1303
|
+
|
|
1304
|
+
EXAMPLES::
|
|
1305
|
+
|
|
1306
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
1307
|
+
sage: v = R.gen(0)
|
|
1308
|
+
sage: H = IwahoriHeckeAlgebra('A2', v**2)
|
|
1309
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
1310
|
+
sage: [H.Cp().product_on_basis(s1,x) for x in [s1,s2]]
|
|
1311
|
+
[(v^-1+v)*Cp[1], Cp[1,2]]
|
|
1312
|
+
sage: [H.C().product_on_basis(s1,x) for x in [s1,s2]]
|
|
1313
|
+
[-(v^-1+v)*C[1], C[1,2]]
|
|
1314
|
+
"""
|
|
1315
|
+
return self(self.to_T_basis(w1) * self.to_T_basis(w2))
|
|
1316
|
+
|
|
1317
|
+
class T(_Basis):
|
|
1318
|
+
r"""
|
|
1319
|
+
The standard basis of Iwahori-Hecke algebra.
|
|
1320
|
+
|
|
1321
|
+
For every simple reflection `s_i` of the Coxeter group, there is a
|
|
1322
|
+
corresponding generator `T_i` of Iwahori-Hecke algebra. These
|
|
1323
|
+
are subject to the relations:
|
|
1324
|
+
|
|
1325
|
+
.. MATH::
|
|
1326
|
+
|
|
1327
|
+
(T_i - q_1) (T_i - q_2) = 0
|
|
1328
|
+
|
|
1329
|
+
together with the braid relations:
|
|
1330
|
+
|
|
1331
|
+
.. MATH::
|
|
1332
|
+
|
|
1333
|
+
T_i T_j T_i \cdots = T_j T_i T_j \cdots,
|
|
1334
|
+
|
|
1335
|
+
where the number of terms on each of the two sides is the order of
|
|
1336
|
+
`s_i s_j` in the Coxeter group.
|
|
1337
|
+
|
|
1338
|
+
Weyl group elements form a basis of Iwahori-Hecke algebra `H`
|
|
1339
|
+
with the property that if `w_1` and `w_2` are Coxeter group elements
|
|
1340
|
+
such that `\ell(w_1 w_2) = \ell(w_1) + \ell(w_2)` then
|
|
1341
|
+
`T_{w_1 w_2} = T_{w_1} T_{w_2}`.
|
|
1342
|
+
|
|
1343
|
+
With the default value `q_2 = -1` and with `q_1 = q` the
|
|
1344
|
+
generating relation may be written
|
|
1345
|
+
`T_i^2 = (q-1) \cdot T_i + q \cdot 1` as in [Iwa1964]_.
|
|
1346
|
+
|
|
1347
|
+
EXAMPLES::
|
|
1348
|
+
|
|
1349
|
+
sage: H = IwahoriHeckeAlgebra("A3", 1)
|
|
1350
|
+
sage: T = H.T()
|
|
1351
|
+
sage: T1,T2,T3 = T.algebra_generators()
|
|
1352
|
+
sage: T1*T2*T3*T1*T2*T1 == T3*T2*T1*T3*T2*T3
|
|
1353
|
+
True
|
|
1354
|
+
sage: w0 = T(H.coxeter_group().long_element())
|
|
1355
|
+
sage: w0
|
|
1356
|
+
T[1,2,3,1,2,1]
|
|
1357
|
+
sage: T = H.T(prefix='s')
|
|
1358
|
+
sage: T.an_element()
|
|
1359
|
+
s[1,2,3] + 2*s[1] + 3*s[2] + 1
|
|
1360
|
+
|
|
1361
|
+
TESTS::
|
|
1362
|
+
|
|
1363
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
1364
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1365
|
+
sage: W = H.coxeter_group()
|
|
1366
|
+
sage: T = H.T()
|
|
1367
|
+
sage: C = H.C()
|
|
1368
|
+
sage: Cp = H.Cp()
|
|
1369
|
+
sage: all(T(C(T[x])) == T[x] for x in W) # long time
|
|
1370
|
+
True
|
|
1371
|
+
sage: all(T(Cp(T[x])) == T[x] for x in W) # long time
|
|
1372
|
+
True
|
|
1373
|
+
|
|
1374
|
+
We check a property of the bar involution and `R`-polynomials::
|
|
1375
|
+
|
|
1376
|
+
sage: KL = KazhdanLusztigPolynomial(W, v)
|
|
1377
|
+
sage: all(T[x].bar() == sum(v^(-2*y.length()) * KL.R(y, x).substitute(v=v^-2) * T[y] for y in W) for x in W) # long time
|
|
1378
|
+
True
|
|
1379
|
+
"""
|
|
1380
|
+
_basis_name = "T" # this is used, for example, by specialize_to and is the default prefix
|
|
1381
|
+
|
|
1382
|
+
def inverse_generator(self, i):
|
|
1383
|
+
r"""
|
|
1384
|
+
Return the inverse of the `i`-th generator, if it exists.
|
|
1385
|
+
|
|
1386
|
+
This method is only available if the Iwahori-Hecke algebra
|
|
1387
|
+
parameters ``q1`` and ``q2`` are both invertible. In this case,
|
|
1388
|
+
the algebra generators are also invertible and this method
|
|
1389
|
+
returns the inverse of ``self.algebra_generator(i)``.
|
|
1390
|
+
|
|
1391
|
+
EXAMPLES::
|
|
1392
|
+
|
|
1393
|
+
sage: P.<q1, q2>=QQ[]
|
|
1394
|
+
sage: F = Frac(P)
|
|
1395
|
+
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2, base_ring=F).T()
|
|
1396
|
+
sage: H.base_ring()
|
|
1397
|
+
Fraction Field of Multivariate Polynomial Ring in q1, q2 over Rational Field
|
|
1398
|
+
sage: H.inverse_generator(1)
|
|
1399
|
+
-1/(q1*q2)*T[1] + ((q1+q2)/(q1*q2))
|
|
1400
|
+
sage: H = IwahoriHeckeAlgebra("A2", q1, base_ring=F).T()
|
|
1401
|
+
sage: H.inverse_generator(2)
|
|
1402
|
+
-(1/(-q1))*T[2] + ((q1-1)/(-q1))
|
|
1403
|
+
sage: P1.<r1, r2> = LaurentPolynomialRing(QQ)
|
|
1404
|
+
sage: H1 = IwahoriHeckeAlgebra("B2", r1, q2=r2, base_ring=P1).T()
|
|
1405
|
+
sage: H1.base_ring()
|
|
1406
|
+
Multivariate Laurent Polynomial Ring in r1, r2 over Rational Field
|
|
1407
|
+
sage: H1.inverse_generator(2)
|
|
1408
|
+
(-r1^-1*r2^-1)*T[2] + (r2^-1+r1^-1)
|
|
1409
|
+
sage: H2 = IwahoriHeckeAlgebra("C2", r1, base_ring=P1).T()
|
|
1410
|
+
sage: H2.inverse_generator(2)
|
|
1411
|
+
(r1^-1)*T[2] + (-1+r1^-1)
|
|
1412
|
+
"""
|
|
1413
|
+
A = self.realization_of()
|
|
1414
|
+
try:
|
|
1415
|
+
# This currently works better than ~(self._q1) if
|
|
1416
|
+
# self.base_ring() is a Laurent polynomial ring since it
|
|
1417
|
+
# avoids accidental coercion into a field of fractions.
|
|
1418
|
+
i1 = normalized_laurent_polynomial(A._base, A._q1 ** -1)
|
|
1419
|
+
i2 = normalized_laurent_polynomial(A._base, A._q2 ** -1)
|
|
1420
|
+
except Exception:
|
|
1421
|
+
raise ValueError("%s and %s must be invertible" % (A._q1, A._q2))
|
|
1422
|
+
return (-i1*i2)*self.algebra_generator(i)+(i1+i2)
|
|
1423
|
+
|
|
1424
|
+
@cached_method
|
|
1425
|
+
def inverse_generators(self):
|
|
1426
|
+
r"""
|
|
1427
|
+
Return the inverses of all the generators, if they exist.
|
|
1428
|
+
|
|
1429
|
+
This method is only available if ``q1`` and ``q2`` are invertible.
|
|
1430
|
+
In that case, the algebra generators are also invertible.
|
|
1431
|
+
|
|
1432
|
+
EXAMPLES::
|
|
1433
|
+
|
|
1434
|
+
sage: P.<q> = PolynomialRing(QQ)
|
|
1435
|
+
sage: F = Frac(P)
|
|
1436
|
+
sage: H = IwahoriHeckeAlgebra("A2", q, base_ring=F).T()
|
|
1437
|
+
sage: T1,T2 = H.algebra_generators()
|
|
1438
|
+
sage: U1,U2 = H.inverse_generators()
|
|
1439
|
+
sage: U1*T1,T1*U1
|
|
1440
|
+
(1, 1)
|
|
1441
|
+
sage: P1.<q> = LaurentPolynomialRing(QQ)
|
|
1442
|
+
sage: H1 = IwahoriHeckeAlgebra("A2", q, base_ring=P1).T(prefix='V')
|
|
1443
|
+
sage: V1,V2 = H1.algebra_generators()
|
|
1444
|
+
sage: W1,W2 = H1.inverse_generators()
|
|
1445
|
+
sage: [W1,W2]
|
|
1446
|
+
[(q^-1)*V[1] + (q^-1-1), (q^-1)*V[2] + (q^-1-1)]
|
|
1447
|
+
sage: V1*W1, W2*V2
|
|
1448
|
+
(1, 1)
|
|
1449
|
+
"""
|
|
1450
|
+
return Family(self.index_set(), self.inverse_generator)
|
|
1451
|
+
|
|
1452
|
+
def product_on_basis(self, w1, w2):
|
|
1453
|
+
r"""
|
|
1454
|
+
Return `T_{w_1} T_{w_2}`, where `w_1` and `w_2` are words in the
|
|
1455
|
+
Coxeter group.
|
|
1456
|
+
|
|
1457
|
+
EXAMPLES::
|
|
1458
|
+
|
|
1459
|
+
sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q)
|
|
1460
|
+
sage: T = H.T()
|
|
1461
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
1462
|
+
sage: [T.product_on_basis(s1,x) for x in [s1,s2]]
|
|
1463
|
+
[(q-1)*T[1] + q, T[1,2]]
|
|
1464
|
+
"""
|
|
1465
|
+
result = self.monomial(w1)
|
|
1466
|
+
for i in w2.reduced_word():
|
|
1467
|
+
result = self.product_by_generator(result, i)
|
|
1468
|
+
return result
|
|
1469
|
+
|
|
1470
|
+
def product_by_generator_on_basis(self, w, i, side='right'):
|
|
1471
|
+
r"""
|
|
1472
|
+
Return the product `T_w T_i` (resp. `T_i T_w`) if ``side`` is
|
|
1473
|
+
``'right'`` (resp. ``'left'``).
|
|
1474
|
+
|
|
1475
|
+
If the quadratic relation is `(T_i-u)(T_i-v) = 0`, then we have
|
|
1476
|
+
|
|
1477
|
+
.. MATH::
|
|
1478
|
+
|
|
1479
|
+
T_w T_i = \begin{cases}
|
|
1480
|
+
T_{ws_i} & \text{if } \ell(ws_i) = \ell(w) + 1, \\
|
|
1481
|
+
(u+v) T_{ws_i} - uv T_w & \text{if } \ell(w s_i) = \ell(w)-1.
|
|
1482
|
+
\end{cases}
|
|
1483
|
+
|
|
1484
|
+
The left action is similar.
|
|
1485
|
+
|
|
1486
|
+
INPUT:
|
|
1487
|
+
|
|
1488
|
+
- ``w`` -- an element of the Coxeter group
|
|
1489
|
+
- ``i`` -- an element of the index set
|
|
1490
|
+
- ``side`` -- ``'right'`` (default) or ``'left'``
|
|
1491
|
+
|
|
1492
|
+
EXAMPLES::
|
|
1493
|
+
|
|
1494
|
+
sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q)
|
|
1495
|
+
sage: T = H.T()
|
|
1496
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
1497
|
+
sage: [T.product_by_generator_on_basis(w, 1) for w in [s1,s2,s1*s2]]
|
|
1498
|
+
[(q-1)*T[1] + q, T[2,1], T[1,2,1]]
|
|
1499
|
+
sage: [T.product_by_generator_on_basis(w, 1, side='left') for w in [s1,s2,s1*s2]]
|
|
1500
|
+
[(q-1)*T[1] + q, T[1,2], (q-1)*T[1,2] + q*T[2]]
|
|
1501
|
+
"""
|
|
1502
|
+
wi = w.apply_simple_reflection(i, side=side)
|
|
1503
|
+
A = self.realization_of()
|
|
1504
|
+
if w.has_descent(i, side=side):
|
|
1505
|
+
# 10% faster than a plain addition on the example of #12528
|
|
1506
|
+
return self.sum_of_terms(((w, A._q_sum), (wi, A._q_prod)),
|
|
1507
|
+
distinct=True)
|
|
1508
|
+
else:
|
|
1509
|
+
return self.monomial(wi)
|
|
1510
|
+
|
|
1511
|
+
def product_by_generator(self, x, i, side='right'):
|
|
1512
|
+
r"""
|
|
1513
|
+
Return `T_i \cdot x`, where `T_i` is the `i`-th generator. This is
|
|
1514
|
+
coded individually for use in ``x._mul_()``.
|
|
1515
|
+
|
|
1516
|
+
EXAMPLES::
|
|
1517
|
+
|
|
1518
|
+
sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q).T()
|
|
1519
|
+
sage: T1, T2 = H.algebra_generators()
|
|
1520
|
+
sage: [H.product_by_generator(x, 1) for x in [T1,T2]]
|
|
1521
|
+
[(q-1)*T[1] + q, T[2,1]]
|
|
1522
|
+
sage: [H.product_by_generator(x, 1, side = "left") for x in [T1,T2]]
|
|
1523
|
+
[(q-1)*T[1] + q, T[1,2]]
|
|
1524
|
+
"""
|
|
1525
|
+
return self.linear_combination((self.product_by_generator_on_basis(w, i, side), c)
|
|
1526
|
+
for (w, c) in x)
|
|
1527
|
+
|
|
1528
|
+
def to_C_basis(self, w):
|
|
1529
|
+
r"""
|
|
1530
|
+
Return `T_w` as a linear combination of `C`-basis elements.
|
|
1531
|
+
|
|
1532
|
+
EXAMPLES::
|
|
1533
|
+
|
|
1534
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
1535
|
+
sage: v = R.gen(0)
|
|
1536
|
+
sage: H = IwahoriHeckeAlgebra('A2', v**2)
|
|
1537
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
1538
|
+
sage: T = H.T()
|
|
1539
|
+
sage: C = H.C()
|
|
1540
|
+
sage: T.to_C_basis(s1)
|
|
1541
|
+
v*T[1] + v^2
|
|
1542
|
+
sage: C(T(s1))
|
|
1543
|
+
v*C[1] + v^2
|
|
1544
|
+
sage: C(v^-1*T(s1) - v)
|
|
1545
|
+
C[1]
|
|
1546
|
+
sage: C(T(s1*s2)+T(s1)+T(s2)+1)
|
|
1547
|
+
v^2*C[1,2] + (v+v^3)*C[1] + (v+v^3)*C[2] + (1+2*v^2+v^4)
|
|
1548
|
+
sage: C(T(s1*s2*s1))
|
|
1549
|
+
v^3*C[1,2,1] + v^4*C[2,1] + v^4*C[1,2] + v^5*C[1] + v^5*C[2] + v^6
|
|
1550
|
+
"""
|
|
1551
|
+
H = self.realization_of()
|
|
1552
|
+
generic_T = H._generic_iwahori_hecke_algebra.T()
|
|
1553
|
+
return generic_T.to_C_basis(w).specialize_to(H)
|
|
1554
|
+
|
|
1555
|
+
def to_Cp_basis(self, w):
|
|
1556
|
+
r"""
|
|
1557
|
+
Return `T_w` as a linear combination of `C^{\prime}`-basis
|
|
1558
|
+
elements.
|
|
1559
|
+
|
|
1560
|
+
EXAMPLES::
|
|
1561
|
+
|
|
1562
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1563
|
+
sage: H = IwahoriHeckeAlgebra('A2', v**2)
|
|
1564
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
1565
|
+
sage: T = H.T()
|
|
1566
|
+
sage: Cp = H.Cp()
|
|
1567
|
+
sage: T.to_Cp_basis(s1)
|
|
1568
|
+
v*Cp[1] - 1
|
|
1569
|
+
sage: Cp(T(s1))
|
|
1570
|
+
v*Cp[1] - 1
|
|
1571
|
+
sage: Cp(T(s1)+1)
|
|
1572
|
+
v*Cp[1]
|
|
1573
|
+
sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)
|
|
1574
|
+
v^2*Cp[1,2]
|
|
1575
|
+
sage: Cp(T(s1*s2*s1))
|
|
1576
|
+
v^3*Cp[1,2,1] - v^2*Cp[2,1] - v^2*Cp[1,2] + v*Cp[1] + v*Cp[2] - 1
|
|
1577
|
+
"""
|
|
1578
|
+
H = self.realization_of()
|
|
1579
|
+
generic_T = H._generic_iwahori_hecke_algebra.T()
|
|
1580
|
+
return generic_T.to_Cp_basis(w).specialize_to(H)
|
|
1581
|
+
|
|
1582
|
+
def bar_on_basis(self, w):
|
|
1583
|
+
"""
|
|
1584
|
+
Return the bar involution of `T_w`, which is `T^{-1}_{w^-1}`.
|
|
1585
|
+
|
|
1586
|
+
EXAMPLES::
|
|
1587
|
+
|
|
1588
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1589
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1590
|
+
sage: W = H.coxeter_group()
|
|
1591
|
+
sage: s1,s2,s3 = W.simple_reflections()
|
|
1592
|
+
sage: T = H.T()
|
|
1593
|
+
sage: b = T.bar_on_basis(s1*s2*s3); b
|
|
1594
|
+
(v^-6)*T[1,2,3] + (v^-6-v^-4)*T[3,1]
|
|
1595
|
+
+ (v^-6-v^-4)*T[1,2] + (v^-6-v^-4)*T[2,3]
|
|
1596
|
+
+ (v^-6-2*v^-4+v^-2)*T[1] + (v^-6-2*v^-4+v^-2)*T[3]
|
|
1597
|
+
+ (v^-6-2*v^-4+v^-2)*T[2] + (v^-6-3*v^-4+3*v^-2-1)
|
|
1598
|
+
sage: b.bar()
|
|
1599
|
+
T[1,2,3]
|
|
1600
|
+
"""
|
|
1601
|
+
return self.monomial(w.inverse()).inverse()
|
|
1602
|
+
|
|
1603
|
+
def hash_involution_on_basis(self, w):
|
|
1604
|
+
r"""
|
|
1605
|
+
Return the hash involution on the basis element ``self[w]``.
|
|
1606
|
+
|
|
1607
|
+
The hash involution `\alpha` is a `\ZZ`-algebra
|
|
1608
|
+
involution of the Iwahori-Hecke algebra determined by
|
|
1609
|
+
`q^{1/2} \mapsto q^{-1/2}`, and `T_w \mapsto
|
|
1610
|
+
(-q_1 q_2)^{-\ell(w)} T_w`, for `w` an element of the
|
|
1611
|
+
corresponding Coxeter group.
|
|
1612
|
+
|
|
1613
|
+
This map is defined in [KL1979]_ and it is used to change between
|
|
1614
|
+
the `C` and `C^{\prime}` bases because
|
|
1615
|
+
`\alpha(C_w) = (-1)^{\ell(w)}C^{\prime}_w`.
|
|
1616
|
+
|
|
1617
|
+
This function is not intended to be called directly. Instead, use
|
|
1618
|
+
:meth:`hash_involution`.
|
|
1619
|
+
|
|
1620
|
+
EXAMPLES::
|
|
1621
|
+
|
|
1622
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
1623
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1624
|
+
sage: T=H.T()
|
|
1625
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
1626
|
+
sage: T.hash_involution_on_basis(s)
|
|
1627
|
+
-(v^-2)*T[1]
|
|
1628
|
+
sage: T[s].hash_involution()
|
|
1629
|
+
-(v^-2)*T[1]
|
|
1630
|
+
sage: h = T[1]*T[2] + (v^3 - v^-1 + 2)*T[3,1,2,3]
|
|
1631
|
+
sage: h.hash_involution()
|
|
1632
|
+
(v^-11+2*v^-8-v^-7)*T[1,2,3,2] + (v^-4)*T[1,2]
|
|
1633
|
+
sage: h.hash_involution().hash_involution() == h
|
|
1634
|
+
True
|
|
1635
|
+
"""
|
|
1636
|
+
H = self.realization_of()
|
|
1637
|
+
return (-H._q_prod)**(-w.length())*self.monomial(w)
|
|
1638
|
+
|
|
1639
|
+
def goldman_involution_on_basis(self, w):
|
|
1640
|
+
r"""
|
|
1641
|
+
Return the Goldman involution to the basis element
|
|
1642
|
+
indexed by ``w``.
|
|
1643
|
+
|
|
1644
|
+
The goldman involution is the algebra involution of the
|
|
1645
|
+
Iwahori-Hecke algebra determined by
|
|
1646
|
+
|
|
1647
|
+
.. MATH::
|
|
1648
|
+
|
|
1649
|
+
T_w \mapsto (-q_1 q_2)^{\ell(w)} T_{w^{-1}}^{-1},
|
|
1650
|
+
|
|
1651
|
+
where `w` is an element of the corresponding Coxeter group.
|
|
1652
|
+
|
|
1653
|
+
This map is defined in [Iwa1964]_ and it is used to define the
|
|
1654
|
+
alternating subalgebra of the Iwahori-Hecke algebra, which is the
|
|
1655
|
+
fixed-point subalgebra of the Goldman involution.
|
|
1656
|
+
|
|
1657
|
+
This function is not intended to be called directly. Instead, use
|
|
1658
|
+
:meth:`goldman_involution`.
|
|
1659
|
+
|
|
1660
|
+
EXAMPLES::
|
|
1661
|
+
|
|
1662
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
1663
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1664
|
+
sage: T=H.T()
|
|
1665
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
1666
|
+
sage: T.goldman_involution_on_basis(s)
|
|
1667
|
+
-T[1] - (1-v^2)
|
|
1668
|
+
sage: T[s].goldman_involution()
|
|
1669
|
+
-T[1] - (1-v^2)
|
|
1670
|
+
sage: h = T[1]*T[2] + (v^3 - v^-1 + 2)*T[3,1,2,3]
|
|
1671
|
+
sage: h.goldman_involution()
|
|
1672
|
+
-(v^-1-2-v^3)*T[1,2,3,2]
|
|
1673
|
+
- (v^-1-2-v+2*v^2-v^3+v^5)*T[3,1,2]
|
|
1674
|
+
- (v^-1-2-v+2*v^2-v^3+v^5)*T[1,2,3]
|
|
1675
|
+
- (v^-1-2-v+2*v^2-v^3+v^5)*T[2,3,2]
|
|
1676
|
+
- (v^-1-2-2*v+4*v^2-2*v^4+2*v^5-v^7)*T[3,1]
|
|
1677
|
+
- (v^-1-3-2*v+4*v^2-2*v^4+2*v^5-v^7)*T[1,2]
|
|
1678
|
+
- (v^-1-2-2*v+4*v^2-2*v^4+2*v^5-v^7)*T[3,2]
|
|
1679
|
+
- (v^-1-2-2*v+4*v^2-2*v^4+2*v^5-v^7)*T[2,3]
|
|
1680
|
+
- (v^-1-3-2*v+5*v^2+v^3-4*v^4+v^5+2*v^6-2*v^7+v^9)*T[1]
|
|
1681
|
+
- (v^-1-2-3*v+6*v^2+2*v^3-6*v^4+2*v^5+2*v^6-3*v^7+v^9)*T[3]
|
|
1682
|
+
- (v^-1-3-3*v+7*v^2+2*v^3-6*v^4+2*v^5+2*v^6-3*v^7+v^9)*T[2]
|
|
1683
|
+
- (v^-1-3-3*v+8*v^2+3*v^3-9*v^4+6*v^6-3*v^7-2*v^8+3*v^9-v^11)
|
|
1684
|
+
sage: h.goldman_involution().goldman_involution() == h
|
|
1685
|
+
True
|
|
1686
|
+
"""
|
|
1687
|
+
H = self.realization_of()
|
|
1688
|
+
return (-H._q_prod)**w.length() * self.monomial(w.inverse()).inverse()
|
|
1689
|
+
|
|
1690
|
+
class Element(CombinatorialFreeModule.Element):
|
|
1691
|
+
r"""
|
|
1692
|
+
A class for elements of an Iwahori-Hecke algebra in the `T` basis.
|
|
1693
|
+
|
|
1694
|
+
TESTS::
|
|
1695
|
+
|
|
1696
|
+
sage: R.<q> = QQ[]
|
|
1697
|
+
sage: H = IwahoriHeckeAlgebra("B3",q).T()
|
|
1698
|
+
sage: T1,T2,T3 = H.algebra_generators()
|
|
1699
|
+
sage: T1+2*T2*T3
|
|
1700
|
+
2*T[2,3] + T[1]
|
|
1701
|
+
sage: T1*T1
|
|
1702
|
+
(q-1)*T[1] + q
|
|
1703
|
+
|
|
1704
|
+
sage: R.<q1,q2> = QQ[]
|
|
1705
|
+
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix='x')
|
|
1706
|
+
sage: sum(H.algebra_generators())^2
|
|
1707
|
+
x[2,1] + x[1,2] + (q1+q2)*x[1] + (q1+q2)*x[2] - 2*q1*q2
|
|
1708
|
+
|
|
1709
|
+
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix='t')
|
|
1710
|
+
sage: t1,t2 = H.algebra_generators()
|
|
1711
|
+
sage: (t1-t2)^3
|
|
1712
|
+
(q1^2-q1*q2+q2^2)*t[1] - (q1^2-q1*q2+q2^2)*t[2]
|
|
1713
|
+
|
|
1714
|
+
sage: R.<q> = QQ[]
|
|
1715
|
+
sage: H = IwahoriHeckeAlgebra("G2", q).T()
|
|
1716
|
+
sage: [T1, T2] = H.algebra_generators()
|
|
1717
|
+
sage: T1*T2*T1*T2*T1*T2 == T2*T1*T2*T1*T2*T1
|
|
1718
|
+
True
|
|
1719
|
+
sage: T1*T2*T1 == T2*T1*T2
|
|
1720
|
+
False
|
|
1721
|
+
|
|
1722
|
+
sage: H = IwahoriHeckeAlgebra("A2", 1).T()
|
|
1723
|
+
sage: [T1,T2] = H.algebra_generators()
|
|
1724
|
+
sage: T1+T2
|
|
1725
|
+
T[1] + T[2]
|
|
1726
|
+
|
|
1727
|
+
sage: -(T1+T2)
|
|
1728
|
+
-T[1] - T[2]
|
|
1729
|
+
sage: 1-T1
|
|
1730
|
+
-T[1] + 1
|
|
1731
|
+
|
|
1732
|
+
sage: T1.parent()
|
|
1733
|
+
Iwahori-Hecke algebra of type A2 in 1,-1 over Integer Ring in the T-basis
|
|
1734
|
+
"""
|
|
1735
|
+
def __invert__(self):
|
|
1736
|
+
r"""
|
|
1737
|
+
Return the inverse if ``self`` is a basis element.
|
|
1738
|
+
|
|
1739
|
+
An element is a basis element if it is `T_w` where `w` is in
|
|
1740
|
+
the Weyl group. The base ring must be a field or Laurent
|
|
1741
|
+
polynomial ring. Other elements of the ring have inverses but
|
|
1742
|
+
the inverse method is only implemented for the basis elements.
|
|
1743
|
+
|
|
1744
|
+
EXAMPLES::
|
|
1745
|
+
|
|
1746
|
+
sage: R.<q> = LaurentPolynomialRing(QQ)
|
|
1747
|
+
sage: H = IwahoriHeckeAlgebra("A2", q).T()
|
|
1748
|
+
sage: [T1,T2] = H.algebra_generators()
|
|
1749
|
+
sage: x = (T1*T2).inverse(); x # indirect doctest
|
|
1750
|
+
(q^-2)*T[2,1] + (q^-2-q^-1)*T[1] + (q^-2-q^-1)*T[2] + (q^-2-2*q^-1+1)
|
|
1751
|
+
sage: x*T1*T2
|
|
1752
|
+
1
|
|
1753
|
+
|
|
1754
|
+
TESTS:
|
|
1755
|
+
|
|
1756
|
+
We check some alternative forms of input for inverting
|
|
1757
|
+
an element::
|
|
1758
|
+
|
|
1759
|
+
sage: R.<q> = LaurentPolynomialRing(QQ)
|
|
1760
|
+
sage: H = IwahoriHeckeAlgebra("A2", q).T()
|
|
1761
|
+
sage: T1,T2 = H.algebra_generators()
|
|
1762
|
+
sage: ~(T1*T2)
|
|
1763
|
+
(q^-2)*T[2,1] + (q^-2-q^-1)*T[1] + (q^-2-q^-1)*T[2] + (q^-2-2*q^-1+1)
|
|
1764
|
+
sage: (T1*T2)^(-1)
|
|
1765
|
+
(q^-2)*T[2,1] + (q^-2-q^-1)*T[1] + (q^-2-q^-1)*T[2] + (q^-2-2*q^-1+1)
|
|
1766
|
+
"""
|
|
1767
|
+
if len(self) != 1:
|
|
1768
|
+
raise NotImplementedError("inverse only implemented for basis elements (monomials in the generators)" % self)
|
|
1769
|
+
H = self.parent()
|
|
1770
|
+
w = self.support_of_term()
|
|
1771
|
+
|
|
1772
|
+
return H.prod(H.inverse_generator(i) for i in reversed(w.reduced_word()))
|
|
1773
|
+
|
|
1774
|
+
standard = T
|
|
1775
|
+
|
|
1776
|
+
class _KLHeckeBasis(_Basis):
|
|
1777
|
+
r"""
|
|
1778
|
+
Abstract class for the common methods for the Kazhdan-Lusztig `C` and
|
|
1779
|
+
`C^{\prime}` bases.
|
|
1780
|
+
"""
|
|
1781
|
+
def __init__(self, IHAlgebra, prefix=None):
|
|
1782
|
+
r"""
|
|
1783
|
+
Initialize the Kazhdan-Lusztig basis of the Iwahori-Hecke
|
|
1784
|
+
algebra ``IHAlgebra``.
|
|
1785
|
+
|
|
1786
|
+
EXAMPLES::
|
|
1787
|
+
|
|
1788
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1789
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1790
|
+
sage: Cp = H.Cp()
|
|
1791
|
+
sage: C = H.C()
|
|
1792
|
+
"""
|
|
1793
|
+
if IHAlgebra._root is None:
|
|
1794
|
+
raise ValueError('the Kazhdan-Lusztig bases are defined '
|
|
1795
|
+
'only when -q_1*q_2 is a square')
|
|
1796
|
+
|
|
1797
|
+
if IHAlgebra._is_generic:
|
|
1798
|
+
klbasis = IwahoriHeckeAlgebra_nonstandard._KLHeckeBasis
|
|
1799
|
+
else:
|
|
1800
|
+
klbasis = IwahoriHeckeAlgebra._KLHeckeBasis
|
|
1801
|
+
super(klbasis, self).__init__(IHAlgebra, prefix)
|
|
1802
|
+
|
|
1803
|
+
# Define conversion from the KL-basis to the T-basis via
|
|
1804
|
+
# specialization from the generic Hecke algebra
|
|
1805
|
+
self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), category=self.category()
|
|
1806
|
+
).register_as_coercion()
|
|
1807
|
+
|
|
1808
|
+
# ...and from the T_basis to the KL-basis.
|
|
1809
|
+
T = IHAlgebra.T()
|
|
1810
|
+
T.module_morphism(getattr(T, 'to_{}_basis'.format(self._basis_name)),
|
|
1811
|
+
codomain=self, category=self.category()
|
|
1812
|
+
).register_as_coercion()
|
|
1813
|
+
|
|
1814
|
+
def bar_on_basis(self, w):
|
|
1815
|
+
r"""
|
|
1816
|
+
Return the bar involution on the Kazhdan-Lusztig basis element
|
|
1817
|
+
indexed by ``w``. By definition, all Kazhdan-Lusztig basis elements
|
|
1818
|
+
are fixed by the bar involution.
|
|
1819
|
+
|
|
1820
|
+
EXAMPLES::
|
|
1821
|
+
|
|
1822
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1823
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1824
|
+
sage: W = H.coxeter_group()
|
|
1825
|
+
sage: s1,s2,s3 = W.simple_reflections()
|
|
1826
|
+
sage: Cp = H.Cp()
|
|
1827
|
+
sage: Cp.bar_on_basis(s1*s2*s1*s3)
|
|
1828
|
+
Cp[1,2,3,1]
|
|
1829
|
+
"""
|
|
1830
|
+
return self.monomial(w)
|
|
1831
|
+
|
|
1832
|
+
def to_T_basis(self, w):
|
|
1833
|
+
r"""
|
|
1834
|
+
Return the Kazhdan-Lusztig basis element ``self[w]`` as a linear
|
|
1835
|
+
combination of ``T``-basis elements.
|
|
1836
|
+
|
|
1837
|
+
EXAMPLES::
|
|
1838
|
+
|
|
1839
|
+
sage: H=IwahoriHeckeAlgebra("A3",1); Cp=H.Cp(); C=H.C()
|
|
1840
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
1841
|
+
sage: C.to_T_basis(s)
|
|
1842
|
+
T[1] - 1
|
|
1843
|
+
sage: Cp.to_T_basis(s)
|
|
1844
|
+
T[1] + 1
|
|
1845
|
+
"""
|
|
1846
|
+
H = self.realization_of()
|
|
1847
|
+
generic_KL = getattr(H._generic_iwahori_hecke_algebra, self._basis_name)()
|
|
1848
|
+
return generic_KL.to_T_basis(w).specialize_to(H)
|
|
1849
|
+
|
|
1850
|
+
class Cp(_KLHeckeBasis):
|
|
1851
|
+
r"""
|
|
1852
|
+
The `C^{\prime}` Kazhdan-Lusztig basis of Iwahori-Hecke algebra.
|
|
1853
|
+
|
|
1854
|
+
Assuming the standard quadratic relations of `(T_r-q)(T_r+1)=0`, for
|
|
1855
|
+
every element `w` in the Coxeter group, there is a unique element
|
|
1856
|
+
`C^{\prime}_w` in the Iwahori-Hecke algebra which is uniquely determined
|
|
1857
|
+
by the two properties:
|
|
1858
|
+
|
|
1859
|
+
.. MATH::
|
|
1860
|
+
|
|
1861
|
+
\begin{aligned}
|
|
1862
|
+
\overline{ C^{\prime}_w } &= C^{\prime}_w, \\
|
|
1863
|
+
C^{\prime}_w &= q^{-\ell(w)/2}
|
|
1864
|
+
\sum_{v \leq w} P_{v,w}(q) T_v,
|
|
1865
|
+
\end{aligned}
|
|
1866
|
+
|
|
1867
|
+
where `\leq` is the Bruhat order on the underlying Coxeter group and
|
|
1868
|
+
`P_{v,w}(q) \in \ZZ[q,q^{-1}]` are polynomials in `\ZZ[q]` such that
|
|
1869
|
+
`P_{w,w}(q) = 1` and if `v < w` then `\deg P_{v,w}(q) \leq
|
|
1870
|
+
\frac{1}{2}(\ell(w)-\ell(v)-1)`.
|
|
1871
|
+
|
|
1872
|
+
More generally, if the quadratic relations are of the form
|
|
1873
|
+
(T_s-q_1)(T_s-q_2)=0` and `\sqrt{-q_1q_2}` exists then, for a simple
|
|
1874
|
+
reflection `s`, the corresponding Kazhdan-Lusztig basis element is:
|
|
1875
|
+
|
|
1876
|
+
.. MATH::
|
|
1877
|
+
|
|
1878
|
+
C^{\prime}_s = (-q_1 q_2)^{-1/2} (T_s + 1).
|
|
1879
|
+
|
|
1880
|
+
See [KL1979]_ for more details.
|
|
1881
|
+
|
|
1882
|
+
If the optional ``coxeter3`` package is available and the
|
|
1883
|
+
Iwahori--Hecke algebra was initialized in the "standard" presentation
|
|
1884
|
+
where `\{q_1,q_2\} = \{v^2,1\}` as sets or the "normalized"
|
|
1885
|
+
presentation where `\{q_1,q_2\} = \{v,-v^{-1}\}` as sets, the function
|
|
1886
|
+
:func:`product_on_basis` in this class computes products in the
|
|
1887
|
+
`C^{\prime}`-basis directly in the basis itself, using ``coxeter3`` to
|
|
1888
|
+
calculate certain `\mu`-coefficients quickly. If the above conditions
|
|
1889
|
+
are not all met, the function computes such products indirectly, by
|
|
1890
|
+
converting elements to the `T`-basis, computing products there, and
|
|
1891
|
+
converting back. The indirect method can be prohibitively slow for
|
|
1892
|
+
more complex calculations; the direct method is faster.
|
|
1893
|
+
|
|
1894
|
+
EXAMPLES::
|
|
1895
|
+
|
|
1896
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
1897
|
+
sage: v = R.gen(0)
|
|
1898
|
+
sage: H = IwahoriHeckeAlgebra('A5', v**2)
|
|
1899
|
+
sage: W = H.coxeter_group()
|
|
1900
|
+
sage: s1,s2,s3,s4,s5 = W.simple_reflections()
|
|
1901
|
+
sage: T = H.T()
|
|
1902
|
+
sage: Cp = H.Cp()
|
|
1903
|
+
sage: T(s1)**2
|
|
1904
|
+
-(1-v^2)*T[1] + v^2
|
|
1905
|
+
sage: T(Cp(s1))
|
|
1906
|
+
(v^-1)*T[1] + (v^-1)
|
|
1907
|
+
sage: T(Cp(s1)*Cp(s2)*Cp(s1))
|
|
1908
|
+
(v^-3)*T[1,2,1] + (v^-3)*T[2,1] + (v^-3)*T[1,2]
|
|
1909
|
+
+ (v^-3+v^-1)*T[1] + (v^-3)*T[2] + (v^-3+v^-1)
|
|
1910
|
+
|
|
1911
|
+
::
|
|
1912
|
+
|
|
1913
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
1914
|
+
sage: v = R.gen(0)
|
|
1915
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1916
|
+
sage: W = H.coxeter_group()
|
|
1917
|
+
sage: s1,s2,s3 = W.simple_reflections()
|
|
1918
|
+
sage: Cp = H.Cp()
|
|
1919
|
+
sage: Cp(s1*s2*s1)
|
|
1920
|
+
Cp[1,2,1]
|
|
1921
|
+
sage: Cp(s1)**2
|
|
1922
|
+
(v^-1+v)*Cp[1]
|
|
1923
|
+
sage: Cp(s1)*Cp(s2)*Cp(s1)
|
|
1924
|
+
Cp[1,2,1] + Cp[1]
|
|
1925
|
+
sage: Cp(s1)*Cp(s2)*Cp(s3)*Cp(s1)*Cp(s2) # long time
|
|
1926
|
+
Cp[1,2,3,1,2] + Cp[1,2,1] + Cp[3,1,2]
|
|
1927
|
+
|
|
1928
|
+
In the following product computations, whether ``coxeter3`` is
|
|
1929
|
+
installed makes a big difference: without ``coxeter3`` the product in
|
|
1930
|
+
type `H_4` takes about 5 seconds to compute and the product in type
|
|
1931
|
+
`A_9` seems infeasible, while with ``coxeter3`` both the computations
|
|
1932
|
+
are instant::
|
|
1933
|
+
|
|
1934
|
+
sage: H = IwahoriHeckeAlgebra('H4', v**2) # optional - coxeter3
|
|
1935
|
+
sage: Cp = H.Cp() # optional - coxeter3
|
|
1936
|
+
sage: Cp[3,4,3]*Cp[3,4,3,4]*Cp[1,2,3,4] # optional - coxeter3
|
|
1937
|
+
(v^-2+2+v^2)*Cp[3,4,3,4,1,2,3,4,2]
|
|
1938
|
+
+ (v^-2+2+v^2)*Cp[3,4,3,4,3,1,2]
|
|
1939
|
+
+ (v^-3+3*v^-1+3*v+v^3)*Cp[3,4,3,4,3,1]
|
|
1940
|
+
+ (v^-1+v)*Cp[3,4,1,2,3,4]
|
|
1941
|
+
+ (v^-1+v)*Cp[3,4,1,2]
|
|
1942
|
+
|
|
1943
|
+
sage: H = IwahoriHeckeAlgebra('A9', v**2) # optional - coxeter3
|
|
1944
|
+
sage: Cp = H.Cp() # optional - coxeter3
|
|
1945
|
+
sage: Cp[1,2,1,8,9,8]*Cp[1,2,3,7,8,9] # optional - coxeter3
|
|
1946
|
+
(v^-2+2+v^2)*Cp[7,8,9,7,8,7,1,2,3,1]
|
|
1947
|
+
+ (v^-2+2+v^2)*Cp[8,9,8,7,1,2,3,1]
|
|
1948
|
+
+ (v^-3+3*v^-1+3*v+v^3)*Cp[8,9,8,1,2,3,1]
|
|
1949
|
+
|
|
1950
|
+
To use ``coxeter3`` for product computations most efficiently, we
|
|
1951
|
+
recommend creating the Iwahori-Hecke algebra from a Coxeter group
|
|
1952
|
+
implemented with ``coxeter3`` to avoid unnecessary conversions, as in
|
|
1953
|
+
the following example with the same product computed in the last one::
|
|
1954
|
+
|
|
1955
|
+
sage: # optional - coxeter3
|
|
1956
|
+
sage: R = LaurentPolynomialRing(QQ, 'v')
|
|
1957
|
+
sage: v = R.gen(0)
|
|
1958
|
+
sage: W = CoxeterGroup('A9', implementation='coxeter3')
|
|
1959
|
+
sage: H = IwahoriHeckeAlgebra(W, v**2)
|
|
1960
|
+
sage: Cp = H.Cp()
|
|
1961
|
+
sage: Cp[1,2,1,8,9,8]*Cp[1,2,3,7,8,9]
|
|
1962
|
+
(v^-2+2+v^2)*Cp[1,2,1,3,7,8,7,9,8,7]
|
|
1963
|
+
+ (v^-2+2+v^2)*Cp[1,2,1,3,8,9,8,7]
|
|
1964
|
+
+ (v^-3+3*v^-1+3*v+v^3)*Cp[1,2,1,3,8,9,8]
|
|
1965
|
+
|
|
1966
|
+
TESTS::
|
|
1967
|
+
|
|
1968
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
1969
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
1970
|
+
sage: W = H.coxeter_group()
|
|
1971
|
+
sage: T = H.T()
|
|
1972
|
+
sage: C = H.C()
|
|
1973
|
+
sage: Cp = H.Cp()
|
|
1974
|
+
sage: all(Cp(T(Cp[x])) == Cp[x] for x in W) # long time
|
|
1975
|
+
True
|
|
1976
|
+
sage: all(Cp(C(Cp[x])) == Cp[x] for x in W) # long time
|
|
1977
|
+
True
|
|
1978
|
+
"""
|
|
1979
|
+
_basis_name = 'Cp' # this is used, for example, by specialize_to and is the default prefix
|
|
1980
|
+
|
|
1981
|
+
def __init__(self, IHAlgebra, prefix=None):
|
|
1982
|
+
r"""
|
|
1983
|
+
TESTS::
|
|
1984
|
+
|
|
1985
|
+
sage: # optional - coxeter3
|
|
1986
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
1987
|
+
sage: W = CoxeterGroup('A3', implementation='coxeter3')
|
|
1988
|
+
sage: H = IwahoriHeckeAlgebra(W, v**2)
|
|
1989
|
+
sage: Cp = H.Cp()
|
|
1990
|
+
sage: Cp._delta == v + ~v
|
|
1991
|
+
True
|
|
1992
|
+
sage: Cp._W_Coxeter3 == H._W
|
|
1993
|
+
True
|
|
1994
|
+
sage: H = IwahoriHeckeAlgebra(W, QQ(1))
|
|
1995
|
+
sage: Cp = H.Cp()
|
|
1996
|
+
sage: Cp._W_Coxeter3 is None
|
|
1997
|
+
True
|
|
1998
|
+
"""
|
|
1999
|
+
super().__init__(IHAlgebra, prefix)
|
|
2000
|
+
|
|
2001
|
+
self._W_Coxeter3 = None
|
|
2002
|
+
|
|
2003
|
+
# See if we meet the conditions to use the direct product_on_basis algorithm.
|
|
2004
|
+
# To use v + ~v as the value delta, we need the standard or
|
|
2005
|
+
# normalized presentations of the Hecke algebra.
|
|
2006
|
+
v = IHAlgebra.base_ring().gen(0)
|
|
2007
|
+
parameters = {IHAlgebra.q1(), IHAlgebra.q2()}
|
|
2008
|
+
if v == IHAlgebra.base_ring().one() or (parameters != {v**2, -1} and parameters != {v, -1/v}):
|
|
2009
|
+
return
|
|
2010
|
+
|
|
2011
|
+
# check if products can be computed directly using ``coxeter3``
|
|
2012
|
+
try:
|
|
2013
|
+
from sage.libs.coxeter3.coxeter_group import CoxeterGroup as Coxeter3Group
|
|
2014
|
+
except ImportError:
|
|
2015
|
+
return
|
|
2016
|
+
|
|
2017
|
+
self._delta = v + ~v
|
|
2018
|
+
if isinstance(IHAlgebra._W, Coxeter3Group):
|
|
2019
|
+
self._W_Coxeter3 = IHAlgebra._W
|
|
2020
|
+
else:
|
|
2021
|
+
self._W_Coxeter3 = CoxeterGroup(IHAlgebra._W.coxeter_type(), implementation='coxeter3')
|
|
2022
|
+
|
|
2023
|
+
def hash_involution_on_basis(self, w):
|
|
2024
|
+
r"""
|
|
2025
|
+
Return the effect of applying the hash involution to the basis
|
|
2026
|
+
element ``self[w]``.
|
|
2027
|
+
|
|
2028
|
+
This function is not intended to be called directly. Instead, use
|
|
2029
|
+
:meth:`hash_involution`.
|
|
2030
|
+
|
|
2031
|
+
EXAMPLES::
|
|
2032
|
+
|
|
2033
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2034
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2035
|
+
sage: Cp=H.Cp()
|
|
2036
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
2037
|
+
sage: Cp.hash_involution_on_basis(s)
|
|
2038
|
+
-Cp[1] + (v^-1+v)
|
|
2039
|
+
sage: Cp[s].hash_involution()
|
|
2040
|
+
-Cp[1] + (v^-1+v)
|
|
2041
|
+
"""
|
|
2042
|
+
return (-1)**w.length() * self(self.realization_of().C().monomial(w))
|
|
2043
|
+
|
|
2044
|
+
def product_on_basis(self, w1, w2):
|
|
2045
|
+
r"""
|
|
2046
|
+
Return the expansion of `C^{\prime}_{w_1} \cdot C^{\prime}_{w_2}`
|
|
2047
|
+
in the `C^{\prime}`-basis.
|
|
2048
|
+
|
|
2049
|
+
If ``coxeter3`` is installed and the Iwahori--Hecke algebra is in
|
|
2050
|
+
the standard or normalized presentation, the product is computed
|
|
2051
|
+
directly using the method described in ALGORITHM. If not, the
|
|
2052
|
+
product is computed indirectly by converting the factors to the
|
|
2053
|
+
`T`-basis, computing the product there, and converting back.
|
|
2054
|
+
|
|
2055
|
+
The following formulas for products of the forms `C^{\prime}_s
|
|
2056
|
+
\cdot C^{\prime}_w` and `C^{\prime}_w \cdot C^{\prime}_s`, where
|
|
2057
|
+
`s` is a generator of the Coxeter group and `w` an arbitrary
|
|
2058
|
+
element, are key to the direct computation method. The formulas are
|
|
2059
|
+
valid for both the standard and normalized presentation of the
|
|
2060
|
+
Hecke algebra.
|
|
2061
|
+
|
|
2062
|
+
.. MATH::
|
|
2063
|
+
|
|
2064
|
+
C^{\prime}_s \cdot C^{\prime}_w = \begin{cases}
|
|
2065
|
+
(q+q^{-1})C^{\prime}_{w}, & \text{if } \ell(sw) = \ell(w)-1,\\
|
|
2066
|
+
C^{\prime}_{sw}+\sum_{v\leq w, sv \leq v} \mu(v,w)C^{\prime}_v,
|
|
2067
|
+
& \text{if } \ell(sw) = \ell(w)+1.
|
|
2068
|
+
\end{cases}
|
|
2069
|
+
|
|
2070
|
+
\qquad\qquad
|
|
2071
|
+
|
|
2072
|
+
C^{\prime}_w \cdot C^{\prime}_s = \begin{cases}
|
|
2073
|
+
(q+q^{-1})C^{\prime}_{w}, & \text{if } \ell(ws) = \ell(w)-1,\\
|
|
2074
|
+
C^{\prime}_{ws}+\sum_{v\leq w, vs \leq v} \mu(v,w)C^{\prime}_v,
|
|
2075
|
+
& \text{if } \ell(ws) = \ell(w)+1.
|
|
2076
|
+
\end{cases}
|
|
2077
|
+
|
|
2078
|
+
In the above, `\leq` is the Bruhat order on the Coxeter group and
|
|
2079
|
+
`\mu(v,w)` is the "leading coefficient of Kazhdan-Lusztig
|
|
2080
|
+
polynomials"; see [KL1979]_ and [Lus2013]_ for more details. The
|
|
2081
|
+
method designates the computation of the `\mu`-coefficients to
|
|
2082
|
+
Sage's interface to Fokko du Cloux's ``coxeter3`` package, which is
|
|
2083
|
+
why the method requires the creation of the Coxeter group using the
|
|
2084
|
+
``'coxeter3'`` implementation.
|
|
2085
|
+
|
|
2086
|
+
ALGORITHM:
|
|
2087
|
+
|
|
2088
|
+
The direct algorithm for computing `C^{\prime}_x \cdot
|
|
2089
|
+
C^{\prime}_y` runs in two steps as follows.
|
|
2090
|
+
|
|
2091
|
+
If `\ell(x) \leq \ell(y)`, we first decompose `C^{\prime}_x` into
|
|
2092
|
+
a polynomial in the generators `C^{\prime}_s (s\in S)` and then
|
|
2093
|
+
multiply that polynomial with `C^{\prime}_y`. If `\ell(x) >
|
|
2094
|
+
\ell(y)`, we decompose `C^{\prime}_y` into a polynomial in
|
|
2095
|
+
`C^{\prime}_s (s\in S)` and multiply that polynomial with
|
|
2096
|
+
`C^{\prime}_x`. The second step (multiplication) is done by
|
|
2097
|
+
repeatedly applying the formulas displayed earlier directly. The
|
|
2098
|
+
first step (decomposition) is done by induction on the Bruhat order
|
|
2099
|
+
as follows: for every element `u\in W` with length `\ell(u)>1`,
|
|
2100
|
+
pick a left descent `s` of `u` and write `u=sw` (so `w=su`), then
|
|
2101
|
+
note that
|
|
2102
|
+
|
|
2103
|
+
.. MATH::
|
|
2104
|
+
|
|
2105
|
+
C^{\prime}_u = C^{\prime}_s \cdot C^{\prime}_{w}
|
|
2106
|
+
- \sum_{v \le u; sv < v} \mu(v,w) C^{\prime}_v
|
|
2107
|
+
|
|
2108
|
+
by the earlier formulas, where the element `w` and all elements
|
|
2109
|
+
`v`'s on the right side are lower than `u` in the Bruhat order;
|
|
2110
|
+
this allows us to finish the computation by decomposing the lower
|
|
2111
|
+
order terms `C^{\prime}_w` and each `C^{\prime}_v`. For example,
|
|
2112
|
+
for `u=121, s=1, w=21` in type `A_3` we have `C^{\prime}_{121} =
|
|
2113
|
+
C^{\prime}_1 C^{\prime}_{21} - C^{\prime}_1`, where the lower
|
|
2114
|
+
order term `C^{\prime}_{21}` further decomposes into `C^{\prime}_2
|
|
2115
|
+
C^{\prime}_1`, therefore
|
|
2116
|
+
|
|
2117
|
+
.. MATH::
|
|
2118
|
+
|
|
2119
|
+
C^{\prime}_{121} = C^{\prime}_1 C^{\prime}_2 C^{\prime}_1
|
|
2120
|
+
- C^{\prime}_1.
|
|
2121
|
+
|
|
2122
|
+
We note that the base cases `\ell(x)=1` or `\ell(x)=0` of the above
|
|
2123
|
+
induction occur when `x` is itself a Coxeter generator `s` or the
|
|
2124
|
+
group identity, respectively. The decomposition is trivial in these
|
|
2125
|
+
cases (we have `C^{\prime}_x=C^{\prime}_s` or `C^{\prime}_x=1`, the
|
|
2126
|
+
unit of the Hecke algebra).
|
|
2127
|
+
|
|
2128
|
+
EXAMPLES::
|
|
2129
|
+
|
|
2130
|
+
sage: # optional - coxeter3
|
|
2131
|
+
sage: R.<v> = LaurentPolynomialRing(ZZ, 'v')
|
|
2132
|
+
sage: W = CoxeterGroup('A3', implementation='coxeter3')
|
|
2133
|
+
sage: H = IwahoriHeckeAlgebra(W, v**2); Cp=H.Cp()
|
|
2134
|
+
sage: Cp.product_on_basis(W([1,2,1]), W([3,1]))
|
|
2135
|
+
(v^-1+v)*Cp[1,2,1,3]
|
|
2136
|
+
sage: Cp.product_on_basis(W([1,2,1]), W([3,1,2]))
|
|
2137
|
+
(v^-1+v)*Cp[1,2,1,3,2] + (v^-1+v)*Cp[1,2,1]
|
|
2138
|
+
"""
|
|
2139
|
+
if self._W_Coxeter3 is None:
|
|
2140
|
+
# We do not meet the conditions to use the direct product
|
|
2141
|
+
# algorithm; fall back to conversion to/from the T-basis.
|
|
2142
|
+
return super().product_on_basis(w1, w2)
|
|
2143
|
+
|
|
2144
|
+
# If self._W_Coxeter3 is not the underlying Coxeter group, we need
|
|
2145
|
+
# to convert elements first for this algorithm.
|
|
2146
|
+
if self._W_Coxeter3 != self.realization_of()._W:
|
|
2147
|
+
w1 = self._W_Coxeter3.from_reduced_word(w1.reduced_word())
|
|
2148
|
+
w2 = self._W_Coxeter3.from_reduced_word(w2.reduced_word())
|
|
2149
|
+
|
|
2150
|
+
# Decomposition: write one of C'_{w1} and C'_{w2} as a polynomial in the
|
|
2151
|
+
# generators C'_{s}.
|
|
2152
|
+
if len(w1) <= len(w2):
|
|
2153
|
+
side = 'left'
|
|
2154
|
+
gen_expression = self._decompose_into_generators(w1)
|
|
2155
|
+
other_element = self.monomial(w2)
|
|
2156
|
+
else:
|
|
2157
|
+
side = 'right'
|
|
2158
|
+
gen_expression = self._decompose_into_generators(w2)
|
|
2159
|
+
other_element = self.monomial(w1)
|
|
2160
|
+
|
|
2161
|
+
# Multiplication: multiply the generators in each term of the above
|
|
2162
|
+
# polynomial onto other_element and add that summand onto result.
|
|
2163
|
+
result = self.zero()
|
|
2164
|
+
for (p, coeff) in gen_expression.items():
|
|
2165
|
+
summand = coeff * other_element
|
|
2166
|
+
if side == 'right':
|
|
2167
|
+
for s in p:
|
|
2168
|
+
summand = self._product_with_generator(s, summand, side)
|
|
2169
|
+
else:
|
|
2170
|
+
for s in reversed(p):
|
|
2171
|
+
summand = self._product_with_generator(s, summand, side)
|
|
2172
|
+
result += summand
|
|
2173
|
+
|
|
2174
|
+
# Again, if self._W_Coxeter3 is not the underlying Coxeter group,
|
|
2175
|
+
# we need to convert the result. Specifically, make sure basis
|
|
2176
|
+
# elements appearing therein are actually indexed by elements of
|
|
2177
|
+
# the original underlying Coxeter group.
|
|
2178
|
+
if self._W_Coxeter3 != self.realization_of()._W:
|
|
2179
|
+
_W = self.realization_of()._W
|
|
2180
|
+
result = self._from_dict({_W.from_reduced_word(w.reduced_word()): c
|
|
2181
|
+
for (w, c) in result}, remove_zeros=False)
|
|
2182
|
+
|
|
2183
|
+
return result
|
|
2184
|
+
|
|
2185
|
+
def _product_with_generator_on_basis(self, s, w, side='left'):
|
|
2186
|
+
r"""
|
|
2187
|
+
Compute the product of `C^{\prime}_s` and `C^{\prime}_w`, putting
|
|
2188
|
+
`C^{\prime}_s` on the given ``side``.
|
|
2189
|
+
|
|
2190
|
+
INPUT:
|
|
2191
|
+
|
|
2192
|
+
- ``s`` -- integer in ``self.index_set()``
|
|
2193
|
+
- ``w`` -- a word in ``self.coxeter_group()``
|
|
2194
|
+
- ``side`` -- string; ``'left'`` or ``'right'``
|
|
2195
|
+
|
|
2196
|
+
EXAMPLES::
|
|
2197
|
+
|
|
2198
|
+
sage: # optional - coxeter3
|
|
2199
|
+
sage: R.<v> = LaurentPolynomialRing(ZZ, 'v')
|
|
2200
|
+
sage: W = CoxeterGroup('A3', implementation='coxeter3')
|
|
2201
|
+
sage: H = IwahoriHeckeAlgebra(W, v**2); Cp = H.Cp()
|
|
2202
|
+
sage: Cp._product_with_generator_on_basis(1, W([2,1]), 'left')
|
|
2203
|
+
Cp[1,2,1] + Cp[1]
|
|
2204
|
+
sage: Cp._product_with_generator_on_basis(1, W([2,1]), 'right')
|
|
2205
|
+
(v^-1+v)*Cp[2,1]
|
|
2206
|
+
sage: Cp._product_with_generator_on_basis(2, W([1,3,2,1,3]), 'right')
|
|
2207
|
+
Cp[1,2,1,3,2,1] + Cp[1,2,3,2] + Cp[1,3,2,1]
|
|
2208
|
+
"""
|
|
2209
|
+
# use the product formula described in the class' documentation
|
|
2210
|
+
if w.has_descent(s, side=side):
|
|
2211
|
+
return self._from_dict({w: self._delta}, remove_zeros=False)
|
|
2212
|
+
|
|
2213
|
+
element = {}
|
|
2214
|
+
between = self._W_Coxeter3.bruhat_interval([], w)
|
|
2215
|
+
R = self.base_ring()
|
|
2216
|
+
for x in between:
|
|
2217
|
+
# Get (coxeter3-implemented) group element corresponding to x
|
|
2218
|
+
x_elt = self._W_Coxeter3(x)
|
|
2219
|
+
if x_elt.has_descent(s, side=side):
|
|
2220
|
+
# Compute mu-coefficient via coxeter3
|
|
2221
|
+
coeff = R(x.mu_coefficient(w))
|
|
2222
|
+
if coeff:
|
|
2223
|
+
element[x_elt] = coeff
|
|
2224
|
+
longer_word = self._W_Coxeter3([s]) * w if side == 'left' else w * self._W_Coxeter3([s])
|
|
2225
|
+
element[longer_word] = R.one()
|
|
2226
|
+
return self._from_dict(element, remove_zeros=False)
|
|
2227
|
+
|
|
2228
|
+
def _product_with_generator(self, s, x, side='left'):
|
|
2229
|
+
r"""
|
|
2230
|
+
Compute the product of `C^{\prime}_s` with any linear
|
|
2231
|
+
combination of `C^{\prime}`-basis elements.
|
|
2232
|
+
|
|
2233
|
+
INPUT:
|
|
2234
|
+
|
|
2235
|
+
- ``s`` -- integer in ``self.index_set()``
|
|
2236
|
+
- ``x`` -- any element of ``self``
|
|
2237
|
+
- ``side`` -- string; ``'left'`` or ``'right'``
|
|
2238
|
+
|
|
2239
|
+
EXAMPLES::
|
|
2240
|
+
|
|
2241
|
+
sage: # optional - coxeter3
|
|
2242
|
+
sage: R.<v> = LaurentPolynomialRing(ZZ, 'v')
|
|
2243
|
+
sage: W = CoxeterGroup('A3', implementation='coxeter3')
|
|
2244
|
+
sage: H = IwahoriHeckeAlgebra(W, v**2); Cp = H.Cp()
|
|
2245
|
+
sage: Cp._product_with_generator(1, Cp[1]+Cp[2], 'left')
|
|
2246
|
+
Cp[1,2] + (v^-1+v)*Cp[1]
|
|
2247
|
+
sage: Cp._product_with_generator(1, Cp[1]+Cp[2], 'right')
|
|
2248
|
+
Cp[2,1] + (v^-1+v)*Cp[1]
|
|
2249
|
+
"""
|
|
2250
|
+
return self.linear_combination((self._product_with_generator_on_basis(s, w, side), coeff) for (w, coeff) in x)
|
|
2251
|
+
|
|
2252
|
+
def _decompose_into_generators(self, u):
|
|
2253
|
+
r"""
|
|
2254
|
+
Decompose `C^{\prime}_u` into a polynomial in the KL generators
|
|
2255
|
+
`C^{\prime}_s`; see the ALGORITHM section of
|
|
2256
|
+
:func:`product_on_basis`.
|
|
2257
|
+
|
|
2258
|
+
OUTPUT:
|
|
2259
|
+
|
|
2260
|
+
A dictionary keyed by tuples with integer values. Each entry
|
|
2261
|
+
represents a term, where the tuple represents a monomial term
|
|
2262
|
+
in the KL generators and the value represents the coefficient
|
|
2263
|
+
of that term. For example, an item `(1,2): 3` stands for
|
|
2264
|
+
`3 \cdot C^{\prime}_1 C^{\prime}_2`.
|
|
2265
|
+
|
|
2266
|
+
EXAMPLES::
|
|
2267
|
+
|
|
2268
|
+
sage: R.<v> = LaurentPolynomialRing(ZZ, 'v') # optional - coxeter3
|
|
2269
|
+
sage: W = CoxeterGroup('A3', implementation='coxeter3') # optional - coxeter3
|
|
2270
|
+
sage: H = IwahoriHeckeAlgebra(W, v**2); Cp=H.Cp() # optional - coxeter3
|
|
2271
|
+
|
|
2272
|
+
When `u` is itself a generator `s`, the decomposition is trivial::
|
|
2273
|
+
|
|
2274
|
+
sage: Cp._decompose_into_generators(W([1])) # optional - coxeter3
|
|
2275
|
+
{(1,): 1}
|
|
2276
|
+
|
|
2277
|
+
Another example, where `C^{\prime}_u` happens to be a monomial
|
|
2278
|
+
(e.g., `C'_{21} = C'_2 C'_1`)::
|
|
2279
|
+
|
|
2280
|
+
sage: Cp._decompose_into_generators(W([2,1])) # optional - coxeter3
|
|
2281
|
+
{(2, 1): 1}
|
|
2282
|
+
|
|
2283
|
+
In more general situations the sum is a polynomial (e.g.,
|
|
2284
|
+
`C'_{121} = C'_1 C'_2 C'_1 - C'_1)`::
|
|
2285
|
+
|
|
2286
|
+
sage: Cp._decompose_into_generators(W([1,2,1])) # optional - coxeter3
|
|
2287
|
+
{(1,): -1, (1, 2, 1): 1}
|
|
2288
|
+
sage: Cp._decompose_into_generators(W([1,2,3,1,2])) # optional - coxeter3
|
|
2289
|
+
{(1,): 1, (1, 2, 1): -1, (1, 2, 1, 3, 2): 1, (1, 3, 2): -1}
|
|
2290
|
+
|
|
2291
|
+
TESTS::
|
|
2292
|
+
|
|
2293
|
+
sage: Cp._decompose_into_generators(W([])) # optional - coxeter3
|
|
2294
|
+
{(): 1}
|
|
2295
|
+
"""
|
|
2296
|
+
# l(y) = 0 or 1
|
|
2297
|
+
if not len(u):
|
|
2298
|
+
return {(): 1}
|
|
2299
|
+
if len(u) == 1:
|
|
2300
|
+
return {(u[0],): 1}
|
|
2301
|
+
|
|
2302
|
+
# l(y) > 1, use the recursive method described in product_on_basis
|
|
2303
|
+
s = u[0]
|
|
2304
|
+
w = u[1:] # so CpC_s * CpC_w = CpC_u + lower order terms
|
|
2305
|
+
|
|
2306
|
+
# get the lower order terms ("sum_term")
|
|
2307
|
+
sum_term = {}
|
|
2308
|
+
between = self._W_Coxeter3.bruhat_interval([], w)
|
|
2309
|
+
R = self.base_ring()
|
|
2310
|
+
for v in between:
|
|
2311
|
+
# Get (coxeter3-implemented) group element corresponding to v
|
|
2312
|
+
v_elt = self._W_Coxeter3(v)
|
|
2313
|
+
if v_elt.has_left_descent(s):
|
|
2314
|
+
# Compute mu-coefficient via coxeter3
|
|
2315
|
+
coeff = R(v.mu_coefficient(w))
|
|
2316
|
+
if coeff:
|
|
2317
|
+
sum_term[v_elt] = coeff
|
|
2318
|
+
|
|
2319
|
+
# recursion: decompose C'_s * C'_w and the lower order terms
|
|
2320
|
+
result = {(s,) + gens: coeff for (gens, coeff) in self._decompose_into_generators(w).items()}
|
|
2321
|
+
zero = R.zero()
|
|
2322
|
+
for (z, c1) in sum_term.items():
|
|
2323
|
+
# Subtract off each term from sum_term.
|
|
2324
|
+
for (gens, c2) in self._decompose_into_generators(z).items():
|
|
2325
|
+
result[gens] = result.get(gens, zero) - c1 * c2
|
|
2326
|
+
|
|
2327
|
+
return result
|
|
2328
|
+
|
|
2329
|
+
C_prime = Cp
|
|
2330
|
+
|
|
2331
|
+
class C(_KLHeckeBasis):
|
|
2332
|
+
r"""
|
|
2333
|
+
The Kazhdan-Lusztig `C`-basis of Iwahori-Hecke algebra.
|
|
2334
|
+
|
|
2335
|
+
Assuming the standard quadratic relations of `(T_r-q)(T_r+1)=0`, for
|
|
2336
|
+
every element `w` in the Coxeter group, there is a unique element
|
|
2337
|
+
`C_w` in the Iwahori-Hecke algebra which is uniquely determined
|
|
2338
|
+
by the two properties:
|
|
2339
|
+
|
|
2340
|
+
.. MATH::
|
|
2341
|
+
|
|
2342
|
+
\begin{aligned}
|
|
2343
|
+
\overline{C_w} &= C_w \\
|
|
2344
|
+
C_w &= (-1)^{\ell(w)} q^{\ell(w)/2}
|
|
2345
|
+
\sum_{v \leq w} (-q)^{-\ell(v)}\overline{P_{v,w}(q)} T_v
|
|
2346
|
+
\end{aligned}
|
|
2347
|
+
|
|
2348
|
+
where `\leq` is the Bruhat order on the underlying Coxeter group and
|
|
2349
|
+
`P_{v,w}(q)\in\ZZ[q,q^{-1}]` are polynomials in `\ZZ[q]` such that
|
|
2350
|
+
`P_{w,w}(q) = 1` and if `v < w` then
|
|
2351
|
+
`\deg P_{v,w}(q) \leq \frac{1}{2}(\ell(w) - \ell(v) - 1)`.
|
|
2352
|
+
This is related to the `C^{\prime}` Kazhdan-Lusztig basis by `C_i =
|
|
2353
|
+
-\alpha(C_i^{\prime})` where `\alpha` is the `\ZZ`-linear Hecke
|
|
2354
|
+
involution defined by `q^{1/2} \mapsto q^{-1/2}` and `\alpha(T_i) =
|
|
2355
|
+
-(q_1 q_2)^{-1/2} T_i`.
|
|
2356
|
+
|
|
2357
|
+
More generally, if the quadratic relations are of the form
|
|
2358
|
+
(T_s-q_1)(T_s-q_2)=0` and `\sqrt{-q_1q_2}` exists then, for a simple
|
|
2359
|
+
reflection `s`, the corresponding Kazhdan-Lusztig basis element is:
|
|
2360
|
+
|
|
2361
|
+
.. MATH::
|
|
2362
|
+
|
|
2363
|
+
C_s = (-q_1 q_2)^{1/2} (1 - (-q_1 q_2)^{-1/2} T_s).
|
|
2364
|
+
|
|
2365
|
+
See [KL1979]_ for more details.
|
|
2366
|
+
|
|
2367
|
+
EXAMPLES::
|
|
2368
|
+
|
|
2369
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
2370
|
+
sage: H = IwahoriHeckeAlgebra('A5', v**2)
|
|
2371
|
+
sage: W = H.coxeter_group()
|
|
2372
|
+
sage: s1,s2,s3,s4,s5 = W.simple_reflections()
|
|
2373
|
+
sage: T = H.T()
|
|
2374
|
+
sage: C = H.C()
|
|
2375
|
+
sage: T(s1)**2
|
|
2376
|
+
-(1-v^2)*T[1] + v^2
|
|
2377
|
+
sage: T(C(s1))
|
|
2378
|
+
(v^-1)*T[1] - v
|
|
2379
|
+
sage: T(C(s1)*C(s2)*C(s1))
|
|
2380
|
+
(v^-3)*T[1,2,1] - (v^-1)*T[2,1] - (v^-1)*T[1,2]
|
|
2381
|
+
+ (v^-1+v)*T[1] + v*T[2] - (v+v^3)
|
|
2382
|
+
|
|
2383
|
+
::
|
|
2384
|
+
|
|
2385
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
2386
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2387
|
+
sage: W = H.coxeter_group()
|
|
2388
|
+
sage: s1,s2,s3 = W.simple_reflections()
|
|
2389
|
+
sage: C = H.C()
|
|
2390
|
+
sage: C(s1*s2*s1)
|
|
2391
|
+
C[1,2,1]
|
|
2392
|
+
sage: C(s1)**2
|
|
2393
|
+
-(v^-1+v)*C[1]
|
|
2394
|
+
sage: C(s1)*C(s2)*C(s1)
|
|
2395
|
+
C[1,2,1] + C[1]
|
|
2396
|
+
|
|
2397
|
+
TESTS::
|
|
2398
|
+
|
|
2399
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2400
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2401
|
+
sage: W = H.coxeter_group()
|
|
2402
|
+
sage: T = H.T()
|
|
2403
|
+
sage: C = H.C()
|
|
2404
|
+
sage: Cp = H.Cp()
|
|
2405
|
+
sage: all(C(T(C[x])) == C[x] for x in W) # long time
|
|
2406
|
+
True
|
|
2407
|
+
sage: all(C(Cp(C[x])) == C[x] for x in W) # long time
|
|
2408
|
+
True
|
|
2409
|
+
|
|
2410
|
+
Check the defining property between `C` and `C^{\prime}`::
|
|
2411
|
+
|
|
2412
|
+
sage: T(C[1])
|
|
2413
|
+
(v^-1)*T[1] - v
|
|
2414
|
+
sage: -T(Cp[1]).hash_involution()
|
|
2415
|
+
(v^-1)*T[1] - v
|
|
2416
|
+
sage: T(Cp[1] + Cp[2]).hash_involution()
|
|
2417
|
+
-(v^-1)*T[1] - (v^-1)*T[2] + 2*v
|
|
2418
|
+
sage: -T(C[1] + C[2])
|
|
2419
|
+
-(v^-1)*T[1] - (v^-1)*T[2] + 2*v
|
|
2420
|
+
sage: Cp(-C[1].hash_involution())
|
|
2421
|
+
Cp[1]
|
|
2422
|
+
sage: Cp(-C[1,2,3].hash_involution())
|
|
2423
|
+
Cp[1,2,3]
|
|
2424
|
+
sage: Cp(C[1,2,1,3].hash_involution())
|
|
2425
|
+
Cp[1,2,3,1]
|
|
2426
|
+
sage: all(C((-1)**x.length()*Cp[x].hash_involution()) == C[x] for x in W) # long time
|
|
2427
|
+
True
|
|
2428
|
+
"""
|
|
2429
|
+
_basis_name = "C" # this is used, for example, by specialize_to and is the default prefix
|
|
2430
|
+
|
|
2431
|
+
def hash_involution_on_basis(self, w):
|
|
2432
|
+
r"""
|
|
2433
|
+
Return the effect of applying the hash involution to the basis
|
|
2434
|
+
element ``self[w]``.
|
|
2435
|
+
|
|
2436
|
+
This function is not intended to be called directly. Instead, use
|
|
2437
|
+
:meth:`hash_involution`.
|
|
2438
|
+
|
|
2439
|
+
EXAMPLES::
|
|
2440
|
+
|
|
2441
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2442
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2443
|
+
sage: C=H.C()
|
|
2444
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
2445
|
+
sage: C.hash_involution_on_basis(s)
|
|
2446
|
+
-C[1] - (v^-1+v)
|
|
2447
|
+
sage: C[s].hash_involution()
|
|
2448
|
+
-C[1] - (v^-1+v)
|
|
2449
|
+
"""
|
|
2450
|
+
return (-1)**w.length() * self(self.realization_of().Cp().monomial(w))
|
|
2451
|
+
|
|
2452
|
+
class A(_Basis):
|
|
2453
|
+
r"""
|
|
2454
|
+
The `A`-basis of an Iwahori-Hecke algebra.
|
|
2455
|
+
|
|
2456
|
+
The `A`-basis of the Iwahori-Hecke algebra is the simplest basis
|
|
2457
|
+
that is invariant under the Goldman involution `\#`, up to sign.
|
|
2458
|
+
For `w` in the underlying Coxeter group define:
|
|
2459
|
+
|
|
2460
|
+
.. MATH::
|
|
2461
|
+
|
|
2462
|
+
A_w = T_w + (-1)^{\ell(w)}T_w^{\#}
|
|
2463
|
+
= T_w + (-1)^{\ell(w)}T_{w^{-1}}^{-1}
|
|
2464
|
+
|
|
2465
|
+
This gives a basis of the Iwahori-Hecke algebra whenever 2 is a unit
|
|
2466
|
+
in the base ring. The `A`-basis induces a `\ZZ / 2\ZZ`-grading
|
|
2467
|
+
on the Iwahori-Hecke algebra.
|
|
2468
|
+
|
|
2469
|
+
The `A`-basis is a basis only when `2` is invertible. An error
|
|
2470
|
+
is raised whenever `2` is not a unit in the base ring.
|
|
2471
|
+
|
|
2472
|
+
EXAMPLES::
|
|
2473
|
+
|
|
2474
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2475
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2476
|
+
sage: A=H.A(); T=H.T()
|
|
2477
|
+
sage: T(A[1])
|
|
2478
|
+
T[1] + (1/2-1/2*v^2)
|
|
2479
|
+
sage: T(A[1,2])
|
|
2480
|
+
T[1,2] + (1/2-1/2*v^2)*T[1] + (1/2-1/2*v^2)*T[2] + (1/2-v^2+1/2*v^4)
|
|
2481
|
+
sage: A[1]*A[2]
|
|
2482
|
+
A[1,2] - (1/4-1/2*v^2+1/4*v^4)
|
|
2483
|
+
|
|
2484
|
+
TESTS::
|
|
2485
|
+
|
|
2486
|
+
sage: R.<v> = LaurentPolynomialRing(GF(2), 'v')
|
|
2487
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2488
|
+
sage: H.A()
|
|
2489
|
+
Traceback (most recent call last):
|
|
2490
|
+
...
|
|
2491
|
+
TypeError: the A-basis is defined only when 2 is invertible
|
|
2492
|
+
"""
|
|
2493
|
+
_basis_name = "A"
|
|
2494
|
+
|
|
2495
|
+
def __init__(self, IHAlgebra, prefix=None):
|
|
2496
|
+
r"""
|
|
2497
|
+
Initialize the `A`-basis of the Iwahori-Hecke algebra ``IHAlgebra``.
|
|
2498
|
+
|
|
2499
|
+
EXAMPLES::
|
|
2500
|
+
|
|
2501
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
2502
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2503
|
+
sage: A = H.A()
|
|
2504
|
+
"""
|
|
2505
|
+
R = IHAlgebra.base_ring()
|
|
2506
|
+
try:
|
|
2507
|
+
R(R.one()/2)
|
|
2508
|
+
except (TypeError, ZeroDivisionError):
|
|
2509
|
+
raise TypeError('the A-basis is defined only when 2 is invertible')
|
|
2510
|
+
|
|
2511
|
+
super().__init__(IHAlgebra, prefix)
|
|
2512
|
+
|
|
2513
|
+
# Define and register coercions from the A basis to the T basis and back again
|
|
2514
|
+
from_A_to_T = self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(),
|
|
2515
|
+
triangular='lower', key=sorting_key,
|
|
2516
|
+
category=self.category())
|
|
2517
|
+
from_A_to_T.register_as_coercion()
|
|
2518
|
+
from_T_to_A = ~from_A_to_T
|
|
2519
|
+
from_T_to_A.register_as_coercion()
|
|
2520
|
+
|
|
2521
|
+
def to_T_basis(self, w):
|
|
2522
|
+
r"""
|
|
2523
|
+
Return the `A`-basis element ``self[w]`` as a linear
|
|
2524
|
+
combination of `T`-basis elements.
|
|
2525
|
+
|
|
2526
|
+
EXAMPLES::
|
|
2527
|
+
|
|
2528
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
2529
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2); A=H.A(); T=H.T()
|
|
2530
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
2531
|
+
sage: A.to_T_basis(s)
|
|
2532
|
+
T[1] + (1/2-1/2*v^2)
|
|
2533
|
+
sage: T(A[1,2])
|
|
2534
|
+
T[1,2] + (1/2-1/2*v^2)*T[1] + (1/2-1/2*v^2)*T[2] + (1/2-v^2+1/2*v^4)
|
|
2535
|
+
sage: A(T[1,2])
|
|
2536
|
+
A[1,2] - (1/2-1/2*v^2)*A[1] - (1/2-1/2*v^2)*A[2]
|
|
2537
|
+
"""
|
|
2538
|
+
T = self.realization_of().T()
|
|
2539
|
+
return (T.monomial(w) + (-1)**w.length()*T.goldman_involution_on_basis(w)) / 2
|
|
2540
|
+
|
|
2541
|
+
def goldman_involution_on_basis(self, w):
|
|
2542
|
+
r"""
|
|
2543
|
+
Return the effect of applying the Goldman involution to the basis
|
|
2544
|
+
element ``self[w]``.
|
|
2545
|
+
|
|
2546
|
+
This function is not intended to be called directly. Instead, use
|
|
2547
|
+
:meth:`goldman_involution`.
|
|
2548
|
+
|
|
2549
|
+
EXAMPLES::
|
|
2550
|
+
|
|
2551
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2552
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2553
|
+
sage: A=H.A()
|
|
2554
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
2555
|
+
sage: A.goldman_involution_on_basis(s)
|
|
2556
|
+
-A[1]
|
|
2557
|
+
sage: A[1,2].goldman_involution()
|
|
2558
|
+
A[1,2]
|
|
2559
|
+
"""
|
|
2560
|
+
return (-1)**w.length() * self.monomial(w)
|
|
2561
|
+
|
|
2562
|
+
class B(_Basis):
|
|
2563
|
+
r"""
|
|
2564
|
+
The `B`-basis of an Iwahori-Hecke algebra.
|
|
2565
|
+
|
|
2566
|
+
The `B`-basis is the unique basis of the Iwahori-Hecke algebra that
|
|
2567
|
+
is invariant under the Goldman involution, up to sign, and invariant
|
|
2568
|
+
under the Kazhdan-Lusztig bar involution. In the generic case, the
|
|
2569
|
+
`B`-basis becomes the group basis of the group algebra of the Coxeter
|
|
2570
|
+
group the `B`-basis upon setting the Hecke parameters equal to `1`.
|
|
2571
|
+
If `w` is an element of the corresponding Coxeter group then
|
|
2572
|
+
the `B`-basis element `B_w` is uniquely determined by the conditions
|
|
2573
|
+
that `B_w^{\#} = (-1)^{\ell(w)} B_w`, where `\#` is the
|
|
2574
|
+
:meth:`Goldman involution <goldman_involution>` and
|
|
2575
|
+
|
|
2576
|
+
.. MATH::
|
|
2577
|
+
|
|
2578
|
+
B_w = T_w + \sum_{v<w}b_{vw}(q) T_v
|
|
2579
|
+
|
|
2580
|
+
where `b_{vw}(q) \neq 0` only if `v < w` in the Bruhat order and
|
|
2581
|
+
`\ell(v) \not\equiv \ell(w) \pmod 2`.
|
|
2582
|
+
|
|
2583
|
+
This gives a basis of the Iwahori-Hecke algebra whenever `2` is a
|
|
2584
|
+
unit in the base ring. The `B`-basis induces a `\ZZ / 2 \ZZ`-grading
|
|
2585
|
+
on the Iwahori-Hecke algebra. The `B`-basis elements are also
|
|
2586
|
+
invariant under the Kazhdan-Lusztig bar involution and hence
|
|
2587
|
+
are related to the Kazhdan-Lusztig bases.
|
|
2588
|
+
|
|
2589
|
+
The `B`-basis is a basis only when `2` is invertible. An error
|
|
2590
|
+
is raised whenever `2` is not a unit in the base ring.
|
|
2591
|
+
|
|
2592
|
+
EXAMPLES::
|
|
2593
|
+
|
|
2594
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2595
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2596
|
+
sage: A=H.A(); T=H.T(); Cp=H.Cp()
|
|
2597
|
+
sage: T(A[1])
|
|
2598
|
+
T[1] + (1/2-1/2*v^2)
|
|
2599
|
+
sage: T(A[1,2])
|
|
2600
|
+
T[1,2] + (1/2-1/2*v^2)*T[1] + (1/2-1/2*v^2)*T[2] + (1/2-v^2+1/2*v^4)
|
|
2601
|
+
sage: A[1]*A[2]
|
|
2602
|
+
A[1,2] - (1/4-1/2*v^2+1/4*v^4)
|
|
2603
|
+
sage: Cp(A[1]*A[2])
|
|
2604
|
+
v^2*Cp[1,2] - (1/2*v+1/2*v^3)*Cp[1] - (1/2*v+1/2*v^3)*Cp[2]
|
|
2605
|
+
+ (1/4+1/2*v^2+1/4*v^4)
|
|
2606
|
+
sage: Cp(A[1])
|
|
2607
|
+
v*Cp[1] - (1/2+1/2*v^2)
|
|
2608
|
+
sage: Cp(A[1,2])
|
|
2609
|
+
v^2*Cp[1,2] - (1/2*v+1/2*v^3)*Cp[1]
|
|
2610
|
+
- (1/2*v+1/2*v^3)*Cp[2] + (1/2+1/2*v^4)
|
|
2611
|
+
sage: Cp(A[1,2,1])
|
|
2612
|
+
v^3*Cp[1,2,1] - (1/2*v^2+1/2*v^4)*Cp[2,1]
|
|
2613
|
+
- (1/2*v^2+1/2*v^4)*Cp[1,2] + (1/2*v+1/2*v^5)*Cp[1]
|
|
2614
|
+
+ (1/2*v+1/2*v^5)*Cp[2] - (1/2+1/2*v^6)
|
|
2615
|
+
|
|
2616
|
+
TESTS::
|
|
2617
|
+
|
|
2618
|
+
sage: R.<v> = LaurentPolynomialRing(ZZ, 'v')
|
|
2619
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2620
|
+
sage: H.B()
|
|
2621
|
+
Traceback (most recent call last):
|
|
2622
|
+
...
|
|
2623
|
+
TypeError: the B-basis is defined only when 2 is invertible
|
|
2624
|
+
"""
|
|
2625
|
+
_basis_name = "B"
|
|
2626
|
+
|
|
2627
|
+
def __init__(self, IHAlgebra, prefix=None):
|
|
2628
|
+
r"""
|
|
2629
|
+
Initialize the `B`-basis of the Iwahori-Hecke algebra ``IHAlgebra``.
|
|
2630
|
+
|
|
2631
|
+
EXAMPLES::
|
|
2632
|
+
|
|
2633
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
2634
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2635
|
+
sage: B = H.B()
|
|
2636
|
+
"""
|
|
2637
|
+
R = IHAlgebra.base_ring()
|
|
2638
|
+
try:
|
|
2639
|
+
R(R.one()/2)
|
|
2640
|
+
except (TypeError, ZeroDivisionError):
|
|
2641
|
+
raise TypeError('the B-basis is defined only when 2 is invertible')
|
|
2642
|
+
|
|
2643
|
+
super().__init__(IHAlgebra, prefix)
|
|
2644
|
+
|
|
2645
|
+
# Define and register coercions from the B basis to the T basis and back again
|
|
2646
|
+
from_B_to_T = self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(),
|
|
2647
|
+
triangular='lower', key=sorting_key,
|
|
2648
|
+
category=self.category())
|
|
2649
|
+
from_B_to_T.register_as_coercion()
|
|
2650
|
+
from_T_to_B = ~from_B_to_T
|
|
2651
|
+
from_T_to_B.register_as_coercion()
|
|
2652
|
+
|
|
2653
|
+
@cached_method
|
|
2654
|
+
def to_T_basis(self, w):
|
|
2655
|
+
r"""
|
|
2656
|
+
Return the `B`-basis element ``self[w]`` as a linear
|
|
2657
|
+
combination of `T`-basis elements.
|
|
2658
|
+
|
|
2659
|
+
EXAMPLES::
|
|
2660
|
+
|
|
2661
|
+
sage: R.<v> = LaurentPolynomialRing(QQ)
|
|
2662
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2); B=H.B(); T=H.T()
|
|
2663
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
2664
|
+
sage: B.to_T_basis(s)
|
|
2665
|
+
T[1] + (1/2-1/2*v^2)
|
|
2666
|
+
sage: T(B[1,2])
|
|
2667
|
+
T[1,2] + (1/2-1/2*v^2)*T[1] + (1/2-1/2*v^2)*T[2]
|
|
2668
|
+
sage: B(T[1,2])
|
|
2669
|
+
B[1,2] - (1/2-1/2*v^2)*B[1] - (1/2-1/2*v^2)*B[2] + (1/2-v^2+1/2*v^4)
|
|
2670
|
+
"""
|
|
2671
|
+
T = self.realization_of().T()
|
|
2672
|
+
Bw = T(self.realization_of().A()[w])
|
|
2673
|
+
odd = [v for v in Bw.support()
|
|
2674
|
+
if v != w and not (v.length() - w.length()) % 2]
|
|
2675
|
+
return Bw - T.sum(Bw.coefficient(v) * self.to_T_basis(v)
|
|
2676
|
+
for v in odd)
|
|
2677
|
+
|
|
2678
|
+
def goldman_involution_on_basis(self, w):
|
|
2679
|
+
r"""
|
|
2680
|
+
Return the Goldman involution to the basis element
|
|
2681
|
+
indexed by ``w``.
|
|
2682
|
+
|
|
2683
|
+
This function is not intended to be called directly. Instead, use
|
|
2684
|
+
:meth:`goldman_involution`.
|
|
2685
|
+
|
|
2686
|
+
EXAMPLES::
|
|
2687
|
+
|
|
2688
|
+
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
|
|
2689
|
+
sage: H = IwahoriHeckeAlgebra('A3', v**2)
|
|
2690
|
+
sage: B=H.B()
|
|
2691
|
+
sage: s=H.coxeter_group().simple_reflection(1)
|
|
2692
|
+
sage: B.goldman_involution_on_basis(s)
|
|
2693
|
+
-B[1]
|
|
2694
|
+
sage: B[1,2].goldman_involution()
|
|
2695
|
+
B[1,2]
|
|
2696
|
+
"""
|
|
2697
|
+
return (-1)**w.length() * self.monomial(w)
|
|
2698
|
+
|
|
2699
|
+
|
|
2700
|
+
# The IwahoriHeckeAlgebra_nonstandard class must have the same basis classes as
|
|
2701
|
+
# the IwahoriHeckeAlgebra class with the same name and they should inherit from
|
|
2702
|
+
# the respective basis class
|
|
2703
|
+
class IwahoriHeckeAlgebra_nonstandard(IwahoriHeckeAlgebra):
|
|
2704
|
+
r"""
|
|
2705
|
+
This is a class which is used behind the scenes by
|
|
2706
|
+
:class:`IwahoriHeckeAlgebra` to compute the Kazhdan-Lusztig bases. It is
|
|
2707
|
+
not meant to be used directly. It implements the slightly idiosyncratic
|
|
2708
|
+
(but convenient) Iwahori-Hecke algebra with two parameters which is
|
|
2709
|
+
defined over the Laurent polynomial ring `\ZZ[u,u^{-1},v,v^{-1}]` in
|
|
2710
|
+
two variables and has quadratic relations:
|
|
2711
|
+
|
|
2712
|
+
.. MATH::
|
|
2713
|
+
|
|
2714
|
+
(T_r - u)(T_r + v^2/u) = 0.
|
|
2715
|
+
|
|
2716
|
+
The point of these relations is that the product of the two parameters is
|
|
2717
|
+
`v^2` which is a square in `\ZZ[u,u^{-1},v,v^{-1}]`. Consequently, the
|
|
2718
|
+
Kazhdan-Lusztig bases are defined for this algebra.
|
|
2719
|
+
|
|
2720
|
+
More generally, if we have a Iwahori-Hecke algebra with two parameters
|
|
2721
|
+
which has quadratic relations of the form:
|
|
2722
|
+
|
|
2723
|
+
.. MATH::
|
|
2724
|
+
|
|
2725
|
+
(T_r - q_1)(T_r - q_2) = 0
|
|
2726
|
+
|
|
2727
|
+
where `-q_1 q_2` is a square then the Kazhdan-Lusztig bases are
|
|
2728
|
+
well-defined for this algebra. Moreover, these bases be computed by
|
|
2729
|
+
specialization from the generic Iwahori-Hecke algebra using the
|
|
2730
|
+
specialization which sends `u \mapsto q_1` and `v \mapsto \sqrt{-q_1 q_2}`,
|
|
2731
|
+
so that `v^2 / u \mapsto -q_2`.
|
|
2732
|
+
|
|
2733
|
+
For example, if `q_1 = q = Q^2` and `q_2 = -1` then `u \mapsto q` and
|
|
2734
|
+
`v \mapsto \sqrt{q} = Q`; this is the standard presentation of the
|
|
2735
|
+
Iwahori-Hecke algebra with `(T_r - q)(T_r + 1) = 0`. On the other hand,
|
|
2736
|
+
when `q_1 = q` and `q_2 = -q^{-1}` then `u \mapsto q` and `v \mapsto 1`.
|
|
2737
|
+
This is the normalized presentation with `(T_r - v)(T_r + v^{-1}) = 0`.
|
|
2738
|
+
|
|
2739
|
+
.. WARNING::
|
|
2740
|
+
|
|
2741
|
+
This class uses non-standard parameters for the Iwahori-Hecke algebra
|
|
2742
|
+
and are related to the standard parameters by an outer automorphism
|
|
2743
|
+
that is non-trivial on the `T`-basis.
|
|
2744
|
+
"""
|
|
2745
|
+
@staticmethod
|
|
2746
|
+
def __classcall_private__(cls, W):
|
|
2747
|
+
r"""
|
|
2748
|
+
TESTS::
|
|
2749
|
+
|
|
2750
|
+
sage: H1 = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
|
|
2751
|
+
sage: W = CoxeterGroup("A2")
|
|
2752
|
+
sage: H2 = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard(W)
|
|
2753
|
+
sage: H1 is H2
|
|
2754
|
+
True
|
|
2755
|
+
"""
|
|
2756
|
+
if W not in CoxeterGroups():
|
|
2757
|
+
W = CoxeterGroup(W)
|
|
2758
|
+
return super().__classcall__(cls, W)
|
|
2759
|
+
|
|
2760
|
+
def __init__(self, W):
|
|
2761
|
+
r"""
|
|
2762
|
+
EXAMPLES::
|
|
2763
|
+
|
|
2764
|
+
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
|
|
2765
|
+
sage: TestSuite(H).run()
|
|
2766
|
+
"""
|
|
2767
|
+
self._W = W
|
|
2768
|
+
self._coxeter_type = W.coxeter_type()
|
|
2769
|
+
|
|
2770
|
+
base_ring = LaurentPolynomialRing(ZZ, 'u,v')
|
|
2771
|
+
u, v = base_ring.gens()
|
|
2772
|
+
|
|
2773
|
+
# We don't want to call IwahoriHeckeAlgebra.__init__ because this would
|
|
2774
|
+
# try and attach a generic Hecke algebra to this algebra leading to
|
|
2775
|
+
# an infinite loop.
|
|
2776
|
+
self._q1 = u
|
|
2777
|
+
self._q2 = normalized_laurent_polynomial(base_ring, -v**2*u**-1)
|
|
2778
|
+
self._root = v
|
|
2779
|
+
|
|
2780
|
+
# Used when multiplying generators: minor speed-up as it avoids the
|
|
2781
|
+
# need to constantly add and multiply the parameters when applying the
|
|
2782
|
+
# quadratic relation: T^2 = (q1+q2)T - q1*q2
|
|
2783
|
+
self._q_sum = normalized_laurent_polynomial(base_ring, self._q1+self._q2)
|
|
2784
|
+
self._q_prod = normalized_laurent_polynomial(base_ring, -self._q1*self._q2)
|
|
2785
|
+
|
|
2786
|
+
self.u_inv = normalized_laurent_polynomial(base_ring, u**-1)
|
|
2787
|
+
self.v_inv = normalized_laurent_polynomial(base_ring, v**-1)
|
|
2788
|
+
|
|
2789
|
+
self._shorthands = ['C', 'Cp', 'T']
|
|
2790
|
+
|
|
2791
|
+
if W.is_finite():
|
|
2792
|
+
self._category = FiniteDimensionalAlgebrasWithBasis(base_ring)
|
|
2793
|
+
else:
|
|
2794
|
+
self._category = AlgebrasWithBasis(base_ring)
|
|
2795
|
+
Parent.__init__(self, base=base_ring, category=self._category.WithRealizations())
|
|
2796
|
+
self._is_generic = True # needed for initialising _KLHeckeBasis
|
|
2797
|
+
|
|
2798
|
+
def _repr_(self):
|
|
2799
|
+
r"""
|
|
2800
|
+
EXAMPLES::
|
|
2801
|
+
|
|
2802
|
+
sage: sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
|
|
2803
|
+
A generic Iwahori-Hecke algebra of type A2 in u,-u^-1*v^2 over
|
|
2804
|
+
Multivariate Laurent Polynomial Ring in u, v over Integer Ring
|
|
2805
|
+
"""
|
|
2806
|
+
try:
|
|
2807
|
+
ct = self._coxeter_type._repr_(compact=True)
|
|
2808
|
+
except TypeError:
|
|
2809
|
+
ct = repr(self._coxeter_type)
|
|
2810
|
+
return "A generic Iwahori-Hecke algebra of type {} in {},{} over {}".format(
|
|
2811
|
+
ct, self._q1, self._q2, self.base_ring())
|
|
2812
|
+
|
|
2813
|
+
def _bar_on_coefficients(self, c):
|
|
2814
|
+
r"""
|
|
2815
|
+
Given a Laurent polynomial ``c`` return the Laurent polynomial obtained
|
|
2816
|
+
by applying the (generic) bar involution to ``c`` .
|
|
2817
|
+
|
|
2818
|
+
This is the ring homomorphism of Laurent polynomials in
|
|
2819
|
+
`\ZZ[u,u^{-1},v,v^{-1}]` which sends `u` to `u^{-1}` and `v`
|
|
2820
|
+
to `v^{-1}`.
|
|
2821
|
+
|
|
2822
|
+
EXAMPLES::
|
|
2823
|
+
|
|
2824
|
+
sage: R.<q>=LaurentPolynomialRing(ZZ)
|
|
2825
|
+
sage: H=IwahoriHeckeAlgebra("A3",q^2)
|
|
2826
|
+
sage: GH=H._generic_iwahori_hecke_algebra
|
|
2827
|
+
sage: GH._bar_on_coefficients(GH.u_inv)
|
|
2828
|
+
u
|
|
2829
|
+
sage: GH._bar_on_coefficients(GH.v_inv)
|
|
2830
|
+
v
|
|
2831
|
+
"""
|
|
2832
|
+
return normalized_laurent_polynomial(self._base, c)(self.u_inv, self.v_inv)
|
|
2833
|
+
|
|
2834
|
+
class _BasesCategory(IwahoriHeckeAlgebra._BasesCategory):
|
|
2835
|
+
"""
|
|
2836
|
+
Category of bases for a generic Iwahori-Hecke algebra.
|
|
2837
|
+
"""
|
|
2838
|
+
def super_categories(self):
|
|
2839
|
+
r"""
|
|
2840
|
+
The super categories of ``self``.
|
|
2841
|
+
|
|
2842
|
+
EXAMPLES::
|
|
2843
|
+
|
|
2844
|
+
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("B2")
|
|
2845
|
+
sage: H._BasesCategory().super_categories()
|
|
2846
|
+
[Category of bases of A generic Iwahori-Hecke algebra of type B2 in u,-u^-1*v^2 over
|
|
2847
|
+
Multivariate Laurent Polynomial Ring in u, v over Integer Ring]
|
|
2848
|
+
"""
|
|
2849
|
+
return [IwahoriHeckeAlgebra._BasesCategory(self.base())]
|
|
2850
|
+
|
|
2851
|
+
class ElementMethods:
|
|
2852
|
+
def specialize_to(self, new_hecke):
|
|
2853
|
+
r"""
|
|
2854
|
+
Return the element in the Iwahori-Hecke algebra ``new_hecke``
|
|
2855
|
+
with respect to the same basis which is obtained from ``self``
|
|
2856
|
+
by specializing the generic parameters in this algebra to the
|
|
2857
|
+
parameters of ``new_hecke``.
|
|
2858
|
+
|
|
2859
|
+
The generic Iwahori-Hecke algebra is defined over
|
|
2860
|
+
`\ZZ[u^\pm, v^\pm]` and has parameters ``u`` and
|
|
2861
|
+
``-v^2/u``. The specialization map sends ``u`` to
|
|
2862
|
+
``new_hecke._q1`` and ``v`` to ``new_hecke._root`` which is
|
|
2863
|
+
thesquare root of ``-new_hecke._q1*new_hecke._q2``, so
|
|
2864
|
+
`-v^2/u` is sent to ``new_hecke._q2``.
|
|
2865
|
+
|
|
2866
|
+
This function is not intended to be called directly. Rather it
|
|
2867
|
+
is called behind the scenes to convert between the
|
|
2868
|
+
Kazhdan-Lusztig and standard bases of the Iwahori-Hecke
|
|
2869
|
+
algebras.
|
|
2870
|
+
|
|
2871
|
+
EXAMPLES::
|
|
2872
|
+
|
|
2873
|
+
sage: R.<a,b>=LaurentPolynomialRing(ZZ,2)
|
|
2874
|
+
sage: H=IwahoriHeckeAlgebra("A3",a^2,-b^2)
|
|
2875
|
+
sage: GH=H._generic_iwahori_hecke_algebra
|
|
2876
|
+
sage: GH.T()(GH.C()[1])
|
|
2877
|
+
(v^-1)*T[1] + (-u*v^-1)
|
|
2878
|
+
sage: ( GH.T()(GH.C()[1]) ).specialize_to(H)
|
|
2879
|
+
(a^-1*b^-1)*T[1] + (-a*b^-1)
|
|
2880
|
+
sage: GH.C()( GH.T()[1] )
|
|
2881
|
+
v*C[1] + u
|
|
2882
|
+
sage: GH.C()( GH.T()[1] ).specialize_to(H)
|
|
2883
|
+
a*b*C[1] + a^2
|
|
2884
|
+
sage: H.C()( H.T()[1] )
|
|
2885
|
+
a*b*C[1] + a^2
|
|
2886
|
+
"""
|
|
2887
|
+
hecke = self.parent().realization_of()
|
|
2888
|
+
q1 = new_hecke._q1
|
|
2889
|
+
root = new_hecke._root
|
|
2890
|
+
# is there an easier way than this to convert the
|
|
2891
|
+
# coefficients to the correct base ring for new_hecke?
|
|
2892
|
+
|
|
2893
|
+
def new_coeff(c):
|
|
2894
|
+
return new_hecke._base(normalized_laurent_polynomial(hecke._base, c)(q1, root))
|
|
2895
|
+
new_basis = getattr(new_hecke, self.parent()._basis_name)()
|
|
2896
|
+
return new_basis._from_dict({w: new_coeff(c) for w, c in self})
|
|
2897
|
+
|
|
2898
|
+
class T(IwahoriHeckeAlgebra.T):
|
|
2899
|
+
r"""
|
|
2900
|
+
The `T`-basis for the generic Iwahori-Hecke algebra.
|
|
2901
|
+
"""
|
|
2902
|
+
@cached_method
|
|
2903
|
+
def to_Cp_basis(self, w):
|
|
2904
|
+
r"""
|
|
2905
|
+
Return `T_w` as a linear combination of `C^{\prime}`-basis
|
|
2906
|
+
elements.
|
|
2907
|
+
|
|
2908
|
+
EXAMPLES::
|
|
2909
|
+
|
|
2910
|
+
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
|
|
2911
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
2912
|
+
sage: T = H.T()
|
|
2913
|
+
sage: Cp = H.Cp()
|
|
2914
|
+
sage: T.to_Cp_basis(s1)
|
|
2915
|
+
v*Cp[1] + (-u^-1*v^2)
|
|
2916
|
+
sage: Cp(T(s1))
|
|
2917
|
+
v*Cp[1] + (-u^-1*v^2)
|
|
2918
|
+
sage: Cp(T(s1)+1)
|
|
2919
|
+
v*Cp[1] + (-u^-1*v^2+1)
|
|
2920
|
+
sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)
|
|
2921
|
+
v^2*Cp[1,2] + (-u^-1*v^3+v)*Cp[1] + (-u^-1*v^3+v)*Cp[2]
|
|
2922
|
+
+ (u^-2*v^4-2*u^-1*v^2+1)
|
|
2923
|
+
sage: Cp(T(s1*s2*s1))
|
|
2924
|
+
v^3*Cp[1,2,1] + (-u^-1*v^4)*Cp[2,1] + (-u^-1*v^4)*Cp[1,2]
|
|
2925
|
+
+ (u^-2*v^5)*Cp[1] + (u^-2*v^5)*Cp[2] + (-u^-3*v^6)
|
|
2926
|
+
"""
|
|
2927
|
+
A = self.realization_of()
|
|
2928
|
+
Cp = A.Cp()
|
|
2929
|
+
|
|
2930
|
+
if w == A._W.one(): # the identity element of the Coxeter group
|
|
2931
|
+
return Cp.one()
|
|
2932
|
+
|
|
2933
|
+
T0 = self.zero()
|
|
2934
|
+
inp = self.monomial(w)
|
|
2935
|
+
result = Cp.zero()
|
|
2936
|
+
while inp != T0:
|
|
2937
|
+
(x, c) = inp.trailing_item(key=sorting_key)
|
|
2938
|
+
inp = inp - c * A._root**x.length() * Cp.to_T_basis(x)
|
|
2939
|
+
result = result + c * A._root**x.length() * Cp.monomial(x)
|
|
2940
|
+
|
|
2941
|
+
return result
|
|
2942
|
+
|
|
2943
|
+
@cached_method
|
|
2944
|
+
def to_C_basis(self, w):
|
|
2945
|
+
r"""
|
|
2946
|
+
Return `T_w` as a linear combination of `C`-basis elements.
|
|
2947
|
+
|
|
2948
|
+
To compute this we piggy back off the `C^{\prime}`-basis
|
|
2949
|
+
conversion using the observation that the hash involution sends
|
|
2950
|
+
`T_w` to `(-q_1 q_1)^{\ell(w)} T_w` and `C_w` to
|
|
2951
|
+
`(-1)^{\ell(w)} C^{\prime}_w`. Therefore, if
|
|
2952
|
+
|
|
2953
|
+
.. MATH::
|
|
2954
|
+
|
|
2955
|
+
T_w = \sum_v a_{vw} C^{\prime}_v
|
|
2956
|
+
|
|
2957
|
+
then
|
|
2958
|
+
|
|
2959
|
+
.. MATH::
|
|
2960
|
+
|
|
2961
|
+
T_w = (-q_1 q_2)^{\ell(w)} \Big( \sum_v a_{vw} C^{\prime}_v
|
|
2962
|
+
\Big)^\#
|
|
2963
|
+
= \sum_v (-1)^{\ell(v)} \overline{a_{vw}} C_v
|
|
2964
|
+
|
|
2965
|
+
Note that we cannot just apply :meth:`hash_involution` here because
|
|
2966
|
+
this involution always returns the answer with respect to the
|
|
2967
|
+
same basis.
|
|
2968
|
+
|
|
2969
|
+
EXAMPLES::
|
|
2970
|
+
|
|
2971
|
+
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
|
|
2972
|
+
sage: s1,s2 = H.coxeter_group().simple_reflections()
|
|
2973
|
+
sage: T = H.T()
|
|
2974
|
+
sage: C = H.C()
|
|
2975
|
+
sage: T.to_C_basis(s1)
|
|
2976
|
+
v*T[1] + u
|
|
2977
|
+
sage: C(T(s1))
|
|
2978
|
+
v*C[1] + u
|
|
2979
|
+
sage: C(T( C[1] ))
|
|
2980
|
+
C[1]
|
|
2981
|
+
sage: C(T(s1*s2)+T(s1)+T(s2)+1)
|
|
2982
|
+
v^2*C[1,2] + (u*v+v)*C[1] + (u*v+v)*C[2] + (u^2+2*u+1)
|
|
2983
|
+
sage: C(T(s1*s2*s1))
|
|
2984
|
+
v^3*C[1,2,1] + u*v^2*C[2,1] + u*v^2*C[1,2] + u^2*v*C[1] + u^2*v*C[2] + u^3
|
|
2985
|
+
"""
|
|
2986
|
+
H = self.realization_of()
|
|
2987
|
+
q_w = (-H._q_prod)**w.length()
|
|
2988
|
+
return self.sum_of_terms((v, (-1)**v.length()*q_w*H._bar_on_coefficients(c))
|
|
2989
|
+
for (v, c) in self.to_Cp_basis(w))
|
|
2990
|
+
|
|
2991
|
+
class Cp(IwahoriHeckeAlgebra.Cp):
|
|
2992
|
+
r"""
|
|
2993
|
+
The Kazhdan-Lusztig `C^{\prime}`-basis for the generic Iwahori-Hecke
|
|
2994
|
+
algebra.
|
|
2995
|
+
"""
|
|
2996
|
+
@cached_method
|
|
2997
|
+
def to_T_basis(self, w):
|
|
2998
|
+
r"""
|
|
2999
|
+
Return `C^{\prime}_w` as a linear combination of `T`-basis
|
|
3000
|
+
elements.
|
|
3001
|
+
|
|
3002
|
+
EXAMPLES::
|
|
3003
|
+
|
|
3004
|
+
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A3")
|
|
3005
|
+
sage: s1,s2,s3 = H.coxeter_group().simple_reflections()
|
|
3006
|
+
sage: T = H.T()
|
|
3007
|
+
sage: Cp = H.Cp()
|
|
3008
|
+
sage: Cp.to_T_basis(s1)
|
|
3009
|
+
(v^-1)*T[1] + (u^-1*v)
|
|
3010
|
+
sage: Cp.to_T_basis(s1*s2)
|
|
3011
|
+
(v^-2)*T[1,2] + (u^-1)*T[1] + (u^-1)*T[2] + (u^-2*v^2)
|
|
3012
|
+
sage: Cp.to_T_basis(s1*s2*s1)
|
|
3013
|
+
(v^-3)*T[1,2,1] + (u^-1*v^-1)*T[2,1] + (u^-1*v^-1)*T[1,2]
|
|
3014
|
+
+ (u^-2*v)*T[1] + (u^-2*v)*T[2] + (u^-3*v^3)
|
|
3015
|
+
sage: T(Cp(s1*s2*s1))
|
|
3016
|
+
(v^-3)*T[1,2,1] + (u^-1*v^-1)*T[2,1] + (u^-1*v^-1)*T[1,2]
|
|
3017
|
+
+ (u^-2*v)*T[1] + (u^-2*v)*T[2] + (u^-3*v^3)
|
|
3018
|
+
sage: T(Cp(s2*s1*s3*s2))
|
|
3019
|
+
(v^-4)*T[2,3,1,2] + (u^-1*v^-2)*T[2,3,1] + (u^-1*v^-2)*T[1,2,1]
|
|
3020
|
+
+ (u^-1*v^-2)*T[3,1,2] + (u^-1*v^-2)*T[2,3,2] + (u^-2)*T[2,1]
|
|
3021
|
+
+ (u^-2)*T[3,1] + (u^-2)*T[1,2] + (u^-2)*T[3,2]
|
|
3022
|
+
+ (u^-2)*T[2,3] + (u^-3*v^2)*T[1] + (u^-3*v^2)*T[3]
|
|
3023
|
+
+ (u^-1+u^-3*v^2)*T[2] + (u^-2*v^2+u^-4*v^4)
|
|
3024
|
+
"""
|
|
3025
|
+
A = self.realization_of()
|
|
3026
|
+
T = A.T()
|
|
3027
|
+
Ts = T.algebra_generators()
|
|
3028
|
+
|
|
3029
|
+
if w == A._W.one(): # the identity element of the Coxeter group
|
|
3030
|
+
return T.one()
|
|
3031
|
+
|
|
3032
|
+
s = w.first_descent()
|
|
3033
|
+
ws = w.apply_simple_reflection(s)
|
|
3034
|
+
|
|
3035
|
+
cpw_s = self.to_T_basis(ws) * A.v_inv * (Ts[s] - A._q2 * T.one())
|
|
3036
|
+
|
|
3037
|
+
i = 1
|
|
3038
|
+
|
|
3039
|
+
def key_func(x):
|
|
3040
|
+
return sorting_key(x.leading_support())
|
|
3041
|
+
|
|
3042
|
+
while i < len(cpw_s):
|
|
3043
|
+
(x, c) = sorted(cpw_s.terms(), key=key_func)[i].leading_item()
|
|
3044
|
+
mu = normalized_laurent_polynomial(A._base, c)[0, -x.length()] # the coefficient of v^-len(x)
|
|
3045
|
+
if mu != 0:
|
|
3046
|
+
cpw_s -= mu * self.to_T_basis(x)
|
|
3047
|
+
else:
|
|
3048
|
+
i += 1
|
|
3049
|
+
|
|
3050
|
+
return cpw_s
|
|
3051
|
+
|
|
3052
|
+
C_prime = Cp
|
|
3053
|
+
|
|
3054
|
+
class C(IwahoriHeckeAlgebra.C):
|
|
3055
|
+
r"""
|
|
3056
|
+
The Kazhdan-Lusztig `C`-basis for the generic Iwahori-Hecke algebra.
|
|
3057
|
+
"""
|
|
3058
|
+
@cached_method
|
|
3059
|
+
def to_T_basis(self, w):
|
|
3060
|
+
r"""
|
|
3061
|
+
Return `C_w` as a linear combination of `T`-basis elements.
|
|
3062
|
+
|
|
3063
|
+
EXAMPLES::
|
|
3064
|
+
|
|
3065
|
+
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A3")
|
|
3066
|
+
sage: s1,s2,s3 = H.coxeter_group().simple_reflections()
|
|
3067
|
+
sage: T = H.T()
|
|
3068
|
+
sage: C = H.C()
|
|
3069
|
+
sage: C.to_T_basis(s1)
|
|
3070
|
+
(v^-1)*T[1] + (-u*v^-1)
|
|
3071
|
+
sage: C.to_T_basis(s1*s2)
|
|
3072
|
+
(v^-2)*T[1,2] + (-u*v^-2)*T[1] + (-u*v^-2)*T[2] + (u^2*v^-2)
|
|
3073
|
+
sage: C.to_T_basis(s1*s2*s1)
|
|
3074
|
+
(v^-3)*T[1,2,1] + (-u*v^-3)*T[2,1] + (-u*v^-3)*T[1,2]
|
|
3075
|
+
+ (u^2*v^-3)*T[1] + (u^2*v^-3)*T[2] + (-u^3*v^-3)
|
|
3076
|
+
sage: T(C(s1*s2*s1))
|
|
3077
|
+
(v^-3)*T[1,2,1] + (-u*v^-3)*T[2,1] + (-u*v^-3)*T[1,2]
|
|
3078
|
+
+ (u^2*v^-3)*T[1] + (u^2*v^-3)*T[2] + (-u^3*v^-3)
|
|
3079
|
+
sage: T(C(s2*s1*s3*s2))
|
|
3080
|
+
(v^-4)*T[2,3,1,2] + (-u*v^-4)*T[2,3,1] + (-u*v^-4)*T[1,2,1]
|
|
3081
|
+
+ (-u*v^-4)*T[3,1,2] + (-u*v^-4)*T[2,3,2] + (u^2*v^-4)*T[2,1]
|
|
3082
|
+
+ (u^2*v^-4)*T[3,1] + (u^2*v^-4)*T[1,2] + (u^2*v^-4)*T[3,2]
|
|
3083
|
+
+ (u^2*v^-4)*T[2,3] + (-u^3*v^-4)*T[1] + (-u^3*v^-4)*T[3]
|
|
3084
|
+
+ (-u^3*v^-4-u*v^-2)*T[2] + (u^4*v^-4+u^2*v^-2)
|
|
3085
|
+
"""
|
|
3086
|
+
# Treat our index as an index for the C'-basis, convert to the T-basis and
|
|
3087
|
+
# then apply the Hecke involution to the result. This gives the
|
|
3088
|
+
# desired result because C_w = (-1)^{len(w)) \tau( C_w' ), where
|
|
3089
|
+
# \tau is the Hecke involution.
|
|
3090
|
+
return (-1)**w.length()*self.realization_of().Cp().to_T_basis(w).hash_involution()
|
|
3091
|
+
|
|
3092
|
+
|
|
3093
|
+
from sage.misc.persist import register_unpickle_override
|
|
3094
|
+
register_unpickle_override('sage.algebras.iwahori_hecke_algebra',
|
|
3095
|
+
'IwahoriHeckeAlgebraT', IwahoriHeckeAlgebra)
|