passagemath-combinat 10.6.42__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. passagemath_combinat/__init__.py +3 -0
  2. passagemath_combinat-10.6.42.dist-info/METADATA +160 -0
  3. passagemath_combinat-10.6.42.dist-info/RECORD +400 -0
  4. passagemath_combinat-10.6.42.dist-info/WHEEL +5 -0
  5. passagemath_combinat-10.6.42.dist-info/top_level.txt +3 -0
  6. passagemath_combinat.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  7. passagemath_combinat.libs/libsymmetrica-81fe8739.so.3.0.0 +0 -0
  8. sage/algebras/affine_nil_temperley_lieb.py +263 -0
  9. sage/algebras/all.py +24 -0
  10. sage/algebras/all__sagemath_combinat.py +35 -0
  11. sage/algebras/askey_wilson.py +935 -0
  12. sage/algebras/associated_graded.py +345 -0
  13. sage/algebras/cellular_basis.py +350 -0
  14. sage/algebras/cluster_algebra.py +2766 -0
  15. sage/algebras/down_up_algebra.py +860 -0
  16. sage/algebras/free_algebra.py +1698 -0
  17. sage/algebras/free_algebra_element.py +345 -0
  18. sage/algebras/free_algebra_quotient.py +405 -0
  19. sage/algebras/free_algebra_quotient_element.py +295 -0
  20. sage/algebras/free_zinbiel_algebra.py +885 -0
  21. sage/algebras/hall_algebra.py +783 -0
  22. sage/algebras/hecke_algebras/all.py +4 -0
  23. sage/algebras/hecke_algebras/ariki_koike_algebra.py +1796 -0
  24. sage/algebras/hecke_algebras/ariki_koike_specht_modules.py +475 -0
  25. sage/algebras/hecke_algebras/cubic_hecke_algebra.py +3520 -0
  26. sage/algebras/hecke_algebras/cubic_hecke_base_ring.py +1473 -0
  27. sage/algebras/hecke_algebras/cubic_hecke_matrix_rep.py +1079 -0
  28. sage/algebras/iwahori_hecke_algebra.py +3095 -0
  29. sage/algebras/jordan_algebra.py +1773 -0
  30. sage/algebras/lie_conformal_algebras/abelian_lie_conformal_algebra.py +113 -0
  31. sage/algebras/lie_conformal_algebras/affine_lie_conformal_algebra.py +156 -0
  32. sage/algebras/lie_conformal_algebras/all.py +18 -0
  33. sage/algebras/lie_conformal_algebras/bosonic_ghosts_lie_conformal_algebra.py +134 -0
  34. sage/algebras/lie_conformal_algebras/examples.py +43 -0
  35. sage/algebras/lie_conformal_algebras/fermionic_ghosts_lie_conformal_algebra.py +131 -0
  36. sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +139 -0
  37. sage/algebras/lie_conformal_algebras/free_bosons_lie_conformal_algebra.py +174 -0
  38. sage/algebras/lie_conformal_algebras/free_fermions_lie_conformal_algebra.py +167 -0
  39. sage/algebras/lie_conformal_algebras/freely_generated_lie_conformal_algebra.py +107 -0
  40. sage/algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py +135 -0
  41. sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +353 -0
  42. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_element.py +236 -0
  43. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py +78 -0
  44. sage/algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py +328 -0
  45. sage/algebras/lie_conformal_algebras/n2_lie_conformal_algebra.py +117 -0
  46. sage/algebras/lie_conformal_algebras/neveu_schwarz_lie_conformal_algebra.py +86 -0
  47. sage/algebras/lie_conformal_algebras/virasoro_lie_conformal_algebra.py +82 -0
  48. sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +205 -0
  49. sage/algebras/nil_coxeter_algebra.py +191 -0
  50. sage/algebras/q_commuting_polynomials.py +673 -0
  51. sage/algebras/q_system.py +608 -0
  52. sage/algebras/quantum_clifford.py +959 -0
  53. sage/algebras/quantum_groups/ace_quantum_onsager.py +693 -0
  54. sage/algebras/quantum_groups/all.py +9 -0
  55. sage/algebras/quantum_groups/fock_space.py +2219 -0
  56. sage/algebras/quantum_groups/q_numbers.py +207 -0
  57. sage/algebras/quantum_groups/quantum_group_gap.py +2695 -0
  58. sage/algebras/quantum_groups/representations.py +591 -0
  59. sage/algebras/quantum_matrix_coordinate_algebra.py +1006 -0
  60. sage/algebras/quantum_oscillator.py +623 -0
  61. sage/algebras/quaternion_algebra.py +20 -0
  62. sage/algebras/quaternion_algebra_element.py +55 -0
  63. sage/algebras/rational_cherednik_algebra.py +525 -0
  64. sage/algebras/schur_algebra.py +670 -0
  65. sage/algebras/shuffle_algebra.py +1011 -0
  66. sage/algebras/splitting_algebra.py +779 -0
  67. sage/algebras/tensor_algebra.py +709 -0
  68. sage/algebras/yangian.py +1082 -0
  69. sage/algebras/yokonuma_hecke_algebra.py +1018 -0
  70. sage/all__sagemath_combinat.py +35 -0
  71. sage/combinat/SJT.py +255 -0
  72. sage/combinat/affine_permutation.py +2405 -0
  73. sage/combinat/algebraic_combinatorics.py +55 -0
  74. sage/combinat/all.py +53 -0
  75. sage/combinat/all__sagemath_combinat.py +195 -0
  76. sage/combinat/alternating_sign_matrix.py +2063 -0
  77. sage/combinat/baxter_permutations.py +346 -0
  78. sage/combinat/bijectionist.py +3220 -0
  79. sage/combinat/binary_recurrence_sequences.py +1180 -0
  80. sage/combinat/blob_algebra.py +685 -0
  81. sage/combinat/catalog_partitions.py +27 -0
  82. sage/combinat/chas/all.py +23 -0
  83. sage/combinat/chas/fsym.py +1180 -0
  84. sage/combinat/chas/wqsym.py +2601 -0
  85. sage/combinat/cluster_complex.py +326 -0
  86. sage/combinat/colored_permutations.py +2039 -0
  87. sage/combinat/colored_permutations_representations.py +964 -0
  88. sage/combinat/composition_signed.py +142 -0
  89. sage/combinat/composition_tableau.py +855 -0
  90. sage/combinat/constellation.py +1729 -0
  91. sage/combinat/core.py +751 -0
  92. sage/combinat/counting.py +12 -0
  93. sage/combinat/crystals/affine.py +742 -0
  94. sage/combinat/crystals/affine_factorization.py +518 -0
  95. sage/combinat/crystals/affinization.py +331 -0
  96. sage/combinat/crystals/alcove_path.py +2013 -0
  97. sage/combinat/crystals/all.py +22 -0
  98. sage/combinat/crystals/bkk_crystals.py +141 -0
  99. sage/combinat/crystals/catalog.py +115 -0
  100. sage/combinat/crystals/catalog_elementary_crystals.py +18 -0
  101. sage/combinat/crystals/catalog_infinity_crystals.py +33 -0
  102. sage/combinat/crystals/catalog_kirillov_reshetikhin.py +18 -0
  103. sage/combinat/crystals/crystals.py +257 -0
  104. sage/combinat/crystals/direct_sum.py +260 -0
  105. sage/combinat/crystals/elementary_crystals.py +1251 -0
  106. sage/combinat/crystals/fast_crystals.py +441 -0
  107. sage/combinat/crystals/fully_commutative_stable_grothendieck.py +1205 -0
  108. sage/combinat/crystals/generalized_young_walls.py +1076 -0
  109. sage/combinat/crystals/highest_weight_crystals.py +436 -0
  110. sage/combinat/crystals/induced_structure.py +695 -0
  111. sage/combinat/crystals/infinity_crystals.py +730 -0
  112. sage/combinat/crystals/kac_modules.py +863 -0
  113. sage/combinat/crystals/kirillov_reshetikhin.py +4196 -0
  114. sage/combinat/crystals/kyoto_path_model.py +497 -0
  115. sage/combinat/crystals/letters.cpython-314-x86_64-linux-musl.so +0 -0
  116. sage/combinat/crystals/letters.pxd +79 -0
  117. sage/combinat/crystals/letters.pyx +3056 -0
  118. sage/combinat/crystals/littelmann_path.py +1518 -0
  119. sage/combinat/crystals/monomial_crystals.py +1262 -0
  120. sage/combinat/crystals/multisegments.py +462 -0
  121. sage/combinat/crystals/mv_polytopes.py +467 -0
  122. sage/combinat/crystals/pbw_crystal.py +511 -0
  123. sage/combinat/crystals/pbw_datum.cpython-314-x86_64-linux-musl.so +0 -0
  124. sage/combinat/crystals/pbw_datum.pxd +4 -0
  125. sage/combinat/crystals/pbw_datum.pyx +487 -0
  126. sage/combinat/crystals/polyhedral_realization.py +372 -0
  127. sage/combinat/crystals/spins.cpython-314-x86_64-linux-musl.so +0 -0
  128. sage/combinat/crystals/spins.pxd +21 -0
  129. sage/combinat/crystals/spins.pyx +756 -0
  130. sage/combinat/crystals/star_crystal.py +290 -0
  131. sage/combinat/crystals/subcrystal.py +464 -0
  132. sage/combinat/crystals/tensor_product.py +1177 -0
  133. sage/combinat/crystals/tensor_product_element.cpython-314-x86_64-linux-musl.so +0 -0
  134. sage/combinat/crystals/tensor_product_element.pxd +35 -0
  135. sage/combinat/crystals/tensor_product_element.pyx +1870 -0
  136. sage/combinat/crystals/virtual_crystal.py +420 -0
  137. sage/combinat/cyclic_sieving_phenomenon.py +204 -0
  138. sage/combinat/debruijn_sequence.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/combinat/debruijn_sequence.pyx +355 -0
  140. sage/combinat/decorated_permutation.py +270 -0
  141. sage/combinat/degree_sequences.cpython-314-x86_64-linux-musl.so +0 -0
  142. sage/combinat/degree_sequences.pyx +588 -0
  143. sage/combinat/derangements.py +527 -0
  144. sage/combinat/descent_algebra.py +1008 -0
  145. sage/combinat/diagram.py +1551 -0
  146. sage/combinat/diagram_algebras.py +5886 -0
  147. sage/combinat/dyck_word.py +4349 -0
  148. sage/combinat/e_one_star.py +1623 -0
  149. sage/combinat/enumerated_sets.py +123 -0
  150. sage/combinat/expnums.cpython-314-x86_64-linux-musl.so +0 -0
  151. sage/combinat/expnums.pyx +148 -0
  152. sage/combinat/fast_vector_partitions.cpython-314-x86_64-linux-musl.so +0 -0
  153. sage/combinat/fast_vector_partitions.pyx +346 -0
  154. sage/combinat/fqsym.py +1977 -0
  155. sage/combinat/free_dendriform_algebra.py +954 -0
  156. sage/combinat/free_prelie_algebra.py +1141 -0
  157. sage/combinat/fully_commutative_elements.py +1077 -0
  158. sage/combinat/fully_packed_loop.py +1523 -0
  159. sage/combinat/gelfand_tsetlin_patterns.py +1409 -0
  160. sage/combinat/gray_codes.py +311 -0
  161. sage/combinat/grossman_larson_algebras.py +667 -0
  162. sage/combinat/growth.py +4352 -0
  163. sage/combinat/hall_polynomial.py +188 -0
  164. sage/combinat/hillman_grassl.py +866 -0
  165. sage/combinat/integer_matrices.py +329 -0
  166. sage/combinat/integer_vectors_mod_permgroup.py +1238 -0
  167. sage/combinat/k_tableau.py +4564 -0
  168. sage/combinat/kazhdan_lusztig.py +215 -0
  169. sage/combinat/key_polynomial.py +885 -0
  170. sage/combinat/knutson_tao_puzzles.py +2286 -0
  171. sage/combinat/lr_tableau.py +311 -0
  172. sage/combinat/matrices/all.py +24 -0
  173. sage/combinat/matrices/hadamard_matrix.py +3790 -0
  174. sage/combinat/matrices/latin.py +2912 -0
  175. sage/combinat/misc.py +401 -0
  176. sage/combinat/multiset_partition_into_sets_ordered.py +3541 -0
  177. sage/combinat/ncsf_qsym/all.py +21 -0
  178. sage/combinat/ncsf_qsym/combinatorics.py +317 -0
  179. sage/combinat/ncsf_qsym/generic_basis_code.py +1427 -0
  180. sage/combinat/ncsf_qsym/ncsf.py +5637 -0
  181. sage/combinat/ncsf_qsym/qsym.py +4053 -0
  182. sage/combinat/ncsf_qsym/tutorial.py +447 -0
  183. sage/combinat/ncsym/all.py +21 -0
  184. sage/combinat/ncsym/bases.py +855 -0
  185. sage/combinat/ncsym/dual.py +593 -0
  186. sage/combinat/ncsym/ncsym.py +2076 -0
  187. sage/combinat/necklace.py +551 -0
  188. sage/combinat/non_decreasing_parking_function.py +634 -0
  189. sage/combinat/nu_dyck_word.py +1474 -0
  190. sage/combinat/output.py +861 -0
  191. sage/combinat/parallelogram_polyomino.py +4326 -0
  192. sage/combinat/parking_functions.py +1602 -0
  193. sage/combinat/partition_algebra.py +1998 -0
  194. sage/combinat/partition_kleshchev.py +1982 -0
  195. sage/combinat/partition_shifting_algebras.py +584 -0
  196. sage/combinat/partition_tuple.py +3114 -0
  197. sage/combinat/path_tableaux/all.py +13 -0
  198. sage/combinat/path_tableaux/catalog.py +29 -0
  199. sage/combinat/path_tableaux/dyck_path.py +380 -0
  200. sage/combinat/path_tableaux/frieze.py +476 -0
  201. sage/combinat/path_tableaux/path_tableau.py +728 -0
  202. sage/combinat/path_tableaux/semistandard.py +510 -0
  203. sage/combinat/perfect_matching.py +779 -0
  204. sage/combinat/plane_partition.py +3300 -0
  205. sage/combinat/q_bernoulli.cpython-314-x86_64-linux-musl.so +0 -0
  206. sage/combinat/q_bernoulli.pyx +128 -0
  207. sage/combinat/quickref.py +81 -0
  208. sage/combinat/recognizable_series.py +2051 -0
  209. sage/combinat/regular_sequence.py +4316 -0
  210. sage/combinat/regular_sequence_bounded.py +543 -0
  211. sage/combinat/restricted_growth.py +81 -0
  212. sage/combinat/ribbon.py +20 -0
  213. sage/combinat/ribbon_shaped_tableau.py +489 -0
  214. sage/combinat/ribbon_tableau.py +1180 -0
  215. sage/combinat/rigged_configurations/all.py +46 -0
  216. sage/combinat/rigged_configurations/bij_abstract_class.py +548 -0
  217. sage/combinat/rigged_configurations/bij_infinity.py +370 -0
  218. sage/combinat/rigged_configurations/bij_type_A.py +163 -0
  219. sage/combinat/rigged_configurations/bij_type_A2_dual.py +338 -0
  220. sage/combinat/rigged_configurations/bij_type_A2_even.py +218 -0
  221. sage/combinat/rigged_configurations/bij_type_A2_odd.py +199 -0
  222. sage/combinat/rigged_configurations/bij_type_B.py +900 -0
  223. sage/combinat/rigged_configurations/bij_type_C.py +267 -0
  224. sage/combinat/rigged_configurations/bij_type_D.py +771 -0
  225. sage/combinat/rigged_configurations/bij_type_D_tri.py +392 -0
  226. sage/combinat/rigged_configurations/bij_type_D_twisted.py +576 -0
  227. sage/combinat/rigged_configurations/bij_type_E67.py +402 -0
  228. sage/combinat/rigged_configurations/bijection.py +143 -0
  229. sage/combinat/rigged_configurations/kleber_tree.py +1475 -0
  230. sage/combinat/rigged_configurations/kr_tableaux.py +1898 -0
  231. sage/combinat/rigged_configurations/rc_crystal.py +461 -0
  232. sage/combinat/rigged_configurations/rc_infinity.py +540 -0
  233. sage/combinat/rigged_configurations/rigged_configuration_element.py +2403 -0
  234. sage/combinat/rigged_configurations/rigged_configurations.py +1918 -0
  235. sage/combinat/rigged_configurations/rigged_partition.cpython-314-x86_64-linux-musl.so +0 -0
  236. sage/combinat/rigged_configurations/rigged_partition.pxd +15 -0
  237. sage/combinat/rigged_configurations/rigged_partition.pyx +680 -0
  238. sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +499 -0
  239. sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +428 -0
  240. sage/combinat/rsk.py +3438 -0
  241. sage/combinat/schubert_polynomial.py +508 -0
  242. sage/combinat/set_partition.py +3318 -0
  243. sage/combinat/set_partition_iterator.cpython-314-x86_64-linux-musl.so +0 -0
  244. sage/combinat/set_partition_iterator.pyx +136 -0
  245. sage/combinat/set_partition_ordered.py +1590 -0
  246. sage/combinat/sf/abreu_nigro.py +346 -0
  247. sage/combinat/sf/all.py +52 -0
  248. sage/combinat/sf/character.py +576 -0
  249. sage/combinat/sf/classical.py +319 -0
  250. sage/combinat/sf/dual.py +996 -0
  251. sage/combinat/sf/elementary.py +549 -0
  252. sage/combinat/sf/hall_littlewood.py +1028 -0
  253. sage/combinat/sf/hecke.py +336 -0
  254. sage/combinat/sf/homogeneous.py +464 -0
  255. sage/combinat/sf/jack.py +1428 -0
  256. sage/combinat/sf/k_dual.py +1458 -0
  257. sage/combinat/sf/kfpoly.py +447 -0
  258. sage/combinat/sf/llt.py +789 -0
  259. sage/combinat/sf/macdonald.py +2019 -0
  260. sage/combinat/sf/monomial.py +525 -0
  261. sage/combinat/sf/multiplicative.py +113 -0
  262. sage/combinat/sf/new_kschur.py +1786 -0
  263. sage/combinat/sf/ns_macdonald.py +964 -0
  264. sage/combinat/sf/orthogonal.py +246 -0
  265. sage/combinat/sf/orthotriang.py +355 -0
  266. sage/combinat/sf/powersum.py +963 -0
  267. sage/combinat/sf/schur.py +880 -0
  268. sage/combinat/sf/sf.py +1653 -0
  269. sage/combinat/sf/sfa.py +7053 -0
  270. sage/combinat/sf/symplectic.py +253 -0
  271. sage/combinat/sf/witt.py +721 -0
  272. sage/combinat/shifted_primed_tableau.py +2735 -0
  273. sage/combinat/shuffle.py +830 -0
  274. sage/combinat/sidon_sets.py +146 -0
  275. sage/combinat/similarity_class_type.py +1721 -0
  276. sage/combinat/sine_gordon.py +618 -0
  277. sage/combinat/six_vertex_model.py +784 -0
  278. sage/combinat/skew_partition.py +2053 -0
  279. sage/combinat/skew_tableau.py +2989 -0
  280. sage/combinat/sloane_functions.py +8935 -0
  281. sage/combinat/specht_module.py +1403 -0
  282. sage/combinat/species/all.py +48 -0
  283. sage/combinat/species/characteristic_species.py +321 -0
  284. sage/combinat/species/composition_species.py +273 -0
  285. sage/combinat/species/cycle_species.py +284 -0
  286. sage/combinat/species/empty_species.py +155 -0
  287. sage/combinat/species/functorial_composition_species.py +148 -0
  288. sage/combinat/species/generating_series.py +673 -0
  289. sage/combinat/species/library.py +148 -0
  290. sage/combinat/species/linear_order_species.py +169 -0
  291. sage/combinat/species/misc.py +83 -0
  292. sage/combinat/species/partition_species.py +290 -0
  293. sage/combinat/species/permutation_species.py +268 -0
  294. sage/combinat/species/product_species.py +423 -0
  295. sage/combinat/species/recursive_species.py +476 -0
  296. sage/combinat/species/set_species.py +192 -0
  297. sage/combinat/species/species.py +820 -0
  298. sage/combinat/species/structure.py +539 -0
  299. sage/combinat/species/subset_species.py +243 -0
  300. sage/combinat/species/sum_species.py +225 -0
  301. sage/combinat/subword.py +564 -0
  302. sage/combinat/subword_complex.py +2122 -0
  303. sage/combinat/subword_complex_c.cpython-314-x86_64-linux-musl.so +0 -0
  304. sage/combinat/subword_complex_c.pyx +119 -0
  305. sage/combinat/super_tableau.py +821 -0
  306. sage/combinat/superpartition.py +1154 -0
  307. sage/combinat/symmetric_group_algebra.py +3774 -0
  308. sage/combinat/symmetric_group_representations.py +1830 -0
  309. sage/combinat/t_sequences.py +877 -0
  310. sage/combinat/tableau.py +9506 -0
  311. sage/combinat/tableau_residues.py +860 -0
  312. sage/combinat/tableau_tuple.py +5353 -0
  313. sage/combinat/tiling.py +2432 -0
  314. sage/combinat/triangles_FHM.py +777 -0
  315. sage/combinat/tutorial.py +1857 -0
  316. sage/combinat/vector_partition.py +337 -0
  317. sage/combinat/words/abstract_word.py +1722 -0
  318. sage/combinat/words/all.py +59 -0
  319. sage/combinat/words/alphabet.py +268 -0
  320. sage/combinat/words/finite_word.py +7201 -0
  321. sage/combinat/words/infinite_word.py +113 -0
  322. sage/combinat/words/lyndon_word.py +652 -0
  323. sage/combinat/words/morphic.py +351 -0
  324. sage/combinat/words/morphism.py +3878 -0
  325. sage/combinat/words/paths.py +2932 -0
  326. sage/combinat/words/shuffle_product.py +278 -0
  327. sage/combinat/words/suffix_trees.py +1873 -0
  328. sage/combinat/words/word.py +769 -0
  329. sage/combinat/words/word_char.cpython-314-x86_64-linux-musl.so +0 -0
  330. sage/combinat/words/word_char.pyx +847 -0
  331. sage/combinat/words/word_datatypes.cpython-314-x86_64-linux-musl.so +0 -0
  332. sage/combinat/words/word_datatypes.pxd +4 -0
  333. sage/combinat/words/word_datatypes.pyx +1067 -0
  334. sage/combinat/words/word_generators.py +2026 -0
  335. sage/combinat/words/word_infinite_datatypes.py +1218 -0
  336. sage/combinat/words/word_options.py +99 -0
  337. sage/combinat/words/words.py +2396 -0
  338. sage/data_structures/all__sagemath_combinat.py +1 -0
  339. sage/databases/all__sagemath_combinat.py +13 -0
  340. sage/databases/findstat.py +4897 -0
  341. sage/databases/oeis.py +2058 -0
  342. sage/databases/sloane.py +393 -0
  343. sage/dynamics/all__sagemath_combinat.py +14 -0
  344. sage/dynamics/cellular_automata/all.py +7 -0
  345. sage/dynamics/cellular_automata/catalog.py +34 -0
  346. sage/dynamics/cellular_automata/elementary.py +612 -0
  347. sage/dynamics/cellular_automata/glca.py +477 -0
  348. sage/dynamics/cellular_automata/solitons.py +1463 -0
  349. sage/dynamics/finite_dynamical_system.py +1249 -0
  350. sage/dynamics/finite_dynamical_system_catalog.py +382 -0
  351. sage/games/all.py +7 -0
  352. sage/games/hexad.py +704 -0
  353. sage/games/quantumino.py +591 -0
  354. sage/games/sudoku.py +889 -0
  355. sage/games/sudoku_backtrack.cpython-314-x86_64-linux-musl.so +0 -0
  356. sage/games/sudoku_backtrack.pyx +189 -0
  357. sage/groups/all__sagemath_combinat.py +1 -0
  358. sage/groups/indexed_free_group.py +489 -0
  359. sage/libs/all__sagemath_combinat.py +6 -0
  360. sage/libs/lrcalc/__init__.py +1 -0
  361. sage/libs/lrcalc/lrcalc.py +525 -0
  362. sage/libs/symmetrica/__init__.py +7 -0
  363. sage/libs/symmetrica/all.py +101 -0
  364. sage/libs/symmetrica/kostka.pxi +168 -0
  365. sage/libs/symmetrica/part.pxi +193 -0
  366. sage/libs/symmetrica/plet.pxi +42 -0
  367. sage/libs/symmetrica/sab.pxi +196 -0
  368. sage/libs/symmetrica/sb.pxi +332 -0
  369. sage/libs/symmetrica/sc.pxi +192 -0
  370. sage/libs/symmetrica/schur.pxi +956 -0
  371. sage/libs/symmetrica/symmetrica.cpython-314-x86_64-linux-musl.so +0 -0
  372. sage/libs/symmetrica/symmetrica.pxi +1172 -0
  373. sage/libs/symmetrica/symmetrica.pyx +39 -0
  374. sage/monoids/all.py +13 -0
  375. sage/monoids/automatic_semigroup.py +1054 -0
  376. sage/monoids/free_abelian_monoid.py +315 -0
  377. sage/monoids/free_abelian_monoid_element.cpython-314-x86_64-linux-musl.so +0 -0
  378. sage/monoids/free_abelian_monoid_element.pxd +16 -0
  379. sage/monoids/free_abelian_monoid_element.pyx +397 -0
  380. sage/monoids/free_monoid.py +335 -0
  381. sage/monoids/free_monoid_element.py +431 -0
  382. sage/monoids/hecke_monoid.py +65 -0
  383. sage/monoids/string_monoid.py +817 -0
  384. sage/monoids/string_monoid_element.py +547 -0
  385. sage/monoids/string_ops.py +143 -0
  386. sage/monoids/trace_monoid.py +972 -0
  387. sage/rings/all__sagemath_combinat.py +2 -0
  388. sage/sat/all.py +4 -0
  389. sage/sat/boolean_polynomials.py +405 -0
  390. sage/sat/converters/__init__.py +6 -0
  391. sage/sat/converters/anf2cnf.py +14 -0
  392. sage/sat/converters/polybori.py +611 -0
  393. sage/sat/solvers/__init__.py +5 -0
  394. sage/sat/solvers/cryptominisat.py +287 -0
  395. sage/sat/solvers/dimacs.py +783 -0
  396. sage/sat/solvers/picosat.py +228 -0
  397. sage/sat/solvers/sat_lp.py +156 -0
  398. sage/sat/solvers/satsolver.cpython-314-x86_64-linux-musl.so +0 -0
  399. sage/sat/solvers/satsolver.pxd +3 -0
  400. sage/sat/solvers/satsolver.pyx +405 -0
@@ -0,0 +1,4196 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.graphs sage.modules
3
+ r"""
4
+ Kirillov-Reshetikhin crystals
5
+ """
6
+
7
+ # ****************************************************************************
8
+ # Copyright (C) 2009 Anne Schilling <anne at math.ucdavis.edu>
9
+ # 2014-2018 Travis Scrimshaw <tcscrims at gmail.com>
10
+ #
11
+ # Distributed under the terms of the GNU General Public License (GPL)
12
+ #
13
+ # This code is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
+ # General Public License for more details.
17
+ #
18
+ # The full text of the GPL is available at:
19
+ #
20
+ # https://www.gnu.org/licenses/
21
+ # ***************************************************************************
22
+ # Acknowledgment: most of the design and implementation of this
23
+ # library is heavily inspired from MuPAD-Combinat.
24
+ # ***************************************************************************
25
+
26
+ from sage.misc.cachefunc import cached_method
27
+ from sage.misc.lazy_attribute import lazy_attribute
28
+ from sage.misc.functional import is_even, is_odd
29
+ from sage.combinat.combinat import CombinatorialObject
30
+ from sage.structure.parent import Parent
31
+ from sage.categories.crystals import CrystalMorphism
32
+ from sage.categories.loop_crystals import KirillovReshetikhinCrystals
33
+ from sage.categories.homset import Hom
34
+ from sage.categories.map import Map
35
+ from sage.rings.integer import Integer
36
+ from sage.rings.rational_field import QQ
37
+ from sage.combinat.crystals.affine import (AffineCrystalFromClassical,
38
+ AffineCrystalFromClassicalElement,
39
+ AffineCrystalFromClassicalAndPromotion,
40
+ AffineCrystalFromClassicalAndPromotionElement)
41
+ from sage.combinat.crystals.highest_weight_crystals import HighestWeightCrystal
42
+ from sage.combinat.crystals.littelmann_path import CrystalOfProjectedLevelZeroLSPaths
43
+ from sage.combinat.crystals.direct_sum import DirectSumOfCrystals
44
+ from sage.combinat.root_system.cartan_type import CartanType
45
+ from sage.combinat.root_system.root_system import RootSystem
46
+ from sage.combinat.crystals.tensor_product import CrystalOfTableaux
47
+ from sage.combinat.tableau import Tableau
48
+ from sage.combinat.partition import Partition, Partitions, partitions_in_box
49
+ from sage.combinat.integer_vector import IntegerVectors
50
+
51
+
52
+ def KirillovReshetikhinCrystalFromLSPaths(cartan_type, r, s=1):
53
+ r"""
54
+ Single column Kirillov-Reshetikhin crystals.
55
+
56
+ This yields the single column Kirillov-Reshetikhin crystals
57
+ from the projected level zero LS paths, see
58
+ :class:`~sage.combinat.crystals.littelmann_path.CrystalOfLSPaths`.
59
+ This works for all types (even exceptional types).
60
+ The weight of the canonical element in this crystal is `\Lambda_r`.
61
+ For other implementation see
62
+ :func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`.
63
+
64
+ EXAMPLES::
65
+
66
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['A',2,1],2) # indirect doctest
67
+ sage: KR = crystals.KirillovReshetikhin(['A',2,1],2,1)
68
+ sage: G = K.digraph()
69
+ sage: GR = KR.digraph()
70
+ sage: G.is_isomorphic(GR, edge_labels = True)
71
+ True
72
+
73
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['C',3,1],2)
74
+ sage: KR = crystals.KirillovReshetikhin(['C',3,1],2,1)
75
+ sage: G = K.digraph()
76
+ sage: GR = KR.digraph()
77
+ sage: G.is_isomorphic(GR, edge_labels = True)
78
+ True
79
+
80
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['E',6,1],1)
81
+ sage: KR = crystals.KirillovReshetikhin(['E',6,1],1,1)
82
+ sage: G = K.digraph()
83
+ sage: GR = KR.digraph()
84
+ sage: G.is_isomorphic(GR, edge_labels = True)
85
+ True
86
+ sage: K.cardinality()
87
+ 27
88
+
89
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['G',2,1],1)
90
+ sage: K.cardinality()
91
+ 7
92
+
93
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['B',3,1],2)
94
+ sage: KR = crystals.KirillovReshetikhin(['B',3,1],2,1)
95
+ sage: KR.cardinality()
96
+ 22
97
+ sage: K.cardinality()
98
+ 22
99
+ sage: G = K.digraph()
100
+ sage: GR = KR.digraph()
101
+ sage: G.is_isomorphic(GR, edge_labels = True)
102
+ True
103
+
104
+ TESTS::
105
+
106
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['G',2,1],2)
107
+ sage: K.cardinality()
108
+ 15
109
+
110
+ For `s > 1` these crystals yield `s`-fold tensor products of
111
+ Kirillov-Reshetikhin crystals::
112
+
113
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['A',1,1],1,3)
114
+ sage: B = crystals.KirillovReshetikhin(['A',1,1],1,1)
115
+ sage: T = crystals.TensorProduct(B,B,B)
116
+ sage: G = K.digraph()
117
+ sage: GT = T.digraph()
118
+ sage: G.is_isomorphic(GT, edge_labels = True)
119
+ True
120
+
121
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['B',2,1],1,2)
122
+ sage: B = crystals.KirillovReshetikhin(['B',2,1],1,1)
123
+ sage: T = crystals.TensorProduct(B,B)
124
+ sage: G = K.digraph()
125
+ sage: GT = T.digraph()
126
+ sage: G.is_isomorphic(GT, edge_labels = True)
127
+ True
128
+
129
+ sage: K = crystals.kirillov_reshetikhin.LSPaths(['B',2,1],2,3)
130
+ sage: B = crystals.KirillovReshetikhin(['B',2,1],2,1)
131
+ sage: T = crystals.TensorProduct(B,B,B)
132
+ sage: GT = T.digraph()
133
+ sage: G = K.digraph()
134
+ sage: G.is_isomorphic(GT, edge_labels = True)
135
+ True
136
+ """
137
+ R = RootSystem(cartan_type)
138
+ La = R.weight_space().basis()
139
+ weight = s*La[r]
140
+ return CrystalOfProjectedLevelZeroLSPaths(weight)
141
+
142
+
143
+ def KirillovReshetikhinCrystal(cartan_type, r, s, model='KN'):
144
+ r"""
145
+ Return the Kirillov-Reshetikhin crystal `B^{r,s}` of the given type
146
+ in the given model.
147
+
148
+ For more information about general crystals see
149
+ :mod:`sage.combinat.crystals.crystals`.
150
+
151
+ There are a variety of models for Kirillov-Reshetikhin crystals. There is
152
+ one using the classical crystal with :func:`Kashiwara-Nakashima tableaux
153
+ <sage.combinat.crystals.kirillov_reshetikhin.KashiwaraNakashimaTableaux>`.
154
+ There is one using :class:`rigged configurations <RiggedConfigurations>`.
155
+ Another tableaux model comes from the bijection between rigged configurations
156
+ and tensor products of tableaux called :class:`Kirillov-Reshetikhin tableaux
157
+ <sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableaux>`
158
+ Lastly there is a model of Kirillov-Reshetikhin crystals for `s = 1` from
159
+ crystals of :func:`LS paths
160
+ <sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystalFromLSPaths>`.
161
+
162
+ INPUT:
163
+
164
+ - ``cartan_type`` -- an affine Cartan type
165
+
166
+ - ``r`` -- a label of finite Dynkin diagram
167
+
168
+ - ``s`` -- positive integer
169
+
170
+ - ``model`` -- (default: ``'KN'``) can be one of the following:
171
+
172
+ * ``'KN'`` or ``'KashiwaraNakashimaTableaux'`` -- use the
173
+ Kashiwara-Nakashima tableaux model
174
+ * ``'KR'`` or ``'KirillovReshetkihinTableaux'`` -- use the
175
+ Kirillov-Reshetkihin tableaux model
176
+ * ``'RC'`` or ``'RiggedConfiguration'`` -- use the rigged
177
+ configuration model
178
+ * ``'LSPaths'`` -- use the LS path model
179
+
180
+ EXAMPLES::
181
+
182
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2, 1)
183
+ sage: K.index_set()
184
+ (0, 1, 2, 3)
185
+ sage: K.list()
186
+ [[[1], [2]], [[1], [3]], [[2], [3]], [[1], [4]], [[2], [4]], [[3], [4]]]
187
+ sage: b=K(rows=[[1],[2]])
188
+ sage: b.weight()
189
+ -Lambda[0] + Lambda[2]
190
+
191
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
192
+ sage: K.automorphism(K.module_generators[0])
193
+ [[2, 2], [3, 3]]
194
+ sage: K.module_generators[0].e(0)
195
+ [[1, 2], [2, 4]]
196
+ sage: K.module_generators[0].f(2)
197
+ [[1, 1], [2, 3]]
198
+ sage: K.module_generators[0].f(1)
199
+ sage: K.module_generators[0].phi(0)
200
+ 0
201
+ sage: K.module_generators[0].phi(1)
202
+ 0
203
+ sage: K.module_generators[0].phi(2)
204
+ 2
205
+ sage: K.module_generators[0].epsilon(0)
206
+ 2
207
+ sage: K.module_generators[0].epsilon(1)
208
+ 0
209
+ sage: K.module_generators[0].epsilon(2)
210
+ 0
211
+ sage: b = K(rows=[[1,2],[2,3]])
212
+ sage: b
213
+ [[1, 2], [2, 3]]
214
+ sage: b.f(2)
215
+ [[1, 2], [3, 3]]
216
+
217
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2, 1)
218
+ sage: K.cartan_type()
219
+ ['D', 4, 1]
220
+ sage: type(K.module_generators[0])
221
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_vertical_with_category.element_class'>
222
+
223
+ The following gives some tests with regards to Lemma 3.11 in [LOS2012]_.
224
+
225
+ TESTS::
226
+
227
+ sage: K = crystals.KirillovReshetikhin(['A',4,2],2,1)
228
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
229
+ sage: [b for b in K if b.Epsilon() == Lambda[0]]
230
+ [[]]
231
+
232
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],1,2)
233
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
234
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[0]]
235
+ [[]]
236
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[3]]
237
+ [[[3, -3]]]
238
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],1,1)
239
+ sage: [b for b in K if b.Epsilon() == Lambda[3]]
240
+ [[[0]]]
241
+
242
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],2,1)
243
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
244
+ sage: [b for b in K if b.Epsilon() == Lambda[0]]
245
+ [[]]
246
+ sage: [b for b in K if b.Epsilon() == Lambda[1]]
247
+ [[[2], [-2]]]
248
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],2,2)
249
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[0]]
250
+ [[]]
251
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[1]]
252
+ [[[1, 2], [-2, -1]]]
253
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],2,3)
254
+ sage: [b for b in K if b.Epsilon() == 3*Lambda[1]] # long time
255
+ [[[1, 2, 2], [-2, -2, -1]]]
256
+
257
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],2,2)
258
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
259
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time
260
+ [[]]
261
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[4]] # long time
262
+ [[[3, -4], [4, -3]]]
263
+
264
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1)
265
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
266
+ sage: [b for b in K if b.Epsilon() == Lambda[0]]
267
+ [[+++, []]]
268
+ sage: [b for b in K if b.Epsilon() == Lambda[1]]
269
+ [[-++, []]]
270
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,3)
271
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time
272
+ [[+++, [[1]]]]
273
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[1]] # long time
274
+ [[-++, [[-1]]]]
275
+
276
+ sage: K = crystals.KirillovReshetikhin(['B',4,1],4,1)
277
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
278
+ sage: [b for b in K if b.Epsilon() == Lambda[0]]
279
+ [[++++, []]]
280
+ sage: [b for b in K if b.Epsilon() == Lambda[1]]
281
+ [[-+++, []]]
282
+
283
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],1,1)
284
+ sage: Lambda = K.weight_lattice_realization().fundamental_weights()
285
+ sage: [b for b in K if b.Epsilon() == Lambda[0]]
286
+ [[[1]]]
287
+ sage: [b for b in K if b.Epsilon() == Lambda[3]]
288
+ [[[-3]]]
289
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],1,3)
290
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[3]] # long time
291
+ [[[3, -3, -3]]]
292
+ sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time
293
+ [[[1]]]
294
+
295
+ We check the various models agree::
296
+
297
+ sage: KN = crystals.KirillovReshetikhin(['D',4,1], 2, 1)
298
+ sage: KR = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='KR')
299
+ sage: RC = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='RC')
300
+ sage: LS = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='LSPaths')
301
+ sage: G = KN.digraph()
302
+ sage: G.is_isomorphic(KR.digraph(), edge_labels=True)
303
+ True
304
+ sage: G.is_isomorphic(RC.digraph(), edge_labels=True)
305
+ True
306
+ sage: G.is_isomorphic(LS.digraph(), edge_labels=True)
307
+ True
308
+
309
+ sage: KN = crystals.KirillovReshetikhin(['D',4,1], 2, 1)
310
+ sage: KN2 = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='KN')
311
+ sage: KN3 = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='KashiwaraNakashimaTableaux')
312
+ sage: KN is KN2 and KN is KN3
313
+ True
314
+
315
+ REFERENCES:
316
+
317
+ - [Shi2002]_
318
+
319
+ - [Sch2008]_
320
+
321
+ - [JS2010]_
322
+
323
+ - [FOS2009]_
324
+
325
+ - [LOS2012]_
326
+ """
327
+ if model in ['KN', 'KashiwaraNakashimaTableaux']:
328
+ return KashiwaraNakashimaTableaux(cartan_type, r, s)
329
+ if model in ['KR', 'KirillovReshetikhinTableaux']:
330
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableaux
331
+ return KirillovReshetikhinTableaux(cartan_type, r, s)
332
+ if model in ['RC', 'RiggedConfigurations']:
333
+ from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations
334
+ return RiggedConfigurations(cartan_type, [[r, s]])
335
+ if model == 'LSPaths':
336
+ return KirillovReshetikhinCrystalFromLSPaths(cartan_type, r, s)
337
+
338
+ raise ValueError("invalid model")
339
+
340
+
341
+ def KashiwaraNakashimaTableaux(cartan_type, r, s):
342
+ r"""
343
+ Return the Kashiwara-Nakashima model for the Kirillov-Reshetikhin crystal
344
+ `B^{r,s}` in the given type.
345
+
346
+ The Kashiwara-Nakashima (KN) model constructs the KR crystal from the
347
+ KN tableaux model for the corresponding classical crystals. This model
348
+ is named for the underlying KN tableaux.
349
+
350
+ Many Kirillov-Reshetikhin crystals are constructed from a
351
+ classical crystal together with an automorphism `p` on the level of
352
+ crystals which corresponds to a Dynkin diagram automorphism mapping
353
+ node 0 to some other node `i`. The action of `f_0` and `e_0` is then
354
+ constructed using `f_0 = p^{-1} \circ f_i \circ p`.
355
+
356
+ For example, for type `A_n^{(1)}` the Kirillov-Reshetikhin crystal `B^{r,s}`
357
+ is obtained from the classical crystal `B(s \omega_r)` using the
358
+ promotion operator. For other types, see [Shi2002]_, [Sch2008]_,
359
+ and [JS2010]_.
360
+
361
+ Other Kirillov-Reshetikhin crystals are constructed using similarity methods.
362
+ See Section 4 of [FOS2009]_.
363
+
364
+ For more information on Kirillov-Reshetikhin crystals, see
365
+ :func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`.
366
+
367
+ EXAMPLES::
368
+
369
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2, 1)
370
+ sage: K2 = crystals.kirillov_reshetikhin.KashiwaraNakashimaTableaux(['A',3,1], 2, 1)
371
+ sage: K is K2
372
+ True
373
+ """
374
+ ct = CartanType(cartan_type)
375
+ assert ct.is_affine()
376
+ if ct.is_untwisted_affine():
377
+ if ct.type() == 'A':
378
+ return KR_type_A(ct, r, s)
379
+ elif ct.type() == 'D':
380
+ if r < ct.rank()-2:
381
+ return KR_type_vertical(ct, r, s)
382
+ elif r in {ct.rank()-2, ct.rank()-1}:
383
+ return KR_type_spin(ct, r, s)
384
+ else:
385
+ raise ValueError("wrong range of parameters")
386
+ elif ct.type() == 'B':
387
+ if r < ct.rank()-1:
388
+ return KR_type_vertical(ct, r, s)
389
+ elif r == ct.rank()-1:
390
+ return KR_type_Bn(ct, r, s)
391
+ else:
392
+ raise ValueError("wrong range of parameters")
393
+ elif ct.type() == 'C':
394
+ if r < ct.rank()-1:
395
+ return KR_type_C(ct, r, s)
396
+ elif r == ct.rank()-1:
397
+ return KR_type_Cn(ct, r, s)
398
+ else:
399
+ raise ValueError("wrong range of parameters")
400
+ elif ct == CartanType(['E', 6, 1]) and r in [1, 6, 2]:
401
+ return KR_type_E6(ct, r, s)
402
+ elif ct == CartanType(['E', 7, 1]) and r in [7]:
403
+ return KR_type_E7(ct, r, s)
404
+ else:
405
+ raise NotImplementedError
406
+ else:
407
+ if ct.dual().type() == 'B':
408
+ return KR_type_vertical(ct, r, s)
409
+ elif ct.type() == 'BC':
410
+ return KR_type_box(ct, r, s)
411
+ elif ct.dual().type() == 'BC':
412
+ return KR_type_A2(ct, r, s)
413
+ elif ct.dual().type() == 'C':
414
+ if r < ct.rank()-1:
415
+ return KR_type_box(ct, r, s)
416
+ elif r == ct.rank()-1:
417
+ return KR_type_Dn_twisted(ct, r, s)
418
+ else:
419
+ raise ValueError("wrong range of parameters")
420
+ elif ct.dual().type() == 'G':
421
+ if r == 1:
422
+ return KR_type_D_tri1(ct, s)
423
+ raise NotImplementedError
424
+ else:
425
+ raise NotImplementedError
426
+
427
+
428
+ class KirillovReshetikhinGenericCrystal(AffineCrystalFromClassical):
429
+ r"""
430
+ Generic class for Kirillov-Reshetikhin crystal `B^{r,s}` of the given type.
431
+
432
+ Input is a Dynkin node ``r``, a positive integer ``s``, and a Cartan type
433
+ ``cartan_type``.
434
+ """
435
+
436
+ def __init__(self, cartan_type, r, s, dual=None):
437
+ r"""
438
+ Initialize a generic Kirillov-Reshetikhin crystal.
439
+
440
+ TESTS::
441
+
442
+ sage: K = crystals.KirillovReshetikhin(CartanType(['A',2,1]), 1, 1)
443
+ sage: K
444
+ Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1)
445
+ sage: K.r()
446
+ 1
447
+ sage: K.s()
448
+ 1
449
+ """
450
+ # We need this here for the classic al_decomposition() call
451
+ Parent.__init__(self, category=KirillovReshetikhinCrystals())
452
+ if dual is None:
453
+ self._cartan_type = cartan_type
454
+ else:
455
+ self._cartan_type = CartanType(cartan_type).dual()
456
+ self._r = r
457
+ self._s = s
458
+ self._dual = dual
459
+ AffineCrystalFromClassical.__init__(self, cartan_type, self.classical_decomposition(),
460
+ KirillovReshetikhinCrystals())
461
+
462
+ def _repr_(self):
463
+ """
464
+ EXAMPLES::
465
+
466
+ sage: crystals.KirillovReshetikhin(CartanType(['A',2,1]), 1, 1) # indirect doctest
467
+ Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1)
468
+ """
469
+ return "Kirillov-Reshetikhin crystal of type %s with (r,s)=(%d,%d)" % (self.cartan_type(), self.r(), self.s())
470
+
471
+ def _element_constructor_(self, *args, **options):
472
+ """
473
+ Construct an element of ``self`` from the input.
474
+
475
+ EXAMPLES::
476
+
477
+ sage: K = crystals.KirillovReshetikhin(['A', 4, 1], 2, 1)
478
+ sage: K(columns=[[2,1]])
479
+ [[1], [2]]
480
+ """
481
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement
482
+ if isinstance(args[0], KirillovReshetikhinTableauxElement):
483
+ elt = args[0]
484
+ # Check to make sure it can be converted
485
+ if elt.cartan_type() != self.cartan_type() \
486
+ or elt.parent().r() != self._r or elt.parent().s() != self._s:
487
+ raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
488
+
489
+ to_hw = elt.to_classical_highest_weight()
490
+ rows = []
491
+ letters = elt.parent().letters
492
+ for i, mult in sorted(to_hw[0].classical_weight()):
493
+ # val in classical weight is a pair (i, mult)
494
+ rows.append([letters(i+1)] * int(mult))
495
+ hw_elt = self(rows=rows)
496
+ f_str = reversed(to_hw[1])
497
+ return hw_elt.f_string(f_str)
498
+ return AffineCrystalFromClassical._element_constructor_(self, *args, **options)
499
+
500
+ def module_generator(self):
501
+ r"""
502
+ Return the unique module generator of classical weight
503
+ `s \Lambda_r` of a Kirillov-Reshetikhin crystal `B^{r,s}`
504
+
505
+ EXAMPLES::
506
+
507
+ sage: K = crystals.KirillovReshetikhin(['C',2,1],1,2)
508
+ sage: K.module_generator()
509
+ [[1, 1]]
510
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],1,1)
511
+ sage: K.module_generator()
512
+ [(1,)]
513
+
514
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],2,1)
515
+ sage: K.module_generator()
516
+ [[1], [2]]
517
+ """
518
+ R = self.weight_lattice_realization()
519
+ Lambda = R.fundamental_weights()
520
+ r = self.r()
521
+ s = self.s()
522
+ weight = s*Lambda[r] - s*Lambda[0] * Lambda[r].level() / Lambda[0].level()
523
+ return next(b for b in self.module_generators if b.weight() == weight)
524
+
525
+ def r(self):
526
+ """
527
+ Return `r` of the underlying Kirillov-Reshetikhin crystal `B^{r,s}`.
528
+
529
+ EXAMPLES::
530
+
531
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2, 1)
532
+ sage: K.r()
533
+ 2
534
+ """
535
+ return self._r
536
+
537
+ def s(self):
538
+ """
539
+ Return `s` of the underlying Kirillov-Reshetikhin crystal `B^{r,s}`.
540
+
541
+ EXAMPLES::
542
+
543
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2, 1)
544
+ sage: K.s()
545
+ 1
546
+ """
547
+ return self._s
548
+
549
+ @cached_method
550
+ def classically_highest_weight_vectors(self):
551
+ """
552
+ Return the classically highest weight vectors of ``self``.
553
+
554
+ EXAMPLES::
555
+
556
+ sage: K = crystals.KirillovReshetikhin(['D', 4, 1], 2, 2)
557
+ sage: K.classically_highest_weight_vectors()
558
+ ([], [[1], [2]], [[1, 1], [2, 2]])
559
+ """
560
+ return tuple([self.retract(mg)
561
+ for mg in self.classical_decomposition().module_generators])
562
+
563
+ def kirillov_reshetikhin_tableaux(self):
564
+ """
565
+ Return the corresponding set of
566
+ :class:`~sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableaux`.
567
+
568
+ EXAMPLES::
569
+
570
+ sage: KRC = crystals.KirillovReshetikhin(['D', 4, 1], 2, 2)
571
+ sage: KRC.kirillov_reshetikhin_tableaux()
572
+ Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and shape (2, 2)
573
+ """
574
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableaux
575
+ return KirillovReshetikhinTableaux(self.cartan_type(), self._r, self._s)
576
+
577
+
578
+ class KirillovReshetikhinGenericCrystalElement(AffineCrystalFromClassicalElement):
579
+ """
580
+ Abstract class for all Kirillov-Reshetikhin crystal elements.
581
+ """
582
+
583
+ def _repr_diagram(self):
584
+ """
585
+ Return a string representation of ``self`` as a diagram.
586
+
587
+ EXAMPLES::
588
+
589
+ sage: C = crystals.KirillovReshetikhin(['D',4,1], 2,1)
590
+ sage: print(C(2,1)._repr_diagram())
591
+ 1
592
+ 2
593
+ """
594
+ return self.lift()._repr_diagram()
595
+
596
+ def pp(self):
597
+ """
598
+ Pretty print ``self``.
599
+
600
+ EXAMPLES::
601
+
602
+ sage: C = crystals.KirillovReshetikhin(['D',4,1], 2,1)
603
+ sage: C(2,1).pp()
604
+ 1
605
+ 2
606
+ sage: C = crystals.KirillovReshetikhin(['B',3,1], 3,3)
607
+ sage: C.module_generators[0].pp()
608
+ + (X) 1
609
+ +
610
+ +
611
+ """
612
+ print(self._repr_diagram())
613
+
614
+ @cached_method
615
+ def to_kirillov_reshetikhin_tableau(self):
616
+ r"""
617
+ Construct the corresponding
618
+ :class:`~sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableauxElement`
619
+ from ``self``.
620
+
621
+ We construct the Kirillov-Reshetikhin tableau element as follows:
622
+
623
+ 1. Let `\lambda` be the shape of ``self``.
624
+ 2. Determine a path `e_{i_1} e_{i_2} \cdots e_{i_k}` to the highest
625
+ weight.
626
+ 3. Apply `f_{i_k} \cdots f_{i_2} f_{i_1}` to a highest weight KR
627
+ tableau from filling the shape `\lambda`.
628
+
629
+ EXAMPLES::
630
+
631
+ sage: KRC = crystals.KirillovReshetikhin(['A', 4, 1], 2, 1)
632
+ sage: KRC(columns=[[2,1]]).to_kirillov_reshetikhin_tableau()
633
+ [[1], [2]]
634
+ sage: KRC = crystals.KirillovReshetikhin(['D', 4, 1], 2, 1)
635
+ sage: KRC(rows=[]).to_kirillov_reshetikhin_tableau()
636
+ [[1], [-1]]
637
+ """
638
+ return self.parent().kirillov_reshetikhin_tableaux()(self)
639
+
640
+ @cached_method
641
+ def to_tableau(self):
642
+ r"""
643
+ Return the :class:`Tableau` corresponding to ``self``.
644
+
645
+ EXAMPLES::
646
+
647
+ sage: C = crystals.KirillovReshetikhin(['D',4,1], 2,1)
648
+ sage: t = C(2,1).to_tableau(); t
649
+ [[1], [2]]
650
+ sage: type(t)
651
+ <class 'sage.combinat.tableau.Tableaux_all_with_category.element_class'>
652
+ """
653
+ return self.lift().to_tableau()
654
+
655
+ def lusztig_involution(self):
656
+ """
657
+ Return the classical Lusztig involution on ``self``.
658
+
659
+ EXAMPLES::
660
+
661
+ sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 2,2)
662
+ sage: elt = KRC(-1,2); elt
663
+ [[2], [-1]]
664
+ sage: elt.lusztig_involution()
665
+ [[1], [-2]]
666
+ """
667
+ li = self.lift().lusztig_involution()
668
+ return self.parent().retract(li)
669
+
670
+
671
+ KirillovReshetikhinGenericCrystal.Element = KirillovReshetikhinGenericCrystalElement
672
+
673
+
674
+ class KirillovReshetikhinCrystalFromPromotion(KirillovReshetikhinGenericCrystal,
675
+ AffineCrystalFromClassicalAndPromotion):
676
+ r"""
677
+ This generic class assumes that the Kirillov-Reshetikhin crystal is
678
+ constructed from a classical crystal using the
679
+ ``classical_decomposition`` and an automorphism ``promotion``
680
+ and its inverse, which corresponds to a Dynkin diagram automorphism
681
+ ``dynkin_diagram_automorphism``.
682
+
683
+ Each instance using this class needs to implement the methods:
684
+
685
+ - ``classical_decomposition``
686
+ - ``promotion``
687
+ - ``promotion_inverse``
688
+ - ``dynkin_diagram_automorphism``
689
+ """
690
+
691
+ def __init__(self, cartan_type, r, s):
692
+ r"""
693
+ TESTS::
694
+
695
+ sage: K = crystals.KirillovReshetikhin(['B',2,1], 1, 1)
696
+ sage: K
697
+ Kirillov-Reshetikhin crystal of type ['B', 2, 1] with (r,s)=(1,1)
698
+ sage: TestSuite(K).run()
699
+ """
700
+ KirillovReshetikhinGenericCrystal.__init__(self, cartan_type, r, s)
701
+ AffineCrystalFromClassicalAndPromotion.__init__(self, cartan_type,
702
+ self.classical_decomposition(),
703
+ self.promotion(),
704
+ self.promotion_inverse(),
705
+ self.dynkin_diagram_automorphism(0),
706
+ KirillovReshetikhinCrystals())
707
+
708
+
709
+ class KirillovReshetikhinCrystalFromPromotionElement(AffineCrystalFromClassicalAndPromotionElement,
710
+ KirillovReshetikhinGenericCrystalElement):
711
+ """
712
+ Element for a Kirillov-Reshetikhin crystal from promotion.
713
+ """
714
+ pass
715
+
716
+
717
+ KirillovReshetikhinCrystalFromPromotion.Element = KirillovReshetikhinCrystalFromPromotionElement
718
+
719
+
720
+ class KR_type_A(KirillovReshetikhinCrystalFromPromotion):
721
+ r"""
722
+ Class of Kirillov-Reshetikhin crystals of type `A_n^{(1)}`.
723
+
724
+ EXAMPLES::
725
+
726
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
727
+ sage: b = K(rows=[[1,2],[2,4]])
728
+ sage: b.f(0)
729
+ [[1, 1], [2, 2]]
730
+ """
731
+
732
+ def classical_decomposition(self):
733
+ """
734
+ Specifies the classical crystal underlying the KR crystal of type A.
735
+
736
+ EXAMPLES::
737
+
738
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
739
+ sage: K.classical_decomposition()
740
+ The crystal of tableaux of type ['A', 3] and shape(s) [[2, 2]]
741
+ """
742
+ return CrystalOfTableaux(self.cartan_type().classical(),
743
+ shape=[self.s()]*self.r())
744
+
745
+ @cached_method
746
+ def promotion(self):
747
+ r"""
748
+ Specifies the promotion operator used to construct the affine
749
+ type `A` crystal.
750
+
751
+ For type `A` this corresponds to the Dynkin diagram automorphism
752
+ which `i \mapsto i+1 \mod n+1`, where `n` is the rank.
753
+
754
+ EXAMPLES::
755
+
756
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
757
+ sage: b = K.classical_decomposition()(rows=[[1,2],[3,4]])
758
+ sage: K.promotion()(b)
759
+ [[1, 3], [2, 4]]
760
+ """
761
+ T = self.classical_crystal
762
+ ct = self._cartan_type[1]
763
+ return CrystalDiagramAutomorphism(T,
764
+ lambda x: T(x.to_tableau().promotion(ct)),
765
+ cache=False)
766
+
767
+ @cached_method
768
+ def promotion_inverse(self):
769
+ r"""
770
+ Specifies the inverse promotion operator used to construct the
771
+ affine type `A` crystal.
772
+
773
+ For type `A` this corresponds to the Dynkin diagram automorphism
774
+ which `i \mapsto i-1 \mod n+1`, where `n` is the rank.
775
+
776
+ EXAMPLES::
777
+
778
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
779
+ sage: b = K.classical_decomposition()(rows=[[1,3],[2,4]])
780
+ sage: K.promotion_inverse()(b)
781
+ [[1, 2], [3, 4]]
782
+ sage: b = K.classical_decomposition()(rows=[[1,2],[3,3]])
783
+ sage: K.promotion_inverse()(K.promotion()(b))
784
+ [[1, 2], [3, 3]]
785
+ """
786
+ T = self.classical_crystal
787
+ ct = self._cartan_type[1]
788
+ return CrystalDiagramAutomorphism(T,
789
+ lambda x: T(x.to_tableau().promotion_inverse(ct)),
790
+ cache=False)
791
+
792
+ def dynkin_diagram_automorphism(self, i):
793
+ r"""
794
+ Specifies the Dynkin diagram automorphism underlying the promotion
795
+ action on the crystal elements. The automorphism needs to map node
796
+ 0 to some other Dynkin node.
797
+
798
+ For type `A` we use the Dynkin diagram automorphism which
799
+ `i \mapsto i+1 \mod n+1`, where `n` is the rank.
800
+
801
+ EXAMPLES::
802
+
803
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
804
+ sage: K.dynkin_diagram_automorphism(0)
805
+ 1
806
+ sage: K.dynkin_diagram_automorphism(3)
807
+ 0
808
+ """
809
+ aut = list(range(1, self.cartan_type().rank())) + [0]
810
+ return aut[i]
811
+
812
+
813
+ class KR_type_vertical(KirillovReshetikhinCrystalFromPromotion):
814
+ r"""
815
+ Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type
816
+ `D_n^{(1)}` for `r \le n-2`, `B_n^{(1)}` for `r < n`, and
817
+ `A_{2n-1}^{(2)}` for `r \le n`.
818
+
819
+ EXAMPLES::
820
+
821
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
822
+ sage: b = K(rows=[])
823
+ sage: b.f(0)
824
+ [[1], [2]]
825
+ sage: b.f(0).f(0)
826
+ [[1, 1], [2, 2]]
827
+ sage: b.e(0)
828
+ [[-2], [-1]]
829
+ sage: b.e(0).e(0)
830
+ [[-2, -2], [-1, -1]]
831
+
832
+ sage: K = crystals.KirillovReshetikhin(['D',5,1], 3,1)
833
+ sage: b = K(rows=[[1]])
834
+ sage: b.e(0)
835
+ [[3], [-3], [-2]]
836
+
837
+ sage: K = crystals.KirillovReshetikhin(['B',3,1], 1,1)
838
+ sage: [[b,b.f(0)] for b in K]
839
+ [[[[1]], None], [[[2]], None], [[[3]], None], [[[0]], None],
840
+ [[[-3]], None], [[[-2]], [[1]]], [[[-1]], [[2]]]]
841
+
842
+ sage: K = crystals.KirillovReshetikhin(['A',5,2], 1,1)
843
+ sage: [[b,b.f(0)] for b in K]
844
+ [[[[1]], None], [[[2]], None], [[[3]], None], [[[-3]], None],
845
+ [[[-2]], [[1]]], [[[-1]], [[2]]]]
846
+ """
847
+
848
+ def classical_decomposition(self):
849
+ r"""
850
+ Specifies the classical crystal underlying the Kirillov-Reshetikhin
851
+ crystal of type `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`.
852
+
853
+ It is given by `B^{r,s} \cong \bigoplus_\Lambda B(\Lambda)`,
854
+ where `\Lambda` are weights obtained from a rectangle of width `s`
855
+ and height `r` by removing vertical dominoes. Here we identify
856
+ the fundamental weight `\Lambda_i` with a column of height `i`.
857
+
858
+ EXAMPLES::
859
+
860
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
861
+ sage: K.classical_decomposition()
862
+ The crystal of tableaux of type ['D', 4] and shape(s) [[], [1, 1], [2, 2]]
863
+ """
864
+ return CrystalOfTableaux(self.cartan_type().classical(),
865
+ shapes=vertical_dominoes_removed(self.r(), self.s()))
866
+
867
+ @cached_method
868
+ def promotion(self):
869
+ r"""
870
+ Specifies the promotion operator used to construct the affine
871
+ type `D_n^{(1)}` etc. crystal.
872
+
873
+ This corresponds to the Dynkin diagram automorphism which
874
+ interchanges nodes 0 and 1, and leaves all other nodes unchanged.
875
+ On the level of crystals it is constructed using `\pm` diagrams.
876
+
877
+ EXAMPLES::
878
+
879
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
880
+ sage: promotion = K.promotion()
881
+ sage: b = K.classical_decomposition()(rows=[])
882
+ sage: promotion(b)
883
+ [[1, 2], [-2, -1]]
884
+ sage: b = K.classical_decomposition()(rows=[[1,3],[2,-1]])
885
+ sage: promotion(b)
886
+ [[1, 3], [2, -1]]
887
+ sage: b = K.classical_decomposition()(rows=[[1],[-3]])
888
+ sage: promotion(b)
889
+ [[2, -3], [-2, -1]]
890
+ """
891
+ T = self.classical_decomposition()
892
+ ind = list(T.index_set())
893
+ ind.remove(1)
894
+ return CrystalDiagramAutomorphism(T, self.promotion_on_highest_weight_vector, ind)
895
+
896
+ def promotion_inverse(self):
897
+ """
898
+ Return inverse of promotion.
899
+
900
+ In this case promotion is an involution, so promotion
901
+ inverse equals promotion.
902
+
903
+ EXAMPLES::
904
+
905
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
906
+ sage: promotion = K.promotion()
907
+ sage: promotion_inverse = K.promotion_inverse()
908
+ sage: all( promotion_inverse(promotion(b.lift())) == b.lift() for b in K )
909
+ True
910
+ """
911
+ return self.promotion()
912
+
913
+ def dynkin_diagram_automorphism(self, i):
914
+ """
915
+ Specifies the Dynkin diagram automorphism underlying the promotion
916
+ action on the crystal elements. The automorphism needs to map
917
+ node 0 to some other Dynkin node.
918
+
919
+ Here we use the Dynkin diagram automorphism which interchanges
920
+ nodes 0 and 1 and leaves all other nodes unchanged.
921
+
922
+ EXAMPLES::
923
+
924
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],1,1)
925
+ sage: K.dynkin_diagram_automorphism(0)
926
+ 1
927
+ sage: K.dynkin_diagram_automorphism(1)
928
+ 0
929
+ sage: K.dynkin_diagram_automorphism(4)
930
+ 4
931
+ """
932
+ aut = [1, 0] + list(range(2, self.cartan_type().rank()))
933
+ return aut[i]
934
+
935
+ def promotion_on_highest_weight_vector(self, b):
936
+ r"""
937
+ Calculate promotion on a `{2, 3, \ldots, n}` highest weight vector `b`.
938
+
939
+ EXAMPLES::
940
+
941
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
942
+ sage: T = K.classical_decomposition()
943
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ]
944
+ sage: [K.promotion_on_highest_weight_vector(b) for b in hw]
945
+ [[[1, 2], [-2, -1]], [[2, 2], [-2, -1]], [[1, 2], [3, -1]],
946
+ [[2], [-2]], [[1, 2], [2, -2]], [[2, 2], [-1, -1]],
947
+ [[2, 2], [3, -1]], [[2, 2], [3, 3]], [], [[1], [2]],
948
+ [[1, 1], [2, 2]], [[2], [-1]], [[1, 2], [2, -1]],
949
+ [[2], [3]], [[1, 2], [2, 3]]]
950
+ """
951
+ return self.from_pm_diagram_to_highest_weight_vector(self.from_highest_weight_vector_to_pm_diagram(b).sigma())
952
+
953
+ def from_highest_weight_vector_to_pm_diagram(self, b):
954
+ r"""
955
+ This gives the bijection between an element ``b`` in the classical
956
+ decomposition of the KR crystal that is `{2, 3, \ldots, n}`-highest
957
+ weight and `\pm` diagrams.
958
+
959
+ EXAMPLES::
960
+
961
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
962
+ sage: T = K.classical_decomposition()
963
+ sage: b = T(rows=[[2],[-2]])
964
+ sage: pm = K.from_highest_weight_vector_to_pm_diagram(b); pm
965
+ [[1, 1], [0, 0], [0]]
966
+ sage: pm.pp()
967
+ +
968
+ -
969
+ sage: b = T(rows=[])
970
+ sage: pm=K.from_highest_weight_vector_to_pm_diagram(b); pm
971
+ [[0, 2], [0, 0], [0]]
972
+ sage: pm.pp()
973
+
974
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ]
975
+ sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)
976
+ True
977
+ """
978
+ n = self.cartan_type().rank() - 1
979
+ inner = Partition([Integer(b.weight()[i]) for i in range(1, n+1)])
980
+ inter = Partition([len([i for i in r if i > 0]) for r in b.to_tableau()])
981
+ outer = b.to_tableau().shape()
982
+ return PMDiagram([self.r(), self.s(), outer, inter, inner], from_shapes=True)
983
+
984
+ def from_pm_diagram_to_highest_weight_vector(self, pm):
985
+ r"""
986
+ This gives the bijection between a `\pm` diagram and an element
987
+ ``b`` in the classical decomposition of the KR crystal that
988
+ is `{2, 3, \ldots, n}`-highest weight.
989
+
990
+ EXAMPLES::
991
+
992
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2)
993
+ sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1, 1], [0, 0], [0]])
994
+ sage: K.from_pm_diagram_to_highest_weight_vector(pm)
995
+ [[2], [-2]]
996
+ """
997
+ u = next(b for b in self.classical_decomposition().module_generators
998
+ if b.to_tableau().shape() == pm.outer_shape())
999
+ ct = self.cartan_type()
1000
+ rank = ct.rank() - 1
1001
+ ct_type = ct.classical().type()
1002
+ assert ct_type in ['B', 'C', 'D']
1003
+ ulist = []
1004
+ for h in pm.heights_of_addable_plus():
1005
+ ulist += list(range(1, h + 1))
1006
+ for h in pm.heights_of_minus():
1007
+ if ct_type == 'D':
1008
+ ulist += list(range(1, rank+1)) + [rank-2-k for k in range(rank-1-h)]
1009
+ elif ct_type == 'B':
1010
+ ulist += list(range(1, rank+1)) + [rank-k for k in range(rank+1-h)]
1011
+ else:
1012
+ ulist += list(range(1, rank+1)) + [rank-1-k for k in range(rank-h)]
1013
+ for i in reversed(ulist):
1014
+ u = u.f(i)
1015
+ return u
1016
+
1017
+
1018
+ class KR_type_E6(KirillovReshetikhinCrystalFromPromotion):
1019
+ r"""
1020
+ Class of Kirillov-Reshetikhin crystals of type `E_6^{(1)}` for `r=1,2,6`.
1021
+
1022
+ EXAMPLES::
1023
+
1024
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1025
+ sage: K.module_generator().e(0)
1026
+ []
1027
+ sage: K.module_generator().e(0).f(0)
1028
+ [[(2, -1), (1,)]]
1029
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 1,1)
1030
+ sage: b = K.module_generator()
1031
+ sage: b
1032
+ [(1,)]
1033
+ sage: b.e(0)
1034
+ [(-2, 1)]
1035
+ sage: b = next(t for t in K if t.epsilon(1) == 1 and t.phi(3) == 1 and t.phi(2) == 0 and t.epsilon(2) == 0)
1036
+ sage: b
1037
+ [(-1, 3)]
1038
+ sage: b.e(0)
1039
+ [(-1, -2, 3)]
1040
+
1041
+ The elements of the Kirillov-Reshetikhin crystals can be constructed from
1042
+ a classical crystal element using
1043
+ :meth:`~sage.combinat.crystals.affine.AffineCrystalFromClassical.retract()`.
1044
+
1045
+ EXAMPLES::
1046
+
1047
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1048
+ sage: La = K.cartan_type().classical().root_system().weight_lattice().fundamental_weights()
1049
+ sage: H = crystals.HighestWeight(La[2])
1050
+ sage: t = H.module_generator()
1051
+ sage: t
1052
+ [[(2, -1), (1,)]]
1053
+ sage: type(K.retract(t))
1054
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_E6_with_category.element_class'>
1055
+ sage: K.retract(t).e(0)
1056
+ []
1057
+
1058
+ TESTS::
1059
+
1060
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,1)
1061
+ sage: La = K.weight_lattice_realization().fundamental_weights()
1062
+ sage: all(b.weight() == sum( (K.affine_weight(b.lift())[i] * La[i] for i in K.index_set()), 0*La[0]) for b in K) # long time (26s on sage.math, 2011)
1063
+ True
1064
+ """
1065
+
1066
+ def classical_decomposition(self):
1067
+ """
1068
+ Specifies the classical crystal underlying the KR crystal
1069
+ of type `E_6^{(1)}`.
1070
+
1071
+ EXAMPLES::
1072
+
1073
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,2)
1074
+ sage: K.classical_decomposition()
1075
+ Direct sum of the crystals Family
1076
+ (Finite dimensional highest weight crystal of type ['E', 6] and highest weight 0,
1077
+ Finite dimensional highest weight crystal of type ['E', 6] and highest weight Lambda[2],
1078
+ Finite dimensional highest weight crystal of type ['E', 6] and highest weight 2*Lambda[2])
1079
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 1,2)
1080
+ sage: K.classical_decomposition()
1081
+ Direct sum of the crystals Family
1082
+ (Finite dimensional highest weight crystal of type ['E', 6] and highest weight 2*Lambda[1],)
1083
+ """
1084
+ La = self.cartan_type().classical().root_system().weight_lattice().fundamental_weights()
1085
+ if self.r() in [1, 6]:
1086
+ dw = [self.s() * La[self.r()]]
1087
+ elif self.r() == 2:
1088
+ dw = [k*La[2] for k in range(self.s()+1)]
1089
+ else:
1090
+ raise NotImplementedError
1091
+ return DirectSumOfCrystals([HighestWeightCrystal(dominant_weight)
1092
+ for dominant_weight in dw],
1093
+ keepkey=False)
1094
+
1095
+ def dynkin_diagram_automorphism(self, i):
1096
+ r"""
1097
+ Specifies the Dynkin diagram automorphism underlying the promotion
1098
+ action on the crystal elements.
1099
+
1100
+ Here we use the Dynkin diagram automorphism of order 3 which maps
1101
+ node 0 to node 1.
1102
+
1103
+ EXAMPLES::
1104
+
1105
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1106
+ sage: [K.dynkin_diagram_automorphism(i) for i in K.index_set()]
1107
+ [1, 6, 3, 5, 4, 2, 0]
1108
+ """
1109
+ aut = [1, 6, 3, 5, 4, 2, 0]
1110
+ return aut[i]
1111
+
1112
+ def affine_weight(self, b):
1113
+ r"""
1114
+ Return the affine level zero weight corresponding to the element
1115
+ ``b`` of the classical crystal underlying ``self``.
1116
+
1117
+ For the coefficients to calculate the level, see Table Aff 1
1118
+ in [Ka1990]_.
1119
+
1120
+ EXAMPLES::
1121
+
1122
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1123
+ sage: [K.affine_weight(x.lift()) for x in K
1124
+ ....: if all(x.epsilon(i) == 0 for i in [2,3,4,5])]
1125
+ [(0, 0, 0, 0, 0, 0, 0),
1126
+ (-2, 0, 1, 0, 0, 0, 0),
1127
+ (-1, -1, 0, 0, 0, 1, 0),
1128
+ (0, 0, 0, 0, 0, 0, 0),
1129
+ (0, 0, 0, 0, 0, 1, -2),
1130
+ (0, -1, 1, 0, 0, 0, -1),
1131
+ (-1, 0, 0, 1, 0, 0, -1),
1132
+ (-1, -1, 0, 0, 1, 0, -1),
1133
+ (0, 0, 0, 0, 0, 0, 0),
1134
+ (0, -2, 0, 1, 0, 0, 0)]
1135
+ """
1136
+ cl = self.cartan_type().classical()
1137
+ simple_roots = cl.root_system().ambient_space().simple_roots()
1138
+ index_set = cl.index_set()
1139
+ weight = [Integer(b.weight().scalar(simple_roots[i]))
1140
+ for i in index_set]
1141
+ E6_coeffs = [1, 2, 2, 3, 2, 1]
1142
+ return tuple([-sum(weight[i] * coeff
1143
+ for i, coeff in enumerate(E6_coeffs))] + weight)
1144
+
1145
+ @cached_method
1146
+ def hw_auxiliary(self):
1147
+ r"""
1148
+ Return the `{2,3,4,5}` highest weight elements of ``self``.
1149
+
1150
+ EXAMPLES::
1151
+
1152
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1153
+ sage: K.hw_auxiliary()
1154
+ ([], [[(2, -1), (1,)]],
1155
+ [[(5, -3), (-1, 3)]],
1156
+ [[(6, -2), (-6, 2)]],
1157
+ [[(5, -2, -6), (-6, 2)]],
1158
+ [[(-1,), (-6, 2)]],
1159
+ [[(3, -1, -6), (1,)]],
1160
+ [[(4, -3, -6), (-1, 3)]],
1161
+ [[(1, -3), (-1, 3)]],
1162
+ [[(-1,), (-1, 3)]])
1163
+ """
1164
+ return tuple([x for x in self.classical_decomposition()
1165
+ if all(x.epsilon(i) == 0 for i in [2, 3, 4, 5])])
1166
+
1167
+ @cached_method
1168
+ def highest_weight_dict(self):
1169
+ r"""
1170
+ Return a dictionary between `\{1,2,3,4,5\}`-highest weight elements,
1171
+ and a tuple of affine weights and its classical component.
1172
+
1173
+ EXAMPLES::
1174
+
1175
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1176
+ sage: sorted(K.highest_weight_dict().items(), key=str)
1177
+ [([[(2, -1), (1,)]], ((-2, 0, 1, 0, 0, 0, 0), 1)),
1178
+ ([[(3, -1, -6), (1,)]], ((-1, 0, 0, 1, 0, 0, -1), 1)),
1179
+ ([[(5, -2, -6), (-6, 2)]], ((0, 0, 0, 0, 0, 1, -2), 1)),
1180
+ ([[(6, -2), (-6, 2)]], ((0, 0, 0, 0, 0, 0, 0), 1)),
1181
+ ([], ((0, 0, 0, 0, 0, 0, 0), 0))]
1182
+ """
1183
+ hw = [x for x in self.hw_auxiliary() if x.epsilon(1) == 0]
1184
+ dic = {x: (self.affine_weight(x), len(x)) for x in hw}
1185
+ assert len(hw) == len(dic)
1186
+ return dic
1187
+
1188
+ @cached_method
1189
+ def highest_weight_dict_inv(self):
1190
+ r"""
1191
+ Return a dictionary between a tuple of affine weights and a classical
1192
+ component, and `\{2,3,4,5,6\}`-highest weight elements.
1193
+
1194
+ EXAMPLES::
1195
+
1196
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1197
+ sage: K.highest_weight_dict_inv()
1198
+ {((-2, 0, 1, 0, 0, 0, 0), 1): [[(2, -1), (1,)]],
1199
+ ((-1, -1, 0, 0, 0, 1, 0), 1): [[(5, -3), (-1, 3)]],
1200
+ ((0, -2, 0, 1, 0, 0, 0), 1): [[(-1,), (-1, 3)]],
1201
+ ((0, 0, 0, 0, 0, 0, 0), 0): [],
1202
+ ((0, 0, 0, 0, 0, 0, 0), 1): [[(1, -3), (-1, 3)]]}
1203
+ """
1204
+ hw = [x for x in self.hw_auxiliary() if x.epsilon(6) == 0]
1205
+ dic = {(self.affine_weight(x), len(x)): x for x in hw}
1206
+ assert len(hw) == len(dic)
1207
+ return dic
1208
+
1209
+ def automorphism_on_affine_weight(self, weight):
1210
+ r"""
1211
+ Act with the Dynkin diagram automorphism on affine weights
1212
+ as outputted by the ``affine_weight`` method.
1213
+
1214
+ EXAMPLES::
1215
+
1216
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1)
1217
+ sage: sorted([x[0], K.automorphism_on_affine_weight(x[0])]
1218
+ ....: for x in K.highest_weight_dict().values())
1219
+ [[(-2, 0, 1, 0, 0, 0, 0), (0, -2, 0, 1, 0, 0, 0)],
1220
+ [(-1, 0, 0, 1, 0, 0, -1), (-1, -1, 0, 0, 0, 1, 0)],
1221
+ [(0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)],
1222
+ [(0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)],
1223
+ [(0, 0, 0, 0, 0, 1, -2), (-2, 0, 1, 0, 0, 0, 0)]]
1224
+ """
1225
+ f = self.dynkin_diagram_automorphism
1226
+ return tuple([weight[f(f(i))] for i in self.index_set()])
1227
+
1228
+ @cached_method
1229
+ def promotion_on_highest_weight_vectors(self):
1230
+ r"""
1231
+ Return a dictionary of the promotion map on `\{1,2,3,4,5\}`-highest
1232
+ weight elements to `\{2,3,4,5,6\}`-highest weight elements
1233
+ in ``self``.
1234
+
1235
+ EXAMPLES::
1236
+
1237
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 2, 1)
1238
+ sage: dic = K.promotion_on_highest_weight_vectors()
1239
+ sage: sorted(dic.items(), key=str)
1240
+ [([[(2, -1), (1,)]], [[(-1,), (-1, 3)]]),
1241
+ ([[(3, -1, -6), (1,)]], [[(5, -3), (-1, 3)]]),
1242
+ ([[(5, -2, -6), (-6, 2)]], [[(2, -1), (1,)]]),
1243
+ ([[(6, -2), (-6, 2)]], []),
1244
+ ([], [[(1, -3), (-1, 3)]])]
1245
+ """
1246
+ dic = self.highest_weight_dict()
1247
+ dic_inv = self.highest_weight_dict_inv()
1248
+ dic_weight = {}
1249
+ for weight, i in dic.values():
1250
+ dic_weight[weight] = dic_weight.get(weight, []) + [i]
1251
+ map_index = lambda i_list: max(i_list[1]) + min(i_list[1]) - i_list[0]
1252
+ map_element = lambda x: (self.automorphism_on_affine_weight(dic[x][0]),
1253
+ map_index((dic[x][1], dic_weight[dic[x][0]])))
1254
+ return {x: dic_inv[map_element(x)] for x in dic}
1255
+
1256
+ @cached_method
1257
+ def promotion_on_highest_weight_vectors_function(self):
1258
+ """
1259
+ Return a lambda function on ``x`` defined by
1260
+ ``self.promotion_on_highest_weight_vectors()[x]``.
1261
+
1262
+ EXAMPLES::
1263
+
1264
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 2, 1)
1265
+ sage: f = K.promotion_on_highest_weight_vectors_function()
1266
+ sage: f(K.module_generator().lift())
1267
+ [[(-1,), (-1, 3)]]
1268
+ """
1269
+ return self.promotion_on_highest_weight_vectors().__getitem__
1270
+
1271
+ @cached_method
1272
+ def promotion(self):
1273
+ r"""
1274
+ Specifies the promotion operator used to construct the
1275
+ affine type `E_6^{(1)}` crystal.
1276
+
1277
+ EXAMPLES::
1278
+
1279
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,1)
1280
+ sage: promotion = K.promotion()
1281
+ sage: all(promotion(promotion(promotion(b))) == b for b in K.classical_decomposition())
1282
+ True
1283
+ sage: K = crystals.KirillovReshetikhin(['E',6,1],1,1)
1284
+ sage: promotion = K.promotion()
1285
+ sage: all(promotion(promotion(promotion(b))) == b for b in K.classical_decomposition())
1286
+ True
1287
+ """
1288
+ T = self.classical_decomposition()
1289
+ ind = [1, 2, 3, 4, 5]
1290
+ return CrystalDiagramAutomorphism(T, self.promotion_on_highest_weight_vectors(), ind,
1291
+ automorphism=self.dynkin_diagram_automorphism)
1292
+
1293
+ @cached_method
1294
+ def promotion_inverse(self):
1295
+ r"""
1296
+ Return the inverse promotion. Since promotion is of order 3,
1297
+ the inverse promotion is the same as promotion applied twice.
1298
+
1299
+ EXAMPLES::
1300
+
1301
+ sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,1)
1302
+ sage: p = K.promotion()
1303
+ sage: p_inv = K.promotion_inverse()
1304
+ sage: all(p_inv(p(b)) == b for b in K.classical_decomposition())
1305
+ True
1306
+ """
1307
+ p = self.promotion()
1308
+ # return lambda x : p(p(x))
1309
+ return p * p
1310
+
1311
+
1312
+ class KR_type_C(KirillovReshetikhinGenericCrystal):
1313
+ r"""
1314
+ Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `C_n^{(1)}`
1315
+ for `r < n`.
1316
+
1317
+ EXAMPLES::
1318
+
1319
+ sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2)
1320
+ sage: K
1321
+ Kirillov-Reshetikhin crystal of type ['C', 2, 1] with (r,s)=(1,2)
1322
+ sage: b = K(rows=[])
1323
+ sage: b.f(0)
1324
+ [[1, 1]]
1325
+ sage: b.e(0)
1326
+ [[-1, -1]]
1327
+ """
1328
+
1329
+ def classical_decomposition(self):
1330
+ r"""
1331
+ Return the classical crystal underlying the Kirillov-Reshetikhin
1332
+ crystal of type `C_n^{(1)}`.
1333
+
1334
+ It is given by `B^{r,s} \cong \bigoplus_{\Lambda} B(\Lambda)`,
1335
+ where `\Lambda` are weights obtained from a rectangle of width `s`
1336
+ and height `r` by removing horizontal dominoes. Here we identify
1337
+ the fundamental weight `\Lambda_i` with a column of height `i`.
1338
+
1339
+ EXAMPLES::
1340
+
1341
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2)
1342
+ sage: K.classical_decomposition()
1343
+ The crystal of tableaux of type ['C', 3] and shape(s) [[], [2], [2, 2]]
1344
+ """
1345
+ return CrystalOfTableaux(self.cartan_type().classical(),
1346
+ shapes=horizontal_dominoes_removed(self.r(), self.s()))
1347
+
1348
+ def ambient_crystal(self):
1349
+ r"""
1350
+ Return the ambient crystal `B^{r,s}` of type `A_{2n+1}^{(2)}`
1351
+ associated to the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.
1352
+
1353
+ This ambient crystal is used to construct the zero arrows.
1354
+
1355
+ EXAMPLES::
1356
+
1357
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,3)
1358
+ sage: K.ambient_crystal()
1359
+ Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,3)
1360
+ """
1361
+ return KashiwaraNakashimaTableaux(['A', 2*self.cartan_type().classical().rank()+1, 2],
1362
+ self.r(), self.s())
1363
+
1364
+ @cached_method
1365
+ def ambient_dict_pm_diagrams(self):
1366
+ r"""
1367
+ Return a dictionary of all self-dual `\pm` diagrams for the
1368
+ ambient crystal whose keys are their inner shape.
1369
+
1370
+ EXAMPLES::
1371
+
1372
+ sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2)
1373
+ sage: K.ambient_dict_pm_diagrams()
1374
+ {[]: [[1, 1], [0]], [2]: [[0, 0], [2]]}
1375
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2)
1376
+ sage: K.ambient_dict_pm_diagrams()
1377
+ {[]: [[1, 1], [0, 0], [0]],
1378
+ [2]: [[0, 0], [1, 1], [0]],
1379
+ [2, 2]: [[0, 0], [0, 0], [2]]}
1380
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,3)
1381
+ sage: K.ambient_dict_pm_diagrams()
1382
+ {[1, 1]: [[1, 1], [0, 0], [1]],
1383
+ [3, 1]: [[0, 0], [1, 1], [1]],
1384
+ [3, 3]: [[0, 0], [0, 0], [3]]}
1385
+ """
1386
+ s = self.s()
1387
+ r = self.r()
1388
+ m = s // 2
1389
+ ulist = (PMDiagram([[j, j] for j in la]+[[s-2*m+2*i]])
1390
+ for i in range(m + 1)
1391
+ for la in IntegerVectors(m-i, min_length=r, max_length=r))
1392
+ return {x.inner_shape(): x for x in ulist}
1393
+
1394
+ @cached_method
1395
+ def ambient_highest_weight_dict(self):
1396
+ r"""
1397
+ Return a dictionary of all `\{2,\ldots,n+1\}`-highest weight vectors
1398
+ in the ambient crystal.
1399
+
1400
+ The key is the inner shape of their corresponding `\pm` diagram,
1401
+ or equivalently, their `\{2,\ldots,n+1\}` weight.
1402
+
1403
+ EXAMPLES::
1404
+
1405
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2)
1406
+ sage: K.ambient_highest_weight_dict()
1407
+ {[]: [[2], [-2]], [2]: [[1, 2], [2, -1]], [2, 2]: [[2, 2], [3, 3]]}
1408
+ """
1409
+ A = self.ambient_dict_pm_diagrams()
1410
+ ambient = self.ambient_crystal()
1411
+ return {key: ambient.retract(ambient.from_pm_diagram_to_highest_weight_vector(A[key]))
1412
+ for key in A}
1413
+
1414
+ @cached_method
1415
+ def highest_weight_dict(self):
1416
+ r"""
1417
+ Return a dictionary of the classical highest weight vectors of
1418
+ ``self`` whose keys are their shape.
1419
+
1420
+ EXAMPLES::
1421
+
1422
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2)
1423
+ sage: K.highest_weight_dict()
1424
+ {[]: [], [2]: [[1, 1]], [2, 2]: [[1, 1], [2, 2]]}
1425
+ """
1426
+ return {x.lift().to_tableau().shape(): x for x in self.module_generators}
1427
+
1428
+ @cached_method
1429
+ def to_ambient_crystal(self):
1430
+ r"""
1431
+ Return a map from the Kirillov-Reshetikhin crystal of type
1432
+ `C_n^{(1)}` to the ambient crystal of type `A_{2n+1}^{(2)}`.
1433
+
1434
+ EXAMPLES::
1435
+
1436
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2)
1437
+ sage: b=K(rows=[[1,1]])
1438
+ sage: K.to_ambient_crystal()(b)
1439
+ [[1, 2], [2, -1]]
1440
+ sage: b=K(rows=[])
1441
+ sage: K.to_ambient_crystal()(b)
1442
+ [[2], [-2]]
1443
+ sage: K.to_ambient_crystal()(b).parent()
1444
+ Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,2)
1445
+ """
1446
+ hwd = self.highest_weight_dict()
1447
+ ahwd = self.ambient_highest_weight_dict()
1448
+ pdict = {hwd[key]: ahwd[key] for key in hwd}
1449
+ classical = self.cartan_type().classical()
1450
+ return self.crystal_morphism(pdict, index_set=classical.index_set(),
1451
+ automorphism=lambda i: i+1,
1452
+ cartan_type=classical, check=False)
1453
+
1454
+ @cached_method
1455
+ def from_ambient_crystal(self):
1456
+ r"""
1457
+ Return a map from the ambient crystal of type `A_{2n+1}^{(2)}` to
1458
+ the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.
1459
+
1460
+ Note that this map is only well-defined on type `C_n^{(1)}` elements
1461
+ that are in the image under :meth:`to_ambient_crystal`.
1462
+
1463
+ EXAMPLES::
1464
+
1465
+ sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2)
1466
+ sage: b = K.ambient_crystal()(rows=[[2,2],[3,3]])
1467
+ sage: K.from_ambient_crystal()(b)
1468
+ [[1, 1], [2, 2]]
1469
+ """
1470
+ hwd = self.highest_weight_dict()
1471
+ ahwd = self.ambient_highest_weight_dict()
1472
+ pdict_inv = {ahwd[key]: hwd[key] for key in hwd}
1473
+ ind = [j+1 for j in self.cartan_type().classical().index_set()]
1474
+ return AmbientRetractMap(self, self.ambient_crystal(), pdict_inv,
1475
+ index_set=ind, automorphism=lambda i: i-1)
1476
+
1477
+
1478
+ class KR_type_CElement(KirillovReshetikhinGenericCrystalElement):
1479
+ r"""
1480
+ Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}`
1481
+ of type `C_n^{(1)}` for `r<n`.
1482
+
1483
+ EXAMPLES::
1484
+
1485
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 1, 2)
1486
+ sage: type(K.module_generators[0])
1487
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_C_with_category.element_class'>
1488
+ """
1489
+
1490
+ def e0(self):
1491
+ r"""
1492
+ Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal,
1493
+ calculating `e_1 e_0` there and pulling the element back.
1494
+
1495
+ EXAMPLES::
1496
+
1497
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 1, 2)
1498
+ sage: b = K(rows=[])
1499
+ sage: b.e(0) # indirect doctest
1500
+ [[-1, -1]]
1501
+ """
1502
+ b = self.parent().to_ambient_crystal()(self).e(1)
1503
+ if b is None:
1504
+ return None
1505
+ b = b.e(0)
1506
+ return self.parent().from_ambient_crystal()(b)
1507
+
1508
+ def f0(self):
1509
+ r"""
1510
+ Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal,
1511
+ calculating `f_1 f_0` there and pulling the element back.
1512
+
1513
+ EXAMPLES::
1514
+
1515
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 1, 2)
1516
+ sage: b = K(rows=[])
1517
+ sage: b.f(0) # indirect doctest
1518
+ [[1, 1]]
1519
+ """
1520
+ b = self.parent().to_ambient_crystal()(self).f(1)
1521
+ if b is None:
1522
+ return None
1523
+ b = b.f(0)
1524
+ return self.parent().from_ambient_crystal()(b)
1525
+
1526
+ def epsilon0(self):
1527
+ r"""
1528
+ Calculate `\varepsilon_0` of ``self`` by mapping the element to
1529
+ the ambient crystal and calculating `\varepsilon_1` there.
1530
+
1531
+ EXAMPLES::
1532
+
1533
+ sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2)
1534
+ sage: b=K(rows=[[1,1]])
1535
+ sage: b.epsilon(0) # indirect doctest
1536
+ 2
1537
+ """
1538
+ b = self.parent().to_ambient_crystal()(self)
1539
+ return b.epsilon(1)
1540
+
1541
+ def phi0(self):
1542
+ r"""
1543
+ Calculate `\varphi_0` of ``self`` by mapping the element to
1544
+ the ambient crystal and calculating `\varphi_1` there.
1545
+
1546
+ EXAMPLES::
1547
+
1548
+ sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2)
1549
+ sage: b=K(rows=[[-1,-1]])
1550
+ sage: b.phi(0) # indirect doctest
1551
+ 2
1552
+ """
1553
+ b = self.parent().to_ambient_crystal()(self)
1554
+ return b.phi(1)
1555
+
1556
+
1557
+ KR_type_C.Element = KR_type_CElement
1558
+
1559
+
1560
+ class KR_type_A2(KirillovReshetikhinGenericCrystal):
1561
+ r"""
1562
+ Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}`
1563
+ for `1 \leq r \leq n` in the realization with classical subalgebra `B_n`.
1564
+ The Cartan type in this case is inputted as the dual of `A_{2n}^{(2)}`.
1565
+
1566
+ This is an alternative implementation to :class:`KR_type_box` that uses
1567
+ the classical decomposition into type `C_n` crystals.
1568
+
1569
+ EXAMPLES::
1570
+
1571
+ sage: C = CartanType(['A',4,2]).dual()
1572
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)
1573
+ sage: K
1574
+ Kirillov-Reshetikhin crystal of type ['BC', 2, 2]^* with (r,s)=(1,1)
1575
+ sage: b = K(rows=[[-1]])
1576
+ sage: b.f(0)
1577
+ [[1]]
1578
+ sage: b.e(0)
1579
+
1580
+ We can now check whether the two KR crystals of type `A_4^{(2)}`
1581
+ (namely the KR crystal and its dual construction) are isomorphic
1582
+ up to relabelling of the edges::
1583
+
1584
+ sage: C = CartanType(['A',4,2])
1585
+ sage: K = crystals.KirillovReshetikhin(C,1,1)
1586
+ sage: Kdual = crystals.KirillovReshetikhin(C.dual(),1,1)
1587
+ sage: G = K.digraph()
1588
+ sage: Gdual = Kdual.digraph()
1589
+ sage: f = {0:2, 1:1, 2:0}
1590
+ sage: Gnew = DiGraph(); Gnew.add_vertices(Gdual.vertices(sort=True)); Gnew.add_edges([(u,v,f[i]) for (u,v,i) in Gdual.edges(sort=True)])
1591
+ sage: G.is_isomorphic(Gnew, edge_labels = True)
1592
+ True
1593
+ """
1594
+
1595
+ def module_generator(self):
1596
+ r"""
1597
+ Return the unique module generator of classical weight
1598
+ `s \Lambda_r` of a Kirillov-Reshetikhin crystal `B^{r,s}`.
1599
+
1600
+ EXAMPLES::
1601
+
1602
+ sage: ct = CartanType(['A',8,2]).dual()
1603
+ sage: K = crystals.KirillovReshetikhin(ct, 3, 5)
1604
+ sage: K.module_generator()
1605
+ [[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3]]
1606
+
1607
+ TESTS:
1608
+
1609
+ Check that :issue:`23028` is fixed::
1610
+
1611
+ sage: ct = CartanType(['A',8,2]).dual()
1612
+ sage: K = crystals.KirillovReshetikhin(ct, 4, 3)
1613
+ sage: K.module_generator()
1614
+ [[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]]
1615
+ sage: K = crystals.KirillovReshetikhin(ct, 4, 1)
1616
+ sage: K.module_generator()
1617
+ [[1], [2], [3], [4]]
1618
+ """
1619
+ R = self.weight_lattice_realization()
1620
+ Lambda = R.fundamental_weights()
1621
+ r = self.r()
1622
+ s = self.s()
1623
+ weight = s*Lambda[r] - s*Lambda[0]
1624
+ if r == self.cartan_type().rank() - 1:
1625
+ weight += s*Lambda[r] # Special case for r == n
1626
+ return next(b for b in self.module_generators if b.weight() == weight)
1627
+
1628
+ def classical_decomposition(self):
1629
+ r"""
1630
+ Return the classical crystal underlying the Kirillov-Reshetikhin
1631
+ crystal of type `A_{2n}^{(2)}` with `B_n` as classical subdiagram.
1632
+
1633
+ It is given by `B^{r,s} \cong \bigoplus_{\Lambda} B(\Lambda)`,
1634
+ where `B(\Lambda)` is a highest weight crystal of type `B_n`
1635
+ of highest weight `\Lambda`. The sum is over all weights `\Lambda`
1636
+ obtained from a rectangle of width `s` and height `r` by removing
1637
+ horizontal dominoes. Here we identify the fundamental weight
1638
+ `\Lambda_i` with a column of height `i`.
1639
+
1640
+ EXAMPLES::
1641
+
1642
+ sage: C = CartanType(['A',4,2]).dual()
1643
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2)
1644
+ sage: K.classical_decomposition()
1645
+ The crystal of tableaux of type ['B', 2] and shape(s) [[], [2], [2, 2]]
1646
+ """
1647
+ return CrystalOfTableaux(['B', self.cartan_type().rank()-1],
1648
+ shapes=horizontal_dominoes_removed(self.r(), self.s()))
1649
+
1650
+ def ambient_crystal(self):
1651
+ r"""
1652
+ Return the ambient crystal `B^{r,s}` of type `B_{n+1}^{(1)}`
1653
+ associated to the Kirillov-Reshetikhin crystal of type
1654
+ `A_{2n}^{(2)}` dual.
1655
+
1656
+ This ambient crystal is used to construct the zero arrows.
1657
+
1658
+ EXAMPLES::
1659
+
1660
+ sage: C = CartanType(['A',4,2]).dual()
1661
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 3)
1662
+ sage: K.ambient_crystal()
1663
+ Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(2,3)
1664
+ """
1665
+ return KR_type_vertical(['B', self.cartan_type().rank(), 1], self.r(), self.s())
1666
+
1667
+ @cached_method
1668
+ def ambient_dict_pm_diagrams(self):
1669
+ r"""
1670
+ Return a dictionary of all self-dual `\pm` diagrams for the
1671
+ ambient crystal whose keys are their inner shape.
1672
+
1673
+ EXAMPLES::
1674
+
1675
+ sage: C = CartanType(['A',4,2]).dual()
1676
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)
1677
+ sage: K.ambient_dict_pm_diagrams()
1678
+ {[1]: [[0, 0], [1]]}
1679
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)
1680
+ sage: K.ambient_dict_pm_diagrams()
1681
+ {[]: [[1, 1], [0]], [2]: [[0, 0], [2]]}
1682
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2)
1683
+ sage: K.ambient_dict_pm_diagrams()
1684
+ {[]: [[1, 1], [0, 0], [0]],
1685
+ [2]: [[0, 0], [1, 1], [0]],
1686
+ [2, 2]: [[0, 0], [0, 0], [2]]}
1687
+ """
1688
+ s = self.s()
1689
+ r = self.r()
1690
+ m = s // 2
1691
+ ulist = (PMDiagram([[j, j] for j in la] + [[s-2*m+2*i]])
1692
+ for i in range(m + 1)
1693
+ for la in IntegerVectors(m-i, min_length=r, max_length=r))
1694
+ return {x.inner_shape(): x for x in ulist}
1695
+
1696
+ @cached_method
1697
+ def ambient_highest_weight_dict(self):
1698
+ r"""
1699
+ Return a dictionary of all `\{2,\ldots,n+1\}`-highest weight vectors
1700
+ in the ambient crystal.
1701
+
1702
+ The key is the inner shape of their corresponding `\pm` diagram,
1703
+ or equivalently, their `\{2,\ldots,n+1\}` weight.
1704
+
1705
+ EXAMPLES::
1706
+
1707
+ sage: C = CartanType(['A',4,2]).dual()
1708
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)
1709
+ sage: K.ambient_highest_weight_dict()
1710
+ {[]: [[1, -1]], [2]: [[2, 2]]}
1711
+ """
1712
+ A = self.ambient_dict_pm_diagrams()
1713
+ ambient = self.ambient_crystal()
1714
+ return {key: ambient.retract(ambient.from_pm_diagram_to_highest_weight_vector(A[key]))
1715
+ for key in A}
1716
+
1717
+ @cached_method
1718
+ def highest_weight_dict(self):
1719
+ r"""
1720
+ Return a dictionary of the classical highest weight vectors
1721
+ of ``self`` whose keys are their shape.
1722
+
1723
+ EXAMPLES::
1724
+
1725
+ sage: C = CartanType(['A',4,2]).dual()
1726
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)
1727
+ sage: K.highest_weight_dict()
1728
+ {[]: [], [2]: [[1, 1]]}
1729
+ """
1730
+ return {x.lift().to_tableau().shape(): x for x in self.module_generators}
1731
+
1732
+ @cached_method
1733
+ def to_ambient_crystal(self):
1734
+ r"""
1735
+ Return a map from the Kirillov-Reshetikhin crystal of type
1736
+ `A_{2n}^{(2)}` to the ambient crystal of type `B_{n+1}^{(1)}`.
1737
+
1738
+ EXAMPLES::
1739
+
1740
+ sage: C = CartanType(['A',4,2]).dual()
1741
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)
1742
+ sage: b=K(rows=[[1,1]])
1743
+ sage: K.to_ambient_crystal()(b)
1744
+ [[2, 2]]
1745
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2)
1746
+ sage: b=K(rows=[[1,1]])
1747
+ sage: K.to_ambient_crystal()(b)
1748
+ [[1, 2], [2, -1]]
1749
+ sage: K.to_ambient_crystal()(b).parent()
1750
+ Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(2,2)
1751
+ """
1752
+ hwd = self.highest_weight_dict()
1753
+ ahwd = self.ambient_highest_weight_dict()
1754
+ pdict = {hwd[key]: ahwd[key] for key in hwd}
1755
+ classical = self.cartan_type().classical()
1756
+ return self.crystal_morphism(pdict, index_set=classical.index_set(),
1757
+ automorphism=lambda i: i+1,
1758
+ cartan_type=classical, check=False)
1759
+
1760
+ @cached_method
1761
+ def from_ambient_crystal(self):
1762
+ r"""
1763
+ Return a map from the ambient crystal of type `B_{n+1}^{(1)}` to
1764
+ the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}`.
1765
+
1766
+ Note that this map is only well-defined on type `A_{2n}^{(2)}`
1767
+ elements that are in the image under :meth:`to_ambient_crystal`.
1768
+
1769
+ EXAMPLES::
1770
+
1771
+ sage: C = CartanType(['A',4,2]).dual()
1772
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)
1773
+ sage: b = K.ambient_crystal()(rows=[[2,2]])
1774
+ sage: K.from_ambient_crystal()(b)
1775
+ [[1, 1]]
1776
+ """
1777
+ hwd = self.highest_weight_dict()
1778
+ ahwd = self.ambient_highest_weight_dict()
1779
+ pdict_inv = {ahwd[key]: hwd[key] for key in hwd}
1780
+ ind = [j+1 for j in self.cartan_type().classical().index_set()]
1781
+ return AmbientRetractMap(self, self.ambient_crystal(), pdict_inv, index_set=ind,
1782
+ automorphism=lambda i: i-1)
1783
+
1784
+
1785
+ class KR_type_A2Element(KirillovReshetikhinGenericCrystalElement):
1786
+ r"""
1787
+ Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of
1788
+ type `A_{2n}^{(2)}` for `r<n` with underlying classical algebra `B_n`.
1789
+
1790
+ EXAMPLES::
1791
+
1792
+ sage: C = CartanType(['A',4,2]).dual()
1793
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)
1794
+ sage: type(K.module_generators[0])
1795
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2_with_category.element_class'>
1796
+ """
1797
+
1798
+ def e0(self):
1799
+ r"""
1800
+ Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal,
1801
+ calculating `e_1 e_0` there and pulling the element back.
1802
+
1803
+ EXAMPLES::
1804
+
1805
+ sage: C = CartanType(['A',4,2]).dual()
1806
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)
1807
+ sage: b = K(rows=[[1]])
1808
+ sage: b.e(0) # indirect doctest
1809
+ [[-1]]
1810
+ """
1811
+ b = self.parent().to_ambient_crystal()(self).e(1)
1812
+ if b is None:
1813
+ return None
1814
+ b = b.e(0)
1815
+ return self.parent().from_ambient_crystal()(b)
1816
+
1817
+ def f0(self):
1818
+ r"""
1819
+ Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal,
1820
+ calculating `f_1 f_0` there and pulling the element back.
1821
+
1822
+ EXAMPLES::
1823
+
1824
+ sage: C = CartanType(['A',4,2]).dual()
1825
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)
1826
+ sage: b = K(rows=[[-1]])
1827
+ sage: b.f(0) # indirect doctest
1828
+ [[1]]
1829
+ """
1830
+ b = self.parent().to_ambient_crystal()(self).f(1)
1831
+ if b is None:
1832
+ return None
1833
+ b = b.f(0)
1834
+ return self.parent().from_ambient_crystal()(b)
1835
+
1836
+ def epsilon0(self):
1837
+ r"""
1838
+ Calculate `\varepsilon_0` of ``self`` by mapping the element to
1839
+ the ambient crystal and calculating ``\varepsilon_1`` there.
1840
+
1841
+ EXAMPLES::
1842
+
1843
+ sage: C = CartanType(['A',4,2]).dual()
1844
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)
1845
+ sage: b=K(rows=[[1]])
1846
+ sage: b.epsilon(0) # indirect doctest
1847
+ 1
1848
+ """
1849
+ b = self.parent().to_ambient_crystal()(self)
1850
+ return b.epsilon(1)
1851
+
1852
+ def phi0(self):
1853
+ r"""
1854
+ Calculate `\varphi_0` of ``self`` by mapping the element to
1855
+ the ambient crystal and calculating `\varphi_1` there.
1856
+
1857
+ EXAMPLES::
1858
+
1859
+ sage: C = CartanType(['A',4,2]).dual()
1860
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)
1861
+ sage: b = K(rows=[[-1]])
1862
+ sage: b.phi(0) # indirect doctest
1863
+ 1
1864
+ """
1865
+ b = self.parent().to_ambient_crystal()(self)
1866
+ return b.phi(1)
1867
+
1868
+
1869
+ KR_type_A2.Element = KR_type_A2Element
1870
+
1871
+
1872
+ class KR_type_box(KirillovReshetikhinGenericCrystal, AffineCrystalFromClassical):
1873
+ r"""
1874
+ Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}`
1875
+ for `r\le n` and type `D_{n+1}^{(2)}` for `r<n`.
1876
+
1877
+ EXAMPLES::
1878
+
1879
+ sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1)
1880
+ sage: K
1881
+ Kirillov-Reshetikhin crystal of type ['BC', 2, 2] with (r,s)=(1,1)
1882
+ sage: b = K(rows=[])
1883
+ sage: b.f(0)
1884
+ [[1]]
1885
+ sage: b.e(0)
1886
+ [[-1]]
1887
+ """
1888
+
1889
+ def __init__(self, cartan_type, r, s):
1890
+ r"""
1891
+ Initialize a Kirillov-Reshetikhin crystal ``self``.
1892
+
1893
+ TESTS::
1894
+
1895
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_box(['A',4,2], 1, 1)
1896
+ sage: K
1897
+ Kirillov-Reshetikhin crystal of type ['BC', 2, 2] with (r,s)=(1,1)
1898
+ sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_box(['D',4,2], 1, 1)
1899
+ sage: K
1900
+ Kirillov-Reshetikhin crystal of type ['C', 3, 1]^* with (r,s)=(1,1)
1901
+ sage: TestSuite(K).run()
1902
+ """
1903
+ KirillovReshetikhinGenericCrystal.__init__(self, cartan_type, r, s)
1904
+ AffineCrystalFromClassical.__init__(self, cartan_type, self.classical_decomposition(),
1905
+ KirillovReshetikhinCrystals())
1906
+
1907
+ def classical_decomposition(self):
1908
+ r"""
1909
+ Return the classical crystal underlying the Kirillov-Reshetikhin
1910
+ crystal of type `A_{2n}^{(2)}` and `D_{n+1}^{(2)}`.
1911
+
1912
+ It is given by `B^{r,s} \cong \bigoplus_{\Lambda} B(\Lambda)`,
1913
+ where `\Lambda` are weights obtained from a rectangle of width `s`
1914
+ and height `r` by removing boxes. Here we identify the fundamental
1915
+ weight `\Lambda_i` with a column of height `i`.
1916
+
1917
+ EXAMPLES::
1918
+
1919
+ sage: K = crystals.KirillovReshetikhin(['A',4,2], 2,2)
1920
+ sage: K.classical_decomposition()
1921
+ The crystal of tableaux of type ['C', 2] and shape(s) [[], [1], [2], [1, 1], [2, 1], [2, 2]]
1922
+ sage: K = crystals.KirillovReshetikhin(['D',4,2], 2,3)
1923
+ sage: K.classical_decomposition()
1924
+ The crystal of tableaux of type ['B', 3] and shape(s) [[], [1], [2], [1, 1], [3], [2, 1], [3, 1], [2, 2], [3, 2], [3, 3]]
1925
+ """
1926
+ return CrystalOfTableaux(self.cartan_type().classical(),
1927
+ shapes=partitions_in_box(self.r(), self.s()))
1928
+
1929
+ def ambient_crystal(self):
1930
+ r"""
1931
+ Return the ambient crystal `B^{r,2s}` of type `C_n^{(1)}`
1932
+ associated to the Kirillov-Reshetikhin crystal.
1933
+
1934
+ The ambient crystal is used to construct the zero arrows.
1935
+
1936
+ EXAMPLES::
1937
+
1938
+ sage: K = crystals.KirillovReshetikhin(['A',4,2], 2,2)
1939
+ sage: K.ambient_crystal()
1940
+ Kirillov-Reshetikhin crystal of type ['C', 2, 1] with (r,s)=(2,4)
1941
+ """
1942
+ # calling KR_type_C instead of KirillovReshetikhin(['C',n,1],r,s) has the advantage that
1943
+ # that this also works for r=n for A_{2n}^{(2)}.
1944
+ return KR_type_C(['C', self.cartan_type().classical().rank(), 1], self.r(), 2*self.s())
1945
+
1946
+ @cached_method
1947
+ def highest_weight_dict(self):
1948
+ r"""
1949
+ Return a dictionary of the classical highest weight vectors
1950
+ of ``self`` whose keys are 2 times their shape.
1951
+
1952
+ EXAMPLES::
1953
+
1954
+ sage: K = crystals.KirillovReshetikhin(['A',6,2], 2,2)
1955
+ sage: K.highest_weight_dict()
1956
+ {[]: [],
1957
+ [2]: [[1]],
1958
+ [2, 2]: [[1], [2]],
1959
+ [4]: [[1, 1]],
1960
+ [4, 2]: [[1, 1], [2]],
1961
+ [4, 4]: [[1, 1], [2, 2]]}
1962
+ """
1963
+ return {Partition([2*i for i in x.lift().to_tableau().shape()]): x
1964
+ for x in self.module_generators}
1965
+
1966
+ @cached_method
1967
+ def ambient_highest_weight_dict(self):
1968
+ r"""
1969
+ Return a dictionary of the classical highest weight vectors of
1970
+ the ambient crystal of ``self`` whose keys are their shape.
1971
+
1972
+ EXAMPLES::
1973
+
1974
+ sage: K = crystals.KirillovReshetikhin(['A',6,2], 2,2)
1975
+ sage: K.ambient_highest_weight_dict()
1976
+ {[]: [],
1977
+ [2]: [[1, 1]],
1978
+ [2, 2]: [[1, 1], [2, 2]],
1979
+ [4]: [[1, 1, 1, 1]],
1980
+ [4, 2]: [[1, 1, 1, 1], [2, 2]],
1981
+ [4, 4]: [[1, 1, 1, 1], [2, 2, 2, 2]]}
1982
+ """
1983
+ return {x.lift().to_tableau().shape(): x
1984
+ for x in self.ambient_crystal().module_generators}
1985
+
1986
+ def similarity_factor(self):
1987
+ r"""
1988
+ Set the similarity factor used to map to the ambient crystal.
1989
+
1990
+ EXAMPLES::
1991
+
1992
+ sage: K = crystals.KirillovReshetikhin(['A',6,2], 2,2)
1993
+ sage: K.similarity_factor()
1994
+ {1: 2, 2: 2, 3: 2}
1995
+ sage: K = crystals.KirillovReshetikhin(['D',5,2], 1,1)
1996
+ sage: K.similarity_factor()
1997
+ {1: 2, 2: 2, 3: 2, 4: 1}
1998
+ """
1999
+ C = self.cartan_type().classical()
2000
+ p = {i: 2 for i in C.index_set()}
2001
+ if C.type() == 'B':
2002
+ p[C.rank()] = 1
2003
+ return p
2004
+
2005
+ @cached_method
2006
+ def to_ambient_crystal(self):
2007
+ r"""
2008
+ Return a map from ``self`` to the ambient crystal of type `C_n^{(1)}`.
2009
+
2010
+ EXAMPLES::
2011
+
2012
+ sage: K = crystals.KirillovReshetikhin(['D',4,2], 1,1)
2013
+ sage: [K.to_ambient_crystal()(b) for b in K]
2014
+ [[], [[1, 1]], [[2, 2]], [[3, 3]], [[3, -3]], [[-3, -3]], [[-2, -2]], [[-1, -1]]]
2015
+ sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1)
2016
+ sage: [K.to_ambient_crystal()(b) for b in K]
2017
+ [[], [[1, 1]], [[2, 2]], [[-2, -2]], [[-1, -1]]]
2018
+ """
2019
+ hwd = self.highest_weight_dict()
2020
+ ahwd = self.ambient_highest_weight_dict()
2021
+ pdict = {hwd[key]: ahwd[key] for key in hwd}
2022
+ classical = self.cartan_type().classical()
2023
+ return self.crystal_morphism(pdict, codomain=self.ambient_crystal(),
2024
+ index_set=classical.index_set(),
2025
+ scaling_factors=self.similarity_factor(),
2026
+ cartan_type=classical, check=False)
2027
+
2028
+ @cached_method
2029
+ def from_ambient_crystal(self):
2030
+ r"""
2031
+ Return a map from the ambient crystal of type `C_n^{(1)}` to the
2032
+ Kirillov-Reshetikhin crystal ``self``.
2033
+
2034
+ Note that this map is only well-defined on elements that are in the
2035
+ image under :meth:`to_ambient_crystal`.
2036
+
2037
+ EXAMPLES::
2038
+
2039
+ sage: K = crystals.KirillovReshetikhin(['D',4,2], 1,1)
2040
+ sage: b = K.ambient_crystal()(rows=[[3,-3]])
2041
+ sage: K.from_ambient_crystal()(b)
2042
+ [[0]]
2043
+ sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1)
2044
+ sage: b = K.ambient_crystal()(rows=[])
2045
+ sage: K.from_ambient_crystal()(b)
2046
+ []
2047
+ """
2048
+ hwd = self.highest_weight_dict()
2049
+ ahwd = self.ambient_highest_weight_dict()
2050
+ pdict_inv = {ahwd[key]: hwd[key] for key in hwd}
2051
+ return AmbientRetractMap(self, self.ambient_crystal(), pdict_inv,
2052
+ index_set=self.cartan_type().classical().index_set(),
2053
+ similarity_factor_domain=self.similarity_factor())
2054
+
2055
+
2056
+ class KR_type_boxElement(KirillovReshetikhinGenericCrystalElement):
2057
+ r"""
2058
+ Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of
2059
+ type `A_{2n}^{(2)}` for `r \leq n` and type `D_{n+1}^{(2)}` for `r < n`.
2060
+
2061
+ EXAMPLES::
2062
+
2063
+ sage: K = crystals.KirillovReshetikhin(['A',4,2],1,2)
2064
+ sage: type(K.module_generators[0])
2065
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_box_with_category.element_class'>
2066
+ """
2067
+
2068
+ def e0(self):
2069
+ r"""
2070
+ Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal,
2071
+ calculating `e_0` there and pulling the element back.
2072
+
2073
+ EXAMPLES::
2074
+
2075
+ sage: K = crystals.KirillovReshetikhin(['A',4,2],1,1)
2076
+ sage: b = K(rows=[])
2077
+ sage: b.e(0) # indirect doctest
2078
+ [[-1]]
2079
+ """
2080
+ b = self.parent().to_ambient_crystal()(self).e(0)
2081
+ if b is None:
2082
+ return None
2083
+ return self.parent().from_ambient_crystal()(b)
2084
+
2085
+ def f0(self):
2086
+ r"""
2087
+ Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal,
2088
+ calculating `f_0` there and pulling the element back.
2089
+
2090
+ EXAMPLES::
2091
+
2092
+ sage: K = crystals.KirillovReshetikhin(['A',4,2],1,1)
2093
+ sage: b = K(rows=[])
2094
+ sage: b.f(0) # indirect doctest
2095
+ [[1]]
2096
+ """
2097
+ b = self.parent().to_ambient_crystal()(self).f(0)
2098
+ if b is None:
2099
+ return None
2100
+ return self.parent().from_ambient_crystal()(b)
2101
+
2102
+ def epsilon0(self):
2103
+ r"""
2104
+ Return `\varepsilon_0` of ``self`` by mapping the element
2105
+ to the ambient crystal and calculating `\varepsilon_0` there.
2106
+
2107
+ EXAMPLES::
2108
+
2109
+ sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1)
2110
+ sage: b = K(rows=[[1]])
2111
+ sage: b.epsilon(0) # indirect doctest
2112
+ 2
2113
+ """
2114
+ b = self.parent().to_ambient_crystal()(self)
2115
+ return b.epsilon(0)
2116
+
2117
+ def phi0(self):
2118
+ r"""
2119
+ Return `\varphi_0` of ``self`` by mapping the element to
2120
+ the ambient crystal and calculating `\varphi_0` there.
2121
+
2122
+ EXAMPLES::
2123
+
2124
+ sage: K = crystals.KirillovReshetikhin(['D',3,2], 1,1)
2125
+ sage: b = K(rows=[[-1]])
2126
+ sage: b.phi(0) # indirect doctest
2127
+ 2
2128
+ """
2129
+ b = self.parent().to_ambient_crystal()(self)
2130
+ return b.phi(0)
2131
+
2132
+
2133
+ KR_type_box.Element = KR_type_boxElement
2134
+
2135
+
2136
+ class KR_type_Bn(KirillovReshetikhinGenericCrystal):
2137
+ r"""
2138
+ Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `B_{n}^{(1)}`.
2139
+
2140
+ EXAMPLES::
2141
+
2142
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2)
2143
+ sage: K
2144
+ Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(3,2)
2145
+ sage: b = K(rows=[[1],[2],[3]])
2146
+ sage: b.f(0)
2147
+ sage: b.e(0)
2148
+ [[3]]
2149
+
2150
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2)
2151
+ sage: [b.weight() for b in K if b.is_highest_weight([1,2,3])]
2152
+ [-Lambda[0] + Lambda[1], -2*Lambda[0] + 2*Lambda[3]]
2153
+ sage: [b.weight() for b in K if b.is_highest_weight([0,2,3])]
2154
+ [Lambda[0] - Lambda[1], -2*Lambda[1] + 2*Lambda[3]]
2155
+ """
2156
+
2157
+ def _element_constructor_(self, *args, **options):
2158
+ """
2159
+ Construct an element of ``self``.
2160
+
2161
+ TESTS::
2162
+
2163
+ sage: KRC = crystals.KirillovReshetikhin(['B',3,1], 3, 3)
2164
+ sage: KRT = crystals.KirillovReshetikhin(['B',3,1], 3, 3, model='KR')
2165
+ sage: elt = KRC.module_generators[1].f_string([3,2,3,1,3,3]); elt
2166
+ [++-, [[2], [0], [-3]]]
2167
+ sage: ret = KRT(elt); ret
2168
+ [[1, 1, 2], [2, 2, -3], [-3, -3, -1]]
2169
+ sage: test = KRC(ret); test
2170
+ [++-, [[2], [0], [-3]]]
2171
+ sage: test == elt
2172
+ True
2173
+ """
2174
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement
2175
+ if isinstance(args[0], KirillovReshetikhinTableauxElement):
2176
+ elt = args[0]
2177
+ # Check to make sure it can be converted
2178
+ if elt.cartan_type() != self.cartan_type() \
2179
+ or elt.parent().r() != self._r or elt.parent().s() != self._s:
2180
+ raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
2181
+
2182
+ to_hw = elt.to_classical_highest_weight()
2183
+ wt = to_hw[0].classical_weight()
2184
+ f_str = reversed(to_hw[1])
2185
+ for x in self.module_generators:
2186
+ if x.classical_weight() == wt:
2187
+ return x.f_string(f_str)
2188
+ raise ValueError("no matching highest weight element found")
2189
+ return KirillovReshetikhinGenericCrystal._element_constructor_(self, *args, **options)
2190
+
2191
+ def classical_decomposition(self):
2192
+ r"""
2193
+ Return the classical crystal underlying the Kirillov-Reshetikhin
2194
+ crystal `B^{n,s}` of type `B_n^{(1)}`.
2195
+
2196
+ It is the same as for `r < n`, given by
2197
+ `B^{n,s} \cong \bigoplus_{\Lambda} B(\Lambda)`, where `\Lambda` are
2198
+ weights obtained from a rectangle of width `s/2` and height `n` by
2199
+ removing horizontal dominoes. Here we identify the fundamental weight
2200
+ `\Lambda_i` with a column of height `i` for `i<n` and a column of
2201
+ width `1/2` for `i=n`.
2202
+
2203
+ EXAMPLES::
2204
+
2205
+ sage: K = crystals.KirillovReshetikhin(['B',3,1], 3, 2)
2206
+ sage: K.classical_decomposition()
2207
+ The crystal of tableaux of type ['B', 3] and shape(s) [[1], [1, 1, 1]]
2208
+ sage: K = crystals.KirillovReshetikhin(['B',3,1], 3, 3)
2209
+ sage: K.classical_decomposition()
2210
+ The crystal of tableaux of type ['B', 3] and shape(s) [[3/2, 1/2, 1/2], [3/2, 3/2, 3/2]]
2211
+ """
2212
+ s = self.s()
2213
+ r = self.r()
2214
+ shapes = vertical_dominoes_removed(r, s // 2)
2215
+ if is_odd(s):
2216
+ shapes = [[i+QQ(1)/QQ(2) for i in sh] + [QQ(1)/QQ(2)]*(r-len(sh))
2217
+ for sh in shapes]
2218
+ return CrystalOfTableaux(self.cartan_type().classical(), shapes=shapes)
2219
+
2220
+ def ambient_crystal(self):
2221
+ r"""
2222
+ Return the ambient crystal `B^{n,s}` of type `A_{2n-1}^{(2)}`
2223
+ associated to the Kirillov-Reshetikhin crystal.
2224
+
2225
+ The ambient crystal is used to construct the zero arrows.
2226
+
2227
+ EXAMPLES::
2228
+
2229
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2)
2230
+ sage: K.ambient_crystal()
2231
+ Kirillov-Reshetikhin crystal of type ['B', 3, 1]^* with (r,s)=(3,2)
2232
+ """
2233
+ return KashiwaraNakashimaTableaux(['A', 2*self.cartan_type().classical().rank()-1, 2],
2234
+ self.r(), self.s())
2235
+
2236
+ @cached_method
2237
+ def highest_weight_dict(self):
2238
+ r"""
2239
+ Return a dictionary of the classical highest weight vectors
2240
+ of ``self`` whose keys are 2 times their shape.
2241
+
2242
+ EXAMPLES::
2243
+
2244
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2)
2245
+ sage: K.highest_weight_dict()
2246
+ {(2,): [[1]], (2, 2, 2): [[1], [2], [3]]}
2247
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,3)
2248
+ sage: K.highest_weight_dict()
2249
+ {(3, 1, 1): [+++, [[1]]], (3, 3, 3): [+++, [[1], [2], [3]]]}
2250
+ """
2251
+ return {tuple([2*i[1] for i in sorted(x.classical_weight())]): x
2252
+ for x in self.module_generators}
2253
+
2254
+ @cached_method
2255
+ def ambient_highest_weight_dict(self):
2256
+ r"""
2257
+ Return a dictionary of the classical highest weight vectors of
2258
+ the ambient crystal of ``self`` whose keys are their shape.
2259
+
2260
+ EXAMPLES::
2261
+
2262
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2)
2263
+ sage: K.ambient_highest_weight_dict()
2264
+ {(2,): [[1, 1]], (2, 1, 1): [[1, 1], [2], [3]], (2, 2, 2): [[1, 1], [2, 2], [3, 3]]}
2265
+
2266
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,3)
2267
+ sage: K.ambient_highest_weight_dict()
2268
+ {(3,): [[1, 1, 1]],
2269
+ (3, 1, 1): [[1, 1, 1], [2], [3]],
2270
+ (3, 2, 2): [[1, 1, 1], [2, 2], [3, 3]],
2271
+ (3, 3, 3): [[1, 1, 1], [2, 2, 2], [3, 3, 3]]}
2272
+ """
2273
+ return {tuple([i[1] for i in sorted(x.classical_weight())]): x
2274
+ for x in self.ambient_crystal().module_generators}
2275
+
2276
+ def similarity_factor(self):
2277
+ r"""
2278
+ Set the similarity factor used to map to the ambient crystal.
2279
+
2280
+ EXAMPLES::
2281
+
2282
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2)
2283
+ sage: K.similarity_factor()
2284
+ {1: 2, 2: 2, 3: 1}
2285
+ """
2286
+ C = self.cartan_type().classical()
2287
+ p = {i: 2 for i in C.index_set()}
2288
+ p[C.rank()] = 1
2289
+ return p
2290
+
2291
+ @cached_method
2292
+ def to_ambient_crystal(self):
2293
+ r"""
2294
+ Return a map from ``self`` to the ambient crystal of type `A_{2n-1}^{(2)}`.
2295
+
2296
+ EXAMPLES::
2297
+
2298
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1)
2299
+ sage: [K.to_ambient_crystal()(b) for b in K]
2300
+ [[[1], [2], [3]], [[1], [2], [-3]], [[1], [3], [-2]], [[2], [3], [-1]], [[1], [-3], [-2]],
2301
+ [[2], [-3], [-1]], [[3], [-2], [-1]], [[-3], [-2], [-1]]]
2302
+ """
2303
+ hwd = self.highest_weight_dict()
2304
+ ahwd = self.ambient_highest_weight_dict()
2305
+ pdict = {hwd[key]: ahwd[key] for key in hwd}
2306
+ classical = self.cartan_type().classical()
2307
+ return self.crystal_morphism(pdict, codomain=self.ambient_crystal(),
2308
+ index_set=classical.index_set(),
2309
+ scaling_factors=self.similarity_factor(),
2310
+ cartan_type=classical, check=False)
2311
+
2312
+ @cached_method
2313
+ def from_ambient_crystal(self):
2314
+ r"""
2315
+ Return a map from the ambient crystal of type `A_{2n-1}^{(2)}` to
2316
+ the Kirillov-Reshetikhin crystal ``self``.
2317
+
2318
+ Note that this map is only well-defined on elements that are in the
2319
+ image under :meth:`to_ambient_crystal`.
2320
+
2321
+ EXAMPLES::
2322
+
2323
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1)
2324
+ sage: [b == K.from_ambient_crystal()(K.to_ambient_crystal()(b)) for b in K]
2325
+ [True, True, True, True, True, True, True, True]
2326
+ sage: b = K.ambient_crystal()(rows=[[1],[2],[-3]])
2327
+ sage: K.from_ambient_crystal()(b)
2328
+ [++-, []]
2329
+ """
2330
+ hwd = self.highest_weight_dict()
2331
+ ahwd = self.ambient_highest_weight_dict()
2332
+ pdict_inv = {ahwd[key]: hwd[key] for key in hwd}
2333
+ return AmbientRetractMap(self, self.ambient_crystal(), pdict_inv,
2334
+ index_set=self.cartan_type().classical().index_set(),
2335
+ similarity_factor_domain=self.similarity_factor())
2336
+
2337
+
2338
+ class KR_type_BnElement(KirillovReshetikhinGenericCrystalElement):
2339
+ r"""
2340
+ Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}`
2341
+ of type `B_n^{(1)}`.
2342
+
2343
+ EXAMPLES::
2344
+
2345
+ sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 2)
2346
+ sage: type(K.module_generators[0])
2347
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Bn_with_category.element_class'>
2348
+ """
2349
+
2350
+ def e0(self):
2351
+ r"""
2352
+ Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal,
2353
+ calculating `e_0` there and pulling the element back.
2354
+
2355
+ EXAMPLES::
2356
+
2357
+ sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1)
2358
+ sage: b = K.module_generators[0]
2359
+ sage: b.e(0) # indirect doctest
2360
+ [--+, []]
2361
+ """
2362
+ b = self.parent().to_ambient_crystal()(self).e_string([0, 0])
2363
+ if b is None:
2364
+ return None
2365
+ return self.parent().from_ambient_crystal()(b)
2366
+
2367
+ def f0(self):
2368
+ r"""
2369
+ Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal,
2370
+ calculating `f_0` there and pulling the element back.
2371
+
2372
+ EXAMPLES::
2373
+
2374
+ sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 1)
2375
+ sage: b = K.module_generators[0]
2376
+ sage: b.f(0) # indirect doctest
2377
+ """
2378
+ b = self.parent().to_ambient_crystal()(self).f_string([0, 0])
2379
+ if b is None:
2380
+ return None
2381
+ return self.parent().from_ambient_crystal()(b)
2382
+
2383
+ def epsilon0(self):
2384
+ r"""
2385
+ Calculate `\varepsilon_0` of ``self`` by mapping the element
2386
+ to the ambient crystal and calculating `\varepsilon_0` there.
2387
+
2388
+ EXAMPLES::
2389
+
2390
+ sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 1)
2391
+ sage: b = K.module_generators[0]
2392
+ sage: b.epsilon(0) # indirect doctest
2393
+ 1
2394
+ """
2395
+ b = self.parent().to_ambient_crystal()(self)
2396
+ return b.epsilon(0) // 2
2397
+
2398
+ def phi0(self):
2399
+ r"""
2400
+ Calculate `\varphi_0` of ``self`` by mapping the element to
2401
+ the ambient crystal and calculating `\varphi_0` there.
2402
+
2403
+ EXAMPLES::
2404
+
2405
+ sage: K = crystals.KirillovReshetikhin(['B', 3, 1], 3, 1)
2406
+ sage: b = K.module_generators[0]
2407
+ sage: b.phi(0) # indirect doctest
2408
+ 0
2409
+ """
2410
+ b = self.parent().to_ambient_crystal()(self)
2411
+ return b.phi(0) // 2
2412
+
2413
+
2414
+ KR_type_Bn.Element = KR_type_BnElement
2415
+
2416
+
2417
+ class KR_type_Cn(KirillovReshetikhinGenericCrystal):
2418
+ r"""
2419
+ Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `C_n^{(1)}`.
2420
+
2421
+ EXAMPLES::
2422
+
2423
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],3,1)
2424
+ sage: [[b,b.f(0)] for b in K]
2425
+ [[[[1], [2], [3]], None], [[[1], [2], [-3]], None],
2426
+ [[[1], [3], [-3]], None], [[[2], [3], [-3]], None],
2427
+ [[[1], [3], [-2]], None], [[[2], [3], [-2]], None],
2428
+ [[[2], [3], [-1]], [[1], [2], [3]]], [[[1], [-3], [-2]], None],
2429
+ [[[2], [-3], [-2]], None], [[[2], [-3], [-1]], [[1], [2], [-3]]],
2430
+ [[[3], [-3], [-2]], None], [[[3], [-3], [-1]], [[1], [3], [-3]]],
2431
+ [[[3], [-2], [-1]], [[1], [3], [-2]]],
2432
+ [[[-3], [-2], [-1]], [[1], [-3], [-2]]]]
2433
+ """
2434
+
2435
+ def classical_decomposition(self):
2436
+ r"""
2437
+ Specifies the classical crystal underlying the Kirillov-Reshetikhin
2438
+ crystal `B^{n,s}` of type `C_n^{(1)}`.
2439
+
2440
+ The classical decomposition is given by
2441
+ `B^{n,s} \cong B(s \Lambda_n)`.
2442
+
2443
+ EXAMPLES::
2444
+
2445
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],3,2)
2446
+ sage: K.classical_decomposition()
2447
+ The crystal of tableaux of type ['C', 3] and shape(s) [[2, 2, 2]]
2448
+ """
2449
+ return CrystalOfTableaux(self.cartan_type().classical(),
2450
+ shape=[self.s()] * self.r())
2451
+
2452
+ def from_highest_weight_vector_to_pm_diagram(self, b):
2453
+ r"""
2454
+ This gives the bijection between an element ``b`` in the classical
2455
+ decomposition of the KR crystal that is `{2,3,..,n}`-highest weight
2456
+ and `\pm` diagrams.
2457
+
2458
+ EXAMPLES::
2459
+
2460
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],3,2)
2461
+ sage: T = K.classical_decomposition()
2462
+ sage: b = T(rows=[[2, 2], [3, 3], [-3, -1]])
2463
+ sage: pm = K.from_highest_weight_vector_to_pm_diagram(b); pm
2464
+ [[0, 0], [1, 0], [0, 1], [0]]
2465
+ sage: pm.pp()
2466
+ . .
2467
+ . +
2468
+ - -
2469
+
2470
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]
2471
+ sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)
2472
+ True
2473
+ """
2474
+ n = self.cartan_type().rank()-1
2475
+ inner = Partition([Integer(b.weight()[i]) for i in range(1, n+1)])
2476
+ inter = Partition([len([i for i in r if i > 0]) for r in b.to_tableau()])
2477
+ outer = b.to_tableau().shape()
2478
+ return PMDiagram([self.r(), self.s(), outer, inter, inner], from_shapes=True)
2479
+
2480
+ def from_pm_diagram_to_highest_weight_vector(self, pm):
2481
+ r"""
2482
+ This gives the bijection between a `\pm` diagram and an element ``b``
2483
+ in the classical decomposition of the KR crystal that is
2484
+ `\{2,3,..,n\}`-highest weight.
2485
+
2486
+ EXAMPLES::
2487
+
2488
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],3,2)
2489
+ sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0, 0], [1, 0], [0, 1], [0]])
2490
+ sage: K.from_pm_diagram_to_highest_weight_vector(pm)
2491
+ [[2, 2], [3, 3], [-3, -1]]
2492
+ """
2493
+ u = next(b for b in self.classical_decomposition().module_generators
2494
+ if b.to_tableau().shape() == pm.outer_shape())
2495
+ ct = self.cartan_type()
2496
+ rank = ct.rank()-1
2497
+ ct_type = ct.classical().type()
2498
+ assert ct_type in ['C']
2499
+ ulist = []
2500
+ for h in pm.heights_of_addable_plus():
2501
+ ulist += list(range(1, h + 1))
2502
+ for h in pm.heights_of_minus():
2503
+ ulist += list(range(1, rank+1))+[rank-1-k for k in range(rank-h)]
2504
+ for i in reversed(ulist):
2505
+ u = u.f(i)
2506
+ return u
2507
+
2508
+
2509
+ class KR_type_CnElement(KirillovReshetikhinGenericCrystalElement):
2510
+ r"""
2511
+ Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}`
2512
+ of type `C_n^{(1)}`.
2513
+
2514
+ EXAMPLES::
2515
+
2516
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 2)
2517
+ sage: type(K.module_generators[0])
2518
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Cn_with_category.element_class'>
2519
+ """
2520
+
2521
+ def e0(self):
2522
+ r"""
2523
+ Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding
2524
+ to the `\{2,...,n\}`-highest weight vector in the component of
2525
+ ``self``, then applying [Definition 6.1, 4], and pulling back from
2526
+ `\pm`-diagrams.
2527
+
2528
+ EXAMPLES::
2529
+
2530
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 2)
2531
+ sage: b = K.module_generators[0]
2532
+ sage: b.e(0) # indirect doctest
2533
+ [[1, 2], [2, 3], [3, -1]]
2534
+ sage: b = K(rows=[[1,2],[2,3],[3,-1]])
2535
+ sage: b.e(0)
2536
+ [[2, 2], [3, 3], [-1, -1]]
2537
+ sage: b=K(rows=[[1, -3], [3, -2], [-3, -1]])
2538
+ sage: b.e(0)
2539
+ [[3, -3], [-3, -2], [-1, -1]]
2540
+ """
2541
+ n = self.parent().cartan_type().n
2542
+ b, l = self.lift().to_highest_weight(index_set=range(2, n + 1))
2543
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2544
+ l1, l2 = pm.pm_diagram[n-1]
2545
+ if l1 == 0:
2546
+ return None
2547
+ pm.pm_diagram[n-1] = [l1-1, l2+1]
2548
+ pm = PMDiagram(pm.pm_diagram)
2549
+ b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)
2550
+ b = b.f_string(reversed(l))
2551
+ return self.parent().retract(b)
2552
+
2553
+ def f0(self):
2554
+ r"""
2555
+ Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding
2556
+ to the `\{2,...,n\}`-highest weight vector in the component of
2557
+ ``self``, then applying [Definition 6.1, 4], and pulling back from
2558
+ `\pm`-diagrams.
2559
+
2560
+ EXAMPLES::
2561
+
2562
+ sage: K = crystals.KirillovReshetikhin(['C',3,1],3,1)
2563
+ sage: b = K.module_generators[0]
2564
+ sage: b.f(0) # indirect doctest
2565
+ """
2566
+ n = self.parent().cartan_type().n
2567
+ b, l = self.lift().to_highest_weight(index_set=range(2, n + 1))
2568
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2569
+ l1, l2 = pm.pm_diagram[n-1]
2570
+ if l2 == 0:
2571
+ return None
2572
+ pm.pm_diagram[n-1] = [l1+1, l2-1]
2573
+ pm = PMDiagram(pm.pm_diagram)
2574
+ b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)
2575
+ b = b.f_string(reversed(l))
2576
+ return self.parent().retract(b)
2577
+
2578
+ def epsilon0(self):
2579
+ r"""
2580
+ Calculate `\varepsilon_0` of ``self`` using Lemma 6.1 of [4].
2581
+
2582
+ EXAMPLES::
2583
+
2584
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 1)
2585
+ sage: b = K.module_generators[0]
2586
+ sage: b.epsilon(0) # indirect doctest
2587
+ 1
2588
+ """
2589
+ n = self.parent().cartan_type().n
2590
+ b = self.lift().to_highest_weight(index_set=range(2, n + 1))[0]
2591
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2592
+ l1, l2 = pm.pm_diagram[n-1]
2593
+ return l1
2594
+
2595
+ def phi0(self):
2596
+ r"""
2597
+ Calculate `\varphi_0` of ``self``.
2598
+
2599
+ EXAMPLES::
2600
+
2601
+ sage: K = crystals.KirillovReshetikhin(['C', 3, 1], 3, 1)
2602
+ sage: b = K.module_generators[0]
2603
+ sage: b.phi(0) # indirect doctest
2604
+ 0
2605
+ """
2606
+ n = self.parent().cartan_type().n
2607
+ b = self.lift().to_highest_weight(index_set=range(2, n + 1))[0]
2608
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2609
+ l1, l2 = pm.pm_diagram[n-1]
2610
+ return l2
2611
+
2612
+
2613
+ KR_type_Cn.Element = KR_type_CnElement
2614
+
2615
+
2616
+ class KR_type_Dn_twisted(KirillovReshetikhinGenericCrystal):
2617
+ r"""
2618
+ Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_{n+1}^{(2)}`.
2619
+
2620
+ EXAMPLES::
2621
+
2622
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1)
2623
+ sage: [[b,b.f(0)] for b in K]
2624
+ [[[+++, []], None], [[++-, []], None], [[+-+, []], None], [[-++, []],
2625
+ [+++, []]], [[+--, []], None], [[-+-, []], [++-, []]], [[--+, []], [+-+, []]],
2626
+ [[---, []], [+--, []]]]
2627
+ """
2628
+
2629
+ def _element_constructor_(self, *args, **options):
2630
+ """
2631
+ Construct an element of ``self``.
2632
+
2633
+ TESTS::
2634
+
2635
+ sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 3, 3)
2636
+ sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 3, 3, model='KR')
2637
+ sage: elt = KRC.module_generators[0].f_string([3,2,3,1,2,3]); elt
2638
+ [++-+, [[2], [3], [4], [-2]]]
2639
+ sage: ret = KRT(elt); ret
2640
+ [[1, 1, 2], [2, 3, 3], [4, 4, 4], [-3, -2, -1]]
2641
+ sage: test = KRC(ret); test
2642
+ [++-+, [[2], [3], [4], [-2]]]
2643
+ sage: test == elt
2644
+ True
2645
+ """
2646
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement
2647
+ if isinstance(args[0], KirillovReshetikhinTableauxElement):
2648
+ elt = args[0]
2649
+ # Check to make sure it can be converted
2650
+ if elt.cartan_type() != self.cartan_type() \
2651
+ or elt.parent().r() != self._r or elt.parent().s() != self._s:
2652
+ raise ValueError("the Kirillov-Reshetikhin tableau must have"
2653
+ " the same Cartan type and shape")
2654
+
2655
+ to_hw = elt.to_classical_highest_weight()
2656
+ wt = to_hw[0].classical_weight()
2657
+ f_str = reversed(to_hw[1])
2658
+ for x in self.module_generators:
2659
+ if x.classical_weight() == wt:
2660
+ return x.f_string(f_str)
2661
+ raise ValueError("no matching highest weight element found")
2662
+ return KirillovReshetikhinGenericCrystal._element_constructor_(self, *args, **options)
2663
+
2664
+ def classical_decomposition(self):
2665
+ r"""
2666
+ Return the classical crystal underlying the Kirillov-Reshetikhin
2667
+ crystal `B^{n,s}` of type `D_{n+1}^{(2)}`.
2668
+
2669
+ The classical decomposition is given by
2670
+ `B^{n,s} \cong B(s \Lambda_n)`.
2671
+
2672
+ EXAMPLES::
2673
+
2674
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1)
2675
+ sage: K.classical_decomposition()
2676
+ The crystal of tableaux of type ['B', 3] and shape(s) [[1/2, 1/2, 1/2]]
2677
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2)
2678
+ sage: K.classical_decomposition()
2679
+ The crystal of tableaux of type ['B', 3] and shape(s) [[1, 1, 1]]
2680
+ """
2681
+ s = self.s()
2682
+ if is_even(s):
2683
+ s = s // 2
2684
+ else:
2685
+ s = s / 2
2686
+ return CrystalOfTableaux(self.cartan_type().classical(),
2687
+ shape=[s]*self.r())
2688
+
2689
+ def from_highest_weight_vector_to_pm_diagram(self, b):
2690
+ r"""
2691
+ This gives the bijection between an element ``b`` in the
2692
+ classical decomposition of the KR crystal that is
2693
+ `\{2,3,\ldots,n\}`-highest weight and `\pm` diagrams.
2694
+
2695
+ EXAMPLES::
2696
+
2697
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1)
2698
+ sage: T = K.classical_decomposition()
2699
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]
2700
+ sage: [K.from_highest_weight_vector_to_pm_diagram(b) for b in hw]
2701
+ [[[0, 0], [0, 0], [1, 0], [0]], [[0, 0], [0, 0], [0, 1], [0]]]
2702
+
2703
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2)
2704
+ sage: T = K.classical_decomposition()
2705
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]
2706
+ sage: [K.from_highest_weight_vector_to_pm_diagram(b) for b in hw]
2707
+ [[[0, 0], [0, 0], [2, 0], [0]], [[0, 0], [0, 0], [0, 0], [2]],
2708
+ [[0, 0], [2, 0], [0, 0], [0]], [[0, 0], [0, 0], [0, 2], [0]]]
2709
+
2710
+ Note that, since the classical decomposition of this crystal is of
2711
+ type `B_n`, there can be (at most one) entry `0` in the
2712
+ `\{2,3,\ldots,n\}`-highest weight elements at height `n`.
2713
+ In the following implementation this is realized as an empty
2714
+ column of height `n` since this uniquely specifies the existence
2715
+ of the `0`.
2716
+
2717
+ EXAMPLES::
2718
+
2719
+ sage: b = hw[1]
2720
+ sage: pm = K.from_highest_weight_vector_to_pm_diagram(b)
2721
+ sage: pm.pp()
2722
+ . .
2723
+ . .
2724
+ . .
2725
+
2726
+ TESTS::
2727
+
2728
+ sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)
2729
+ True
2730
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2)
2731
+ sage: T = K.classical_decomposition()
2732
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]
2733
+ sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)
2734
+ True
2735
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,3)
2736
+ sage: T = K.classical_decomposition()
2737
+ sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]
2738
+ sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)
2739
+ True
2740
+ """
2741
+ n = self.cartan_type().rank() - 1
2742
+ s = self.s()
2743
+ if is_odd(s):
2744
+ t = b[0]
2745
+ b = b[1]
2746
+ else:
2747
+ t = b.parent()(rows=[])
2748
+ inner = [Integer(2*b.weight()[i]+2*t.weight()[i])
2749
+ for i in range(1, n+1)]
2750
+ inter1 = Partition([len([1 for i in r if i > 0])
2751
+ for r in b.to_tableau()])
2752
+ inter = Partition([len([1 for i in r if i >= 0])
2753
+ for r in b.to_tableau()])
2754
+ if inter != inter1:
2755
+ inner[n-1] += 2
2756
+ inner = Partition(inner)
2757
+ inter = [2*i for i in inter]+[0]*(n-len(inter))
2758
+ w = t.weight()
2759
+ if w[0] == 0 and w[n-1] == 0:
2760
+ v = [0]*n
2761
+ else:
2762
+ v = [1]*n
2763
+ if w[0] < 0 and w[n-1] > 0:
2764
+ v[n-1] = 0
2765
+ elif w[0] > 0 and w[n-1] < 0:
2766
+ v[n-1] = 0
2767
+ v[n-2] = -1
2768
+ inter = Partition([inter[i] + v[i] for i in range(n)])
2769
+ outer = Partition([s]*n)
2770
+ return PMDiagram([n, s, outer, inter, inner], from_shapes=True)
2771
+
2772
+ def from_pm_diagram_to_highest_weight_vector(self, pm):
2773
+ r"""
2774
+ This gives the bijection between a `\pm` diagram and an element
2775
+ ``b`` in the classical decomposition of the KR crystal that is
2776
+ `\{2,3,\ldots,n\}`-highest weight.
2777
+
2778
+ EXAMPLES::
2779
+
2780
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2)
2781
+ sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0, 0], [0, 0], [0, 0], [2]])
2782
+ sage: K.from_pm_diagram_to_highest_weight_vector(pm)
2783
+ [[2], [3], [0]]
2784
+ """
2785
+ u = self.classical_decomposition().module_generators[0]
2786
+ ct = self.cartan_type()
2787
+ rank = ct.rank()-1
2788
+ assert ct.classical().type() in ['B']
2789
+ ulist = []
2790
+ plus = pm.heights_of_addable_plus()
2791
+ minus = pm.heights_of_minus()
2792
+ l = len([i for i in plus if i == rank-1])
2793
+ a = (len(plus) + l) // 2
2794
+ ulist += sum(([i]*a for i in range(1, rank+1)), [])
2795
+ a = (len(minus)-l) // 2
2796
+ ulist += (list(range(1, rank + 1)) + [rank]) * a
2797
+ for i in reversed(ulist):
2798
+ u = u.f(i)
2799
+ return u
2800
+
2801
+
2802
+ class KR_type_Dn_twistedElement(KirillovReshetikhinGenericCrystalElement):
2803
+ r"""
2804
+ Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}`
2805
+ of type `D_{n+1}^{(2)}`.
2806
+
2807
+ EXAMPLES::
2808
+
2809
+ sage: K = crystals.KirillovReshetikhin(['D', 4, 2], 3, 2)
2810
+ sage: type(K.module_generators[0])
2811
+ <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Dn_twisted_with_category.element_class'>
2812
+ """
2813
+
2814
+ def e0(self):
2815
+ r"""
2816
+ Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding
2817
+ to the `\{2,\ldots,n\}`-highest weight vector in the component of
2818
+ ``self``, then applying [Definition 6.2, 4], and pulling back from
2819
+ `\pm`-diagrams.
2820
+
2821
+ EXAMPLES::
2822
+
2823
+ sage: K = crystals.KirillovReshetikhin(['D', 4, 2], 3, 3)
2824
+ sage: b = K.module_generators[0]
2825
+ sage: b.e(0) # indirect doctest
2826
+ [+++, [[2], [3], [0]]]
2827
+ """
2828
+ n = self.parent().cartan_type().rank()-1
2829
+ s = self.parent().s()
2830
+ b, l = self.lift().to_highest_weight(index_set=range(2, n + 1))
2831
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2832
+ l1, l2 = pm.pm_diagram[n-1]
2833
+ l3 = pm.pm_diagram[n-2][0]
2834
+ if l1+l2+l3 == s and l1 == 0:
2835
+ return None
2836
+ if l1+l2+l3 < s:
2837
+ pm.pm_diagram[n-1][1] = l2+2
2838
+ pm.pm_diagram[n][0] -= 2
2839
+ elif l1 > 1:
2840
+ pm.pm_diagram[n-1][0] = l1-2
2841
+ pm.pm_diagram[n][0] += 2
2842
+ elif l1 == 1:
2843
+ pm.pm_diagram[n-1][0] = 0
2844
+ pm.pm_diagram[n-1][1] = l2+1
2845
+ pm = PMDiagram(pm.pm_diagram)
2846
+ b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)
2847
+ b = b.f_string(reversed(l))
2848
+ return self.parent().retract(b)
2849
+
2850
+ def f0(self):
2851
+ r"""
2852
+ Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding
2853
+ to the `\{2,\ldots,n\}`-highest weight vector in the component of
2854
+ ``self``, then applying [Definition 6.2, 4], and pulling back from
2855
+ `\pm`-diagrams.
2856
+
2857
+ EXAMPLES::
2858
+
2859
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2)
2860
+ sage: b = K.module_generators[0]
2861
+ sage: b.f(0) # indirect doctest
2862
+ """
2863
+ n = self.parent().cartan_type().rank()-1
2864
+ s = self.parent().s()
2865
+ b, l = self.lift().to_highest_weight(index_set=range(2, n + 1))
2866
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2867
+ l1, l2 = pm.pm_diagram[n-1]
2868
+ l3 = pm.pm_diagram[n-2][0]
2869
+ if l1+l2+l3 == s and l2 == 0:
2870
+ return None
2871
+ if l1+l2+l3 < s:
2872
+ pm.pm_diagram[n-1][0] = l1+2
2873
+ pm.pm_diagram[n][0] -= 2
2874
+ elif l2 > 1:
2875
+ pm.pm_diagram[n-1][1] = l2-2
2876
+ pm.pm_diagram[n][0] += 2
2877
+ elif l2 == 1:
2878
+ pm.pm_diagram[n-1][1] = 0
2879
+ pm.pm_diagram[n-1][0] = l1+1
2880
+ pm = PMDiagram(pm.pm_diagram)
2881
+ b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)
2882
+ b = b.f_string(reversed(l))
2883
+ return self.parent().retract(b)
2884
+
2885
+ def epsilon0(self):
2886
+ r"""
2887
+ Calculate `\varepsilon_0` of ``self`` using Lemma 6.2 of [4].
2888
+
2889
+ EXAMPLES::
2890
+
2891
+ sage: K = crystals.KirillovReshetikhin(['D', 4, 2], 3, 1)
2892
+ sage: b = K.module_generators[0]
2893
+ sage: b.epsilon(0) # indirect doctest
2894
+ 1
2895
+
2896
+ TESTS:
2897
+
2898
+ Check that :issue:`19982` is fixed::
2899
+
2900
+ sage: K = crystals.KirillovReshetikhin(['D',3,2], 2,3)
2901
+ sage: def eps0_defn(elt):
2902
+ ....: x = elt.e(0)
2903
+ ....: eps = 0
2904
+ ....: while x is not None:
2905
+ ....: x = x.e(0)
2906
+ ....: eps = eps + 1
2907
+ ....: return eps
2908
+ sage: all(eps0_defn(x) == x.epsilon0() for x in K)
2909
+ True
2910
+ """
2911
+ n = self.parent().cartan_type().rank() - 1
2912
+ b, l = self.lift().to_highest_weight(index_set=range(2, n + 1))
2913
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2914
+ l1 = pm.pm_diagram[n-1][0]
2915
+ l4 = pm.pm_diagram[n][0]
2916
+ return l1 + l4 // 2
2917
+
2918
+ def phi0(self):
2919
+ r"""
2920
+ Calculate `\varphi_0` of ``self``.
2921
+
2922
+ EXAMPLES::
2923
+
2924
+ sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1)
2925
+ sage: b = K.module_generators[0]
2926
+ sage: b.phi(0) # indirect doctest
2927
+ 0
2928
+
2929
+ TESTS:
2930
+
2931
+ Check that :issue:`19982` is fixed::
2932
+
2933
+ sage: K = crystals.KirillovReshetikhin(['D',3,2], 2,3)
2934
+ sage: def phi0_defn(elt):
2935
+ ....: x = elt.f(0)
2936
+ ....: phi = 0
2937
+ ....: while x is not None:
2938
+ ....: x = x.f(0)
2939
+ ....: phi = phi + 1
2940
+ ....: return phi
2941
+ sage: all(phi0_defn(x) == x.phi0() for x in K)
2942
+ True
2943
+ """
2944
+ n = self.parent().cartan_type().rank() - 1
2945
+ b, l = self.lift().to_highest_weight(index_set=range(2, n + 1))
2946
+ pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)
2947
+ l2 = pm.pm_diagram[n-1][1]
2948
+ l4 = pm.pm_diagram[n][0]
2949
+ return l2 + l4 // 2
2950
+
2951
+
2952
+ KR_type_Dn_twisted.Element = KR_type_Dn_twistedElement
2953
+
2954
+
2955
+ class KR_type_spin(KirillovReshetikhinCrystalFromPromotion):
2956
+ r"""
2957
+ Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_n^{(1)}`.
2958
+
2959
+ EXAMPLES::
2960
+
2961
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],4,1); K
2962
+ Kirillov-Reshetikhin crystal of type ['D', 4, 1] with (r,s)=(4,1)
2963
+ sage: [[b,b.f(0)] for b in K]
2964
+ [[[++++, []], None], [[++--, []], None], [[+-+-, []], None],
2965
+ [[-++-, []], None], [[+--+, []], None], [[-+-+, []], None],
2966
+ [[--++, []], [++++, []]], [[----, []], [++--, []]]]
2967
+
2968
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],4,2); K
2969
+ Kirillov-Reshetikhin crystal of type ['D', 4, 1] with (r,s)=(4,2)
2970
+ sage: [[b,b.f(0)] for b in K]
2971
+ [[[[1], [2], [3], [4]], None], [[[1], [2], [-4], [4]], None],
2972
+ [[[1], [3], [-4], [4]], None], [[[2], [3], [-4], [4]], None],
2973
+ [[[1], [4], [-4], [4]], None], [[[2], [4], [-4], [4]], None],
2974
+ [[[3], [4], [-4], [4]], [[1], [2], [3], [4]]],
2975
+ [[[-4], [4], [-4], [4]], [[1], [2], [-4], [4]]],
2976
+ [[[-4], [4], [-4], [-3]], [[1], [2], [-4], [-3]]],
2977
+ [[[-4], [4], [-4], [-2]], [[1], [3], [-4], [-3]]],
2978
+ [[[-4], [4], [-4], [-1]], [[2], [3], [-4], [-3]]],
2979
+ [[[-4], [4], [-3], [-2]], [[1], [4], [-4], [-3]]],
2980
+ [[[-4], [4], [-3], [-1]], [[2], [4], [-4], [-3]]],
2981
+ [[[-4], [4], [-2], [-1]], [[-4], [4], [-4], [4]]],
2982
+ [[[-4], [-3], [-2], [-1]], [[-4], [4], [-4], [-3]]],
2983
+ [[[1], [2], [-4], [-3]], None], [[[1], [3], [-4], [-3]], None],
2984
+ [[[2], [3], [-4], [-3]], None], [[[1], [3], [-4], [-2]], None],
2985
+ [[[2], [3], [-4], [-2]], None], [[[2], [3], [-4], [-1]], None],
2986
+ [[[1], [4], [-4], [-3]], None], [[[2], [4], [-4], [-3]], None],
2987
+ [[[3], [4], [-4], [-3]], None],
2988
+ [[[3], [4], [-4], [-2]], [[1], [3], [-4], [4]]],
2989
+ [[[3], [4], [-4], [-1]], [[2], [3], [-4], [4]]],
2990
+ [[[1], [4], [-4], [-2]], None], [[[2], [4], [-4], [-2]], None],
2991
+ [[[2], [4], [-4], [-1]], None], [[[1], [4], [-3], [-2]], None],
2992
+ [[[2], [4], [-3], [-2]], None], [[[2], [4], [-3], [-1]], None],
2993
+ [[[3], [4], [-3], [-2]], [[1], [4], [-4], [4]]],
2994
+ [[[3], [4], [-3], [-1]], [[2], [4], [-4], [4]]],
2995
+ [[[3], [4], [-2], [-1]], [[3], [4], [-4], [4]]]]
2996
+
2997
+ TESTS::
2998
+
2999
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1)
3000
+ sage: all(b.e(0).f(0) == b for b in K if b.epsilon(0)>0)
3001
+ True
3002
+
3003
+ sage: K = crystals.KirillovReshetikhin(['D',5,1],5,2)
3004
+ sage: all(b.f(0).e(0) == b for b in K if b.phi(0)>0)
3005
+ True
3006
+ """
3007
+
3008
+ def _element_constructor_(self, *args, **options):
3009
+ """
3010
+ Construct an element of ``self`` from the input.
3011
+
3012
+ EXAMPLES::
3013
+
3014
+ sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 4, 3, model='KR')
3015
+ sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 4, 3)
3016
+ sage: elt = KRT(-3,-4,2,1,-3,-4,2,1,-2,-4,3,1); elt
3017
+ [[1, 1, 1], [2, 2, 3], [-4, -4, -4], [-3, -3, -2]]
3018
+ sage: KRC(elt) # indirect doctest
3019
+ [++--, [[1], [3], [-4], [-3]]]
3020
+
3021
+ TESTS:
3022
+
3023
+ Spinor test::
3024
+
3025
+ sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 4, 3)
3026
+ sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 4, 3, model='KR')
3027
+ sage: elt = KRC.module_generator().f_string([4,2,4,3,4,1]); elt
3028
+ [++--, [[2], [4], [-4], [-3]]]
3029
+ sage: ret = KRT(elt); ret
3030
+ [[1, 1, 2], [2, 2, 4], [-4, -4, -3], [-3, -3, -1]]
3031
+ sage: test = KRC(ret); test
3032
+ [++--, [[2], [4], [-4], [-3]]]
3033
+ sage: test == elt
3034
+ True
3035
+ """
3036
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement
3037
+ if isinstance(args[0], KirillovReshetikhinTableauxElement):
3038
+ elt = args[0]
3039
+ # Check to make sure it can be converted
3040
+ if elt.cartan_type() != self.cartan_type() \
3041
+ or elt.parent().r() != self._r or elt.parent().s() != self._s:
3042
+ raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
3043
+
3044
+ to_hw = elt.to_classical_highest_weight()
3045
+ f_str = reversed(to_hw[1])
3046
+ return self.maximal_vector().f_string(f_str)
3047
+ return KirillovReshetikhinCrystalFromPromotion._element_constructor_(self, *args, **options)
3048
+
3049
+ def classical_decomposition(self):
3050
+ r"""
3051
+ Return the classical crystal underlying the Kirillov-Reshetikhin
3052
+ crystal `B^{r,s}` of type `D_n^{(1)}` for `r=n-1,n`.
3053
+
3054
+ The classical decomposition is given by
3055
+ `B^{n,s} \cong B(s \Lambda_r)`.
3056
+
3057
+ EXAMPLES::
3058
+
3059
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],4,1)
3060
+ sage: K.classical_decomposition()
3061
+ The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, 1/2]]
3062
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1)
3063
+ sage: K.classical_decomposition()
3064
+ The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, -1/2]]
3065
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],3,2)
3066
+ sage: K.classical_decomposition()
3067
+ The crystal of tableaux of type ['D', 4] and shape(s) [[1, 1, 1, -1]]
3068
+
3069
+ TESTS:
3070
+
3071
+ Check that this is robust against python ints::
3072
+
3073
+ sage: K = crystals.KirillovReshetikhin(['D',4,1], 4, int(1))
3074
+ sage: K.classical_crystal
3075
+ The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, 1/2]]
3076
+ """
3077
+ C = self.cartan_type().classical()
3078
+ s = QQ(self.s())
3079
+ if self.r() == C.n:
3080
+ c = [s / QQ(2)]*C.n
3081
+ else:
3082
+ c = [s / QQ(2)]*(C.n-1) + [-s / QQ(2)]
3083
+ return CrystalOfTableaux(C, shape=c)
3084
+
3085
+ def dynkin_diagram_automorphism(self, i):
3086
+ """
3087
+ Specifies the Dynkin diagram automorphism underlying the promotion
3088
+ action on the crystal elements.
3089
+
3090
+ Here we use the Dynkin diagram automorphism which interchanges
3091
+ nodes 0 and 1 and leaves all other nodes unchanged.
3092
+
3093
+ EXAMPLES::
3094
+
3095
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],4,1)
3096
+ sage: K.dynkin_diagram_automorphism(0)
3097
+ 1
3098
+ sage: K.dynkin_diagram_automorphism(1)
3099
+ 0
3100
+ sage: K.dynkin_diagram_automorphism(4)
3101
+ 4
3102
+ """
3103
+ aut = [1, 0] + list(range(2, self.cartan_type().rank()))
3104
+ return aut[i]
3105
+
3106
+ @cached_method
3107
+ def promotion_on_highest_weight_vectors(self):
3108
+ r"""
3109
+ Return the promotion operator on `\{2,3,\ldots,n\}`-highest
3110
+ weight vectors.
3111
+
3112
+ A `\{2,3,\ldots,n\}`-highest weight vector in `B(s\Lambda_n)` of
3113
+ weight `w = (w_1,\ldots,w_n)` is mapped to a
3114
+ `\{2,3,\ldots,n\}`-highest weight vector in `B(s\Lambda_{n-1})`
3115
+ of weight `(-w_1,w_2,\ldots,w_n)` and vice versa.
3116
+
3117
+ .. SEEALSO::
3118
+
3119
+ - :meth:`promotion_on_highest_weight_vectors_inverse`
3120
+ - :meth:`promotion`
3121
+
3122
+ EXAMPLES::
3123
+
3124
+ sage: KR = crystals.KirillovReshetikhin(['D',4,1],4,2)
3125
+ sage: prom = KR.promotion_on_highest_weight_vectors()
3126
+ sage: T = KR.classical_decomposition()
3127
+ sage: HW = [t for t in T if t.is_highest_weight([2,3,4])]
3128
+ sage: for t in HW:
3129
+ ....: print("{} {}".format(t, prom[t]))
3130
+ [[1], [2], [3], [4]] [[2], [3], [4], [-1]]
3131
+ [[2], [3], [-4], [4]] [[2], [3], [4], [-4]]
3132
+ [[2], [3], [-4], [-1]] [[1], [2], [3], [-4]]
3133
+
3134
+ sage: KR = crystals.KirillovReshetikhin(['D',4,1],4,1)
3135
+ sage: prom = KR.promotion_on_highest_weight_vectors()
3136
+ sage: T = KR.classical_decomposition()
3137
+ sage: HW = [t for t in T if t.is_highest_weight([2,3,4])]
3138
+ sage: for t in HW:
3139
+ ....: print("{} {}".format(t, prom[t]))
3140
+ [++++, []] [-+++, []]
3141
+ [-++-, []] [+++-, []]
3142
+ """
3143
+ T = self.classical_decomposition()
3144
+ ind = list(T.index_set())
3145
+ ind.remove(1)
3146
+ C = T.cartan_type()
3147
+ n = C.n
3148
+ sh = list(T.shapes[0])
3149
+ sh[n-1] = -sh[n-1]
3150
+ T_dual = CrystalOfTableaux(C, shape=sh)
3151
+ hw = [t for t in T if t.is_highest_weight(index_set=ind)]
3152
+ hw_dual = [t for t in T_dual if t.is_highest_weight(index_set=ind)]
3153
+ dic_weight = {tuple(t.weight().to_vector()): t for t in hw}
3154
+ dic_weight_dual = {tuple(t.weight().to_vector()): t for t in hw_dual}
3155
+
3156
+ def neg(x):
3157
+ y = list(x) # map a (shallow) copy
3158
+ y[0] = -y[0]
3159
+ return tuple(y)
3160
+
3161
+ return {dic_weight[w]: dic_weight_dual[neg(w)] for w in dic_weight}
3162
+
3163
+ @cached_method
3164
+ def promotion_on_highest_weight_vectors_inverse(self):
3165
+ r"""
3166
+ Return the inverse promotion operator on
3167
+ `\{2,3,\ldots,n\}`-highest weight vectors.
3168
+
3169
+ .. SEEALSO::
3170
+
3171
+ - :meth:`promotion_on_highest_weight_vectors`
3172
+ - :meth:`promotion_inverse`
3173
+
3174
+ EXAMPLES::
3175
+
3176
+ sage: KR = crystals.KirillovReshetikhin(['D',4,1],3,2)
3177
+ sage: prom = KR.promotion_on_highest_weight_vectors()
3178
+ sage: prom_inv = KR.promotion_on_highest_weight_vectors_inverse()
3179
+ sage: T = KR.classical_decomposition()
3180
+ sage: HW = [t for t in T if t.is_highest_weight([2,3,4])]
3181
+ sage: all(prom_inv[prom[t]] == t for t in HW)
3182
+ True
3183
+ """
3184
+ D = self.promotion_on_highest_weight_vectors()
3185
+ return {Dt: t for t, Dt in D.items()}
3186
+
3187
+ @cached_method
3188
+ def promotion(self):
3189
+ r"""
3190
+ Return the promotion operator on `B^{r,s}` of type
3191
+ `D_n^{(1)}` for `r = n-1,n`.
3192
+
3193
+ EXAMPLES::
3194
+
3195
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1)
3196
+ sage: T = K.classical_decomposition()
3197
+ sage: promotion = K.promotion()
3198
+ sage: for t in T:
3199
+ ....: print("{} {}".format(t, promotion(t)))
3200
+ [+++-, []] [-++-, []]
3201
+ [++-+, []] [-+-+, []]
3202
+ [+-++, []] [--++, []]
3203
+ [-+++, []] [++++, []]
3204
+ [+---, []] [----, []]
3205
+ [-+--, []] [++--, []]
3206
+ [--+-, []] [+-+-, []]
3207
+ [---+, []] [+--+, []]
3208
+ """
3209
+ T = self.classical_decomposition()
3210
+ ind = list(T.index_set())
3211
+ ind.remove(1)
3212
+ return CrystalDiagramAutomorphism(T, self.promotion_on_highest_weight_vectors(), ind)
3213
+
3214
+ @cached_method
3215
+ def promotion_inverse(self):
3216
+ r"""
3217
+ Return the inverse promotion operator on `B^{r,s}` of type
3218
+ `D_n^{(1)}` for `r=n-1,n`.
3219
+
3220
+ EXAMPLES::
3221
+
3222
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1)
3223
+ sage: T = K.classical_decomposition()
3224
+ sage: promotion = K.promotion()
3225
+ sage: promotion_inverse = K.promotion_inverse()
3226
+ sage: all(promotion_inverse(promotion(t)) == t for t in T)
3227
+ True
3228
+ """
3229
+ D = self.promotion_on_highest_weight_vectors_inverse()
3230
+ T = list(D)[0].parent()
3231
+ ind = list(T.index_set())
3232
+ ind.remove(1)
3233
+ return CrystalDiagramAutomorphism(T, self.promotion_on_highest_weight_vectors_inverse(), ind)
3234
+
3235
+
3236
+ class KR_type_D_tri1(KirillovReshetikhinGenericCrystal):
3237
+ r"""
3238
+ Class of Kirillov-Reshetikhin crystals `B^{1,s}` of type `D_4^{(3)}`.
3239
+
3240
+ The crystal structure was defined in Section 4 of [KMOY2007]_ using
3241
+ the coordinate representation.
3242
+ """
3243
+
3244
+ def __init__(self, ct, s):
3245
+ r"""
3246
+ Initialize ``self``.
3247
+
3248
+ EXAMPLES::
3249
+
3250
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 2)
3251
+ sage: TestSuite(K).run()
3252
+ """
3253
+ KirillovReshetikhinGenericCrystal.__init__(self, ct, 1, s)
3254
+
3255
+ def classical_decomposition(self):
3256
+ """
3257
+ Return the classical decomposition of ``self``.
3258
+
3259
+ EXAMPLES::
3260
+
3261
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5)
3262
+ sage: K.classical_decomposition()
3263
+ The crystal of tableaux of type ['G', 2]
3264
+ and shape(s) [[], [1], [2], [3], [4], [5]]
3265
+ """
3266
+ sh = [Partition([j]) for j in range(self._s+1)]
3267
+ return CrystalOfTableaux(self.cartan_type().classical(), shapes=sh)
3268
+
3269
+ def from_coordinates(self, coords):
3270
+ r"""
3271
+ Return an element of ``self`` from the coordinates ``coords``.
3272
+
3273
+ EXAMPLES::
3274
+
3275
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5)
3276
+ sage: K.from_coordinates((0, 2, 3, 1, 0, 1))
3277
+ [[2, 2, 3, 0, -1]]
3278
+ """
3279
+ C = self.classical_decomposition()
3280
+ if not sum(coords):
3281
+ # Special empty element (i.e. the unique element of B(0))
3282
+ return self.element_class(self, C.module_generators[0])
3283
+
3284
+ l = C.letters
3285
+ lst = ([l(1)]*coords[0] + [l(2)]*coords[1] + [l(3)]*(coords[2]//2)
3286
+ + [l(0)]*(coords[2] % 2) + [l(-3)]*(coords[3]//2)
3287
+ + [l(-2)]*coords[4] + [l(-1)]*coords[5])
3288
+ return self.element_class(self, C(*lst))
3289
+
3290
+ def _element_constructor_(self, *args, **options):
3291
+ """
3292
+ Construct an element of ``self``.
3293
+
3294
+ TESTS::
3295
+
3296
+ sage: KRC = crystals.KirillovReshetikhin(['D',4,3], 1, 3)
3297
+ sage: KRT = crystals.KirillovReshetikhin(['D',4,3], 1, 3, model='KR')
3298
+ sage: elt = KRC.module_generators[2].f_string([1,1,2,1,2]); elt
3299
+ [[3, 0]]
3300
+ sage: ret = KRT(elt); ret
3301
+ [[3, 0, E]]
3302
+ sage: test = KRC(ret); test
3303
+ [[3, 0]]
3304
+ sage: test == elt
3305
+ True
3306
+ """
3307
+ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement
3308
+ if isinstance(args[0], KirillovReshetikhinTableauxElement):
3309
+ elt = args[0]
3310
+ # Check to make sure it can be converted
3311
+ if elt.cartan_type() != self.cartan_type() \
3312
+ or elt.parent().r() != self._r or elt.parent().s() != self._s:
3313
+ raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
3314
+
3315
+ to_hw = elt.to_classical_highest_weight()
3316
+ # The classically HW element consists of 1, -1, and 'E'
3317
+ wt = sum(x.value for x in to_hw[0] if x.value != 'E')
3318
+ letters = elt.parent().letters
3319
+ if wt:
3320
+ rows = [[letters(1)]*int(wt)]
3321
+ else:
3322
+ rows = []
3323
+ hw_elt = self(rows=rows)
3324
+ f_str = reversed(to_hw[1])
3325
+ return hw_elt.f_string(f_str)
3326
+ return KirillovReshetikhinGenericCrystal._element_constructor_(self, *args, **options)
3327
+
3328
+ class Element(KirillovReshetikhinGenericCrystalElement):
3329
+ @cached_method
3330
+ def coordinates(self):
3331
+ """
3332
+ Return ``self`` as coordinates.
3333
+
3334
+ EXAMPLES::
3335
+
3336
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 3)
3337
+ sage: all(K.from_coordinates(x.coordinates()) == x for x in K)
3338
+ True
3339
+ """
3340
+ letters = self.parent().classical_decomposition().letters
3341
+ l = list(self.value)
3342
+ return (l.count(letters(1)), l.count(letters(2)),
3343
+ 2*l.count(letters(3)) + l.count(letters(0)),
3344
+ 2*l.count(letters(-3)) + l.count(letters(0)),
3345
+ l.count(letters(-2)), l.count(letters(-1)))
3346
+
3347
+ @lazy_attribute
3348
+ def _A(self):
3349
+ r"""
3350
+ Compute the vector `A = (0, z_1, z_1 + z_2, z_1 + z_2 + 3 z_4,
3351
+ z_1 + z_2 + z_3 + 3 z_4, 2 z_1 + z_2 + z_3 + 3 z_4)`, where
3352
+ `z_1 = \bar{x}_1 - x_1`, `z_2 = \bar{x}_2 - \bar{x}_3`,
3353
+ `z_3 = x_3 - x_2`, and `z_4 = (\bar{x}_3 - x_3) / 2`.
3354
+
3355
+ EXAMPLES::
3356
+
3357
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1,1)
3358
+ sage: [mg._A for mg in K.module_generators]
3359
+ [(0, 0, 0, 0, 0, 0), (0, -1, -1, -1, -1, -2)]
3360
+ """
3361
+ coords = self.coordinates()
3362
+ z = [coords[-1] - coords[0], coords[-2] - coords[-3],
3363
+ coords[2] - coords[1], (coords[-3] - coords[2]) // 2]
3364
+ return (0, z[0], z[0] + z[1], z[0] + z[1] + 3*z[3],
3365
+ sum(z) + 2*z[3], sum(z) + z[0] + 2*z[3])
3366
+
3367
+ def e0(self):
3368
+ r"""
3369
+ Return the action of `e_0` on ``self``.
3370
+
3371
+ EXAMPLES::
3372
+
3373
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1,1)
3374
+ sage: [x.e0() for x in K]
3375
+ [[[-1]], [], [[-3]], [[-2]], None, None, None, None]
3376
+ """
3377
+ A = self._A
3378
+ c = list(self.coordinates())
3379
+ M = max(A)
3380
+ if A[5] == M:
3381
+ if c[0] + c[1] + (c[2] + c[3]) // 2 + c[4] + c[5] == self.parent()._s:
3382
+ return None
3383
+ c[5] += 1
3384
+ return self.parent().from_coordinates(c)
3385
+ if A[4] == M:
3386
+ c[0] -= 1
3387
+ c[2] += 1
3388
+ c[3] += 1
3389
+ return self.parent().from_coordinates(c)
3390
+ if A[3] == M:
3391
+ c[1] -= 1
3392
+ c[3] += 2
3393
+ return self.parent().from_coordinates(c)
3394
+ if A[2] == M:
3395
+ c[2] -= 2
3396
+ c[4] += 1
3397
+ return self.parent().from_coordinates(c)
3398
+ if A[1] == M:
3399
+ c[2] -= 1
3400
+ c[3] -= 1
3401
+ c[5] += 1
3402
+ return self.parent().from_coordinates(c)
3403
+ if A[0] == M:
3404
+ c[0] -= 1
3405
+ return self.parent().from_coordinates(c)
3406
+
3407
+ def f0(self):
3408
+ r"""
3409
+ Return the action of `f_0` on ``self``.
3410
+
3411
+ EXAMPLES::
3412
+
3413
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1,1)
3414
+ sage: [x.f0() for x in K]
3415
+ [[[1]], None, None, None, None, [[2]], [[3]], []]
3416
+ """
3417
+ A = self._A
3418
+ c = list(self.coordinates())
3419
+ M = max(A)
3420
+ if A[0] == M:
3421
+ if c[0] + c[1] + (c[2] + c[3]) // 2 + c[4] + c[5] == self.parent()._s:
3422
+ return None
3423
+ c[0] += 1
3424
+ return self.parent().from_coordinates(c)
3425
+ if A[1] == M:
3426
+ c[2] += 1
3427
+ c[3] += 1
3428
+ c[5] -= 1
3429
+ return self.parent().from_coordinates(c)
3430
+ if A[2] == M:
3431
+ c[2] += 2
3432
+ c[4] -= 1
3433
+ return self.parent().from_coordinates(c)
3434
+ if A[3] == M:
3435
+ c[1] += 1
3436
+ c[3] -= 2
3437
+ return self.parent().from_coordinates(c)
3438
+ if A[4] == M:
3439
+ c[0] += 1
3440
+ c[2] -= 1
3441
+ c[3] -= 1
3442
+ return self.parent().from_coordinates(c)
3443
+ if A[5] == M:
3444
+ c[5] -= 1
3445
+ return self.parent().from_coordinates(c)
3446
+
3447
+ def epsilon0(self):
3448
+ r"""
3449
+ Return `\varepsilon_0` of ``self``.
3450
+
3451
+ EXAMPLES::
3452
+
3453
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5)
3454
+ sage: [mg.epsilon0() for mg in K.module_generators]
3455
+ [5, 6, 7, 8, 9, 10]
3456
+ """
3457
+ c = self.coordinates()
3458
+ z = [c[-1] - c[0], c[-2] - c[-3], c[2] - c[1], (c[-3] - c[2]) // 2]
3459
+ s = c[0] + c[1] + (c[2] + c[3]) // 2 + c[4] + c[5]
3460
+ return self.parent()._s - s + max(self._A) - (2*z[0] + z[1] + z[2] + 3*z[3])
3461
+
3462
+ def phi0(self):
3463
+ r"""
3464
+ Return `\varphi_0` of ``self``.
3465
+
3466
+ EXAMPLES::
3467
+
3468
+ sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5)
3469
+ sage: [mg.phi0() for mg in K.module_generators]
3470
+ [5, 4, 3, 2, 1, 0]
3471
+ """
3472
+ c = self.coordinates()
3473
+ s = c[0] + c[1] + (c[2] + c[3]) // 2 + c[4] + c[5]
3474
+ return self.parent()._s - s + max(self._A)
3475
+
3476
+
3477
+ class CrystalOfTableaux_E7(CrystalOfTableaux):
3478
+ r"""
3479
+ The type `E_7` crystal `B(s\Lambda_7)`.
3480
+
3481
+ This is a helper class for the corresponding:class:`KR crystal
3482
+ <sage.combinat.crystals.kirillov_reshetikhin.KR_type_E7>` `B^{7,s}`.
3483
+ """
3484
+
3485
+ def module_generator(self, shape):
3486
+ r"""
3487
+ Return the module generator of ``self`` with shape ``shape``.
3488
+
3489
+ .. NOTE::
3490
+
3491
+ Only implemented for single rows (i.e., highest weight
3492
+ `s\Lambda_7`).
3493
+
3494
+ EXAMPLES::
3495
+
3496
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import CrystalOfTableaux_E7
3497
+ sage: T = CrystalOfTableaux_E7(CartanType(['E',7]), shapes=(Partition([5]),))
3498
+ sage: T.module_generator([5])
3499
+ [[(7,), (7,), (7,), (7,), (7,)]]
3500
+ """
3501
+ if len(shape) != 1:
3502
+ raise NotImplementedError("only implemented for single row shapes")
3503
+ return self(*[self.letters.highest_weight_vector()]*shape[0])
3504
+
3505
+
3506
+ class KR_type_E7(KirillovReshetikhinGenericCrystal):
3507
+ r"""
3508
+ The Kirillov-Reshetikhin crystal `B^{7,s}` of type `E_7^{(1)}`.
3509
+ """
3510
+
3511
+ def __init__(self, ct, r, s):
3512
+ r"""
3513
+ Initialize ``self``.
3514
+
3515
+ EXAMPLES::
3516
+
3517
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 1)
3518
+ sage: TestSuite(K).run()
3519
+
3520
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 2)
3521
+ sage: TestSuite(K).run() # long time
3522
+ """
3523
+ assert r == 7
3524
+ KirillovReshetikhinGenericCrystal.__init__(self, ct, 7, s)
3525
+
3526
+ def classical_decomposition(self):
3527
+ """
3528
+ Return the classical decomposition of ``self``.
3529
+
3530
+ EXAMPLES::
3531
+
3532
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 4)
3533
+ sage: K.classical_decomposition()
3534
+ The crystal of tableaux of type ['E', 7] and shape(s) [[4]]
3535
+ """
3536
+ return CrystalOfTableaux_E7(self.cartan_type().classical(),
3537
+ shapes=(Partition([self._s]),))
3538
+
3539
+ @cached_method
3540
+ def A7_decomposition(self):
3541
+ r"""
3542
+ Return the decomposition of ``self`` into `A_7` highest
3543
+ weight crystals.
3544
+
3545
+ The `A_7` decomposition of `B^{7,s}` is given by
3546
+ the parameters `m_4, m_5, m_6, m_7 \geq 0` such that
3547
+ `m_4 + m_5 \leq m_7` and `s = m_4 + m_5 + m_6 + m_7`. The
3548
+ corresponding `A_7` highest weight crystal has highest weight
3549
+ `\lambda = (m_7 - m_4 - m_5) \Lambda_6 + m_5 \Lambda_4
3550
+ + m_6 \Lambda_2`.
3551
+
3552
+ EXAMPLES::
3553
+
3554
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 3)
3555
+ sage: K.A7_decomposition()
3556
+ The crystal of tableaux of type ['A', 7] and shape(s)
3557
+ [[3, 3, 3, 3, 3, 3], [3, 3, 2, 2, 2, 2], [3, 3, 1, 1, 1, 1], [3, 3],
3558
+ [2, 2, 2, 2, 1, 1], [2, 2, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1]]
3559
+ """
3560
+ from sage.geometry.polyhedron.constructor import Polyhedron
3561
+ # variables are m_4, m_5, m_6, m_7
3562
+ P = Polyhedron(ieqs=[[0, 1, 0, 0, 0],
3563
+ [0, 0, 1, 0, 0],
3564
+ [0, 0, 0, 1, 0],
3565
+ [0, 0, 0, 0, 1],
3566
+ [0, -1, -1, 0, 1]],
3567
+ eqns=[[-self._s, 1, 1, 1, 1]])
3568
+ shapes = [Partition([6]*(p[3]-p[1]-p[0])+[4]*p[1]+[2]*p[2]).conjugate()
3569
+ for p in P.integral_points()]
3570
+ return CrystalOfTableaux(['A', 7], shapes=shapes)
3571
+
3572
+ @lazy_attribute
3573
+ def _highest_weight_to_A7_elements(self):
3574
+ """
3575
+ Return a dictionary that maps the A6 highest weight elements of
3576
+ ``self`` to their corresponding element in the `A_7` decomposition.
3577
+
3578
+ EXAMPLES::
3579
+
3580
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 2)
3581
+ sage: sorted(K._highest_weight_to_A7_elements.items(), key=str)
3582
+ [([[(-1, -2, 4), (-2, 1)]], [[1], [2], [3], [4]]),
3583
+ ([[(-1, 2), (-2, 1)]], []),
3584
+ ([[(-2, 1), (-2, 1)]], [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6]]),
3585
+ ([[(-2, 3), (-2, 1)]], [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 8]]),
3586
+ ([[(-2, 3), (-2, 3)]], [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [8, 8]]),
3587
+ ([[(-2, 3), (-2, 6)]], [[1, 1], [2, 2], [3], [4], [5], [8]]),
3588
+ ([[(-2, 6), (-2, 1)]], [[1, 1], [2, 2], [3], [4], [5], [6]]),
3589
+ ([[(-2, 6), (-2, 6)]], [[1, 1], [2, 2]]),
3590
+ ([[(-6, 5), (-2, 6)]], [[1], [2], [3], [8]]),
3591
+ ([[(7,), (-2, 1)]], [[1, 1], [2, 8], [3], [4], [5], [6]]),
3592
+ ([[(7,), (-2, 3)]], [[1, 1], [2, 8], [3], [4], [5], [8]]),
3593
+ ([[(7,), (-2, 6)]], [[1, 1], [2, 8]]),
3594
+ ([[(7,), (7,)]], [[1, 1], [8, 8]])]
3595
+ """
3596
+ d = {}
3597
+ A7 = self.A7_decomposition()
3598
+ for b in self:
3599
+ if not b.is_highest_weight([1, 3, 4, 5, 6, 7]):
3600
+ continue
3601
+ wt = [b.phi(i) for i in [7, 6, 5, 4, 3, 1]]
3602
+ la = Partition([6]*(wt[4]+wt[5])+[4]*(wt[2]+wt[3])+[2]*(wt[0]+wt[1])).conjugate()
3603
+ # mu = Partition(sum(([6-i]*m for i,m in enumerate(wt)), [])).conjugate()
3604
+ x = A7.module_generator(la)
3605
+ for i in range(wt[0]):
3606
+ x = x.f_string([2, 3, 4, 5, 6, 7])
3607
+ for i in range(wt[2]):
3608
+ x = x.f_string([4, 5, 6, 7])
3609
+ for i in range(wt[4]):
3610
+ x = x.f_string([6, 7])
3611
+ d[b] = x
3612
+ return d
3613
+
3614
+ @cached_method
3615
+ def to_A7_crystal(self):
3616
+ r"""
3617
+ Return the map decomposing the KR crystal `B^{7,s}` of
3618
+ type `E_7^{(1)}` into type `A_7` highest weight crystals.
3619
+
3620
+ EXAMPLES::
3621
+
3622
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 2)
3623
+ sage: K.to_A7_crystal()
3624
+ ['A', 6] relabelled by {1: 1, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7} -> ['A', 7] Virtual Crystal morphism:
3625
+ From: Kirillov-Reshetikhin crystal of type ['E', 7, 1] with (r,s)=(7,2)
3626
+ To: The crystal of tableaux of type ['A', 7] and shape(s)
3627
+ [[2, 2, 2, 2, 2, 2], [2, 2, 1, 1, 1, 1], [2, 2], [1, 1, 1, 1], []]
3628
+ Defn: ...
3629
+ """
3630
+ d = self._highest_weight_to_A7_elements
3631
+ return self.crystal_morphism(d, automorphism={1: 6, 3: 5, 4: 4,
3632
+ 5: 3, 6: 2, 7: 1},
3633
+ index_set=[1, 3, 4, 5, 6, 7],
3634
+ check=False)
3635
+
3636
+ @cached_method
3637
+ def from_A7_crystal(self):
3638
+ r"""
3639
+ Return the inclusion of the KR crystal `B^{7,s}` of
3640
+ type `E_7^{(1)}` into type `A_7` highest weight crystals.
3641
+
3642
+ EXAMPLES::
3643
+
3644
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 2)
3645
+ sage: K.from_A7_crystal()
3646
+ ['A', 6] -> ['E', 7, 1] Virtual Crystal morphism:
3647
+ From: The crystal of tableaux of type ['A', 7] and shape(s)
3648
+ [[2, 2, 2, 2, 2, 2], [2, 2, 1, 1, 1, 1], [2, 2], [1, 1, 1, 1], []]
3649
+ To: Kirillov-Reshetikhin crystal of type ['E', 7, 1] with (r,s)=(7,2)
3650
+ Defn: ...
3651
+ """
3652
+ A7 = self.A7_decomposition()
3653
+ d = self._highest_weight_to_A7_elements
3654
+ d_inv = {d[b]: b for b in d}
3655
+ return A7.crystal_morphism(d_inv, automorphism={6: 1, 5: 3, 4: 4,
3656
+ 3: 5, 2: 6, 1: 7},
3657
+ index_set=[1, 2, 3, 4, 5, 6],
3658
+ check=False)
3659
+
3660
+ class Element(KirillovReshetikhinGenericCrystalElement):
3661
+ def e0(self):
3662
+ r"""
3663
+ Return the action of `e_0` on ``self``.
3664
+
3665
+ EXAMPLES::
3666
+
3667
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 2)
3668
+ sage: mg = K.module_generator()
3669
+ sage: mg.e0()
3670
+ [[(7,), (-1, 7)]]
3671
+ sage: mg.e0().e0()
3672
+ [[(-1, 7), (-1, 7)]]
3673
+ sage: mg.e_string([0,0,0]) is None
3674
+ True
3675
+ """
3676
+ P = self.parent()
3677
+ x = P.to_A7_crystal()(self).e(7)
3678
+ if x is None:
3679
+ return None
3680
+ return P.from_A7_crystal()(x)
3681
+
3682
+ def f0(self):
3683
+ r"""
3684
+ Return the action of `f_0` on ``self``.
3685
+
3686
+ EXAMPLES::
3687
+
3688
+ sage: K = crystals.KirillovReshetikhin(['E',7,1], 7, 2)
3689
+ sage: mg = K.module_generator()
3690
+ sage: x = mg.f_string([7,6,5,4,3,2,4,5,6,1,3,4,5,2,4,3,1])
3691
+ sage: x.f0()
3692
+ [[(7,), (7,)]]
3693
+ sage: mg.f0() is None
3694
+ True
3695
+ """
3696
+ P = self.parent()
3697
+ x = P.to_A7_crystal()(self).f(7)
3698
+ if x is None:
3699
+ return None
3700
+ return P.from_A7_crystal()(x)
3701
+
3702
+ #####################################################################
3703
+
3704
+
3705
+ class PMDiagram(CombinatorialObject):
3706
+ r"""
3707
+ Class of `\pm` diagrams. These diagrams are in one-to-one bijection with
3708
+ `X_{n-1}` highest weight vectors in an `X_n` highest weight crystal
3709
+ `X=B,C,D`. See Section 4.1 of [Sch2008]_.
3710
+
3711
+ The input is a list `pm = [[a_0,b_0], [a_1,b_1], ...,
3712
+ [a_{n-1},b_{n-1}], [b_n]]` of pairs and a last 1-tuple (or list of
3713
+ length 1). The pair `[a_i,b_i]` specifies the number of `a_i` `+` and
3714
+ `b_i` `-` in the `i`-th row of the `\pm` diagram if `n-i` is odd and the
3715
+ number of `a_i` `\pm` pairs above row `i` and `b_i` columns of height `i`
3716
+ not containing any `+` or `-` if `n-i` is even.
3717
+
3718
+ Setting the option ``from_shapes = True`` one can also input a `\pm`
3719
+ diagram in terms of its outer, intermediate, and inner shape by
3720
+ specifying a list ``[n, s, outer, intermediate, inner]``
3721
+ where ``s`` is the width of the `\pm` diagram, and ``outer``,
3722
+ ``intermediate``, and ``inner`` are the outer, intermediate, and inner
3723
+ shapes, respectively.
3724
+
3725
+ EXAMPLES::
3726
+
3727
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3728
+ sage: pm = PMDiagram([[0,1],[1,2],[1]])
3729
+ sage: pm.pm_diagram
3730
+ [[0, 1], [1, 2], [1]]
3731
+ sage: pm._list
3732
+ [1, 1, 2, 0, 1]
3733
+ sage: pm.n
3734
+ 2
3735
+ sage: pm.width
3736
+ 5
3737
+ sage: pm.pp()
3738
+ . . . .
3739
+ . + - -
3740
+ sage: PMDiagram([2,5,[4,4],[4,2],[4,1]], from_shapes=True)
3741
+ [[0, 1], [1, 2], [1]]
3742
+
3743
+ TESTS::
3744
+
3745
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3746
+ sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])
3747
+ sage: PMDiagram([pm.n, pm.width, pm.outer_shape(), pm.intermediate_shape(), pm.inner_shape()], from_shapes=True) == pm
3748
+ True
3749
+ sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])
3750
+ sage: PMDiagram([pm.n, pm.width, pm.outer_shape(), pm.intermediate_shape(), pm.inner_shape()], from_shapes=True) == pm
3751
+ True
3752
+ """
3753
+
3754
+ def __init__(self, pm_diagram, from_shapes=None):
3755
+ r"""
3756
+ Initialize ``self``.
3757
+
3758
+ TESTS::
3759
+
3760
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3761
+ sage: pm = PMDiagram([[0,1],[1,2],[1]]); pm
3762
+ [[0, 1], [1, 2], [1]]
3763
+ sage: PMDiagram([2,5,[4,4],[4,2],[4,1]], from_shapes=True)
3764
+ [[0, 1], [1, 2], [1]]
3765
+ sage: TestSuite(pm).run()
3766
+ """
3767
+ if from_shapes:
3768
+ n = pm_diagram[0]
3769
+ s = pm_diagram[1]
3770
+ outer = [s] + list(pm_diagram[2]) + [0]*n
3771
+ intermediate = [s] + list(pm_diagram[3]) + [0]*n
3772
+ inner = [s] + list(pm_diagram[4]) + [0]*n
3773
+ pm = [[inner[n]]]
3774
+ for i in range((n+1)//2):
3775
+ pm.append([intermediate[n-2*i]-inner[n-2*i], inner[n-2*i-1]-intermediate[n-2*i]])
3776
+ pm.append([outer[n-2*i]-inner[n-2*i-1], inner[n-2*i-2]-outer[n-2*i]])
3777
+ if is_odd(n):
3778
+ pm.pop(n+1)
3779
+ pm_diagram = list(reversed(pm))
3780
+ self.pm_diagram = pm_diagram
3781
+ self.n = len(pm_diagram)-1
3782
+ self._list = [i for a in reversed(pm_diagram) for i in a]
3783
+ self.width = sum(self._list)
3784
+
3785
+ def _repr_(self) -> str:
3786
+ r"""
3787
+ Turning on pretty printing allows to display the `\pm` diagram as a
3788
+ tableau with the `+` and `-` displayed.
3789
+
3790
+ EXAMPLES::
3791
+
3792
+ sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]])
3793
+ [[1, 0], [0, 1], [2, 0], [0, 0], [0]]
3794
+ """
3795
+ return repr(self.pm_diagram)
3796
+
3797
+ def _repr_diagram(self) -> str:
3798
+ """
3799
+ Return a string representation of ``self`` as a diagram.
3800
+
3801
+ EXAMPLES::
3802
+
3803
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3804
+ sage: pm = PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]])
3805
+ sage: print(pm._repr_diagram())
3806
+ . . . +
3807
+ . . - -
3808
+ + +
3809
+ - -
3810
+ sage: pm = PMDiagram([[0,2], [0,0], [0]])
3811
+ sage: print(pm._repr_diagram())
3812
+ """
3813
+ ish = self.inner_shape() + [0] * self.n
3814
+ msh = self.intermediate_shape() + [0] * self.n
3815
+ osh = self.outer_shape() + [0] * self.n
3816
+ t = (['.'] * ish[i] + ['+'] * (msh[i]-ish[i]) + ['-'] * (osh[i]-msh[i])
3817
+ for i in range(self.n))
3818
+ t = [i for i in t if i]
3819
+ return Tableau(t)._repr_diagram() if t else ''
3820
+
3821
+ def pp(self):
3822
+ """
3823
+ Pretty print ``self``.
3824
+
3825
+ EXAMPLES::
3826
+
3827
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3828
+ sage: pm = PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]])
3829
+ sage: pm.pp()
3830
+ . . . +
3831
+ . . - -
3832
+ + +
3833
+ - -
3834
+ sage: pm = PMDiagram([[0,2], [0,0], [0]])
3835
+ sage: pm.pp()
3836
+ """
3837
+ print(self._repr_diagram())
3838
+
3839
+ def inner_shape(self):
3840
+ """
3841
+ Return the inner shape of the pm diagram.
3842
+
3843
+ EXAMPLES::
3844
+
3845
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3846
+ sage: pm = PMDiagram([[0,1],[1,2],[1]])
3847
+ sage: pm.inner_shape()
3848
+ [4, 1]
3849
+ sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])
3850
+ sage: pm.inner_shape()
3851
+ [7, 5, 3, 1]
3852
+ sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])
3853
+ sage: pm.inner_shape()
3854
+ [10, 7, 5, 3, 1]
3855
+ """
3856
+ ll = self._list
3857
+ t = [sum(ll[0:2*i+1]) for i in range(self.n)]
3858
+ return Partition(list(reversed(t)))
3859
+
3860
+ def outer_shape(self):
3861
+ r"""
3862
+ Return the outer shape of the `\pm` diagram.
3863
+
3864
+ EXAMPLES::
3865
+
3866
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3867
+ sage: pm = PMDiagram([[0,1],[1,2],[1]])
3868
+ sage: pm.outer_shape()
3869
+ [4, 4]
3870
+ sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])
3871
+ sage: pm.outer_shape()
3872
+ [8, 8, 4, 4]
3873
+ sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])
3874
+ sage: pm.outer_shape()
3875
+ [13, 8, 8, 4, 4]
3876
+ """
3877
+ t = []
3878
+ ll = self._list
3879
+ for i in range(self.n // 2):
3880
+ t.append(sum(ll[0:4*i+4]))
3881
+ t.append(sum(ll[0:4*i+4]))
3882
+ if is_even(self.n+1):
3883
+ t.append(sum(ll[0:2*self.n+2]))
3884
+ return Partition(list(reversed(t)))
3885
+
3886
+ def intermediate_shape(self):
3887
+ """
3888
+ Return the intermediate shape of the pm diagram (inner shape plus
3889
+ positions of plusses).
3890
+
3891
+ EXAMPLES::
3892
+
3893
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3894
+ sage: pm = PMDiagram([[0,1],[1,2],[1]])
3895
+ sage: pm.intermediate_shape()
3896
+ [4, 2]
3897
+ sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])
3898
+ sage: pm.intermediate_shape()
3899
+ [8, 6, 4, 2]
3900
+ sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])
3901
+ sage: pm.intermediate_shape()
3902
+ [11, 8, 6, 4, 2]
3903
+ sage: pm = PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]])
3904
+ sage: pm.intermediate_shape()
3905
+ [4, 2, 2]
3906
+ sage: pm = PMDiagram([[1, 0], [0, 0], [0, 0], [0, 0], [0]])
3907
+ sage: pm.intermediate_shape()
3908
+ [1]
3909
+ """
3910
+ p = self.inner_shape()
3911
+ p = p + [0 for _ in range(self.n)]
3912
+ ll = list(reversed(self._list))
3913
+ p = [p[i] + ll[2*i+1] for i in range(self.n)]
3914
+ return Partition(p)
3915
+
3916
+ def heights_of_minus(self) -> list:
3917
+ r"""
3918
+ Return a list with the heights of all minus in the `\pm` diagram.
3919
+
3920
+ EXAMPLES::
3921
+
3922
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3923
+ sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])
3924
+ sage: pm.heights_of_minus()
3925
+ [5, 5, 3, 3, 1, 1]
3926
+ sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])
3927
+ sage: pm.heights_of_minus()
3928
+ [4, 4, 2, 2]
3929
+ """
3930
+ n = self.n
3931
+ heights = []
3932
+ for i in range((n + 1) // 2):
3933
+ heights += [n-2*i]*((self.outer_shape()+[0]*n)[n-2*i-1]-(self.intermediate_shape()+[0]*n)[n-2*i-1])
3934
+ return heights
3935
+
3936
+ def heights_of_addable_plus(self) -> list:
3937
+ r"""
3938
+ Return a list with the heights of all addable plus in the `\pm` diagram.
3939
+
3940
+ EXAMPLES::
3941
+
3942
+ sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram
3943
+ sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])
3944
+ sage: pm.heights_of_addable_plus()
3945
+ [1, 1, 2, 3, 4, 5]
3946
+ sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])
3947
+ sage: pm.heights_of_addable_plus()
3948
+ [1, 2, 3, 4]
3949
+ """
3950
+ heights = []
3951
+ for i in range(1, self.n+1):
3952
+ heights += [i]*self.sigma().pm_diagram[i][0]
3953
+ return heights
3954
+
3955
+ def sigma(self):
3956
+ """
3957
+ Return sigma on pm diagrams as needed for the analogue of the Dynkin diagram automorphism
3958
+ that interchanges nodes `0` and `1` for type `D_n(1)`, `B_n(1)`, `A_{2n-1}(2)` for
3959
+ Kirillov-Reshetikhin crystals.
3960
+
3961
+ EXAMPLES::
3962
+
3963
+ sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])
3964
+ sage: pm.sigma()
3965
+ [[1, 0], [2, 1], [1]]
3966
+ """
3967
+ pm = self.pm_diagram
3968
+ return PMDiagram([list(reversed(a)) for a in pm])
3969
+
3970
+
3971
+ #######################################################################
3972
+
3973
+ def vertical_dominoes_removed(r, s):
3974
+ """
3975
+ Return all partitions obtained from a rectangle of width s and height r by removing
3976
+ vertical dominoes.
3977
+
3978
+ EXAMPLES::
3979
+
3980
+ sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(2,2)
3981
+ [[], [1, 1], [2, 2]]
3982
+ sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(3,2)
3983
+ [[2], [2, 1, 1], [2, 2, 2]]
3984
+ sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(4,2)
3985
+ [[], [1, 1], [1, 1, 1, 1], [2, 2], [2, 2, 1, 1], [2, 2, 2, 2]]
3986
+ """
3987
+ return [x.conjugate() for x in horizontal_dominoes_removed(s, r)]
3988
+
3989
+
3990
+ def horizontal_dominoes_removed(r, s):
3991
+ """
3992
+ Return all partitions obtained from a rectangle of width s and height r by removing
3993
+ horizontal dominoes.
3994
+
3995
+ EXAMPLES::
3996
+
3997
+ sage: sage.combinat.crystals.kirillov_reshetikhin.horizontal_dominoes_removed(2,2)
3998
+ [[], [2], [2, 2]]
3999
+ sage: sage.combinat.crystals.kirillov_reshetikhin.horizontal_dominoes_removed(3,2)
4000
+ [[], [2], [2, 2], [2, 2, 2]]
4001
+ """
4002
+ ulist = [list(x) + [0]*(r-x.length()) for x in partitions_in_box(r, s//2)]
4003
+ two = lambda x: 2 * (x - s // 2) + s
4004
+ return [Partition([two(y) for y in x]) for x in ulist]
4005
+
4006
+ #####################################################################
4007
+ # Morphisms
4008
+
4009
+
4010
+ class AmbientRetractMap(Map):
4011
+ r"""
4012
+ The retraction map from the ambient crystal.
4013
+
4014
+ Consider a crystal embedding `\phi : X \to Y`, then the elements `X`
4015
+ can be considered as a subcrystal of the ambient crystal `Y`. The
4016
+ ambient retract is the partial map `\tilde{\phi} : Y \to X` such that
4017
+ `\tilde{\phi} \circ \phi` is the identity on `X`.
4018
+ """
4019
+
4020
+ def __init__(self, base, ambient, pdict_inv, index_set,
4021
+ similarity_factor_domain=None, automorphism=None):
4022
+ """
4023
+ Initialize ``self``.
4024
+
4025
+ EXAMPLES::
4026
+
4027
+ sage: K = crystals.KirillovReshetikhin(['B',3,1], 3,1)
4028
+ sage: phi = K.from_ambient_crystal()
4029
+ sage: TestSuite(phi).run(skip=['_test_category', '_test_pickling'])
4030
+ """
4031
+ from sage.categories.sets_with_partial_maps import SetsWithPartialMaps
4032
+ Map.__init__(self, Hom(ambient, base, SetsWithPartialMaps()))
4033
+
4034
+ if similarity_factor_domain is None:
4035
+ similarity_factor_domain = {i: 1 for i in index_set}
4036
+ if automorphism is None:
4037
+ automorphism = lambda i: i
4038
+
4039
+ self._pdict_inv = pdict_inv
4040
+ self._automorphism = automorphism
4041
+ self._similarity_factor_domain = similarity_factor_domain
4042
+ self._index_set = index_set
4043
+
4044
+ def _repr_type(self):
4045
+ """
4046
+ Return a string describing ``self``.
4047
+
4048
+ EXAMPLES::
4049
+
4050
+ sage: K = crystals.KirillovReshetikhin(['B',3,1], 3,1)
4051
+ sage: phi = K.from_ambient_crystal()
4052
+ sage: phi._repr_type()
4053
+ 'Ambient retract'
4054
+ """
4055
+ return "Ambient retract"
4056
+
4057
+ def _call_(self, x):
4058
+ """
4059
+ A fast map from the virtual image to the base crystal.
4060
+
4061
+ EXAMPLES::
4062
+
4063
+ sage: K = crystals.KirillovReshetikhin(['B',3,1], 3,1)
4064
+ sage: phi = K.from_ambient_crystal()
4065
+ sage: b = K.ambient_crystal()(rows=[[1],[2],[-3]])
4066
+ sage: phi(b)
4067
+ [++-, []]
4068
+ """
4069
+ automorphism = self._automorphism
4070
+ sfd = self._similarity_factor_domain
4071
+ for i in self._index_set:
4072
+ c = x.e_string([i for k in range(sfd[i])])
4073
+ if c is not None:
4074
+ d = self(c).f(automorphism(i))
4075
+ assert d is not None
4076
+ # now we know that x is hw
4077
+ return d
4078
+ return self._pdict_inv[x]
4079
+
4080
+
4081
+ class CrystalDiagramAutomorphism(CrystalMorphism):
4082
+ """
4083
+ The crystal automorphism induced from the diagram automorphism.
4084
+
4085
+ For example, in type `A_n^{(1)}` this is the promotion operator and in
4086
+ type `D_n^{(1)}`, this corresponds to the automorphism induced from
4087
+ interchanging the `0` and `1` nodes in the Dynkin diagram.
4088
+
4089
+ INPUT:
4090
+
4091
+ - ``C`` -- a crystal
4092
+ - ``on_hw`` -- a function for the images of the ``index_set``-highest
4093
+ weight elements
4094
+ - ``index_set`` -- (default: the empty set) the index set
4095
+ - ``automorphism`` -- (default: the identity) the twisting automorphism
4096
+ - ``cache`` -- boolean (default: ``True``); cache the result
4097
+ """
4098
+
4099
+ def __init__(self, C, on_hw, index_set=None, automorphism=None, cache=True):
4100
+ """
4101
+ Construct the promotion operator.
4102
+
4103
+ TESTS::
4104
+
4105
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
4106
+ sage: p = K.promotion()
4107
+ sage: TestSuite(p).run(skip=['_test_category', '_test_pickling'])
4108
+ """
4109
+ if automorphism is None:
4110
+ automorphism = lambda i: i
4111
+ if index_set is None:
4112
+ index_set = ()
4113
+ self._twist = automorphism
4114
+ if isinstance(on_hw, dict):
4115
+ self._on_hw = on_hw.__getitem__
4116
+ else:
4117
+ self._on_hw = on_hw
4118
+ parent = Hom(C, C)
4119
+
4120
+ self._cache = {}
4121
+ self._cache_result = bool(cache)
4122
+ if isinstance(cache, dict):
4123
+ self._cache = cache
4124
+ self._index_set = tuple(index_set)
4125
+ CrystalMorphism.__init__(self, parent, C.cartan_type())
4126
+
4127
+ def _call_(self, x):
4128
+ """
4129
+ Return the image of ``x`` under ``self``.
4130
+
4131
+ EXAMPLES::
4132
+
4133
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
4134
+ sage: p = K.promotion()
4135
+ sage: elt = K(3,1,3,1)
4136
+ sage: p(elt.lift())
4137
+ [[2, 2], [4, 4]]
4138
+ """
4139
+ # We do our own caching so we can take advantage of known images above us
4140
+ if x in self._cache:
4141
+ return self._cache[x]
4142
+
4143
+ ind = self._index_set
4144
+ cur = x
4145
+ path = []
4146
+ while cur not in self._cache:
4147
+ n = None
4148
+ for i in ind:
4149
+ n = cur.e(i)
4150
+ if n is not None:
4151
+ path.append(self._twist(i))
4152
+ cur = n
4153
+ break
4154
+
4155
+ if n is None: # We're at a I-highest weight element
4156
+ break
4157
+
4158
+ if cur in self._cache:
4159
+ cur = self._cache[cur]
4160
+ else:
4161
+ cur = self._on_hw(cur)
4162
+
4163
+ y = cur.f_string(reversed(path))
4164
+ assert y is not None
4165
+ self._cache[x] = y
4166
+ return y
4167
+
4168
+ def _repr_type(self) -> str:
4169
+ """
4170
+ Return a string describing ``self``.
4171
+
4172
+ EXAMPLES::
4173
+
4174
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
4175
+ sage: K.promotion()._repr_type()
4176
+ 'Diagram automorphism'
4177
+ """
4178
+ return "Diagram automorphism"
4179
+
4180
+ def is_isomorphism(self) -> bool:
4181
+ """
4182
+ Return ``True`` as ``self`` is a crystal isomorphism.
4183
+
4184
+ EXAMPLES::
4185
+
4186
+ sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2)
4187
+ sage: K.promotion().is_isomorphism()
4188
+ True
4189
+ """
4190
+ return True
4191
+
4192
+ # All of these are consequences of being an isomorphism
4193
+ is_surjective = is_isomorphism
4194
+ is_embedding = is_isomorphism
4195
+ is_strict = is_isomorphism
4196
+ __bool__ = is_isomorphism