passagemath-combinat 10.6.42__cp314-cp314t-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/DELVEWHEEL +2 -0
  3. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  4. passagemath_combinat-10.6.42.dist-info/RECORD +401 -0
  5. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  6. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  7. passagemath_combinat.libs/libgmp-10-3a5f019e2510aeaad918cab2b57a689d.dll +0 -0
  8. passagemath_combinat.libs/libsymmetrica-3-7dcf900932804d0df5fd0919b4668720.dll +0 -0
  9. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  10. sage/algebras/all.py +24 -0
  11. sage/algebras/all__sagemath_combinat.py +35 -0
  12. sage/algebras/askey_wilson.py +935 -0
  13. sage/algebras/associated_graded.py +345 -0
  14. sage/algebras/cellular_basis.py +350 -0
  15. sage/algebras/cluster_algebra.py +2766 -0
  16. sage/algebras/down_up_algebra.py +860 -0
  17. sage/algebras/free_algebra.py +1698 -0
  18. sage/algebras/free_algebra_element.py +345 -0
  19. sage/algebras/free_algebra_quotient.py +405 -0
  20. sage/algebras/free_algebra_quotient_element.py +295 -0
  21. sage/algebras/free_zinbiel_algebra.py +885 -0
  22. sage/algebras/hall_algebra.py +783 -0
  23. sage/algebras/hecke_algebras/all.py +4 -0
  24. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  25. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  28. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  29. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  30. sage/algebras/jordan_algebra.py +1773 -0
  31. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  32. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  33. sage/algebras/lie_conformal_algebras/all.py +18 -0
  34. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  35. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  36. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  37. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  38. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  39. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  40. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  41. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  45. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  46. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  47. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  48. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  49. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  50. sage/algebras/nil_coxeter_algebra.py +191 -0
  51. sage/algebras/q_commuting_polynomials.py +673 -0
  52. sage/algebras/q_system.py +608 -0
  53. sage/algebras/quantum_clifford.py +959 -0
  54. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  55. sage/algebras/quantum_groups/all.py +9 -0
  56. sage/algebras/quantum_groups/fock_space.py +2219 -0
  57. sage/algebras/quantum_groups/q_numbers.py +207 -0
  58. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  59. sage/algebras/quantum_groups/representations.py +591 -0
  60. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  61. sage/algebras/quantum_oscillator.py +623 -0
  62. sage/algebras/quaternion_algebra.py +20 -0
  63. sage/algebras/quaternion_algebra_element.py +55 -0
  64. sage/algebras/rational_cherednik_algebra.py +525 -0
  65. sage/algebras/schur_algebra.py +670 -0
  66. sage/algebras/shuffle_algebra.py +1011 -0
  67. sage/algebras/splitting_algebra.py +779 -0
  68. sage/algebras/tensor_algebra.py +709 -0
  69. sage/algebras/yangian.py +1082 -0
  70. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  71. sage/all__sagemath_combinat.py +44 -0
  72. sage/combinat/SJT.py +255 -0
  73. sage/combinat/affine_permutation.py +2405 -0
  74. sage/combinat/algebraic_combinatorics.py +55 -0
  75. sage/combinat/all.py +53 -0
  76. sage/combinat/all__sagemath_combinat.py +195 -0
  77. sage/combinat/alternating_sign_matrix.py +2063 -0
  78. sage/combinat/baxter_permutations.py +346 -0
  79. sage/combinat/bijectionist.py +3220 -0
  80. sage/combinat/binary_recurrence_sequences.py +1180 -0
  81. sage/combinat/blob_algebra.py +685 -0
  82. sage/combinat/catalog_partitions.py +27 -0
  83. sage/combinat/chas/all.py +23 -0
  84. sage/combinat/chas/fsym.py +1180 -0
  85. sage/combinat/chas/wqsym.py +2601 -0
  86. sage/combinat/cluster_complex.py +326 -0
  87. sage/combinat/colored_permutations.py +2039 -0
  88. sage/combinat/colored_permutations_representations.py +964 -0
  89. sage/combinat/composition_signed.py +142 -0
  90. sage/combinat/composition_tableau.py +855 -0
  91. sage/combinat/constellation.py +1729 -0
  92. sage/combinat/core.py +751 -0
  93. sage/combinat/counting.py +12 -0
  94. sage/combinat/crystals/affine.py +742 -0
  95. sage/combinat/crystals/affine_factorization.py +518 -0
  96. sage/combinat/crystals/affinization.py +331 -0
  97. sage/combinat/crystals/alcove_path.py +2013 -0
  98. sage/combinat/crystals/all.py +22 -0
  99. sage/combinat/crystals/bkk_crystals.py +141 -0
  100. sage/combinat/crystals/catalog.py +115 -0
  101. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  102. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  103. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  104. sage/combinat/crystals/crystals.py +257 -0
  105. sage/combinat/crystals/direct_sum.py +260 -0
  106. sage/combinat/crystals/elementary_crystals.py +1251 -0
  107. sage/combinat/crystals/fast_crystals.py +441 -0
  108. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  109. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  110. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  111. sage/combinat/crystals/induced_structure.py +695 -0
  112. sage/combinat/crystals/infinity_crystals.py +730 -0
  113. sage/combinat/crystals/kac_modules.py +863 -0
  114. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  115. sage/combinat/crystals/kyoto_path_model.py +497 -0
  116. sage/combinat/crystals/letters.cp314t-win_amd64.pyd +0 -0
  117. sage/combinat/crystals/letters.pxd +79 -0
  118. sage/combinat/crystals/letters.pyx +3056 -0
  119. sage/combinat/crystals/littelmann_path.py +1518 -0
  120. sage/combinat/crystals/monomial_crystals.py +1262 -0
  121. sage/combinat/crystals/multisegments.py +462 -0
  122. sage/combinat/crystals/mv_polytopes.py +467 -0
  123. sage/combinat/crystals/pbw_crystal.py +511 -0
  124. sage/combinat/crystals/pbw_datum.cp314t-win_amd64.pyd +0 -0
  125. sage/combinat/crystals/pbw_datum.pxd +4 -0
  126. sage/combinat/crystals/pbw_datum.pyx +487 -0
  127. sage/combinat/crystals/polyhedral_realization.py +372 -0
  128. sage/combinat/crystals/spins.cp314t-win_amd64.pyd +0 -0
  129. sage/combinat/crystals/spins.pxd +21 -0
  130. sage/combinat/crystals/spins.pyx +756 -0
  131. sage/combinat/crystals/star_crystal.py +290 -0
  132. sage/combinat/crystals/subcrystal.py +464 -0
  133. sage/combinat/crystals/tensor_product.py +1177 -0
  134. sage/combinat/crystals/tensor_product_element.cp314t-win_amd64.pyd +0 -0
  135. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  136. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  137. sage/combinat/crystals/virtual_crystal.py +420 -0
  138. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  139. sage/combinat/debruijn_sequence.cp314t-win_amd64.pyd +0 -0
  140. sage/combinat/debruijn_sequence.pyx +355 -0
  141. sage/combinat/decorated_permutation.py +270 -0
  142. sage/combinat/degree_sequences.cp314t-win_amd64.pyd +0 -0
  143. sage/combinat/degree_sequences.pyx +588 -0
  144. sage/combinat/derangements.py +527 -0
  145. sage/combinat/descent_algebra.py +1008 -0
  146. sage/combinat/diagram.py +1551 -0
  147. sage/combinat/diagram_algebras.py +5886 -0
  148. sage/combinat/dyck_word.py +4349 -0
  149. sage/combinat/e_one_star.py +1623 -0
  150. sage/combinat/enumerated_sets.py +123 -0
  151. sage/combinat/expnums.cp314t-win_amd64.pyd +0 -0
  152. sage/combinat/expnums.pyx +148 -0
  153. sage/combinat/fast_vector_partitions.cp314t-win_amd64.pyd +0 -0
  154. sage/combinat/fast_vector_partitions.pyx +346 -0
  155. sage/combinat/fqsym.py +1977 -0
  156. sage/combinat/free_dendriform_algebra.py +954 -0
  157. sage/combinat/free_prelie_algebra.py +1141 -0
  158. sage/combinat/fully_commutative_elements.py +1077 -0
  159. sage/combinat/fully_packed_loop.py +1523 -0
  160. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  161. sage/combinat/gray_codes.py +311 -0
  162. sage/combinat/grossman_larson_algebras.py +667 -0
  163. sage/combinat/growth.py +4352 -0
  164. sage/combinat/hall_polynomial.py +188 -0
  165. sage/combinat/hillman_grassl.py +866 -0
  166. sage/combinat/integer_matrices.py +329 -0
  167. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  168. sage/combinat/k_tableau.py +4564 -0
  169. sage/combinat/kazhdan_lusztig.py +215 -0
  170. sage/combinat/key_polynomial.py +885 -0
  171. sage/combinat/knutson_tao_puzzles.py +2286 -0
  172. sage/combinat/lr_tableau.py +311 -0
  173. sage/combinat/matrices/all.py +24 -0
  174. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  175. sage/combinat/matrices/latin.py +2912 -0
  176. sage/combinat/misc.py +401 -0
  177. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  178. sage/combinat/ncsf_qsym/all.py +21 -0
  179. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  180. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  181. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  182. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  183. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  184. sage/combinat/ncsym/all.py +21 -0
  185. sage/combinat/ncsym/bases.py +855 -0
  186. sage/combinat/ncsym/dual.py +593 -0
  187. sage/combinat/ncsym/ncsym.py +2076 -0
  188. sage/combinat/necklace.py +551 -0
  189. sage/combinat/non_decreasing_parking_function.py +634 -0
  190. sage/combinat/nu_dyck_word.py +1474 -0
  191. sage/combinat/output.py +861 -0
  192. sage/combinat/parallelogram_polyomino.py +4326 -0
  193. sage/combinat/parking_functions.py +1602 -0
  194. sage/combinat/partition_algebra.py +1998 -0
  195. sage/combinat/partition_kleshchev.py +1982 -0
  196. sage/combinat/partition_shifting_algebras.py +584 -0
  197. sage/combinat/partition_tuple.py +3114 -0
  198. sage/combinat/path_tableaux/all.py +13 -0
  199. sage/combinat/path_tableaux/catalog.py +29 -0
  200. sage/combinat/path_tableaux/dyck_path.py +380 -0
  201. sage/combinat/path_tableaux/frieze.py +476 -0
  202. sage/combinat/path_tableaux/path_tableau.py +728 -0
  203. sage/combinat/path_tableaux/semistandard.py +510 -0
  204. sage/combinat/perfect_matching.py +779 -0
  205. sage/combinat/plane_partition.py +3300 -0
  206. sage/combinat/q_bernoulli.cp314t-win_amd64.pyd +0 -0
  207. sage/combinat/q_bernoulli.pyx +128 -0
  208. sage/combinat/quickref.py +81 -0
  209. sage/combinat/recognizable_series.py +2051 -0
  210. sage/combinat/regular_sequence.py +4316 -0
  211. sage/combinat/regular_sequence_bounded.py +543 -0
  212. sage/combinat/restricted_growth.py +81 -0
  213. sage/combinat/ribbon.py +20 -0
  214. sage/combinat/ribbon_shaped_tableau.py +489 -0
  215. sage/combinat/ribbon_tableau.py +1180 -0
  216. sage/combinat/rigged_configurations/all.py +46 -0
  217. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  218. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  219. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  222. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  223. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  224. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  225. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  226. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  227. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  228. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  229. sage/combinat/rigged_configurations/bijection.py +143 -0
  230. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  231. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  232. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  233. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  234. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  235. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  236. sage/combinat/rigged_configurations/rigged_partition.cp314t-win_amd64.pyd +0 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  238. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  240. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  241. sage/combinat/rsk.py +3438 -0
  242. sage/combinat/schubert_polynomial.py +508 -0
  243. sage/combinat/set_partition.py +3318 -0
  244. sage/combinat/set_partition_iterator.cp314t-win_amd64.pyd +0 -0
  245. sage/combinat/set_partition_iterator.pyx +136 -0
  246. sage/combinat/set_partition_ordered.py +1590 -0
  247. sage/combinat/sf/abreu_nigro.py +346 -0
  248. sage/combinat/sf/all.py +52 -0
  249. sage/combinat/sf/character.py +576 -0
  250. sage/combinat/sf/classical.py +319 -0
  251. sage/combinat/sf/dual.py +996 -0
  252. sage/combinat/sf/elementary.py +549 -0
  253. sage/combinat/sf/hall_littlewood.py +1028 -0
  254. sage/combinat/sf/hecke.py +336 -0
  255. sage/combinat/sf/homogeneous.py +464 -0
  256. sage/combinat/sf/jack.py +1428 -0
  257. sage/combinat/sf/k_dual.py +1458 -0
  258. sage/combinat/sf/kfpoly.py +447 -0
  259. sage/combinat/sf/llt.py +789 -0
  260. sage/combinat/sf/macdonald.py +2019 -0
  261. sage/combinat/sf/monomial.py +525 -0
  262. sage/combinat/sf/multiplicative.py +113 -0
  263. sage/combinat/sf/new_kschur.py +1786 -0
  264. sage/combinat/sf/ns_macdonald.py +964 -0
  265. sage/combinat/sf/orthogonal.py +246 -0
  266. sage/combinat/sf/orthotriang.py +355 -0
  267. sage/combinat/sf/powersum.py +963 -0
  268. sage/combinat/sf/schur.py +880 -0
  269. sage/combinat/sf/sf.py +1653 -0
  270. sage/combinat/sf/sfa.py +7053 -0
  271. sage/combinat/sf/symplectic.py +253 -0
  272. sage/combinat/sf/witt.py +721 -0
  273. sage/combinat/shifted_primed_tableau.py +2735 -0
  274. sage/combinat/shuffle.py +830 -0
  275. sage/combinat/sidon_sets.py +146 -0
  276. sage/combinat/similarity_class_type.py +1721 -0
  277. sage/combinat/sine_gordon.py +618 -0
  278. sage/combinat/six_vertex_model.py +784 -0
  279. sage/combinat/skew_partition.py +2053 -0
  280. sage/combinat/skew_tableau.py +2989 -0
  281. sage/combinat/sloane_functions.py +8935 -0
  282. sage/combinat/specht_module.py +1403 -0
  283. sage/combinat/species/all.py +48 -0
  284. sage/combinat/species/characteristic_species.py +321 -0
  285. sage/combinat/species/composition_species.py +273 -0
  286. sage/combinat/species/cycle_species.py +284 -0
  287. sage/combinat/species/empty_species.py +155 -0
  288. sage/combinat/species/functorial_composition_species.py +148 -0
  289. sage/combinat/species/generating_series.py +673 -0
  290. sage/combinat/species/library.py +148 -0
  291. sage/combinat/species/linear_order_species.py +169 -0
  292. sage/combinat/species/misc.py +83 -0
  293. sage/combinat/species/partition_species.py +290 -0
  294. sage/combinat/species/permutation_species.py +268 -0
  295. sage/combinat/species/product_species.py +423 -0
  296. sage/combinat/species/recursive_species.py +476 -0
  297. sage/combinat/species/set_species.py +192 -0
  298. sage/combinat/species/species.py +820 -0
  299. sage/combinat/species/structure.py +539 -0
  300. sage/combinat/species/subset_species.py +243 -0
  301. sage/combinat/species/sum_species.py +225 -0
  302. sage/combinat/subword.py +564 -0
  303. sage/combinat/subword_complex.py +2122 -0
  304. sage/combinat/subword_complex_c.cp314t-win_amd64.pyd +0 -0
  305. sage/combinat/subword_complex_c.pyx +119 -0
  306. sage/combinat/super_tableau.py +821 -0
  307. sage/combinat/superpartition.py +1154 -0
  308. sage/combinat/symmetric_group_algebra.py +3774 -0
  309. sage/combinat/symmetric_group_representations.py +1830 -0
  310. sage/combinat/t_sequences.py +877 -0
  311. sage/combinat/tableau.py +9506 -0
  312. sage/combinat/tableau_residues.py +860 -0
  313. sage/combinat/tableau_tuple.py +5353 -0
  314. sage/combinat/tiling.py +2432 -0
  315. sage/combinat/triangles_FHM.py +777 -0
  316. sage/combinat/tutorial.py +1857 -0
  317. sage/combinat/vector_partition.py +337 -0
  318. sage/combinat/words/abstract_word.py +1722 -0
  319. sage/combinat/words/all.py +59 -0
  320. sage/combinat/words/alphabet.py +268 -0
  321. sage/combinat/words/finite_word.py +7201 -0
  322. sage/combinat/words/infinite_word.py +113 -0
  323. sage/combinat/words/lyndon_word.py +652 -0
  324. sage/combinat/words/morphic.py +351 -0
  325. sage/combinat/words/morphism.py +3878 -0
  326. sage/combinat/words/paths.py +2932 -0
  327. sage/combinat/words/shuffle_product.py +278 -0
  328. sage/combinat/words/suffix_trees.py +1873 -0
  329. sage/combinat/words/word.py +769 -0
  330. sage/combinat/words/word_char.cp314t-win_amd64.pyd +0 -0
  331. sage/combinat/words/word_char.pyx +847 -0
  332. sage/combinat/words/word_datatypes.cp314t-win_amd64.pyd +0 -0
  333. sage/combinat/words/word_datatypes.pxd +4 -0
  334. sage/combinat/words/word_datatypes.pyx +1067 -0
  335. sage/combinat/words/word_generators.py +2026 -0
  336. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  337. sage/combinat/words/word_options.py +99 -0
  338. sage/combinat/words/words.py +2396 -0
  339. sage/data_structures/all__sagemath_combinat.py +1 -0
  340. sage/databases/all__sagemath_combinat.py +13 -0
  341. sage/databases/findstat.py +4897 -0
  342. sage/databases/oeis.py +2058 -0
  343. sage/databases/sloane.py +393 -0
  344. sage/dynamics/all__sagemath_combinat.py +14 -0
  345. sage/dynamics/cellular_automata/all.py +7 -0
  346. sage/dynamics/cellular_automata/catalog.py +34 -0
  347. sage/dynamics/cellular_automata/elementary.py +612 -0
  348. sage/dynamics/cellular_automata/glca.py +477 -0
  349. sage/dynamics/cellular_automata/solitons.py +1463 -0
  350. sage/dynamics/finite_dynamical_system.py +1249 -0
  351. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  352. sage/games/all.py +7 -0
  353. sage/games/hexad.py +704 -0
  354. sage/games/quantumino.py +591 -0
  355. sage/games/sudoku.py +889 -0
  356. sage/games/sudoku_backtrack.cp314t-win_amd64.pyd +0 -0
  357. sage/games/sudoku_backtrack.pyx +189 -0
  358. sage/groups/all__sagemath_combinat.py +1 -0
  359. sage/groups/indexed_free_group.py +489 -0
  360. sage/libs/all__sagemath_combinat.py +6 -0
  361. sage/libs/lrcalc/__init__.py +1 -0
  362. sage/libs/lrcalc/lrcalc.py +525 -0
  363. sage/libs/symmetrica/__init__.py +7 -0
  364. sage/libs/symmetrica/all.py +101 -0
  365. sage/libs/symmetrica/kostka.pxi +168 -0
  366. sage/libs/symmetrica/part.pxi +193 -0
  367. sage/libs/symmetrica/plet.pxi +42 -0
  368. sage/libs/symmetrica/sab.pxi +196 -0
  369. sage/libs/symmetrica/sb.pxi +332 -0
  370. sage/libs/symmetrica/sc.pxi +192 -0
  371. sage/libs/symmetrica/schur.pxi +956 -0
  372. sage/libs/symmetrica/symmetrica.cp314t-win_amd64.pyd +0 -0
  373. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  374. sage/libs/symmetrica/symmetrica.pyx +39 -0
  375. sage/monoids/all.py +13 -0
  376. sage/monoids/automatic_semigroup.py +1054 -0
  377. sage/monoids/free_abelian_monoid.py +315 -0
  378. sage/monoids/free_abelian_monoid_element.cp314t-win_amd64.pyd +0 -0
  379. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  380. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  381. sage/monoids/free_monoid.py +335 -0
  382. sage/monoids/free_monoid_element.py +431 -0
  383. sage/monoids/hecke_monoid.py +65 -0
  384. sage/monoids/string_monoid.py +817 -0
  385. sage/monoids/string_monoid_element.py +547 -0
  386. sage/monoids/string_ops.py +143 -0
  387. sage/monoids/trace_monoid.py +972 -0
  388. sage/rings/all__sagemath_combinat.py +2 -0
  389. sage/sat/all.py +4 -0
  390. sage/sat/boolean_polynomials.py +405 -0
  391. sage/sat/converters/__init__.py +6 -0
  392. sage/sat/converters/anf2cnf.py +14 -0
  393. sage/sat/converters/polybori.py +611 -0
  394. sage/sat/solvers/__init__.py +5 -0
  395. sage/sat/solvers/cryptominisat.py +287 -0
  396. sage/sat/solvers/dimacs.py +783 -0
  397. sage/sat/solvers/picosat.py +228 -0
  398. sage/sat/solvers/sat_lp.py +156 -0
  399. sage/sat/solvers/satsolver.cp314t-win_amd64.pyd +0 -0
  400. sage/sat/solvers/satsolver.pxd +3 -0
  401. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,2695 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: optional - gap_package_quagroup sage.combinat sage.libs.gap sage.modules
3
+ """
4
+ Quantum Groups Using GAP's QuaGroup Package
5
+
6
+ AUTHORS:
7
+
8
+ - Travis Scrimshaw (03-2017): initial version
9
+
10
+ See the :gap_package:`documentation for GAP's QuaGroup package <quagroup/doc/chap0_mj.html>`,
11
+ originally authored by Willem Adriaan de Graaf.
12
+ """
13
+
14
+ # ****************************************************************************
15
+ # Copyright (C) 2017 Travis Scrimshaw <tcscrims at gmail.com>
16
+ #
17
+ # This program is free software: you can redistribute it and/or modify
18
+ # it under the terms of the GNU General Public License as published by
19
+ # the Free Software Foundation, either version 2 of the License, or
20
+ # (at your option) any later version.
21
+ # https://www.gnu.org/licenses/
22
+ # ****************************************************************************
23
+
24
+ import re
25
+
26
+ from copy import copy
27
+
28
+ from sage.misc.lazy_attribute import lazy_attribute
29
+ from sage.misc.lazy_import import lazy_import
30
+ from sage.misc.cachefunc import cached_method
31
+ from sage.structure.parent import Parent
32
+ from sage.structure.element import Element
33
+ from sage.structure.unique_representation import UniqueRepresentation
34
+ from sage.structure.sage_object import SageObject
35
+ from sage.structure.richcmp import op_EQ, op_NE, richcmp
36
+ from sage.sets.non_negative_integers import NonNegativeIntegers
37
+ from sage.sets.family import Family
38
+ from sage.combinat.root_system.cartan_type import CartanType
39
+ from sage.libs.gap.libgap import libgap
40
+ from sage.features.gap import GapPackage
41
+ from sage.rings.rational_field import QQ
42
+ from sage.categories.algebras import Algebras
43
+ from sage.categories.cartesian_product import cartesian_product
44
+ from sage.categories.fields import Fields
45
+ from sage.categories.homset import HomsetWithBase, Hom
46
+ from sage.categories.hopf_algebras import HopfAlgebras
47
+ from sage.categories.modules import Modules
48
+ from sage.categories.morphism import Morphism
49
+ from sage.categories.rings import Rings
50
+
51
+ lazy_import('sage.graphs.digraph', 'DiGraph')
52
+
53
+
54
+ class QuaGroupModuleElement(Element):
55
+ """
56
+ Base class for elements created using QuaGroup.
57
+ """
58
+ def __init__(self, parent, libgap_elt):
59
+ """
60
+ Initialize ``self``.
61
+
62
+ EXAMPLES::
63
+
64
+ sage: Q = QuantumGroup(['G',2])
65
+ sage: TestSuite(Q.an_element()).run()
66
+ """
67
+ self._libgap = libgap(libgap_elt)
68
+ Element.__init__(self, parent)
69
+
70
+ def _repr_(self):
71
+ """
72
+ Return a string representation of ``self``.
73
+
74
+ EXAMPLES::
75
+
76
+ sage: Q = QuantumGroup(['G',2])
77
+ sage: Q.an_element()
78
+ 1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ] + K1
79
+ + (-q^-1 + q^-3)*K1[ K1 ; 1 ]
80
+
81
+ sage: Q = QuantumGroup(['D',4])
82
+ sage: Q.F_simple()
83
+ Finite family {1: F[a1], 2: F[a2], 3: F[a3], 4: F[a4]}
84
+ """
85
+ # We add some space between the terms
86
+ # FIXME: This doesn't work to avoid within the () for the coeff's
87
+ c = re.compile(r"\+(?! [^(]* \))")
88
+ ret = re.sub(c, ' + ', repr(self._libgap))
89
+ # Replace Ei and Fi with the corresponding root in short form.
90
+ # Do the largest index first so, e.g., F12 gets replaced as 12
91
+ # instead of as 1.
92
+ for i, al in reversed(list(enumerate(self.parent()._pos_roots))):
93
+ short = '+'.join('%s*a%s' % (coeff, index)
94
+ if coeff != 1 else 'a%s' % index
95
+ for index, coeff in al)
96
+ ret = ret.replace('F%s' % (i + 1), 'F[%s]' % short)
97
+ ret = ret.replace('E%s' % (i + 1), 'E[%s]' % short)
98
+ return ret
99
+
100
+ def _latex_(self):
101
+ r"""
102
+ Return a latex representation of ``self``.
103
+
104
+ EXAMPLES::
105
+
106
+ sage: Q = QuantumGroup(['G',2])
107
+ sage: latex(Q.an_element())
108
+ 1+{(q)} F_{\alpha_{1}}+E_{\alpha_{1}}+{(q^{2}-1-q^{-2}+q^{-4})}
109
+ [ K_{1} ; 2 ]+K_{1}+{(-q^{-1}+q^{-3})} K_{1}[ K_{1} ; 1 ]
110
+
111
+ sage: Q = QuantumGroup(['D',4])
112
+ sage: latex(list(Q.F_simple()))
113
+ \left[F_{\alpha_{1}}, F_{\alpha_{2}},
114
+ F_{\alpha_{3}}, F_{\alpha_{4}}\right]
115
+ """
116
+ from sage.misc.latex import latex
117
+ ret = repr(self._libgap)
118
+ # Do the largest index first so, e.g., F12 gets replaced as 12
119
+ # instead of as 1.
120
+ for i, al in reversed(list(enumerate(self.parent()._pos_roots))):
121
+ ret = ret.replace('F%s' % (i + 1), 'F_{%s}' % latex(al))
122
+ ret = ret.replace('E%s' % (i + 1), 'E_{%s}' % latex(al))
123
+ for i, ii in reversed(list(enumerate(self.parent()._cartan_type.index_set()))):
124
+ ret = ret.replace('K%s' % (i + 1), 'K_{%s}' % ii)
125
+ # Fugly string parsing to get good looking latex
126
+ # TODO: Find a better way
127
+ ret = ret.replace('(', '{(')
128
+ ret = ret.replace(')', ')}')
129
+ ret = ret.replace('v0', 'v_0')
130
+ ret = ret.replace('*', ' ')
131
+ c = re.compile(r"q\^-?[0-9]*")
132
+ for m in reversed(list(c.finditer(ret))):
133
+ ret = ret[:m.start() + 2] + '{' + ret[m.start() + 2:m.end()] + '}' + ret[m.end():]
134
+ return ret
135
+
136
+ def __reduce__(self):
137
+ """
138
+ Used in pickling.
139
+
140
+ EXAMPLES::
141
+
142
+ sage: Q = QuantumGroup(['G',2])
143
+ sage: x = Q.an_element()
144
+ sage: loads(dumps(x)) == x
145
+ True
146
+ """
147
+ data = self._libgap.ExtRepOfObj()
148
+ R = self.base_ring()
149
+ ret = []
150
+ for i in range(len(data) // 2):
151
+ ret.append(data[2 * i].sage())
152
+ ret.append(R(str(data[2 * i + 1])))
153
+ return (_unpickle_generic_element, (self.parent(), ret))
154
+
155
+ def __hash__(self):
156
+ r"""
157
+ Return the hash of ``self``.
158
+
159
+ EXAMPLES::
160
+
161
+ sage: Q = QuantumGroup(['B',3])
162
+ sage: x = Q.an_element()
163
+ sage: hash(x) == hash(x.gap())
164
+ True
165
+ """
166
+ return hash(self._libgap)
167
+
168
+ def _richcmp_(self, other, op):
169
+ """
170
+ Rich comparison of ``self`` and ``other`` by ``op``.
171
+
172
+ EXAMPLES::
173
+
174
+ sage: Q = QuantumGroup(['A',2])
175
+ sage: x = Q.an_element()
176
+ sage: F1, F12, F2 = Q.F()
177
+ sage: q = Q.q()
178
+ sage: x == F1
179
+ False
180
+ sage: x != F1
181
+ True
182
+ sage: F2 * F1
183
+ (q)*F[a1]*F[a2] + F[a1+a2]
184
+ sage: F2 * F1 == q * F1 * F2 + F12
185
+ True
186
+ """
187
+ return richcmp(self._libgap, other._libgap, op)
188
+
189
+ def gap(self):
190
+ r"""
191
+ Return the gap representation of ``self``.
192
+
193
+ EXAMPLES::
194
+
195
+ sage: Q = QuantumGroup(['B',3])
196
+ sage: x = Q.an_element()
197
+ sage: x.gap()
198
+ 1+(q)*F1+E1+(q^4-1-q^-4+q^-8)*[ K1 ; 2 ]+K1+(-q^-2+q^-6)*K1[ K1 ; 1 ]
199
+ """
200
+ return self._libgap
201
+
202
+ _libgap_ = _gap_ = gap
203
+
204
+ def _add_(self, other):
205
+ r"""
206
+ Add ``self`` and ``other``.
207
+
208
+ EXAMPLES::
209
+
210
+ sage: Q = QuantumGroup(['G',2])
211
+ sage: F1, F2 = Q.F_simple()
212
+ sage: F1 * F2 + F2 * F1
213
+ (q^3 + 1)*F[a1]*F[a2] + F[a1+a2]
214
+ """
215
+ return self.__class__(self.parent(), self._libgap + other._libgap)
216
+
217
+ def _sub_(self, other):
218
+ r"""
219
+ Subtract ``self`` and ``other``.
220
+
221
+ EXAMPLES::
222
+
223
+ sage: Q = QuantumGroup(['G',2])
224
+ sage: F1, F2 = Q.F_simple()
225
+ sage: F1 * F2 - F2 * F1
226
+ (-q^3 + 1)*F[a1]*F[a2] + (-1)*F[a1+a2]
227
+ """
228
+ return self.__class__(self.parent(), self._libgap - other._libgap)
229
+
230
+ def _acted_upon_(self, scalar, self_on_left=True):
231
+ r"""
232
+ Return the action of ``scalar`` on ``self``.
233
+
234
+ EXAMPLES::
235
+
236
+ sage: Q = QuantumGroup(['B',2])
237
+ sage: q = Q.q()
238
+ sage: x = Q.one().f_tilde([1,2,1,1,2,2]); x
239
+ F[a1+a2]^(3)
240
+ sage: 3 * x
241
+ (3)*F[a1+a2]^(3)
242
+ sage: x * (5/3)
243
+ (5/3)*F[a1+a2]^(3)
244
+ sage: q^-10 * x
245
+ (q^-10)*F[a1+a2]^(3)
246
+ sage: (1 + q^2 - q^-1) * x
247
+ (q^2 + 1-q^-1)*F[a1+a2]^(3)
248
+ """
249
+ try:
250
+ scalar = self.parent().base_ring()(scalar)
251
+ scalar = scalar.subs(q=self.parent()._libgap_q)
252
+ except (TypeError, ValueError):
253
+ return None
254
+ return self.__class__(self.parent(), self._libgap * libgap(scalar))
255
+
256
+ def e_tilde(self, i):
257
+ r"""
258
+ Return the action of the Kashiwara operator
259
+ `\widetilde{e}_i` on ``self``.
260
+
261
+ INPUT:
262
+
263
+ - ``i`` -- an element of the index set or a list to
264
+ perform a string of operators
265
+
266
+ EXAMPLES::
267
+
268
+ sage: Q = QuantumGroup(['B',2])
269
+ sage: x = Q.one().f_tilde([1,2,1,1,2,2])
270
+ sage: x.e_tilde([2,2,1,2])
271
+ F[a1]^(2)
272
+ """
273
+ # Do not override this method, instead implement _et
274
+ if isinstance(i, (list, tuple)):
275
+ ret = self
276
+ for j in i:
277
+ if not ret: # ret == 0
278
+ return ret
279
+ ret = ret._et(j)
280
+ return ret
281
+ return self._et(i)
282
+
283
+ def f_tilde(self, i):
284
+ r"""
285
+ Return the action of the Kashiwara operator
286
+ `\widetilde{f}_i` on ``self``.
287
+
288
+ INPUT:
289
+
290
+ - ``i`` -- an element of the index set or a list to
291
+ perform a string of operators
292
+
293
+ EXAMPLES::
294
+
295
+ sage: Q = QuantumGroup(['B',2])
296
+ sage: Q.one().f_tilde(1)
297
+ F[a1]
298
+ sage: Q.one().f_tilde(2)
299
+ F[a2]
300
+ sage: Q.one().f_tilde([1,2,1,1,2])
301
+ F[a1]*F[a1+a2]^(2)
302
+ """
303
+ # Do not override this method, instead implement _ft
304
+ if isinstance(i, (list, tuple)):
305
+ ret = self
306
+ for j in i:
307
+ if not ret: # ret == 0
308
+ return ret
309
+ ret = ret._ft(j)
310
+ return ret
311
+ return self._ft(i)
312
+
313
+
314
+ class QuantumGroup(UniqueRepresentation, Parent):
315
+ r"""
316
+ A Drinfel'd-Jimbo quantum group (implemented using the optional GAP
317
+ package ``QuaGroup``).
318
+
319
+ EXAMPLES:
320
+
321
+ We check the quantum Serre relations. We first we import the
322
+ `q`-binomial using the `q`-int for quantum groups::
323
+
324
+ sage: from sage.algebras.quantum_groups.q_numbers import q_binomial
325
+
326
+ We verify the Serre relations for type `A_2`::
327
+
328
+ sage: Q = algebras.QuantumGroup(['A',2])
329
+ sage: F1,F12,F2 = Q.F()
330
+ sage: q = Q.q()
331
+ sage: F1^2*F2 - q_binomial(2,1,q) * F1*F2*F1 + F2*F1^2
332
+ 0
333
+
334
+ We verify the Serre relations for type `B_2`::
335
+
336
+ sage: Q = algebras.QuantumGroup(['B',2])
337
+ sage: F1, F12, F122, F2 = Q.F()
338
+ sage: F1^2*F2 - q_binomial(2,1,q^2) * F1*F2*F1 + F2*F1^2
339
+ 0
340
+ sage: (F2^3*F1 - q_binomial(3,1,q) * F2^2*F1*F2
341
+ ....: + q_binomial(3,2,q) * F2*F1*F2^2 - F1*F2^3)
342
+ 0
343
+
344
+ REFERENCES:
345
+
346
+ - :wikipedia:`Quantum_group`
347
+ """
348
+ @staticmethod
349
+ def __classcall_private__(cls, cartan_type, q=None):
350
+ """
351
+ Initialize ``self``.
352
+
353
+ TESTS::
354
+
355
+ sage: Q = QuantumGroup(['A',2])
356
+ sage: Q is QuantumGroup('A2', None)
357
+ True
358
+ """
359
+ cartan_type = CartanType(cartan_type)
360
+ return super().__classcall__(cls, cartan_type, q)
361
+
362
+ def __init__(self, cartan_type, q):
363
+ """
364
+ Initialize ``self``.
365
+
366
+ TESTS::
367
+
368
+ sage: Q = QuantumGroup(['A',2])
369
+ sage: TestSuite(Q).run() # long time
370
+
371
+ sage: Q = QuantumGroup(['G',2])
372
+ sage: TestSuite(Q).run() # long time
373
+ """
374
+ self._cartan_type = cartan_type
375
+ GapPackage("QuaGroup", spkg='gap_package_quagroup').require()
376
+ libgap.LoadPackage('QuaGroup')
377
+ R = libgap.eval('RootSystem("%s",%s)' % (cartan_type.type(), cartan_type.rank()))
378
+ Q = self._cartan_type.root_system().root_lattice()
379
+ I = cartan_type.index_set()
380
+ self._pos_roots = [Q.sum_of_terms([(ii, root[i])
381
+ for i, ii in enumerate(I)
382
+ if root[i] != 0])
383
+ for root in R.PositiveRootsInConvexOrder().sage()]
384
+ if q is None:
385
+ self._libgap = R.QuantizedUEA()
386
+ self._libgap_q = libgap.eval('_q')
387
+ self._libgap_base = libgap.eval('QuantumField')
388
+ base_field = QQ['q'].fraction_field()
389
+ q = base_field.gen()
390
+ else:
391
+ base_field = q.parent()
392
+ self._libgap = R.QuantizedUEA(base_field, q)
393
+ self._libgap_base = libgap(base_field)
394
+ self._libgap_q = libgap(q)
395
+ self._q = q
396
+ Parent.__init__(self, base=base_field, category=HopfAlgebras(Fields()))
397
+
398
+ def _repr_(self):
399
+ """
400
+ Return a string representation of ``self``.
401
+
402
+ EXAMPLES::
403
+
404
+ sage: QuantumGroup(['A',2])
405
+ Quantum Group of type ['A', 2] with q=q
406
+ """
407
+ return "Quantum Group of type {} with q={}".format(self._cartan_type, self._q)
408
+
409
+ def _latex_(self):
410
+ r"""
411
+ Return a latex representation of ``self``.
412
+
413
+ EXAMPLES::
414
+
415
+ sage: latex(QuantumGroup(['A',3]))
416
+ U_{q}(A_{3})
417
+ sage: zeta3 = CyclotomicField(3).gen()
418
+ sage: latex(QuantumGroup(['G',2], q=zeta3))
419
+ U_{\zeta_{3}}(G_2)
420
+ """
421
+ from sage.misc.latex import latex
422
+ return "U_{%s}(%s)" % (latex(self._q), latex(self._cartan_type))
423
+
424
+ def gap(self):
425
+ """
426
+ Return the gap representation of ``self``.
427
+
428
+ EXAMPLES::
429
+
430
+ sage: Q = QuantumGroup(['A',2])
431
+ sage: Q.gap()
432
+ QuantumUEA( <root system of type A2>, Qpar = q )
433
+ """
434
+ return self._libgap
435
+
436
+ _libgap_ = _gap_ = gap
437
+
438
+ def cartan_type(self):
439
+ """
440
+ Return the Cartan type of ``self``.
441
+
442
+ EXAMPLES::
443
+
444
+ sage: Q = QuantumGroup(['A',2])
445
+ sage: Q.cartan_type()
446
+ ['A', 2]
447
+ """
448
+ return self._cartan_type
449
+
450
+ def _element_constructor_(self, elt):
451
+ """
452
+ Construct an element of ``self`` from ``elt``.
453
+
454
+ EXAMPLES::
455
+
456
+ sage: Q = QuantumGroup(['A',2])
457
+ sage: Q(0)
458
+ 0
459
+ sage: Q(4)
460
+ (4)*1
461
+ sage: Q(4).parent() is Q
462
+ True
463
+ sage: Q(Q.q()).parent() is Q
464
+ True
465
+ sage: Q(Q.an_element()) == Q.an_element()
466
+ True
467
+ """
468
+ if not elt:
469
+ return self.zero()
470
+ if elt in self.base_ring():
471
+ return elt * self.one()
472
+ return self.element_class(self, elt)
473
+
474
+ # Special elements
475
+ # ----------------
476
+
477
+ @cached_method
478
+ def one(self):
479
+ """
480
+ Return the multiplicative identity of ``self``.
481
+
482
+ EXAMPLES::
483
+
484
+ sage: Q = QuantumGroup(['A',2])
485
+ sage: Q.one()
486
+ 1
487
+ """
488
+ return self.element_class(self, self._libgap.One())
489
+
490
+ @cached_method
491
+ def zero(self):
492
+ """
493
+ Return the multiplicative identity of ``self``.
494
+
495
+ EXAMPLES::
496
+
497
+ sage: Q = QuantumGroup(['A',2])
498
+ sage: Q.zero()
499
+ 0
500
+ """
501
+ return self.element_class(self, self._libgap.ZeroImmutable())
502
+
503
+ @cached_method
504
+ def gens(self) -> tuple:
505
+ """
506
+ Return the generators of ``self``.
507
+
508
+ EXAMPLES::
509
+
510
+ sage: Q = QuantumGroup(['A',2])
511
+ sage: Q.gens()
512
+ (F[a1], F[a1+a2], F[a2],
513
+ K1, (-q + q^-1)*[ K1 ; 1 ] + K1,
514
+ K2, (-q + q^-1)*[ K2 ; 1 ] + K2,
515
+ E[a1], E[a1+a2], E[a2])
516
+ """
517
+ return tuple([self.element_class(self, gen)
518
+ for gen in self._libgap.GeneratorsOfAlgebra()])
519
+
520
+ def E(self):
521
+ r"""
522
+ Return the family of generators `\{E_{\alpha}\}_{\alpha \in \Phi}`,
523
+ where `\Phi` is the root system of ``self``.
524
+
525
+ EXAMPLES::
526
+
527
+ sage: Q = QuantumGroup(['B',2])
528
+ sage: list(Q.E())
529
+ [E[a1], E[a1+a2], E[a1+2*a2], E[a2]]
530
+ """
531
+ N = len(self._pos_roots) + len(self._cartan_type.index_set()) * 2
532
+ d = {al: self.gens()[N + i] for i, al in enumerate(self._pos_roots)}
533
+ return Family(self._pos_roots, d.__getitem__)
534
+
535
+ def E_simple(self):
536
+ r"""
537
+ Return the family of generators `\{E_i := E_{\alpha_i}\}_{i \in I}`.
538
+
539
+ EXAMPLES::
540
+
541
+ sage: Q = QuantumGroup(['B',2])
542
+ sage: Q.E_simple()
543
+ Finite family {1: E[a1], 2: E[a2]}
544
+ """
545
+ I = self._cartan_type.index_set()
546
+ gens = self.algebra_generators()
547
+ d = {i: gens['E%s' % i] for i in I}
548
+ return Family(I, d.__getitem__)
549
+
550
+ def F(self):
551
+ r"""
552
+ Return the family of generators `\{F_{\alpha}\}_{\alpha \in \Phi}`,
553
+ where `\Phi` is the root system of ``self``.
554
+
555
+ EXAMPLES::
556
+
557
+ sage: Q = QuantumGroup(['G',2])
558
+ sage: list(Q.F())
559
+ [F[a1], F[3*a1+a2], F[2*a1+a2], F[3*a1+2*a2], F[a1+a2], F[a2]]
560
+ """
561
+ d = {al: self.gens()[i] for i, al in enumerate(self._pos_roots)}
562
+ return Family(self._pos_roots, d.__getitem__)
563
+
564
+ def F_simple(self):
565
+ r"""
566
+ Return the family of generators `\{F_i := F_{\alpha_i}\}_{i \in I}`.
567
+
568
+ EXAMPLES::
569
+
570
+ sage: Q = QuantumGroup(['G',2])
571
+ sage: Q.F_simple()
572
+ Finite family {1: F[a1], 2: F[a2]}
573
+ """
574
+ I = self._cartan_type.index_set()
575
+ gens = self.algebra_generators()
576
+ d = {i: gens['F%s' % i] for i in I}
577
+ return Family(I, d.__getitem__)
578
+
579
+ def K(self):
580
+ r"""
581
+ Return the family of generators `\{K_i\}_{i \in I}`.
582
+
583
+ EXAMPLES::
584
+
585
+ sage: Q = QuantumGroup(['A',3])
586
+ sage: Q.K()
587
+ Finite family {1: K1, 2: K2, 3: K3}
588
+ sage: Q.K_inverse()
589
+ Finite family {1: (-q + q^-1)*[ K1 ; 1 ] + K1,
590
+ 2: (-q + q^-1)*[ K2 ; 1 ] + K2,
591
+ 3: (-q + q^-1)*[ K3 ; 1 ] + K3}
592
+ """
593
+ N = len(self._pos_roots)
594
+ I = self._cartan_type.index_set()
595
+ d = {ii: self.gens()[N + 2 * i] for i, ii in enumerate(I)}
596
+ return Family(I, d.__getitem__)
597
+
598
+ def K_inverse(self):
599
+ r"""
600
+ Return the family of generators `\{K_i^{-1}\}_{i \in I}`.
601
+
602
+ EXAMPLES::
603
+
604
+ sage: Q = QuantumGroup(['A',3])
605
+ sage: Q.K_inverse()
606
+ Finite family {1: (-q + q^-1)*[ K1 ; 1 ] + K1,
607
+ 2: (-q + q^-1)*[ K2 ; 1 ] + K2,
608
+ 3: (-q + q^-1)*[ K3 ; 1 ] + K3}
609
+ """
610
+ N = len(self._pos_roots)
611
+ I = self._cartan_type.index_set()
612
+ d = {ii: self.gens()[N + 2 * i + 1] for i, ii in enumerate(I)}
613
+ return Family(I, d.__getitem__)
614
+
615
+ @cached_method
616
+ def algebra_generators(self):
617
+ """
618
+ Return the algebra generators of ``self``.
619
+
620
+ EXAMPLES::
621
+
622
+ sage: Q = QuantumGroup(['A',2])
623
+ sage: list(Q.algebra_generators())
624
+ [F[a1], F[a2],
625
+ K1, K2,
626
+ (-q + q^-1)*[ K1 ; 1 ] + K1, (-q + q^-1)*[ K2 ; 1 ] + K2,
627
+ E[a1], E[a2]]
628
+ """
629
+ I = self._cartan_type.index_set()
630
+ simples = self._cartan_type.root_system().root_lattice().simple_roots()
631
+ ret = {}
632
+ for i, al in enumerate(simples):
633
+ ii = I[i]
634
+ ret['F%s' % ii] = self.F()[al]
635
+ ret['K%s' % ii] = self.K()[ii]
636
+ ret['Ki%s' % ii] = self.K_inverse()[ii]
637
+ ret['E%s' % ii] = self.E()[al]
638
+ keys = (['F%s' % i for i in I] + ['K%s' % i for i in I]
639
+ + ['Ki%s' % i for i in I] + ['E%s' % i for i in I])
640
+ return Family(keys, ret.__getitem__)
641
+
642
+ def _an_element_(self):
643
+ """
644
+ Return an element of ``self``.
645
+
646
+ EXAMPLES::
647
+
648
+ sage: Q = QuantumGroup(['A',2])
649
+ sage: Q.an_element()
650
+ 1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ]
651
+ + K1 + (-q^-1 + q^-3)*K1[ K1 ; 1 ]
652
+ """
653
+ i = self._cartan_type.index_set()[0]
654
+ al = self._cartan_type.root_system().root_lattice().simple_root(i)
655
+ return self.E()[al] + self.K()[i] + self.K_inverse()[i]**2 + self.q()*self.F()[al]
656
+
657
+ def some_elements(self):
658
+ """
659
+ Return some elements of ``self``.
660
+
661
+ EXAMPLES::
662
+
663
+ sage: Q = QuantumGroup(['A',1])
664
+ sage: Q.some_elements()
665
+ [1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ]
666
+ + K1 + (-q^-1 + q^-3)*K1[ K1 ; 1 ],
667
+ K1, F[a1], E[a1]]
668
+ """
669
+ return ([self.an_element()] + list(self.K())
670
+ + list(self.F_simple()) + list(self.E_simple()))
671
+
672
+ def q(self):
673
+ """
674
+ Return the parameter `q`.
675
+
676
+ EXAMPLES::
677
+
678
+ sage: Q = QuantumGroup(['A',3])
679
+ sage: Q.q()
680
+ q
681
+ sage: zeta3 = CyclotomicField(3).gen()
682
+ sage: Q = QuantumGroup(['B',2], q=zeta3)
683
+ sage: Q.q()
684
+ zeta3
685
+ """
686
+ return self._q
687
+
688
+ # Misc
689
+ # ----
690
+
691
+ def _Hom_(self, Y, category):
692
+ """
693
+ Return the highest weight module of weight ``weight`` of ``self``.
694
+
695
+ EXAMPLES::
696
+
697
+ sage: Q = QuantumGroup(['A',2])
698
+ sage: B = Q.lower_half()
699
+ sage: H = Hom(Q, B); H
700
+ Set of Morphisms from Quantum Group of type ['A', 2] with q=q to
701
+ Lower Half of Quantum Group of type ['A', 2] with q=q in Category of rings
702
+ sage: type(H)
703
+ <class '...QuantumGroupHomset_with_category_with_equality_by_id'>
704
+ """
705
+ if category is not None and not category.is_subcategory(Rings()):
706
+ raise TypeError("%s is not a subcategory of Rings()" % category)
707
+ if Y not in Rings():
708
+ raise TypeError("%s is not a ring" % Y)
709
+ return QuantumGroupHomset(self, Y, category=category)
710
+
711
+ def highest_weight_module(self, weight):
712
+ """
713
+ Return the highest weight module of weight ``weight`` of ``self``.
714
+
715
+ EXAMPLES::
716
+
717
+ sage: Q = QuantumGroup(['A',2])
718
+ sage: Q.highest_weight_module([1,3])
719
+ Highest weight module of weight Lambda[1] + 3*Lambda[2] of
720
+ Quantum Group of type ['A', 2] with q=q
721
+ """
722
+ return HighestWeightModule(self, weight)
723
+
724
+ def lower_half(self):
725
+ """
726
+ Return the lower half of the quantum group ``self``.
727
+
728
+ EXAMPLES::
729
+
730
+ sage: Q = QuantumGroup(['A',2])
731
+ sage: Q.lower_half()
732
+ Lower Half of Quantum Group of type ['A', 2] with q=q
733
+ """
734
+ return LowerHalfQuantumGroup(self)
735
+
736
+ # Hopf structure
737
+ # --------------
738
+
739
+ def coproduct(self, elt, n=1):
740
+ r"""
741
+ Return the coproduct of ``elt`` (iterated ``n`` times).
742
+
743
+ The comultiplication `\Delta \colon U_q(\mathfrak{g}) \to
744
+ U_q(\mathfrak{g}) \otimes U_q(\mathfrak{g})` is defined by
745
+
746
+ .. MATH::
747
+
748
+ \begin{aligned}
749
+ \Delta(E_i) &= E_i \otimes 1 + K_i \otimes E_i, \\
750
+ \Delta(F_i) &= F_i \otimes K_i^{-1} + 1 \otimes F_i, \\
751
+ \Delta(K_i) &= K_i \otimes K_i.
752
+ \end{aligned}
753
+
754
+ EXAMPLES::
755
+
756
+ sage: Q = QuantumGroup(['B',2])
757
+ sage: [Q.coproduct(e) for e in Q.E()]
758
+ [1*(E[a1]<x>1) + 1*(K1<x>E[a1]),
759
+ 1*(E[a1+a2]<x>1) + 1*(K1*K2<x>E[a1+a2]) + q^2-q^-2*(K2*E[a1]<x>E[a2]),
760
+ q^4-q^2-1 + q^-2*(E[a1]<x>E[a2]^(2)) + 1*(E[a1+2*a2]<x>1)
761
+ + 1*(K1<x>E[a1+2*a2]) + q-q^-1*(K1*K2[ K2 ; 1 ]<x>E[a1+2*a2])
762
+ + q-q^-1*(K2*E[a1+a2]<x>E[a2]) + q^5-2*q^3
763
+ + 2*q^-1-q^-3*(K2[ K2 ; 1 ]*E[a1]<x>E[a2]^(2)),
764
+ 1*(E[a2]<x>1) + 1*(K2<x>E[a2])]
765
+ sage: [Q.coproduct(f, 2) for f in Q.F_simple()]
766
+ [1*(1<x>1<x>F[a1]) + -q^2 + q^-2*(1<x>F[a1]<x>[ K1 ; 1 ])
767
+ + 1*(1<x>F[a1]<x>K1) + q^4-2 + q^-4*(F[a1]<x>[ K1 ; 1 ]<x>[ K1 ; 1 ])
768
+ + -q^2 + q^-2*(F[a1]<x>[ K1 ; 1 ]<x>K1) + -q^2
769
+ + q^-2*(F[a1]<x>K1<x>[ K1 ; 1 ]) + 1*(F[a1]<x>K1<x>K1),
770
+ 1*(1<x>1<x>F[a2]) + -q + q^-1*(1<x>F[a2]<x>[ K2 ; 1 ])
771
+ + 1*(1<x>F[a2]<x>K2) + q^2-2 + q^-2*(F[a2]<x>[ K2 ; 1 ]<x>[ K2 ; 1 ])
772
+ + -q + q^-1*(F[a2]<x>[ K2 ; 1 ]<x>K2) + -q
773
+ + q^-1*(F[a2]<x>K2<x>[ K2 ; 1 ]) + 1*(F[a2]<x>K2<x>K2)]
774
+ """
775
+ D = self._libgap.ComultiplicationMap(n+1)
776
+ # TODO: This is not the correct parent. Need to create it.
777
+ return self.element_class(self, libgap.Image(D, elt._libgap))
778
+
779
+ def antipode(self, elt):
780
+ r"""
781
+ Return the antipode of ``elt``.
782
+
783
+ The antipode `S \colon U_q(\mathfrak{g}) \to U_q(\mathfrak{g})`
784
+ is the anti-automorphism defined by
785
+
786
+ .. MATH::
787
+
788
+ S(E_i) = -K_i^{-1}E_i, \qquad
789
+ S(F_i) = -F_iK_i, \qquad
790
+ S(K_i) = K_i^{-1}.
791
+
792
+ EXAMPLES::
793
+
794
+ sage: Q = QuantumGroup(['B',2])
795
+ sage: [Q.antipode(f) for f in Q.F()]
796
+ [(-1)*F[a1]*K1,
797
+ (-q^6 + q^2)*F[a1]*F[a2]*K1*K2 + (-q^4)*F[a1+a2]*K1*K2,
798
+ (-q^8 + q^6 + q^4-q^2)*F[a1]*F[a2]^(2)*K1
799
+ + (-q^9 + 2*q^7-2*q^3 + q)*F[a1]*F[a2]^(2)*K1*K2[ K2 ; 1 ]
800
+ + (-q^5 + q^3)*F[a1+a2]*F[a2]*K1
801
+ + (-q^6 + 2*q^4-q^2)*F[a1+a2]*F[a2]*K1*K2[ K2 ; 1 ]
802
+ + (-q^4)*F[a1+2*a2]*K1 + (-q^5 + q^3)*F[a1+2*a2]*K1*K2[ K2 ; 1 ],
803
+ (-1)*F[a2]*K2]
804
+ """
805
+ S = self._libgap.AntipodeMap()
806
+ return self.element_class(self, libgap.Image(S, elt._libgap))
807
+
808
+ def counit(self, elt):
809
+ r"""
810
+ Return the counit of ``elt``.
811
+
812
+ The counit `\varepsilon \colon U_q(\mathfrak{g}) \to \QQ(q)` is
813
+ defined by
814
+
815
+ .. MATH::
816
+
817
+ \varepsilon(E_i) = \varepsilon(F_i) = 0, \qquad
818
+ \varepsilon(K_i) = 1.
819
+
820
+ EXAMPLES::
821
+
822
+ sage: Q = QuantumGroup(['B',2])
823
+ sage: x = Q.an_element()^2
824
+ sage: Q.counit(x)
825
+ 4
826
+ sage: Q.counit(Q.one())
827
+ 1
828
+ sage: Q.counit(Q.zero())
829
+ 0
830
+ """
831
+ # We need to extract the constant coefficient because the
832
+ # counit in QuaGroup doesn't support it
833
+ R = self.base_ring()
834
+ ext_rep = list(elt._libgap.ExtRepOfObj())
835
+ constant = R.zero()
836
+ for i in range(len(ext_rep) // 2):
837
+ if ext_rep[2 * i].Length() == 0:
838
+ ext_rep.pop(2 * i) # Pop the key
839
+ constant = R(str(ext_rep.pop(2 * i))) # Pop the coefficient
840
+ break
841
+ # To reconstruct, we need the following
842
+ F = self._libgap.FamilyObj().ElementsFamily()
843
+ elt = F.ObjByExtRep(ext_rep)
844
+ co = self._libgap.CounitMap()
845
+ return R(str(co(elt))) + constant
846
+
847
+ class Element(QuaGroupModuleElement):
848
+ def _mul_(self, other):
849
+ r"""
850
+ Multiply ``self`` and ``other``.
851
+
852
+ EXAMPLES::
853
+
854
+ sage: Q = QuantumGroup(['G',2])
855
+ sage: F1, F2 = Q.F_simple()
856
+ sage: F1 * F2 * F1 * F2
857
+ F[a1]*F[a1+a2]*F[a2] + (q^7 + q^5 + q + q^-1)*F[a1]^(2)*F[a2]^(2)
858
+ sage: E1, E2 = Q.E_simple()
859
+ sage: F1 * E1
860
+ F[a1]*E[a1]
861
+ sage: E1 * F1
862
+ F[a1]*E[a1] + [ K1 ; 1 ]
863
+ """
864
+ return self.__class__(self.parent(), self._libgap * other._libgap)
865
+
866
+ def bar(self):
867
+ r"""
868
+ Return the bar involution on ``self``.
869
+
870
+ The bar involution is defined by
871
+
872
+ .. MATH::
873
+
874
+ \overline{E_i} = E_i, \qquad\qquad
875
+ \overline{F_i} = F_i, \qquad\qquad
876
+ \overline{K_i} = K_i^{-1}.
877
+
878
+ EXAMPLES::
879
+
880
+ sage: Q = QuantumGroup(['A',2])
881
+ sage: [gen.bar() for gen in Q.gens()]
882
+ [F[a1],
883
+ (q-q^-1)*F[a1]*F[a2] + F[a1+a2],
884
+ F[a2],
885
+ (-q + q^-1)*[ K1 ; 1 ] + K1, K1,
886
+ (-q + q^-1)*[ K2 ; 1 ] + K2, K2,
887
+ E[a1],
888
+ (-q^2 + 1)*E[a1]*E[a2] + (q^2)*E[a1+a2],
889
+ E[a2]]
890
+ """
891
+ bar = self.parent()._libgap.BarAutomorphism()
892
+ return self.__class__(self.parent(), libgap.Image(bar, self._libgap))
893
+
894
+ def omega(self):
895
+ r"""
896
+ Return the action of the `\omega` automorphism on ``self``.
897
+
898
+ The `\omega` automorphism is defined by
899
+
900
+ .. MATH::
901
+
902
+ \omega(E_i) = F_i, \qquad\qquad
903
+ \omega(F_i) = E_i, \qquad\qquad
904
+ \omega(K_i) = K_i^{-1}.
905
+
906
+ EXAMPLES::
907
+
908
+ sage: Q = QuantumGroup(['A',2])
909
+ sage: [gen.omega() for gen in Q.gens()]
910
+ [E[a1],
911
+ (-q)*E[a1+a2],
912
+ E[a2],
913
+ (-q + q^-1)*[ K1 ; 1 ] + K1,
914
+ K1,
915
+ (-q + q^-1)*[ K2 ; 1 ] + K2,
916
+ K2,
917
+ F[a1],
918
+ (-q^-1)*F[a1+a2],
919
+ F[a2]]
920
+ """
921
+ omega = self.parent()._libgap.AutomorphismOmega()
922
+ return self.__class__(self.parent(), libgap.Image(omega, self._libgap))
923
+
924
+ def tau(self):
925
+ r"""
926
+ Return the action of the `\tau` anti-automorphism on ``self``.
927
+
928
+ The `\tau` anti-automorphism is defined by
929
+
930
+ .. MATH::
931
+
932
+ \tau(E_i) = E_i, \qquad\qquad
933
+ \tau(F_i) = F_i, \qquad\qquad
934
+ \tau(K_i) = K_i^{-1}.
935
+
936
+ EXAMPLES::
937
+
938
+ sage: Q = QuantumGroup(['A',2])
939
+ sage: [gen.tau() for gen in Q.gens()]
940
+ [F[a1],
941
+ (-q^2 + 1)*F[a1]*F[a2] + (-q)*F[a1+a2],
942
+ F[a2],
943
+ (-q + q^-1)*[ K1 ; 1 ] + K1,
944
+ K1,
945
+ (-q + q^-1)*[ K2 ; 1 ] + K2,
946
+ K2,
947
+ E[a1],
948
+ (q-q^-1)*E[a1]*E[a2] + (-q)*E[a1+a2],
949
+ E[a2]]
950
+ """
951
+ tau = self.parent()._libgap.AntiAutomorphismTau()
952
+ return self.__class__(self.parent(), libgap.Image(tau, self._libgap))
953
+
954
+ def braid_group_action(self, braid):
955
+ r"""
956
+ Return the action of the braid group element ``braid``.
957
+
958
+ The braid group operator `T_i \colon U_q(\mathfrak{g}) \to
959
+ U_q(\mathfrak{g})` is defined by
960
+
961
+ .. MATH::
962
+
963
+ \begin{aligned}
964
+ T_i(E_i) &= -F_iK_i, \\
965
+ T_i(E_j) &= \sum_{k=0}^{-a_{ij}} (-1)^k q_i^{-k} E_i^{(-a_{ij}-k)} E_j E_i^{(k)} \text{ if } i \neq j,\\
966
+ T_i(K_j) &= K_jK_i^{a_{ij}}, \\
967
+ T_i(F_i) &= -K_i^{-1}E_i, \\
968
+ T_i(F_j) &= \sum_{k=0}^{-a_{ij}} (-1)^k q_i^{-k} F_i^{(k)} F_j F_i^{(-a_{ij}-k)} \text{ if } i \neq j,
969
+ \end{aligned}
970
+
971
+ where `a_{ij} = \langle \alpha_j, \alpha_i^\vee \rangle` is the
972
+ `(i,j)`-entry of the Cartan matrix associated to `\mathfrak{g}`.
973
+
974
+ INPUT:
975
+
976
+ - ``braid`` -- a reduced word of a braid group element
977
+
978
+ EXAMPLES::
979
+
980
+ sage: Q = QuantumGroup(['A',2])
981
+ sage: F1 = Q.F_simple()[1]
982
+ sage: F1.braid_group_action([1])
983
+ (q-q^-1)*[ K1 ; 1 ]*E[a1] + (-1)*K1*E[a1]
984
+ sage: F1.braid_group_action([1,2])
985
+ F[a2]
986
+ sage: F1.braid_group_action([2,1])
987
+ (-q^3 + 3*q-3*q^-1 + q^-3)*[ K1 ; 1 ]*[ K2 ; 1 ]*E[a1]*E[a2]
988
+ + (q^3-2*q + q^-1)*[ K1 ; 1 ]*[ K2 ; 1 ]*E[a1+a2]
989
+ + (q^2-2 + q^-2)*[ K1 ; 1 ]*K2*E[a1]*E[a2]
990
+ + (-q^2 + 1)*[ K1 ; 1 ]*K2*E[a1+a2]
991
+ + (q^2-2 + q^-2)*K1*[ K2 ; 1 ]*E[a1]*E[a2]
992
+ + (-q^2 + 1)*K1*[ K2 ; 1 ]*E[a1+a2]
993
+ + (-q + q^-1)*K1*K2*E[a1]*E[a2] + (q)*K1*K2*E[a1+a2]
994
+ sage: F1.braid_group_action([1,2,1]) == F1.braid_group_action([2,1,2])
995
+ True
996
+ sage: F1.braid_group_action([]) == F1
997
+ True
998
+ """
999
+ if not braid:
1000
+ return self
1001
+ QU = self.parent()._libgap
1002
+ tau = QU.AntiAutomorphismTau()
1003
+ ret = QU.IdentityMapping()
1004
+ for i in braid:
1005
+ if i < 0:
1006
+ i = -i
1007
+ T = QU.AutomorphismTalpha(i)
1008
+ ret *= tau * T * tau
1009
+ else:
1010
+ ret *= QU.AutomorphismTalpha(i)
1011
+ return self.__class__(self.parent(), libgap.Image(ret, self._libgap))
1012
+
1013
+ def _et(self, i):
1014
+ r"""
1015
+ Return the action of the Kashiwara operator `\widetilde{e}_i`
1016
+ on ``self``.
1017
+
1018
+ EXAMPLES::
1019
+
1020
+ sage: Q = QuantumGroup(['G',2])
1021
+ sage: [(g.e_tilde(1), g.e_tilde(2)) for g in Q.F()]
1022
+ [(1, 0), (0, F[a1]^(3)), (0, F[a1]^(2)),
1023
+ (0, F[3*a1+a2]), (0, F[a1]), (0, 1)]
1024
+
1025
+ TESTS::
1026
+
1027
+ sage: Q = QuantumGroup(['A',2])
1028
+ sage: Q.one()._et(1)
1029
+ 0
1030
+ sage: Q.zero().e_tilde(1)
1031
+ 0
1032
+ """
1033
+ if not self: # self == 0
1034
+ return self
1035
+ ret = self._libgap.Ealpha(i)
1036
+ if not ret:
1037
+ return self.parent().zero()
1038
+ return self.__class__(self.parent(), ret)
1039
+
1040
+ def _ft(self, i):
1041
+ r"""
1042
+ Return the action of the Kashiwara operator `\widetilde{f}_i`
1043
+ on ``self``.
1044
+
1045
+ EXAMPLES::
1046
+
1047
+ sage: Q = QuantumGroup(['G',2])
1048
+ sage: [(g._ft(1), g._ft(2)) for g in Q.F()]
1049
+ [(F[a1]^(2), F[a1+a2]),
1050
+ (F[a1]*F[3*a1+a2], F[3*a1+2*a2]),
1051
+ (F[a1]*F[2*a1+a2], F[a1+a2]^(2)),
1052
+ (F[a1]*F[3*a1+2*a2], F[a1+a2]^(3)),
1053
+ (F[a1]*F[a1+a2], F[a1+a2]*F[a2]),
1054
+ (F[a1]*F[a2], F[a2]^(2))]
1055
+ sage: Q.one().f_tilde([1,2,1,1,2,2])
1056
+ F[2*a1+a2]*F[a1+a2]*F[a2]
1057
+
1058
+ TESTS::
1059
+
1060
+ sage: Q = QuantumGroup(['A',2])
1061
+ sage: Q.zero().f_tilde(1)
1062
+ 0
1063
+ """
1064
+ if not self: # self == 0
1065
+ return self
1066
+ ret = self._libgap.Falpha(i)
1067
+ if not ret:
1068
+ return self.parent().zero()
1069
+ return self.__class__(self.parent(), ret)
1070
+
1071
+
1072
+ #####################################################################
1073
+ # Morphisms
1074
+
1075
+ class QuantumGroupMorphism(Morphism):
1076
+ r"""
1077
+ A morphism whose domain is a quantum group.
1078
+ """
1079
+ def __init__(self, parent, im_gens, check=True):
1080
+ r"""
1081
+ Initialize ``self``.
1082
+
1083
+ EXAMPLES::
1084
+
1085
+ sage: Q = QuantumGroup(['A',1])
1086
+ sage: F, K, Ki, E = Q.gens()
1087
+ sage: phi = Q.hom([E, Ki, K, F])
1088
+ sage: TestSuite(phi).run(skip='_test_category')
1089
+ """
1090
+ self._repr_type_str = "Quantum group homomorphism"
1091
+ Morphism.__init__(self, parent)
1092
+ Q = parent.domain()
1093
+ self._im_gens = tuple(im_gens)
1094
+ if check and len(im_gens) != len(Q.algebra_generators()):
1095
+ raise ValueError("number of images must equal the number of generators")
1096
+ self._libgap = Q._libgap.QEAHomomorphism(parent.codomain(), im_gens)
1097
+
1098
+ def __reduce__(self):
1099
+ r"""
1100
+ For pickling.
1101
+
1102
+ EXAMPLES::
1103
+
1104
+ sage: Q = QuantumGroup(['A',1])
1105
+ sage: F, K, Ki, E = Q.gens()
1106
+ sage: phi = Q.hom([E, Ki, K, F])
1107
+ sage: loads(dumps(phi)) == phi
1108
+ True
1109
+ """
1110
+ return (self.parent(), (self._im_gens,))
1111
+
1112
+ def _call_(self, val):
1113
+ r"""
1114
+ Return the image of ``val`` under ``self``.
1115
+
1116
+ EXAMPLES::
1117
+
1118
+ sage: Q = QuantumGroup(['A',1])
1119
+ sage: F, K, Ki, E = Q.gens()
1120
+ sage: phi = Q.hom([E, Ki, K, F])
1121
+ sage: phi(F)
1122
+ E[a1]
1123
+ sage: phi(E*F)
1124
+ F[a1]*E[a1]
1125
+ sage: phi(F*E)
1126
+ F[a1]*E[a1] + [ K1 ; 1 ]
1127
+ sage: phi(E*K)
1128
+ (-q + q^-1)*F[a1]*[ K1 ; 1 ] + F[a1]*K1
1129
+ sage: phi(F*E) == phi(F) * phi(E)
1130
+ True
1131
+ """
1132
+ try:
1133
+ return self.codomain()(self._libgap.ImageElm(val))
1134
+ except TypeError:
1135
+ return self.codomain()(str(self._libgap.ImageElm(val)))
1136
+
1137
+ def __richcmp__(self, other, op):
1138
+ r"""
1139
+ Rich comparison of ``self`` and ``other`` by ``op``.
1140
+
1141
+ EXAMPLES::
1142
+
1143
+ sage: Q = QuantumGroup(['A',1])
1144
+ sage: F, K, Ki, E = Q.gens()
1145
+ sage: phi = Q.hom([E, Ki, K, F])
1146
+ sage: psi = Q.hom([F, K, Ki, E])
1147
+ sage: phi == Q.hom([E, Ki, K, F])
1148
+ True
1149
+ sage: phi == psi
1150
+ False
1151
+ sage: psi != Q.hom([F, K, Ki, E])
1152
+ False
1153
+ sage: phi != psi
1154
+ True
1155
+
1156
+ sage: QB = QuantumGroup(['B',3])
1157
+ sage: QC = QuantumGroup(['C',3])
1158
+ sage: x = ZZ.one()
1159
+ sage: phi = QB.hom([x]*len(QB.algebra_generators()))
1160
+ sage: psi = QC.hom([x]*len(QC.algebra_generators()))
1161
+ sage: phi.im_gens() == psi.im_gens()
1162
+ True
1163
+ sage: phi == psi
1164
+ False
1165
+ """
1166
+ if op == op_EQ:
1167
+ return (type(self) is type(other)
1168
+ and self.domain() is other.domain()
1169
+ and self._im_gens == other._im_gens)
1170
+ if op == op_NE:
1171
+ return not (self == other)
1172
+ return NotImplemented
1173
+
1174
+ def im_gens(self):
1175
+ r"""
1176
+ Return the image of the generators under ``self``.
1177
+
1178
+ EXAMPLES::
1179
+
1180
+ sage: Q = QuantumGroup(['A',1])
1181
+ sage: F, K, Ki, E = Q.gens()
1182
+ sage: phi = Q.hom([E, Ki, K, F])
1183
+ sage: phi.im_gens()
1184
+ (E[a1], (-q + q^-1)*[ K1 ; 1 ] + K1, K1, F[a1])
1185
+ """
1186
+ return self._im_gens
1187
+
1188
+ def _repr_defn(self):
1189
+ r"""
1190
+ Used in constructing the string representation of ``self``.
1191
+
1192
+ EXAMPLES::
1193
+
1194
+ sage: Q = QuantumGroup(['A',1])
1195
+ sage: F, K, Ki, E = Q.gens()
1196
+ sage: phi = Q.hom([E, Ki, K, F])
1197
+ sage: print(phi._repr_defn())
1198
+ F[a1] |--> E[a1]
1199
+ K1 |--> (-q + q^-1)*[ K1 ; 1 ] + K1
1200
+ (-q + q^-1)*[ K1 ; 1 ] + K1 |--> K1
1201
+ E[a1] |--> F[a1]
1202
+ """
1203
+ return '\n'.join('%s |--> %s' % (gen, self._im_gens[i])
1204
+ for i, gen in enumerate(self.domain().algebra_generators()))
1205
+
1206
+
1207
+ class QuantumGroupHomset(HomsetWithBase):
1208
+ r"""
1209
+ The homset whose domain is a quantum group.
1210
+ """
1211
+ def __call__(self, im_gens, check=True):
1212
+ r"""
1213
+ Construct an element of ``self``.
1214
+
1215
+ EXAMPLES::
1216
+
1217
+ sage: Q = QuantumGroup(['A',1])
1218
+ sage: H = Hom(Q, Q)
1219
+ sage: F, K, Ki, E = Q.gens()
1220
+ sage: phi = H([E, Ki, K, F]); phi
1221
+ Quantum group homomorphism endomorphism of Quantum Group of type ['A', 1] with q=q
1222
+ Defn: F[a1] |--> E[a1]
1223
+ K1 |--> (-q + q^-1)*[ K1 ; 1 ] + K1
1224
+ (-q + q^-1)*[ K1 ; 1 ] + K1 |--> K1
1225
+ E[a1] |--> F[a1]
1226
+ sage: H(phi) == phi
1227
+ True
1228
+ sage: H2 = Hom(Q, Q, Modules(Fields()))
1229
+ sage: H == H2
1230
+ False
1231
+ sage: H2(phi)
1232
+ Quantum group homomorphism endomorphism of Quantum Group of type ['A', 1] with q=q
1233
+ Defn: F[a1] |--> E[a1]
1234
+ K1 |--> (-q + q^-1)*[ K1 ; 1 ] + K1
1235
+ (-q + q^-1)*[ K1 ; 1 ] + K1 |--> K1
1236
+ E[a1] |--> F[a1]
1237
+ """
1238
+ if isinstance(im_gens, QuantumGroupMorphism):
1239
+ if im_gens.parent() is self:
1240
+ return im_gens
1241
+ if im_gens.parent() != self:
1242
+ return QuantumGroupMorphism(self, im_gens.im_gens())
1243
+ raise TypeError("unable to coerce {}".format(im_gens))
1244
+ return QuantumGroupMorphism(self, im_gens)
1245
+
1246
+
1247
+ def projection_lower_half(Q):
1248
+ r"""
1249
+ Return the projection onto the lower half of the quantum group.
1250
+
1251
+ EXAMPLES::
1252
+
1253
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import projection_lower_half
1254
+ sage: Q = QuantumGroup(['G',2])
1255
+ sage: phi = projection_lower_half(Q); phi
1256
+ Quantum group homomorphism endomorphism of Quantum Group of type ['G', 2] with q=q
1257
+ Defn: F[a1] |--> F[a1]
1258
+ F[a2] |--> F[a2]
1259
+ K1 |--> 0
1260
+ K2 |--> 0
1261
+ (-q + q^-1)*[ K1 ; 1 ] + K1 |--> 0
1262
+ (-q^3 + q^-3)*[ K2 ; 1 ] + K2 |--> 0
1263
+ E[a1] |--> 0
1264
+ E[a2] |--> 0
1265
+ sage: all(phi(f) == f for f in Q.F())
1266
+ True
1267
+ sage: all(phi(e) == Q.zero() for e in Q.E())
1268
+ True
1269
+ sage: all(phi(K) == Q.zero() for K in Q.K())
1270
+ True
1271
+ """
1272
+ I = Q._cartan_type.index_set()
1273
+ return Hom(Q, Q)(list(Q.F_simple()) + [Q.zero()] * (len(I) * 3))
1274
+
1275
+
1276
+ #####################################################################
1277
+ # Representations
1278
+
1279
+ class QuaGroupRepresentationElement(QuaGroupModuleElement):
1280
+ """
1281
+ Element of a quantum group representation.
1282
+ """
1283
+ def __reduce__(self):
1284
+ """
1285
+ Used in pickling.
1286
+
1287
+ EXAMPLES::
1288
+
1289
+ sage: Q = QuantumGroup(['B',2])
1290
+ sage: F1, F2 = Q.F_simple()
1291
+ sage: q = Q.q()
1292
+ sage: V = Q.highest_weight_module([2,1])
1293
+ sage: v = V.highest_weight_vector()
1294
+ sage: x = (2 - q) * v + F1*v + q*F2*F1*v
1295
+ sage: loads(dumps(x)) == x
1296
+ True
1297
+ """
1298
+ return (self.parent(), (self.monomial_coefficients(),))
1299
+
1300
+ def _acted_upon_(self, scalar, self_on_left=False):
1301
+ r"""
1302
+ Return the action of ``scalar`` on ``self``.
1303
+
1304
+ EXAMPLES::
1305
+
1306
+ sage: Q = QuantumGroup(['B',2])
1307
+ sage: F1, F2 = Q.F_simple()
1308
+ sage: q = Q.q()
1309
+ sage: V = Q.highest_weight_module([2,1])
1310
+ sage: v = V.highest_weight_vector()
1311
+ sage: F1 * v
1312
+ F[a1]*v0
1313
+ sage: F2 * v
1314
+ F[a2]*v0
1315
+ sage: F1^2 * v
1316
+ (q^2 + q^-2)*F[a1]^(2)*v0
1317
+ sage: F2^2 * v
1318
+ 0*v0
1319
+ sage: (F1 * F2) * v
1320
+ F[a1]*F[a2]*v0
1321
+ sage: F1 * (F2 * v)
1322
+ F[a1]*F[a2]*v0
1323
+ sage: (2 - q) * v + F1*v + q*F2*F1*v
1324
+ (-q + 2)*1*v0 + F[a1]*v0 + (q^3)*F[a1]*F[a2]*v0 + (q)*F[a1+a2]*v0
1325
+ """
1326
+ try:
1327
+ if scalar.parent() is self.parent()._Q:
1328
+ if self_on_left: # Only act: scalar * v
1329
+ return None
1330
+ return self.__class__(self.parent(), scalar._libgap ** self._libgap)
1331
+ except AttributeError:
1332
+ pass
1333
+ return QuaGroupModuleElement._acted_upon_(self, scalar, self_on_left)
1334
+
1335
+ _lmul_ = _acted_upon_
1336
+
1337
+ def _et(self, i):
1338
+ r"""
1339
+ Return the action of `\widetilde{e}_i` on ``self``.
1340
+
1341
+ EXAMPLES::
1342
+
1343
+ sage: Q = QuantumGroup(['A',2])
1344
+ sage: V = Q.highest_weight_module([1,1])
1345
+ sage: v = V.highest_weight_vector()
1346
+ sage: v._et(1)
1347
+ 0*v0
1348
+ sage: V.zero().e_tilde(1)
1349
+ 0*v0
1350
+ """
1351
+ if not self: # self == 0
1352
+ return self
1353
+ V = self.parent()
1354
+ ret = V._libgap.Ealpha(self._libgap, i)
1355
+ return self.__class__(V, ret)
1356
+
1357
+ def _ft(self, i):
1358
+ r"""
1359
+ Return the action of `\widetilde{e}_i` on ``self``.
1360
+
1361
+ EXAMPLES::
1362
+
1363
+ sage: Q = QuantumGroup(['C',2])
1364
+ sage: V = Q.highest_weight_module([1,1])
1365
+ sage: v = V.highest_weight_vector()
1366
+ sage: v._ft(1)
1367
+ F[a1]*v0
1368
+ sage: v._ft(2)
1369
+ F[a2]*v0
1370
+ sage: v.f_tilde([1,1])
1371
+ 0*v0
1372
+ sage: v.f_tilde([2,2])
1373
+ 0*v0
1374
+ sage: v.f_tilde([2,1,1])
1375
+ (-q^-3)*F[a1]*F[a1+a2]*v0 + (-q^-4)*F[2*a1+a2]*v0
1376
+ sage: v.f_tilde([1,2,2])
1377
+ F[a1+a2]*F[a2]*v0
1378
+ sage: V.zero().f_tilde(1)
1379
+ 0*v0
1380
+ """
1381
+ if not self: # self == 0
1382
+ return self
1383
+ V = self.parent()
1384
+ ret = V._libgap.Falpha(self._libgap, i)
1385
+ return self.__class__(V, ret)
1386
+
1387
+ def monomial_coefficients(self, copy=True):
1388
+ r"""
1389
+ Return the dictionary of ``self`` whose keys are the basis indices
1390
+ and the values are coefficients.
1391
+
1392
+ EXAMPLES::
1393
+
1394
+ sage: Q = QuantumGroup(['A',2])
1395
+ sage: V = Q.highest_weight_module([1,1])
1396
+ sage: v = V.highest_weight_vector()
1397
+ sage: F1, F2 = Q.F_simple()
1398
+ sage: q = Q.q()
1399
+ sage: x = v + F1*v + q*F2*F1*v; x
1400
+ 1*v0 + F[a1]*v0 + (q^2)*F[a1]*F[a2]*v0 + (q)*F[a1+a2]*v0
1401
+ sage: sorted(x.monomial_coefficients().items(), key=str)
1402
+ [(0, 1), (1, 1), (3, q^2), (4, q)]
1403
+ """
1404
+ R = self.parent()._Q.base_ring()
1405
+ B = self.parent()._libgap.Basis()
1406
+ data = [R(str(c)) for c in libgap.Coefficients(B, self._libgap)]
1407
+ return {i: c for i, c in enumerate(data) if c != 0}
1408
+
1409
+ def _vector_(self, R=None, order=None, sparse=False):
1410
+ """
1411
+ Return ``self`` as a vector.
1412
+
1413
+ EXAMPLES::
1414
+
1415
+ sage: Q = QuantumGroup(['A',2])
1416
+ sage: V = Q.highest_weight_module([1,1])
1417
+ sage: v = V.highest_weight_vector()
1418
+ sage: vector(v)
1419
+ (1, 0, 0, 0, 0, 0, 0, 0)
1420
+ sage: F1, F2 = Q.F_simple()
1421
+ sage: q = Q.q()
1422
+ sage: x = v + F1*v + q*F2*F1*v; x
1423
+ 1*v0 + F[a1]*v0 + (q^2)*F[a1]*F[a2]*v0 + (q)*F[a1+a2]*v0
1424
+ sage: vector(x)
1425
+ (1, 1, 0, q^2, q, 0, 0, 0)
1426
+
1427
+ sage: v._vector_(sparse=True)
1428
+ (1, 0, 0, 0, 0, 0, 0, 0)
1429
+ sage: x._vector_(sparse=True)
1430
+ (1, 1, 0, q^2, q, 0, 0, 0)
1431
+
1432
+ sage: M = V.submodule([V.an_element()])
1433
+ sage: M
1434
+ Free module generated by {0} over Fraction Field of Univariate Polynomial Ring in q over Rational Field
1435
+ """
1436
+ V = self.parent()._dense_free_module(R)
1437
+ if sparse:
1438
+ V = V.sparse_module()
1439
+ if order is None:
1440
+ return V(self.monomial_coefficients())
1441
+
1442
+ v = copy(V.zero())
1443
+ if order is None:
1444
+ for i, c in self.monomial_coefficients().items():
1445
+ v[i] = c
1446
+ else:
1447
+ for i, c in self.monomial_coefficients().items():
1448
+ v[order[i]] = c
1449
+ return v
1450
+
1451
+
1452
+ class CrystalGraphVertex(SageObject):
1453
+ r"""
1454
+ Helper class used as the vertices of a crystal graph.
1455
+ """
1456
+ def __init__(self, V, s):
1457
+ """
1458
+ Initialize ``self``.
1459
+
1460
+ EXAMPLES::
1461
+
1462
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
1463
+ sage: Q = QuantumGroup(['A',2])
1464
+ sage: V = Q.highest_weight_module([1,0])
1465
+ sage: v = CrystalGraphVertex(V, '<F2*v0>')
1466
+ sage: TestSuite(v).run()
1467
+ """
1468
+ self.V = V
1469
+ self.s = s
1470
+
1471
+ def __hash__(self):
1472
+ """
1473
+ Return the hash of ``self``.
1474
+
1475
+ EXAMPLES::
1476
+
1477
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
1478
+ sage: Q = QuantumGroup(['A',2])
1479
+ sage: V = Q.highest_weight_module([1,0])
1480
+ sage: v = CrystalGraphVertex(V, '<F2*v0>')
1481
+ sage: hash(v) == hash('<F2*v0>')
1482
+ True
1483
+ """
1484
+ return hash(self.s)
1485
+
1486
+ def __eq__(self, other):
1487
+ """
1488
+ Check equality of ``self`` and ``other``.
1489
+
1490
+ EXAMPLES::
1491
+
1492
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
1493
+ sage: Q = QuantumGroup(['A',2])
1494
+ sage: V = Q.highest_weight_module([1,0])
1495
+ sage: v = CrystalGraphVertex(V, '<F2*v0>')
1496
+ sage: vp = CrystalGraphVertex(V, '<F2*v0>')
1497
+ sage: v == vp
1498
+ True
1499
+ sage: vpp = CrystalGraphVertex(V, '<1*v0>')
1500
+ sage: v == vpp
1501
+ False
1502
+ """
1503
+ return isinstance(other, CrystalGraphVertex) and self.s == other.s
1504
+
1505
+ def _repr_(self):
1506
+ """
1507
+ Return a string representation of ``self``.
1508
+
1509
+ EXAMPLES::
1510
+
1511
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
1512
+ sage: Q = QuantumGroup(['A',2])
1513
+ sage: V = Q.highest_weight_module([1,0])
1514
+ sage: CrystalGraphVertex(V, '<F2*v0>')
1515
+ <F2*v0>
1516
+ """
1517
+ return self.s
1518
+
1519
+ def _latex_(self):
1520
+ r"""
1521
+ Return a latex representation of ``self``.
1522
+
1523
+ EXAMPLES::
1524
+
1525
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import CrystalGraphVertex
1526
+ sage: Q = QuantumGroup(['A',2])
1527
+ sage: V = Q.highest_weight_module([1,0])
1528
+ sage: v = CrystalGraphVertex(V, '<F2*v0>')
1529
+ sage: latex(v)
1530
+ \langle F_{\alpha_{1} + \alpha_{2}} v_0 \rangle
1531
+ """
1532
+ # Essentially same as QuaGroupModuleElement._latex_
1533
+ from sage.misc.latex import latex
1534
+ ret = self.s[1:-1] # Strip leading '<' and trailing '>'
1535
+ for i, al in enumerate(self.V._pos_roots):
1536
+ ret = ret.replace('F%s' % (i + 1), 'F_{%s}' % latex(al))
1537
+ ret = ret.replace('E%s' % (i + 1), 'E_{%s}' % latex(al))
1538
+ for i, ii in enumerate(self.V._cartan_type.index_set()):
1539
+ ret = ret.replace('K%s' % (i + 1), 'K_{%s}' % ii)
1540
+ # Fugly string parsing to get good looking latex
1541
+ # TODO: Find a better way
1542
+ ret = ret.replace('(', '{(')
1543
+ ret = ret.replace(')', ')}')
1544
+ ret = ret.replace('v0', 'v_0')
1545
+ ret = ret.replace('*', ' ')
1546
+ ret = ret.replace('<x>', ' \\otimes ')
1547
+ c = re.compile(r"q\^-?[0-9]*")
1548
+ for m in reversed(list(c.finditer(ret))):
1549
+ ret = ret[:m.start()+2]+'{'+ret[m.start()+2:m.end()]+'}'+ret[m.end():]
1550
+ return '\\langle {} \\rangle'.format(ret)
1551
+
1552
+
1553
+ class QuantumGroupModule(Parent, UniqueRepresentation):
1554
+ r"""
1555
+ Abstract base class for quantum group representations.
1556
+ """
1557
+ def __init__(self, Q, category):
1558
+ r"""
1559
+ Initialize ``self``.
1560
+
1561
+ EXAMPLES::
1562
+
1563
+ sage: Q = QuantumGroup(['G',2])
1564
+ sage: V = Q.highest_weight_module([1,0])
1565
+ sage: TestSuite(V).run()
1566
+ """
1567
+ self._Q = Q
1568
+ self._libgap_q = Q._libgap_q
1569
+ self._libgap_base = Q._libgap_base
1570
+ self._cartan_type = Q._cartan_type
1571
+ self._pos_roots = Q._pos_roots
1572
+ Parent.__init__(self, base=Q.base_ring(), category=category)
1573
+
1574
+ def _latex_(self):
1575
+ r"""
1576
+ Return a latex representation of ``self``.
1577
+
1578
+ EXAMPLES::
1579
+
1580
+ sage: Q = QuantumGroup(['A',2])
1581
+ sage: V = Q.highest_weight_module([1,0])
1582
+ sage: T = tensor([V,V])
1583
+ sage: S = T.highest_weight_decomposition()[0]
1584
+ sage: latex(S)
1585
+ \begin{tikzpicture}...
1586
+ ...
1587
+ \end{tikzpicture}
1588
+ """
1589
+ from sage.misc.latex import latex
1590
+ return latex(self.crystal_graph())
1591
+
1592
+ def gap(self):
1593
+ r"""
1594
+ Return the gap representation of ``self``.
1595
+
1596
+ EXAMPLES::
1597
+
1598
+ sage: Q = QuantumGroup(['A',2])
1599
+ sage: V = Q.highest_weight_module([1,1])
1600
+ sage: V.gap()
1601
+ <8-dimensional left-module over QuantumUEA( <root system of type A2>,
1602
+ Qpar = q )>
1603
+ """
1604
+ return self._libgap
1605
+
1606
+ _libgap_ = _gap_ = gap
1607
+
1608
+ def _element_constructor_(self, elt):
1609
+ """
1610
+ Construct an element of ``self``.
1611
+
1612
+ EXAMPLES::
1613
+
1614
+ sage: Q = QuantumGroup(['A',2])
1615
+ sage: V = Q.highest_weight_module([1,1])
1616
+ sage: q = Q.q()
1617
+ sage: V(0)
1618
+ 0*v0
1619
+ sage: V({1: q^2 - q^-2, 3: 2})
1620
+ (q^2-q^-2)*F[a1]*v0 + (2)*F[a1]*F[a2]*v0
1621
+ """
1622
+ if not elt:
1623
+ return self.zero()
1624
+ if isinstance(elt, dict):
1625
+ return self._from_dict(elt)
1626
+ return self.element_class(self, elt)
1627
+
1628
+ @cached_method
1629
+ def basis(self):
1630
+ r"""
1631
+ Return a basis of ``self``.
1632
+
1633
+ EXAMPLES::
1634
+
1635
+ sage: Q = QuantumGroup(['A',2])
1636
+ sage: V = Q.highest_weight_module([1,1])
1637
+ sage: V.basis()
1638
+ Family (1*v0, F[a1]*v0, F[a2]*v0, F[a1]*F[a2]*v0, F[a1+a2]*v0,
1639
+ F[a1]*F[a1+a2]*v0, F[a1+a2]*F[a2]*v0, F[a1+a2]^(2)*v0)
1640
+ """
1641
+ return Family([self.element_class(self, b) for b in self._libgap.Basis()])
1642
+
1643
+ @cached_method
1644
+ def crystal_basis(self):
1645
+ r"""
1646
+ Return the crystal basis of ``self``.
1647
+
1648
+ EXAMPLES::
1649
+
1650
+ sage: Q = QuantumGroup(['A',2])
1651
+ sage: V = Q.highest_weight_module([1,1])
1652
+ sage: V.crystal_basis()
1653
+ Family (1*v0, F[a1]*v0, F[a2]*v0, F[a1]*F[a2]*v0,
1654
+ (q)*F[a1]*F[a2]*v0 + F[a1+a2]*v0, F[a1+a2]*F[a2]*v0,
1655
+ (-q^-2)*F[a1]*F[a1+a2]*v0, (-q^-1)*F[a1+a2]^(2)*v0)
1656
+ """
1657
+ return Family([self.element_class(self, b) for b in self._libgap.CrystalBasis()])
1658
+
1659
+ @cached_method
1660
+ def R_matrix(self):
1661
+ """
1662
+ Return the `R`-matrix of ``self``.
1663
+
1664
+ EXAMPLES::
1665
+
1666
+ sage: Q = QuantumGroup(['A',1])
1667
+ sage: V = Q.highest_weight_module([1])
1668
+ sage: V.R_matrix()
1669
+ [ 1 0 0 0]
1670
+ [ 0 q -q^2 + 1 0]
1671
+ [ 0 0 q 0]
1672
+ [ 0 0 0 1]
1673
+ """
1674
+ R = self._libgap.RMatrix()
1675
+ F = self._Q.base_ring()
1676
+ from sage.matrix.constructor import matrix
1677
+ M = matrix(F, [[F(str(elt)) for elt in row] for row in R])
1678
+ M.set_immutable()
1679
+ return M
1680
+
1681
+ def crystal_graph(self):
1682
+ r"""
1683
+ Return the crystal graph of ``self``.
1684
+
1685
+ EXAMPLES::
1686
+
1687
+ sage: Q = QuantumGroup(['A',2])
1688
+ sage: V = Q.highest_weight_module([1,1])
1689
+ sage: G = V.crystal_graph(); G
1690
+ Digraph on 8 vertices
1691
+
1692
+ sage: B = crystals.Tableaux(['A',2], shape=[2,1])
1693
+ sage: G.is_isomorphic(B.digraph(), edge_labels=True)
1694
+ True
1695
+ """
1696
+ G = self._libgap.CrystalGraph()
1697
+ vertices = [CrystalGraphVertex(self, repr(p)) for p in G['points']]
1698
+ edges = [[vertices[e[0][0]-1], vertices[e[0][1]-1], e[1]]
1699
+ for e in G['edges'].sage()]
1700
+ G = DiGraph([vertices, edges], format='vertices_and_edges')
1701
+ from sage.graphs.dot2tex_utils import have_dot2tex
1702
+ if have_dot2tex():
1703
+ G.set_latex_options(format='dot2tex',
1704
+ edge_labels=True,
1705
+ color_by_label=self._cartan_type._index_set_coloring)
1706
+ return G
1707
+
1708
+ @cached_method
1709
+ def zero(self):
1710
+ r"""
1711
+ Return the zero element of ``self``.
1712
+
1713
+ EXAMPLES::
1714
+
1715
+ sage: Q = QuantumGroup(['A',2])
1716
+ sage: V = Q.highest_weight_module([1,1])
1717
+ sage: V.zero()
1718
+ 0*v0
1719
+ """
1720
+ return self.element_class(self, self._libgap.ZeroImmutable())
1721
+
1722
+
1723
+ class HighestWeightModule(QuantumGroupModule):
1724
+ """
1725
+ A highest weight module of a quantum group.
1726
+ """
1727
+ @staticmethod
1728
+ def __classcall_private__(cls, Q, weight):
1729
+ """
1730
+ Normalize input to ensure a unique representation.
1731
+
1732
+ EXAMPLES::
1733
+
1734
+ sage: Q = QuantumGroup(['A',2])
1735
+ sage: La = Q.cartan_type().root_system().weight_lattice().fundamental_weights()
1736
+ sage: V = Q.highest_weight_module([1,3])
1737
+ sage: V is Q.highest_weight_module(La[1]+3*La[2])
1738
+ True
1739
+ """
1740
+ P = Q._cartan_type.root_system().weight_lattice()
1741
+ if isinstance(weight, (list, tuple)):
1742
+ La = P.fundamental_weights()
1743
+ weight = P.sum(la * weight[i] for i, la in enumerate(La))
1744
+ else:
1745
+ weight = P(weight)
1746
+ return super().__classcall__(cls, Q, weight)
1747
+
1748
+ def __init__(self, Q, weight):
1749
+ """
1750
+ Initialize ``self``.
1751
+
1752
+ EXAMPLES::
1753
+
1754
+ sage: Q = QuantumGroup(['A',2])
1755
+ sage: V = Q.highest_weight_module([1,1])
1756
+ sage: TestSuite(V).run()
1757
+ """
1758
+ self._libgap = Q._libgap.HighestWeightModule(list(weight.to_vector()))
1759
+ self._weight = weight
1760
+ cat = Modules(Q.base_ring()).FiniteDimensional().WithBasis()
1761
+ QuantumGroupModule.__init__(self, Q, cat)
1762
+
1763
+ def _repr_(self):
1764
+ """
1765
+ Return a string representation of ``self``.
1766
+
1767
+ EXAMPLES::
1768
+
1769
+ sage: Q = QuantumGroup(['A',2])
1770
+ sage: Q.highest_weight_module([1,1])
1771
+ Highest weight module of weight Lambda[1] + Lambda[2] of
1772
+ Quantum Group of type ['A', 2] with q=q
1773
+ """
1774
+ return "Highest weight module of weight {} of {}".format(self._weight, self._Q)
1775
+
1776
+ def _latex_(self):
1777
+ r"""
1778
+ Return a latex representation of ``self``.
1779
+
1780
+ EXAMPLES::
1781
+
1782
+ sage: Q = QuantumGroup(['A',2])
1783
+ sage: V = Q.highest_weight_module([1,2])
1784
+ sage: latex(V)
1785
+ V(\Lambda_{1} + 2 \Lambda_{2})
1786
+ """
1787
+ from sage.misc.latex import latex
1788
+ return "V({})".format(latex(self._weight))
1789
+
1790
+ @cached_method
1791
+ def highest_weight_vector(self):
1792
+ """
1793
+ Return the highest weight vector of ``self``.
1794
+
1795
+ EXAMPLES::
1796
+
1797
+ sage: Q = QuantumGroup(['A',2])
1798
+ sage: V = Q.highest_weight_module([1,1])
1799
+ sage: V.highest_weight_vector()
1800
+ 1*v0
1801
+ """
1802
+ return self.element_class(self, self._libgap.HighestWeightsAndVectors()[1][0][0])
1803
+
1804
+ an_element = highest_weight_vector
1805
+
1806
+ def tensor(self, *V, **options):
1807
+ """
1808
+ Return the tensor product of ``self`` with ``V``.
1809
+
1810
+ EXAMPLES::
1811
+
1812
+ sage: Q = QuantumGroup(['A',2])
1813
+ sage: V = Q.highest_weight_module([1,1])
1814
+ sage: Vp = Q.highest_weight_module([1,0])
1815
+ sage: Vp.tensor(V)
1816
+ Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q
1817
+ # Highest weight module of weight Lambda[1] + Lambda[2] of Quantum Group of type ['A', 2] with q=q
1818
+ """
1819
+ return TensorProductOfHighestWeightModules(self, *V, **options)
1820
+
1821
+ Element = QuaGroupRepresentationElement
1822
+
1823
+
1824
+ class TensorProductOfHighestWeightModules(QuantumGroupModule):
1825
+ def __init__(self, *modules, **options):
1826
+ """
1827
+ Initialize ``self``.
1828
+
1829
+ EXAMPLES::
1830
+
1831
+ sage: Q = QuantumGroup(['A',2])
1832
+ sage: V = Q.highest_weight_module([1,1])
1833
+ sage: T = tensor([V,V])
1834
+ sage: TestSuite(T).run()
1835
+ """
1836
+ Q = modules[0]._Q
1837
+ self._modules = tuple(modules)
1838
+ self._libgap = libgap.TensorProductOfAlgebraModules([m._libgap for m in modules])
1839
+ cat = Modules(Q.base_ring()).TensorProducts().FiniteDimensional().WithBasis()
1840
+ QuantumGroupModule.__init__(self, Q, category=cat)
1841
+
1842
+ def _repr_(self):
1843
+ """
1844
+ Return a string representation of ``self``.
1845
+
1846
+ EXAMPLES::
1847
+
1848
+ sage: Q = QuantumGroup(['A',2])
1849
+ sage: V = Q.highest_weight_module([1,0])
1850
+ sage: T = tensor([V,V])
1851
+ sage: T
1852
+ Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q
1853
+ # Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q
1854
+ """
1855
+ return " # ".join(repr(M) for M in self._modules)
1856
+
1857
+ def _latex_(self):
1858
+ r"""
1859
+ Return a string representation of ``self``.
1860
+
1861
+ EXAMPLES::
1862
+
1863
+ sage: Q = QuantumGroup(['A',2])
1864
+ sage: V = Q.highest_weight_module([1,0])
1865
+ sage: T = tensor([V,V])
1866
+ sage: latex(T)
1867
+ V(\Lambda_{1}) \otimes V(\Lambda_{1})
1868
+ """
1869
+ from sage.misc.latex import latex
1870
+ return " \\otimes ".join(latex(M) for M in self._modules)
1871
+
1872
+ @lazy_attribute
1873
+ def _highest_weights_and_vectors(self):
1874
+ """
1875
+ Return the highest weights and the corresponding vectors.
1876
+
1877
+ .. NOTE::
1878
+
1879
+ The resulting objects are GAP objects.
1880
+
1881
+ EXAMPLES::
1882
+
1883
+ sage: Q = QuantumGroup(['A',2])
1884
+ sage: V = Q.highest_weight_module([0,1])
1885
+ sage: T = tensor([V,V])
1886
+ sage: T._highest_weights_and_vectors
1887
+ [ [ [ 0, 2 ], [ 1, 0 ] ],
1888
+ [ [ 1*(1*v0<x>1*v0) ], [ -q^-1*(1*v0<x>F3*v0)+1*(F3*v0<x>1*v0) ] ] ]
1889
+ """
1890
+ return self._libgap.HighestWeightsAndVectors()
1891
+
1892
+ def highest_weight_vectors(self):
1893
+ r"""
1894
+ Return the highest weight vectors of ``self``.
1895
+
1896
+ EXAMPLES::
1897
+
1898
+ sage: Q = QuantumGroup(['A',2])
1899
+ sage: V = Q.highest_weight_module([1,0])
1900
+ sage: T = tensor([V,V])
1901
+ sage: T.highest_weight_vectors()
1902
+ [1*(1*v0<x>1*v0), -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)]
1903
+ """
1904
+ return [self.element_class(self, v)
1905
+ for vecs in self._highest_weights_and_vectors[1]
1906
+ for v in vecs]
1907
+
1908
+ some_elements = highest_weight_vectors
1909
+
1910
+ def _an_element_(self):
1911
+ """
1912
+ Return an element of ``self``.
1913
+
1914
+ EXAMPLES::
1915
+
1916
+ sage: Q = QuantumGroup(['A',2])
1917
+ sage: V = Q.highest_weight_module([1,0])
1918
+ sage: T = tensor([V,V])
1919
+ sage: T.an_element()
1920
+ 1*(1*v0<x>1*v0)
1921
+ """
1922
+ return self.highest_weight_vectors()[0]
1923
+
1924
+ @cached_method
1925
+ def highest_weight_decomposition(self):
1926
+ """
1927
+ Return the highest weight decomposition of ``self``.
1928
+
1929
+ EXAMPLES::
1930
+
1931
+ sage: Q = QuantumGroup(['A',2])
1932
+ sage: V = Q.highest_weight_module([1,0])
1933
+ sage: T = tensor([V,V])
1934
+ sage: T.highest_weight_decomposition()
1935
+ [Highest weight submodule with weight 2*Lambda[1] generated by 1*(1*v0<x>1*v0),
1936
+ Highest weight submodule with weight Lambda[2] generated by -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)]
1937
+ """
1938
+ return [HighestWeightSubmodule(self, self.element_class(self, v), tuple(wt.sage()))
1939
+ for wt, vecs in zip(*self._highest_weights_and_vectors)
1940
+ for v in vecs]
1941
+
1942
+ def tensor_factors(self):
1943
+ r"""
1944
+ Return the factors of ``self``.
1945
+
1946
+ EXAMPLES::
1947
+
1948
+ sage: Q = QuantumGroup(['A',2])
1949
+ sage: V = Q.highest_weight_module([1,0])
1950
+ sage: T = tensor([V,V])
1951
+ sage: T.tensor_factors()
1952
+ (Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q,
1953
+ Highest weight module of weight Lambda[1] of Quantum Group of type ['A', 2] with q=q)
1954
+ """
1955
+ return self._modules
1956
+
1957
+ Element = QuaGroupRepresentationElement
1958
+
1959
+
1960
+ class HighestWeightSubmodule(QuantumGroupModule):
1961
+ def __init__(self, ambient, gen, weight):
1962
+ """
1963
+ Initialize ``self``.
1964
+
1965
+ EXAMPLES::
1966
+
1967
+ sage: Q = QuantumGroup(['A',2])
1968
+ sage: V = Q.highest_weight_module([1,0])
1969
+ sage: T = tensor([V,V])
1970
+ sage: S = T.highest_weight_decomposition()[0]
1971
+ sage: TestSuite(S).run()
1972
+ """
1973
+ self._ambient = ambient
1974
+ # We do not use the generic ambient category since submodules of tensor
1975
+ # products are considered to be tensor products.
1976
+ # This should be reverted after this has changed.
1977
+ #cat = ambient.category()
1978
+ cat = Modules(ambient.base_ring()).FiniteDimensional().WithBasis()
1979
+ QuantumGroupModule.__init__(self, ambient._Q, cat.Subobjects())
1980
+
1981
+ self._gen = gen
1982
+
1983
+ self._libgap = self._ambient._libgap.HWModuleByGenerator(gen, weight)
1984
+
1985
+ # Convert the weight to an element of the weight lattice
1986
+ P = self._Q._cartan_type.root_system().weight_lattice()
1987
+ La = P.fundamental_weights()
1988
+ self._weight = P.sum(la * weight[i] for i, la in enumerate(La))
1989
+
1990
+ def _repr_(self):
1991
+ """
1992
+ Return a string representation of ``self``.
1993
+
1994
+ EXAMPLES::
1995
+
1996
+ sage: Q = QuantumGroup(['A',2])
1997
+ sage: V = Q.highest_weight_module([1,0])
1998
+ sage: T = tensor([V,V])
1999
+ sage: T.highest_weight_decomposition()
2000
+ [Highest weight submodule with weight 2*Lambda[1]
2001
+ generated by 1*(1*v0<x>1*v0),
2002
+ Highest weight submodule with weight Lambda[2]
2003
+ generated by -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)]
2004
+ """
2005
+ return "Highest weight submodule with weight {} generated by {}".format(self._weight, self._gen)
2006
+
2007
+ @lazy_attribute
2008
+ def _ambient_basis_map(self):
2009
+ """
2010
+ A dict that maps the basis of ``self`` to the ambient module.
2011
+
2012
+ EXAMPLES::
2013
+
2014
+ sage: Q = QuantumGroup(['A',2])
2015
+ sage: V = Q.highest_weight_module([1,0])
2016
+ sage: T = tensor([V,V])
2017
+ sage: S = T.highest_weight_decomposition()[0]
2018
+ sage: S._ambient_basis_map
2019
+ {0: 1*(1*v0<x>1*v0),
2020
+ 1: 1*(1*v0<x>F[a1]*v0) + q^-1*(F[a1]*v0<x>1*v0),
2021
+ 2: 1*(F[a1]*v0<x>F[a1]*v0),
2022
+ 3: 1*(1*v0<x>F[a1+a2]*v0) + q^-1*(F[a1+a2]*v0<x>1*v0),
2023
+ 4: 1*(F[a1]*v0<x>F[a1+a2]*v0) + q^-1*(F[a1+a2]*v0<x>F[a1]*v0),
2024
+ 5: 1*(F[a1+a2]*v0<x>F[a1+a2]*v0)}
2025
+ """
2026
+ B = list(self.basis())
2027
+ d = {self.highest_weight_vector(): self._gen}
2028
+ todo = {self.highest_weight_vector()}
2029
+ I = self._cartan_type.index_set()
2030
+ while todo:
2031
+ x = todo.pop()
2032
+ for i in I:
2033
+ y = x.f_tilde(i)
2034
+ if y and y not in d:
2035
+ d[y] = d[x].f_tilde(i)
2036
+ todo.add(y)
2037
+ return {B.index(k): d[k] for k in d}
2038
+
2039
+ def ambient(self):
2040
+ """
2041
+ Return the ambient module of ``self``.
2042
+
2043
+ EXAMPLES::
2044
+
2045
+ sage: Q = QuantumGroup(['A',2])
2046
+ sage: V = Q.highest_weight_module([1,0])
2047
+ sage: T = tensor([V,V])
2048
+ sage: S = T.highest_weight_decomposition()[0]
2049
+ sage: S.ambient() is T
2050
+ True
2051
+ """
2052
+ return self._ambient
2053
+
2054
+ @lazy_attribute
2055
+ def lift(self):
2056
+ """
2057
+ The lift morphism from ``self`` to the ambient space.
2058
+
2059
+ EXAMPLES::
2060
+
2061
+ sage: Q = QuantumGroup(['A',2])
2062
+ sage: V = Q.highest_weight_module([1,0])
2063
+ sage: T = tensor([V,V])
2064
+ sage: S = T.highest_weight_decomposition()[0]
2065
+ sage: S.lift
2066
+ Generic morphism:
2067
+ From: Highest weight submodule with weight 2*Lambda[1] generated by 1*(1*v0<x>1*v0)
2068
+ To: Highest weight module ... # Highest weight module ...
2069
+ sage: x = sum(S.basis())
2070
+ sage: x.lift()
2071
+ 1*(1*v0<x>1*v0) + 1*(1*v0<x>F[a1]*v0) + 1*(1*v0<x>F[a1+a2]*v0)
2072
+ + q^-1*(F[a1]*v0<x>1*v0) + 1*(F[a1]*v0<x>F[a1]*v0)
2073
+ + 1*(F[a1]*v0<x>F[a1+a2]*v0) + q^-1*(F[a1+a2]*v0<x>1*v0)
2074
+ + q^-1*(F[a1+a2]*v0<x>F[a1]*v0) + 1*(F[a1+a2]*v0<x>F[a1+a2]*v0)
2075
+ """
2076
+ return self.module_morphism(self._ambient_basis_map.__getitem__,
2077
+ codomain=self._ambient, unitriangular='lower')
2078
+
2079
+ def retract(self, elt):
2080
+ """
2081
+ The retract map from the ambient space to ``self``.
2082
+
2083
+ EXAMPLES::
2084
+
2085
+ sage: Q = QuantumGroup(['A',2])
2086
+ sage: V = Q.highest_weight_module([1,0])
2087
+ sage: T = tensor([V,V])
2088
+ sage: all(S.retract(S.lift(x)) == x
2089
+ ....: for S in T.highest_weight_decomposition()
2090
+ ....: for x in S.basis())
2091
+ True
2092
+ """
2093
+ c = self.lift.matrix().solve_right(elt._vector_())
2094
+ return self._from_dict(c.dict(), coerce=False, remove_zeros=False)
2095
+
2096
+ def highest_weight_vector(self):
2097
+ """
2098
+ Return the highest weight vector of ``self``.
2099
+
2100
+ EXAMPLES::
2101
+
2102
+ sage: Q = QuantumGroup(['A',2])
2103
+ sage: V = Q.highest_weight_module([1,0])
2104
+ sage: T = tensor([V,V])
2105
+ sage: S = T.highest_weight_decomposition()[1]
2106
+ sage: u = S.highest_weight_vector(); u
2107
+ (1)*e.1
2108
+ sage: u.lift()
2109
+ -q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)
2110
+ """
2111
+ I = self._cartan_type.index_set()
2112
+ zero = self._libgap.ZeroImmutable()
2113
+ for v in self.basis():
2114
+ if all(self._libgap.Ealpha(v._libgap, i) == zero for i in I):
2115
+ return v
2116
+ return self.zero()
2117
+
2118
+ an_element = highest_weight_vector
2119
+
2120
+ def crystal_graph(self, use_ambient=True):
2121
+ """
2122
+ Return the crystal graph of ``self``.
2123
+
2124
+ INPUT:
2125
+
2126
+ - ``use_ambient`` -- boolean (default: ``True``); if ``True``,
2127
+ the vertices are given in terms of the ambient module
2128
+
2129
+ EXAMPLES::
2130
+
2131
+ sage: Q = QuantumGroup(['A',2])
2132
+ sage: V = Q.highest_weight_module([1,0])
2133
+ sage: T = tensor([V,V])
2134
+ sage: S = T.highest_weight_decomposition()[1]
2135
+ sage: G = S.crystal_graph()
2136
+ sage: sorted(G.vertices(sort=False), key=str)
2137
+ [<-q^-1*(1*v0<x>F[a1+a2]*v0) + 1*(F[a1+a2]*v0<x>1*v0)>,
2138
+ <-q^-1*(1*v0<x>F[a1]*v0) + 1*(F[a1]*v0<x>1*v0)>,
2139
+ <-q^-1*(F[a1]*v0<x>F[a1+a2]*v0) + 1*(F[a1+a2]*v0<x>F[a1]*v0)>]
2140
+ sage: sorted(S.crystal_graph(False).vertices(sort=False), key=str)
2141
+ [<(1)*e.1>, <(1)*e.2>, <(1)*e.3>]
2142
+ """
2143
+ G = self._libgap.CrystalGraph()
2144
+ if not use_ambient:
2145
+ return QuantumGroupModule.crystal_graph(self)
2146
+ # Mostly a copy; there is likely a better way with a helper function
2147
+ B = self.basis()
2148
+ d = {repr(B[k]._libgap): '<{!r}>'.format(self._ambient_basis_map[k])
2149
+ for k in self._ambient_basis_map}
2150
+ vertices = [CrystalGraphVertex(self, d[repr(p)[1:-1]])
2151
+ for p in G['points']]
2152
+ edges = [[vertices[e[0][0]-1], vertices[e[0][1]-1], e[1]]
2153
+ for e in G['edges'].sage()]
2154
+ G = DiGraph([vertices, edges], format='vertices_and_edges')
2155
+ from sage.graphs.dot2tex_utils import have_dot2tex
2156
+ if have_dot2tex():
2157
+ G.set_latex_options(format='dot2tex',
2158
+ edge_labels=True,
2159
+ color_by_label=self._cartan_type._index_set_coloring)
2160
+ return G
2161
+
2162
+ Element = QuaGroupRepresentationElement
2163
+
2164
+
2165
+ # TODO: Generalized this to Verma modules
2166
+ class LowerHalfQuantumGroup(Parent, UniqueRepresentation):
2167
+ """
2168
+ The lower half of the quantum group.
2169
+ """
2170
+ @staticmethod
2171
+ def __classcall_private__(cls, Q):
2172
+ """
2173
+ Initialize ``self``.
2174
+
2175
+ EXAMPLES::
2176
+
2177
+ sage: from sage.algebras.quantum_groups.quantum_group_gap import LowerHalfQuantumGroup
2178
+ sage: Q = QuantumGroup(['A',2])
2179
+ sage: Q.lower_half() is LowerHalfQuantumGroup(Q)
2180
+ True
2181
+ """
2182
+ from sage.combinat.root_system.cartan_type import CartanType_abstract
2183
+ if isinstance(Q, CartanType_abstract):
2184
+ Q = QuantumGroup(Q)
2185
+ return super().__classcall__(cls, Q)
2186
+
2187
+ def __init__(self, Q):
2188
+ """
2189
+ Initialize ``self``.
2190
+
2191
+ EXAMPLES::
2192
+
2193
+ sage: Q = QuantumGroup(['A',2])
2194
+ sage: B = Q.lower_half()
2195
+ sage: TestSuite(B).run()
2196
+ """
2197
+ self._Q = Q
2198
+ self._libgap = Q._libgap
2199
+ self._libgap_q = Q._libgap_q
2200
+ self._libgap_base = Q._libgap_base
2201
+ self._cartan_type = Q._cartan_type
2202
+ self._pos_roots = Q._pos_roots
2203
+ self._proj = projection_lower_half(Q)
2204
+ B = Q.base_ring()
2205
+ Parent.__init__(self, base=B, category=Algebras(B).WithBasis().Subobjects())
2206
+
2207
+ def _repr_(self):
2208
+ r"""
2209
+ Return a string representation of ``self``.
2210
+
2211
+ EXAMPLES::
2212
+
2213
+ sage: Q = QuantumGroup(['A',2])
2214
+ sage: Q.lower_half()
2215
+ Lower Half of Quantum Group of type ['A', 2] with q=q
2216
+ """
2217
+ return "Lower Half of {}".format(self._Q)
2218
+
2219
+ def _latex_(self):
2220
+ r"""
2221
+ Return a latex representation of ``self``.
2222
+
2223
+ EXAMPLES::
2224
+
2225
+ sage: Q = QuantumGroup(['A',2])
2226
+ sage: latex(Q.lower_half())
2227
+ U^-_{q}(A_{2})
2228
+ """
2229
+ from sage.misc.latex import latex
2230
+ return "U^-_{%s}(%s)" % (latex(self._Q._q), latex(self._cartan_type))
2231
+
2232
+ def _element_constructor_(self, elt):
2233
+ r"""
2234
+ Construct an element of ``self``.
2235
+
2236
+ EXAMPLES::
2237
+
2238
+ sage: Q = QuantumGroup(['A',2])
2239
+ sage: B = Q.lower_half()
2240
+ sage: q = Q.q()
2241
+ sage: B(0)
2242
+ 0
2243
+ sage: B(1 + q^2)
2244
+ (q^2 + 1)*1
2245
+ sage: B({(1,2,0): q, (0,0,2): q^2 - 2})
2246
+ (q)*F[a1]*F[a1+a2]^(2) + (q^2-2)*F[a2]^(2)
2247
+ """
2248
+ if not elt:
2249
+ return self.zero()
2250
+ if isinstance(elt, dict):
2251
+ return self._from_dict(elt)
2252
+ if elt in self.base_ring():
2253
+ return elt * self.one()
2254
+ if elt.parent() is self._Q:
2255
+ return self.element_class(self, self._proj(elt)._libgap)
2256
+ return self.element_class(self, elt)
2257
+
2258
+ def ambient(self):
2259
+ r"""
2260
+ Return the ambient quantum group of ``self``.
2261
+
2262
+ EXAMPLES::
2263
+
2264
+ sage: Q = QuantumGroup(['A',2])
2265
+ sage: B = Q.lower_half()
2266
+ sage: B.ambient() is Q
2267
+ True
2268
+ """
2269
+ return self._Q
2270
+
2271
+ @cached_method
2272
+ def highest_weight_vector(self):
2273
+ """
2274
+ Return the highest weight vector of ``self``.
2275
+
2276
+ EXAMPLES::
2277
+
2278
+ sage: Q = QuantumGroup(['A',2])
2279
+ sage: B = Q.lower_half()
2280
+ sage: B.highest_weight_vector()
2281
+ 1
2282
+ """
2283
+ return self.element_class(self, self._Q.one()._libgap)
2284
+
2285
+ one = highest_weight_vector
2286
+ an_element = highest_weight_vector
2287
+
2288
+ @cached_method
2289
+ def zero(self):
2290
+ """
2291
+ Return the zero element of ``self``.
2292
+
2293
+ EXAMPLES::
2294
+
2295
+ sage: Q = QuantumGroup(['A',2])
2296
+ sage: B = Q.lower_half()
2297
+ sage: B.zero()
2298
+ 0
2299
+ """
2300
+ return self.element_class(self, self._Q._libgap.ZeroImmutable())
2301
+
2302
+ @cached_method
2303
+ def algebra_generators(self):
2304
+ r"""
2305
+ Return the algebra generators of ``self``.
2306
+
2307
+ EXAMPLES::
2308
+
2309
+ sage: Q = QuantumGroup(['A',2])
2310
+ sage: B = Q.lower_half()
2311
+ sage: B.algebra_generators()
2312
+ Finite family {1: F[a1], 2: F[a2]}
2313
+ """
2314
+ F = self._Q.F_simple()
2315
+ keys = F.keys()
2316
+ d = {i: self.element_class(self, F[i]._libgap) for i in keys}
2317
+ return Family(keys, d.__getitem__)
2318
+
2319
+ gens = algebra_generators
2320
+
2321
+ def _construct_monomial(self, k):
2322
+ """
2323
+ Construct a monomial of ``self`` indexed by ``k``.
2324
+
2325
+ EXAMPLES::
2326
+
2327
+ sage: Q = QuantumGroup(['A',2])
2328
+ sage: B = Q.lower_half()
2329
+ sage: B._construct_monomial((1,2,1))
2330
+ F[a1]*F[a1+a2]^(2)*F[a2]
2331
+ sage: B._construct_monomial((3,0,1))
2332
+ F[a1]^(3)*F[a2]
2333
+ """
2334
+ F = self._libgap.FamilyObj().ElementsFamily()
2335
+ one = self._libgap_base.One()
2336
+ data = []
2337
+ for i, val in enumerate(k):
2338
+ if val == 0:
2339
+ continue
2340
+ data.append(i + 1)
2341
+ data.append(val)
2342
+ return self.element_class(self, F.ObjByExtRep([data, one]))
2343
+
2344
+ @cached_method
2345
+ def basis(self):
2346
+ r"""
2347
+ Return the basis of ``self``.
2348
+
2349
+ This returns the PBW basis of ``self``, which is given by
2350
+ monomials in `\{F_{\alpha}\}`, where `\alpha` runs over all
2351
+ positive roots.
2352
+
2353
+ EXAMPLES::
2354
+
2355
+ sage: Q = QuantumGroup(['A',2])
2356
+ sage: B = Q.lower_half()
2357
+ sage: basis = B.basis(); basis
2358
+ Lazy family (monomial(i))_{i in The Cartesian product of
2359
+ (Non negative integers, Non negative integers, Non negative integers)}
2360
+ sage: basis[1,2,1]
2361
+ F[a1]*F[a1+a2]^(2)*F[a2]
2362
+ sage: basis[1,2,4]
2363
+ F[a1]*F[a1+a2]^(2)*F[a2]^(4)
2364
+ sage: basis[1,0,4]
2365
+ F[a1]*F[a2]^(4)
2366
+ """
2367
+ I = cartesian_product([NonNegativeIntegers()]*len(self._pos_roots))
2368
+ return Family(I, self._construct_monomial, name='monomial')
2369
+
2370
+ def _construct_canonical_basis_elts(self, k):
2371
+ r"""
2372
+ Construct the monomial elements of ``self`` indexed by ``k``.
2373
+
2374
+ EXAMPLES::
2375
+
2376
+ sage: Q = QuantumGroup(['A',2])
2377
+ sage: B = Q.lower_half()
2378
+ sage: B._construct_canonical_basis_elts((1,2))
2379
+ [F[a1]*F[a2]^(2), (q^2)*F[a1]*F[a2]^(2) + F[a1+a2]*F[a2]]
2380
+ """
2381
+ B = self._libgap.CanonicalBasis()
2382
+ return [self.element_class(self, v) for v in B.PBWElements(k)]
2383
+
2384
+ @cached_method
2385
+ def canonical_basis_elements(self):
2386
+ r"""
2387
+ Construct the monomial elements of ``self`` indexed by ``k``.
2388
+
2389
+ EXAMPLES::
2390
+
2391
+ sage: Q = QuantumGroup(['A',2])
2392
+ sage: B = Q.lower_half()
2393
+ sage: C = B.canonical_basis_elements(); C
2394
+ Lazy family (Canonical basis(i))_{i in The Cartesian product of
2395
+ (Non negative integers, Non negative integers)}
2396
+ sage: C[2,1]
2397
+ [F[a1]^(2)*F[a2], F[a1]*F[a1+a2] + (q^2)*F[a1]^(2)*F[a2]]
2398
+ sage: C[1,2]
2399
+ [F[a1]*F[a2]^(2), (q^2)*F[a1]*F[a2]^(2) + F[a1+a2]*F[a2]]
2400
+ """
2401
+ I = cartesian_product([NonNegativeIntegers()]*len(self._cartan_type.index_set()))
2402
+ return Family(I, self._construct_canonical_basis_elts, name='Canonical basis')
2403
+
2404
+ def lift(self, elt):
2405
+ r"""
2406
+ Lift ``elt`` to the ambient quantum group of ``self``.
2407
+
2408
+ EXAMPLES::
2409
+
2410
+ sage: Q = QuantumGroup(['A',2])
2411
+ sage: B = Q.lower_half()
2412
+ sage: x = B.lift(B.an_element()); x
2413
+ 1
2414
+ sage: x.parent() is Q
2415
+ True
2416
+ """
2417
+ return self._Q.element_class(self._Q, elt._libgap)
2418
+
2419
+ def retract(self, elt):
2420
+ r"""
2421
+ Retract ``elt`` from the ambient quantum group to ``self``.
2422
+
2423
+ EXAMPLES::
2424
+
2425
+ sage: Q = QuantumGroup(['A',2])
2426
+ sage: B = Q.lower_half()
2427
+ sage: x = Q.an_element(); x
2428
+ 1 + (q)*F[a1] + E[a1] + (q^2-1-q^-2 + q^-4)*[ K1 ; 2 ]
2429
+ + K1 + (-q^-1 + q^-3)*K1[ K1 ; 1 ]
2430
+ sage: B.retract(x)
2431
+ 1 + (q)*F[a1]
2432
+ """
2433
+ return self.element_class(self, self._proj(elt)._libgap)
2434
+
2435
+ class Element(QuaGroupModuleElement):
2436
+ """
2437
+ An element of the lower half of the quantum group.
2438
+ """
2439
+ def _acted_upon_(self, scalar, self_on_left=False):
2440
+ r"""
2441
+ Return the action of ``scalar`` on ``self``.
2442
+
2443
+ EXAMPLES::
2444
+
2445
+ sage: Q = QuantumGroup(['A',2])
2446
+ sage: B = Q.lower_half()
2447
+ sage: F1, F2 = Q.F_simple()
2448
+ sage: v = B.highest_weight_vector(); v
2449
+ 1
2450
+ sage: 2 * v
2451
+ (2)*1
2452
+ sage: v * (3/2)
2453
+ (3/2)*1
2454
+ sage: F1 * v
2455
+ F[a1]
2456
+ sage: F2 * (F1 * v)
2457
+ (q)*F[a1]*F[a2] + F[a1+a2]
2458
+ sage: (F1 * v) * F2
2459
+ F[a1]*F[a2]
2460
+ """
2461
+ try:
2462
+ if scalar.parent() is self.parent()._Q:
2463
+ if self_on_left:
2464
+ ret = self._libgap * scalar._libgap
2465
+ else:
2466
+ ret = scalar._libgap * self._libgap
2467
+ return self.__class__(self.parent(), self.parent()._proj(ret)._libgap)
2468
+ except AttributeError:
2469
+ pass
2470
+ return QuaGroupModuleElement._acted_upon_(self, scalar, self_on_left)
2471
+
2472
+ _lmul_ = _acted_upon_
2473
+
2474
+ def _mul_(self, other):
2475
+ r"""
2476
+ Multiply ``self`` and ``other``.
2477
+
2478
+ EXAMPLES::
2479
+
2480
+ sage: Q = QuantumGroup(['A',2])
2481
+ sage: B = Q.lower_half()
2482
+ sage: F1, F2 = Q.F_simple()
2483
+ sage: v = B.highest_weight_vector()
2484
+ sage: f1, f2 = F1 * v, F2 * v
2485
+ sage: f1 * f2
2486
+ F[a1]*F[a2]
2487
+ sage: f1^2 * f2
2488
+ (q + q^-1)*F[a1]^(2)*F[a2]
2489
+ sage: f2 * f1^2 * f2
2490
+ (q + q^-1)*F[a1]*F[a1+a2]*F[a2]
2491
+ + (q^4 + 2*q^2 + 1)*F[a1]^(2)*F[a2]^(2)
2492
+ """
2493
+ ret = self.parent()._proj(self._libgap * other._libgap)
2494
+ return self.__class__(self.parent(), ret._libgap)
2495
+
2496
+ def monomial_coefficients(self, copy=True):
2497
+ r"""
2498
+ Return the dictionary of ``self`` whose keys are the basis
2499
+ indices and the values are coefficients.
2500
+
2501
+ EXAMPLES::
2502
+
2503
+ sage: Q = QuantumGroup(['A',2])
2504
+ sage: B = Q.lower_half()
2505
+ sage: x = B.retract(Q.an_element()); x
2506
+ 1 + (q)*F[a1]
2507
+ sage: sorted(x.monomial_coefficients().items(), key=str)
2508
+ [((0, 0, 0), 1), ((1, 0, 0), q)]
2509
+ """
2510
+ ext_rep = self._libgap.ExtRepOfObj()
2511
+ num_pos_roots = len(self.parent()._pos_roots)
2512
+ R = self.parent().base_ring()
2513
+ d = {}
2514
+ for i in range(len(ext_rep)//2):
2515
+ exp = [0] * num_pos_roots
2516
+ mon = ext_rep[2*i].sage()
2517
+ for j in range(len(mon)//2):
2518
+ exp[mon[2*j]-1] = mon[2*j+1]
2519
+ d[tuple(exp)] = R(str(ext_rep[2*i+1]))
2520
+ return d
2521
+
2522
+ def bar(self):
2523
+ r"""
2524
+ Return the bar involution on ``self``.
2525
+
2526
+ EXAMPLES::
2527
+
2528
+ sage: Q = QuantumGroup(['A',2])
2529
+ sage: F1, F2 = Q.F_simple()
2530
+ sage: B = Q.lower_half()
2531
+ sage: x = B(Q.an_element()); x
2532
+ 1 + (q)*F[a1]
2533
+ sage: x.bar()
2534
+ 1 + (q^-1)*F[a1]
2535
+ sage: (F1*x).bar() == F1 * x.bar()
2536
+ True
2537
+ sage: (F2*x).bar() == F2 * x.bar()
2538
+ True
2539
+
2540
+ sage: Q = QuantumGroup(['G',2])
2541
+ sage: F1, F2 = Q.F_simple()
2542
+ sage: q = Q.q()
2543
+ sage: B = Q.lower_half()
2544
+ sage: x = B(q^-2*F1*F2^2*F1)
2545
+ sage: x
2546
+ (q + q^-5)*F[a1]*F[a1+a2]*F[a2]
2547
+ + (q^8 + q^6 + q^2 + 1)*F[a1]^(2)*F[a2]^(2)
2548
+ sage: x.bar()
2549
+ (q^5 + q^-1)*F[a1]*F[a1+a2]*F[a2]
2550
+ + (q^12 + q^10 + q^6 + q^4)*F[a1]^(2)*F[a2]^(2)
2551
+ """
2552
+ bar = self.parent()._libgap.BarAutomorphism()
2553
+ # bar does not introduce E/K/Ki's
2554
+ return self.__class__(self.parent(), libgap.Image(bar, self._libgap))
2555
+
2556
+ def tau(self):
2557
+ r"""
2558
+ Return the action of the `\tau` anti-automorphism on ``self``.
2559
+
2560
+ EXAMPLES::
2561
+
2562
+ sage: Q = QuantumGroup(['A',2])
2563
+ sage: F1, F2 = Q.F_simple()
2564
+ sage: B = Q.lower_half()
2565
+ sage: x = B(Q.an_element()); x
2566
+ 1 + (q)*F[a1]
2567
+ sage: x.tau()
2568
+ 1 + (q)*F[a1]
2569
+ sage: (F1*x).tau() == x.tau() * F1.tau()
2570
+ True
2571
+ sage: (F2*x).tau() == x.tau() * F2.tau()
2572
+ True
2573
+
2574
+ sage: Q = QuantumGroup(['G',2])
2575
+ sage: F1, F2 = Q.F_simple()
2576
+ sage: q = Q.q()
2577
+ sage: B = Q.lower_half()
2578
+ sage: x = B(q^-2*F1*F2^2*F1)
2579
+ sage: x
2580
+ (q + q^-5)*F[a1]*F[a1+a2]*F[a2]
2581
+ + (q^8 + q^6 + q^2 + 1)*F[a1]^(2)*F[a2]^(2)
2582
+ sage: x.tau()
2583
+ (q + q^-5)*F[a1]*F[a1+a2]*F[a2]
2584
+ + (q^8 + q^6 + q^2 + 1)*F[a1]^(2)*F[a2]^(2)
2585
+ """
2586
+ tau = self.parent()._libgap.AntiAutomorphismTau()
2587
+ # tau does not introduce E/K/Ki's
2588
+ return self.__class__(self.parent(), libgap.Image(tau, self._libgap))
2589
+
2590
+ def braid_group_action(self, braid):
2591
+ r"""
2592
+ Return the action of the braid group element ``braid``
2593
+ projected into ``self``.
2594
+
2595
+ INPUT:
2596
+
2597
+ - ``braid`` -- a reduced word of a braid group element
2598
+
2599
+ EXAMPLES::
2600
+
2601
+ sage: Q = QuantumGroup(['A',2])
2602
+ sage: L = Q.lower_half()
2603
+ sage: v = L.highest_weight_vector().f_tilde([1,2,2,1]); v
2604
+ F[a1]*F[a1+a2]*F[a2]
2605
+ sage: v.braid_group_action([1])
2606
+ (-q^3-q)*F[a2]^(2)
2607
+ sage: v.braid_group_action([]) == v
2608
+ True
2609
+ """
2610
+ if not braid:
2611
+ return self
2612
+ Q = self.parent()
2613
+ QU = Q._libgap
2614
+ tau = QU.AntiAutomorphismTau()
2615
+ f = QU.IdentityMapping()
2616
+ for i in braid:
2617
+ if i < 0:
2618
+ i = -i
2619
+ T = QU.AutomorphismTalpha(i)
2620
+ f *= tau * T * tau
2621
+ else:
2622
+ f *= QU.AutomorphismTalpha(i)
2623
+ ret = libgap.Image(f, self._libgap)
2624
+ return self.__class__(Q, Q._proj(ret)._libgap)
2625
+
2626
+ def _et(self, i):
2627
+ r"""
2628
+ Return the action of `\widetilde{e}_i` on ``self``.
2629
+
2630
+ EXAMPLES::
2631
+
2632
+ sage: Q = QuantumGroup(['A',2])
2633
+ sage: L = Q.lower_half()
2634
+ sage: v = L.highest_weight_vector()
2635
+ sage: v._et(1)
2636
+ 0
2637
+ sage: w = v.f_tilde([1,2,1]); w
2638
+ F[a1]*F[a1+a2]
2639
+ sage: w._et(1)
2640
+ F[a1+a2]
2641
+ sage: w._et(2)
2642
+ F[a1]^(2)
2643
+ sage: L.zero().e_tilde(1)
2644
+ 0
2645
+ """
2646
+ if not self: # self == 0
2647
+ return self
2648
+ Q = self.parent()
2649
+ ret = self._libgap.Ealpha(i)
2650
+ if not ret:
2651
+ return self.parent().zero()
2652
+ return self.__class__(Q, Q._proj(ret)._libgap)
2653
+
2654
+ def _ft(self, i):
2655
+ r"""
2656
+ Return the action of `\widetilde{e}_i` on ``self``.
2657
+
2658
+ EXAMPLES::
2659
+
2660
+ sage: Q = QuantumGroup(['A',2])
2661
+ sage: L = Q.lower_half()
2662
+ sage: v = L.highest_weight_vector()
2663
+ sage: v._ft(1)
2664
+ F[a1]
2665
+ sage: L.zero().f_tilde(1)
2666
+ 0
2667
+ """
2668
+ if not self: # self == 0
2669
+ return self
2670
+ Q = self.parent()
2671
+ ret = self._libgap.Falpha(i)
2672
+ if not ret:
2673
+ return self.parent().zero()
2674
+ return self.__class__(Q, Q._proj(ret)._libgap)
2675
+
2676
+
2677
+ def _unpickle_generic_element(parent, data):
2678
+ """
2679
+ Used to unpickle an element of ``parent`` using ``data``.
2680
+
2681
+ EXAMPLES::
2682
+
2683
+ sage: Q = QuantumGroup(['D',4])
2684
+ sage: x = Q.an_element()
2685
+ sage: loads(dumps(x)) == x # indirect doctest
2686
+ True
2687
+ """
2688
+ F = parent._libgap.FamilyObj().ElementsFamily()
2689
+ ret = []
2690
+ # We need to multiply by this to get the right type in GAP
2691
+ one = parent._libgap_base.One()
2692
+ for i in range(len(data) // 2):
2693
+ ret.append(libgap(data[2 * i]))
2694
+ ret.append(one * libgap(data[2 * i + 1].subs(q=parent._libgap_q)))
2695
+ return parent.element_class(parent, F.ObjByExtRep(ret))