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.
Files changed (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. 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)