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,1918 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.graphs sage.modules
3
+ r"""
4
+ Rigged configurations
5
+
6
+ AUTHORS:
7
+
8
+ - Travis Scrimshaw (2010-09-26): initial version
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2010-2012 Travis Scrimshaw <tscrim@ucdavis.edu>
13
+ #
14
+ # Distributed under the terms of the GNU General Public License (GPL)
15
+ #
16
+ # This code is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ # General Public License for more details.
20
+ #
21
+ # The full text of the GPL is available at:
22
+ #
23
+ # https://www.gnu.org/licenses/
24
+ # ****************************************************************************
25
+
26
+ import itertools
27
+
28
+ from sage.misc.cachefunc import cached_method
29
+ from sage.misc.lazy_attribute import lazy_attribute
30
+ from sage.structure.global_options import GlobalOptions
31
+ from sage.structure.unique_representation import UniqueRepresentation
32
+ from sage.structure.parent import Parent
33
+ from sage.combinat.misc import IterableFunctionCall
34
+ import sage.combinat.tableau as tableau
35
+ from sage.rings.rational_field import QQ
36
+ from sage.categories.loop_crystals import KirillovReshetikhinCrystals
37
+ from sage.combinat.root_system.cartan_type import CartanType
38
+ from sage.combinat.rigged_configurations.kleber_tree import KleberTree, VirtualKleberTree
39
+ from sage.combinat.rigged_configurations.rigged_configuration_element import (
40
+ RiggedConfigurationElement, KRRCSimplyLacedElement, KRRCNonSimplyLacedElement,
41
+ KRRCTypeA2DualElement)
42
+ from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition
43
+
44
+
45
+ # Used in the KR crystals catalog so that there is a common interface
46
+ def KirillovReshetikhinCrystal(cartan_type, r, s):
47
+ r"""
48
+ Return the KR crystal `B^{r,s}` using
49
+ :class:`rigged configurations <RiggedConfigurations>`.
50
+
51
+ This is the rigged configuration `RC(B^{r,s})` or `RC(L)` with
52
+ `L = (L_i^{(a)})` and `L_i^{(a)} = \delta_{a,r} \delta_{i,s}`.
53
+
54
+ EXAMPLES::
55
+
56
+ sage: K1 = crystals.kirillov_reshetikhin.RiggedConfigurations(['A',6,2], 2, 1)
57
+ sage: K2 = crystals.kirillov_reshetikhin.LSPaths(['A',6,2], 2, 1)
58
+ sage: K1.digraph().is_isomorphic(K2.digraph(), edge_labels=True)
59
+ True
60
+
61
+ TESTS:
62
+
63
+ We explicitly import and check we get the same crystal::
64
+
65
+ sage: from sage.combinat.rigged_configurations.rigged_configurations import KirillovReshetikhinCrystal
66
+ sage: K1 = crystals.kirillov_reshetikhin.RiggedConfigurations(['A',6,2], 2, 1)
67
+ sage: K1 is KirillovReshetikhinCrystal(['A',6,2], 2, 1)
68
+ True
69
+ """
70
+ return RiggedConfigurations(cartan_type, [[r, s]])
71
+
72
+
73
+ # Note on implementation, this class is used for simply-laced types only
74
+ class RiggedConfigurations(UniqueRepresentation, Parent):
75
+ r"""
76
+ Rigged configurations as `U_q^{\prime}(\mathfrak{g})`-crystals.
77
+
78
+ Let `\overline{I}` denote the classical index set associated to the Cartan
79
+ type of the rigged configurations. A rigged configuration of multiplicity
80
+ array `L_i^{(a)}` and dominant weight `\Lambda` is a sequence of partitions
81
+ `\{ \nu^{(a)} \mid a \in \overline{I} \}` such that
82
+
83
+ .. MATH::
84
+
85
+ \sum_{\overline{I} \times \ZZ_{>0}} i m_i^{(a)} \alpha_a
86
+ = \sum_{\overline{I} \times \ZZ_{>0}} i L_i^{(a)} \Lambda_a
87
+ - \Lambda
88
+
89
+ where `\alpha_a` is a simple root, `\Lambda_a` is a fundamental weight,
90
+ and `m_i^{(a)}` is the number of rows of length `i` in the partition
91
+ `\nu^{(a)}`.
92
+
93
+ Each partition `\nu^{(a)}`, in the sequence also comes with a sequence of
94
+ statistics `p_i^{(a)}` called *vacancy numbers* and a weakly decreasing
95
+ sequence `J_i^{(a)}` of length `m_i^{(a)}` called *riggings*.
96
+ Vacancy numbers are computed based upon the partitions and `L_i^{(a)}`,
97
+ and the riggings must satisfy `\max J_i^{(a)} \leq p_i^{(a)}`. We call
98
+ such a partition a *rigged partition*. For more, see
99
+ [RigConBijection]_ [CrysStructSchilling06]_ [BijectionLRT]_.
100
+
101
+ Rigged configurations form combinatorial objects first introduced by
102
+ Kerov, Kirillov and Reshetikhin that arose from studies of statistical
103
+ mechanical models using the Bethe Ansatz. They are sequences of rigged
104
+ partitions. A rigged partition is a partition together with a label
105
+ associated to each part that satisfy certain constraints. The labels
106
+ are also called riggings.
107
+
108
+ Rigged configurations exist for all affine Kac-Moody Lie algebras. See
109
+ for example [HKOTT2002]_. In Sage they are specified by providing a Cartan
110
+ type and a list of rectangular shapes `B`. The list of all (highest
111
+ weight) rigged configurations for given `B` is computed via the (virtual)
112
+ Kleber algorithm (see also
113
+ :class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree` and
114
+ :class:`~sage.combinat.rigged_configurations.kleber_tree.VirtualKleberTree`).
115
+
116
+ Rigged configurations in simply-laced types all admit a classical crystal
117
+ structure [CrysStructSchilling06]_. For non-simply-laced types, the
118
+ crystal is given by using virtual rigged configurations [OSS03]_. The
119
+ highest weight rigged configurations are those where all riggings are
120
+ nonnegative. The list of all rigged configurations is computed from the
121
+ highest weight ones using the crystal operators.
122
+
123
+ Rigged configurations are conjecturally in bijection with
124
+ :class:`~sage.combinat.rigged_configurations.tensor_product_kr_tableaux.TensorProductOfKirillovReshetikhinTableaux`
125
+ of non-exceptional affine types where the list `B` corresponds to the
126
+ tensor factors `B^{r,s}`. The bijection has been proven in types `A_n^{(1)}`
127
+ and `D_n^{(1)}` and when the only nonzero entries of `L_i^{(a)}` are either
128
+ only `L_1^{(a)}` or only `L_i^{(1)}` (corresponding to single columns or
129
+ rows respectively) [RigConBijection]_, [BijectionLRT]_, [BijectionDn]_.
130
+
131
+ KR crystals are implemented in Sage, see
132
+ :func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`,
133
+ however, in the bijection with rigged configurations a different
134
+ realization of the elements in the crystal are obtained, which are
135
+ coined KR tableaux, see
136
+ :class:`~sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableaux`.
137
+ For more details see [OSS2011]_.
138
+
139
+ .. NOTE::
140
+
141
+ All non-simply-laced rigged configurations have not been proven to
142
+ give rise to aligned virtual crystals (i.e. have the correct crystal
143
+ structure or isomorphic as affine crystals to the tensor product of
144
+ KR tableaux).
145
+
146
+ INPUT:
147
+
148
+ - ``cartan_type`` -- a Cartan type
149
+
150
+ - ``B`` -- list of positive integer tuples `(r,s)` corresponding to the
151
+ tensor factors in the bijection with tensor product of
152
+ Kirillov-Reshetikhin tableaux or equivalently the sequence of width `s`
153
+ and height `r` rectangles
154
+
155
+ REFERENCES:
156
+
157
+ .. [HKOTT2002] \G. Hatayama, A. Kuniba, M. Okado, T. Takagi, Z. Tsuboi.
158
+ Paths, Crystals and Fermionic Formulae.
159
+ Prog. Math. Phys. **23** (2002) Pages 205-272.
160
+
161
+ .. [CrysStructSchilling06] Anne Schilling.
162
+ Crystal structure on rigged configurations.
163
+ International Mathematics Research Notices.
164
+ Volume 2006. (2006) Article ID 97376. Pages 1-27.
165
+
166
+ .. [RigConBijection] Masato Okado, Anne Schilling, Mark Shimozono.
167
+ A crystal to rigged configuration bijection for non-exceptional affine
168
+ algebras.
169
+ Algebraic Combinatorics and Quantum Groups.
170
+ Edited by N. Jing. World Scientific. (2003) Pages 85-124.
171
+
172
+ .. [BijectionDn] Anne Schilling.
173
+ A bijection between type `D_n^{(1)}` crystals and rigged configurations.
174
+ J. Algebra. **285** (2005) 292-334
175
+
176
+ .. [BijectionLRT] Anatol N. Kirillov, Anne Schilling, Mark Shimozono.
177
+ A bijection between Littlewood-Richardson tableaux and rigged
178
+ configurations.
179
+ Selecta Mathematica (N.S.). **8** (2002) Pages 67-135.
180
+ (:mathscinet:`MR1890195`).
181
+
182
+ EXAMPLES::
183
+
184
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2], [1, 1]])
185
+ sage: RC
186
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((3, 2), (1, 2), (1, 1))
187
+
188
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1]]); RC
189
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 1),)
190
+ sage: RC.cardinality()
191
+ 6
192
+ sage: len(RC.list()) == RC.cardinality()
193
+ True
194
+ sage: RC.list() # random
195
+ [
196
+ <BLANKLINE>
197
+ 0[ ]0
198
+ (/) (/) (/) -1[ ]-1 -1[ ]-1
199
+ -1[ ]-1
200
+ (/) -1[ ]-1 0[ ]0 0[ ]0 1[ ]1 -1[ ]-1
201
+ <BLANKLINE>
202
+ (/) (/) -1[ ]-1 (/) -1[ ]-1 0[ ]0
203
+ , , , , ,
204
+ ]
205
+
206
+ A rigged configuration element with all riggings equal to the vacancy
207
+ numbers can be created as follows::
208
+
209
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]]); RC
210
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((3, 2), (2, 1), (1, 1), (1, 1))
211
+ sage: elt = RC(partition_list=[[1],[],[]]); elt
212
+ <BLANKLINE>
213
+ 0[ ]0
214
+ <BLANKLINE>
215
+ (/)
216
+ <BLANKLINE>
217
+ (/)
218
+ <BLANKLINE>
219
+
220
+ If on the other hand we also want to specify the riggings, this can be
221
+ achieved as follows::
222
+
223
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2], [1, 1]])
224
+ sage: RC(partition_list=[[2],[2],[2]])
225
+ <BLANKLINE>
226
+ 1[ ][ ]1
227
+ <BLANKLINE>
228
+ 0[ ][ ]0
229
+ <BLANKLINE>
230
+ 0[ ][ ]0
231
+ sage: RC(partition_list=[[2],[2],[2]], rigging_list=[[0],[0],[0]])
232
+ <BLANKLINE>
233
+ 1[ ][ ]0
234
+ <BLANKLINE>
235
+ 0[ ][ ]0
236
+ <BLANKLINE>
237
+ 0[ ][ ]0
238
+
239
+ A larger example::
240
+
241
+ sage: RC = RiggedConfigurations(['D', 7, 1], [[3,3],[5,2],[4,3],[2,3],[4,4],[3,1],[1,4],[2,2]])
242
+ sage: elt = RC(partition_list=[[2],[3,2,1],[2,2,1,1],[2,2,1,1,1,1],[3,2,1,1,1,1],[2,1,1],[2,2]],
243
+ ....: rigging_list=[[2],[1,0,0],[4,1,2,1],[1,0,0,0,0,0],[0,1,0,0,0,0],[0,0,0],[0,0]])
244
+ sage: elt
245
+ <BLANKLINE>
246
+ 3[ ][ ]2
247
+ <BLANKLINE>
248
+ 1[ ][ ][ ]1
249
+ 2[ ][ ]0
250
+ 1[ ]0
251
+ <BLANKLINE>
252
+ 4[ ][ ]4
253
+ 4[ ][ ]1
254
+ 3[ ]2
255
+ 3[ ]1
256
+ <BLANKLINE>
257
+ 2[ ][ ]1
258
+ 2[ ][ ]0
259
+ 0[ ]0
260
+ 0[ ]0
261
+ 0[ ]0
262
+ 0[ ]0
263
+ <BLANKLINE>
264
+ 0[ ][ ][ ]0
265
+ 2[ ][ ]1
266
+ 0[ ]0
267
+ 0[ ]0
268
+ 0[ ]0
269
+ 0[ ]0
270
+ <BLANKLINE>
271
+ 0[ ][ ]0
272
+ 0[ ]0
273
+ 0[ ]0
274
+ <BLANKLINE>
275
+ 0[ ][ ]0
276
+ 0[ ][ ]0
277
+ <BLANKLINE>
278
+
279
+ To obtain the KR tableau under the bijection between rigged configurations
280
+ and KR tableaux, we can type the following. This example was checked
281
+ against Reiho Sakamoto's Mathematica program on rigged configurations::
282
+
283
+ sage: output = elt.to_tensor_product_of_kirillov_reshetikhin_tableaux(); output
284
+ [[1, 1, 1], [2, 3, 3], [3, 4, -5]] (X) [[1, 1], [2, 2], [3, 3], [5, -6], [6, -5]] (X)
285
+ [[1, 1, 2], [2, 2, 3], [3, 3, 7], [4, 4, -7]] (X) [[1, 1, 1], [2, 2, 2]] (X)
286
+ [[1, 1, 1, 3], [2, 2, 3, 4], [3, 3, 4, 5], [4, 4, 5, 6]] (X) [[1], [2], [3]] (X) [[1, 1, 1, 1]] (X) [[1, 1], [2, 2]]
287
+ sage: elt.to_tensor_product_of_kirillov_reshetikhin_tableaux().to_rigged_configuration() == elt
288
+ True
289
+ sage: output.to_rigged_configuration().to_tensor_product_of_kirillov_reshetikhin_tableaux() == output
290
+ True
291
+
292
+ We can also convert between rigged configurations and tensor products of
293
+ KR crystals::
294
+
295
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 1]])
296
+ sage: elt = RC(partition_list=[[1],[1,1],[1],[1]])
297
+ sage: tp_krc = elt.to_tensor_product_of_kirillov_reshetikhin_crystals(); tp_krc
298
+ [[]]
299
+ sage: ret = RC(tp_krc)
300
+ sage: ret == elt
301
+ True
302
+
303
+ ::
304
+
305
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[4,1], [3,3]])
306
+ sage: KR1 = crystals.KirillovReshetikhin(['D', 4, 1], 4, 1)
307
+ sage: KR2 = crystals.KirillovReshetikhin(['D', 4, 1], 3, 3)
308
+ sage: T = crystals.TensorProduct(KR1, KR2)
309
+ sage: t = T[1]; t
310
+ [[++++, []], [+++-, [[1], [2], [4], [-4]]]]
311
+ sage: ret = RC(t)
312
+ sage: ret.to_tensor_product_of_kirillov_reshetikhin_crystals()
313
+ [[++++, []], [+++-, [[1], [2], [4], [-4]]]]
314
+
315
+ TESTS::
316
+
317
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]])
318
+ sage: len(RC.module_generators)
319
+ 17
320
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[1, 1]])
321
+ sage: RC.cardinality()
322
+ 8
323
+
324
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2, 1]])
325
+ sage: c = RC.cardinality(); c
326
+ 29
327
+ sage: K = crystals.KirillovReshetikhin(['D',4,1],2,1)
328
+ sage: K.cardinality() == c
329
+ True
330
+ """
331
+ @staticmethod
332
+ def __classcall_private__(cls, cartan_type, B):
333
+ r"""
334
+ Normalize the input arguments to ensure unique representation.
335
+
336
+ EXAMPLES::
337
+
338
+ sage: RC1 = RiggedConfigurations(CartanType(['A',3,1]), [[2,2]])
339
+ sage: RC2 = RiggedConfigurations(['A',3,1], [(2,2)])
340
+ sage: RC3 = RiggedConfigurations(['A',3,1], ((2,2),))
341
+ sage: RC2 is RC1, RC3 is RC1
342
+ (True, True)
343
+ """
344
+ cartan_type = CartanType(cartan_type)
345
+ if not cartan_type.is_affine():
346
+ raise ValueError("The Cartan type must be affine")
347
+
348
+ # Standardize B input into a tuple of tuples
349
+ B = tuple(tuple(factor) for factor in B)
350
+ if not B:
351
+ raise ValueError("must contain at least one factor")
352
+
353
+ if cartan_type.type() == 'BC': # Type `A_{2n}^{(2)}`
354
+ return RCTypeA2Even(cartan_type, B)
355
+ if cartan_type.dual().type() == 'BC': # Type 'A_{2n}^{(2)\dagger`
356
+ return RCTypeA2Dual(cartan_type, B)
357
+ # We check the classical type to account for A^{(1)}_1 which is not
358
+ # a virtual rigged configuration.
359
+ if not cartan_type.classical().is_simply_laced():
360
+ return RCNonSimplyLaced(cartan_type, B)
361
+
362
+ return super().__classcall__(cls, cartan_type, B)
363
+
364
+ def __init__(self, cartan_type, B):
365
+ r"""
366
+ Initialize the RiggedConfigurations class.
367
+
368
+ EXAMPLES::
369
+
370
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3,1], [1,2]])
371
+ sage: TestSuite(RC).run() # long time
372
+ sage: RC = RiggedConfigurations(['A',1,1], [[1,1], [1,1]])
373
+ sage: TestSuite(RC).run()
374
+ sage: RC = RiggedConfigurations(['A',2,1], [[1,1], [2,1]])
375
+ sage: TestSuite(RC).run()
376
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2,1], [1,1]])
377
+ sage: TestSuite(RC).run() # long time
378
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[3,1]])
379
+ sage: TestSuite(RC).run() # long time
380
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[4,2]])
381
+ sage: TestSuite(RC).run() # long time
382
+ """
383
+ self._cartan_type = cartan_type
384
+ self.dims = B
385
+ cl = cartan_type.classical()
386
+ self._rc_index = cl.index_set()
387
+ self._rc_index_inverse = {i: ii for ii,i in enumerate(self._rc_index)}
388
+ # We store the Cartan matrix for the vacancy number calculations for speed
389
+ self._cartan_matrix = cl.cartan_matrix()
390
+ Parent.__init__(self, category=KirillovReshetikhinCrystals().TensorProducts())
391
+
392
+ # add options to class
393
+ class options(GlobalOptions):
394
+ r"""
395
+ Set and display the options for rigged configurations.
396
+ If no parameters are set, then the function returns a copy of
397
+ the options dictionary.
398
+
399
+ The ``options`` to partitions can be accessed as the method
400
+ :obj:`RiggedConfigurations.options` of
401
+ :class:`RiggedConfigurations`.
402
+
403
+ @OPTIONS@
404
+
405
+ EXAMPLES::
406
+
407
+ sage: RC = RiggedConfigurations(['A',3,1], [[2,2],[1,1],[1,1]])
408
+ sage: elt = RC(partition_list=[[3,1], [3], [1]])
409
+ sage: elt
410
+ <BLANKLINE>
411
+ -3[ ][ ][ ]-3
412
+ -1[ ]-1
413
+ <BLANKLINE>
414
+ 1[ ][ ][ ]1
415
+ <BLANKLINE>
416
+ -1[ ]-1
417
+ <BLANKLINE>
418
+ sage: RiggedConfigurations.options(display='horizontal', convention='french')
419
+ sage: elt
420
+ -1[ ]-1 1[ ][ ][ ]1 -1[ ]-1
421
+ -3[ ][ ][ ]-3
422
+
423
+ Changing the ``convention`` for rigged configurations also changes the
424
+ ``convention`` option for tableaux and vice versa::
425
+
426
+ sage: T = Tableau([[1,2,3],[4,5]])
427
+ sage: T.pp()
428
+ 4 5
429
+ 1 2 3
430
+ sage: Tableaux.options.convention="english"
431
+ sage: elt
432
+ -3[ ][ ][ ]-3 1[ ][ ][ ]1 -1[ ]-1
433
+ -1[ ]-1
434
+ sage: T.pp()
435
+ 1 2 3
436
+ 4 5
437
+ sage: RiggedConfigurations.options._reset()
438
+ """
439
+ NAME = 'RiggedConfigurations'
440
+ module = 'sage.combinat.rigged_configurations.rigged_configurations'
441
+ display = dict(default='vertical',
442
+ description='Specifies how rigged configurations should be printed',
443
+ values=dict(vertical='displayed vertically',
444
+ horizontal='displayed horizontally'),
445
+ case_sensitive=False)
446
+ element_ascii_art = dict(default=True,
447
+ description='display using the repr option ``element_ascii_art``',
448
+ checker=lambda x: isinstance(x, bool))
449
+ half_width_boxes_type_B = dict(default=True,
450
+ description='display the last rigged partition in affine type B as half width boxes',
451
+ checker=lambda x: isinstance(x, bool))
452
+ convention = dict(link_to=(tableau.Tableaux.options,'convention'))
453
+ notation = dict(alt_name='convention')
454
+
455
+ def _repr_(self):
456
+ """
457
+ Return a string representation of ``self``.
458
+
459
+ EXAMPLES::
460
+
461
+ sage: RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2], [1, 1]])
462
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((3, 2), (1, 2), (1, 1))
463
+ """
464
+ return "Rigged configurations of type {} and factor(s) {}".format(self._cartan_type, self.dims)
465
+
466
+ def _repr_option(self, key):
467
+ """
468
+ Metadata about the :meth:`_repr_` output.
469
+
470
+ See :meth:`sage.structure.parent._repr_option` for details.
471
+
472
+ EXAMPLES::
473
+
474
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1]])
475
+ sage: RC._repr_option('element_ascii_art')
476
+ True
477
+ """
478
+ if key == 'element_ascii_art':
479
+ return self.options.element_ascii_art
480
+ return super()._repr_option(key)
481
+
482
+ def __iter__(self):
483
+ """
484
+ Iterate over ``self``.
485
+
486
+ EXAMPLES::
487
+
488
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1], [1,1]])
489
+ sage: L = [x for x in RC]
490
+ sage: len(L)
491
+ 24
492
+ """
493
+ index_set = self._rc_index
494
+ from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet
495
+ return RecursivelyEnumeratedSet(self.module_generators,
496
+ lambda x: [x.f(i) for i in index_set],
497
+ structure='graded').breadth_first_search_iterator()
498
+
499
+ @lazy_attribute
500
+ def module_generators(self):
501
+ r"""
502
+ Module generators for this set of rigged configurations.
503
+
504
+ Iterate over the highest weight rigged configurations by moving
505
+ through the
506
+ :class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree`
507
+ and then setting appropriate values of the partitions.
508
+
509
+ EXAMPLES::
510
+
511
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[2,1]])
512
+ sage: for x in RC.module_generators: x
513
+ <BLANKLINE>
514
+ (/)
515
+ <BLANKLINE>
516
+ (/)
517
+ <BLANKLINE>
518
+ (/)
519
+ <BLANKLINE>
520
+ (/)
521
+ <BLANKLINE>
522
+ <BLANKLINE>
523
+ 0[ ]0
524
+ <BLANKLINE>
525
+ 0[ ]0
526
+ 0[ ]0
527
+ <BLANKLINE>
528
+ 0[ ]0
529
+ <BLANKLINE>
530
+ 0[ ]0
531
+ <BLANKLINE>
532
+
533
+ TESTS:
534
+
535
+ We check that this works with relabelled Cartan types (:issue:`16876`)::
536
+
537
+ sage: ct = CartanType(['A',3,1]).relabel(lambda x: x+2)
538
+ sage: RC = RiggedConfigurations(ct, [[4,1],[5,1]])
539
+ sage: len(RC.module_generators)
540
+ 2
541
+ sage: ct = CartanType(['A',3,1]).relabel(lambda x: (x+2) % 4)
542
+ sage: RC = RiggedConfigurations(ct, [[0,1],[1,1]])
543
+ sage: len(RC.module_generators)
544
+ 2
545
+ """
546
+ module_gens = []
547
+ n = len(self._rc_index)
548
+
549
+ for tree_node in self.kleber_tree():
550
+ shapes = []
551
+ cur = tree_node
552
+ path_lambda = [cur.up_root.to_vector()] # Build the lambda values
553
+ # Note that these are not same lambda as in the paper,
554
+ # but a less computational version.
555
+ while cur.parent_node is not None:
556
+ path_lambda.insert(0, (cur.parent_node.up_root - cur.up_root).to_vector())
557
+ cur = cur.parent_node
558
+
559
+ for a in range(n):
560
+ shapes.append([])
561
+ for i, cur_lambda in enumerate(path_lambda):
562
+ for j in range(cur_lambda[a]):
563
+ shapes[-1].insert(0, i)
564
+
565
+ # Start with a base to calculate the vacancy numbers
566
+ # Make a copy just to be safe
567
+ base = self.element_class(self, partition_list=shapes[:])
568
+
569
+ # Build out the blocks for the partition values
570
+ vac_nums = []
571
+ blocks = []
572
+ L = []
573
+
574
+ for partition in base:
575
+ vac_nums.append(partition.vacancy_numbers)
576
+ blocks.append([[]])
577
+
578
+ # If the partition is empty, there's nothing to do
579
+ if not partition._list:
580
+ L.append([[]])
581
+ continue
582
+
583
+ # Setup the first block
584
+ block_len = partition[0]
585
+ for i, rowLen in enumerate(partition):
586
+ # If we've gone to a different sized block, then update the
587
+ # values which change when moving to a new block size
588
+ if block_len != rowLen:
589
+ blocks[-1].append([])
590
+ block_len = rowLen
591
+
592
+ blocks[-1][-1].append(partition.vacancy_numbers[i])
593
+
594
+ L2 = []
595
+ for block in blocks[-1]:
596
+ L2.append(IterableFunctionCall(self._block_iterator, block))
597
+ L.append(itertools.product(*L2))
598
+
599
+ C = itertools.product(*L)
600
+ for curBlocks in C:
601
+ module_gens.append( self.element_class(self, KT_constructor=[shapes[:],
602
+ self._blocks_to_values(curBlocks[:]),
603
+ vac_nums[:]]) )
604
+
605
+ return tuple(module_gens)
606
+
607
+ def _block_iterator(self, container):
608
+ r"""
609
+ Iterate over all possible riggings for a particular block.
610
+
611
+ Helper iterator which iterates over all possible partitions contained
612
+ within the container.
613
+
614
+ INPUT:
615
+
616
+ - ``container`` -- list of widths of the rows of the container
617
+
618
+ TESTS::
619
+
620
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
621
+ sage: for x in RC._block_iterator([]): x
622
+ []
623
+ sage: for x in RC._block_iterator([2,3]): x
624
+ [0, 0]
625
+ [1, 0]
626
+ [1, 1]
627
+ [2, 0]
628
+ [2, 1]
629
+ [2, 2]
630
+ """
631
+ if not container:
632
+ yield []
633
+ return
634
+
635
+ pos = 0
636
+ length = len(container)
637
+ ret_part = [-1] * length
638
+ while pos >= 0:
639
+ ret_part[pos] += 1
640
+
641
+ if ret_part[pos] > container[pos] or (pos != 0 and ret_part[pos] > ret_part[pos - 1]):
642
+ ret_part[pos] = -1
643
+ pos -= 1
644
+ else:
645
+ pos += 1
646
+
647
+ if pos == length:
648
+ yield ret_part[:]
649
+ pos -= 1
650
+
651
+ def _blocks_to_values(self, blocks):
652
+ r"""
653
+ Convert an array of blocks into a list of partition values.
654
+
655
+ INPUT:
656
+
657
+ - ``blocks`` -- the (2-dim) array blocks of the partition values
658
+
659
+ TESTS::
660
+
661
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
662
+ sage: RC._blocks_to_values([[[2, 1]]])
663
+ [[2, 1]]
664
+ """
665
+ values = []
666
+ for part_block in blocks:
667
+ if not part_block:
668
+ values.append([])
669
+ else:
670
+ values.append(part_block[0][:]) # Need to make a copy
671
+ for block in part_block[1:]:
672
+ values[-1].extend(block)
673
+ return values
674
+
675
+ def classically_highest_weight_vectors(self):
676
+ """
677
+ Return the classically highest weight elements of ``self``.
678
+
679
+ TESTS::
680
+
681
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 2]])
682
+ sage: ascii_art(RC.classically_highest_weight_vectors())
683
+ ( (/) (/) (/) (/) )
684
+ """
685
+ return self.module_generators
686
+
687
+ def _element_constructor_(self, *lst, **options):
688
+ """
689
+ Construct a ``RiggedConfigurationElement``.
690
+
691
+ Typically the user should not call this method since it does not check
692
+ if it is a valid configuration. Instead the user should use the
693
+ iterator methods.
694
+
695
+ EXAMPLES::
696
+
697
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
698
+ sage: RC(partition_list=[[1], [1], [], []], rigging_list=[[-1], [0], [], []])
699
+ <BLANKLINE>
700
+ -1[ ]-1
701
+ <BLANKLINE>
702
+ 0[ ]0
703
+ <BLANKLINE>
704
+ (/)
705
+ <BLANKLINE>
706
+ (/)
707
+ <BLANKLINE>
708
+
709
+ TESTS::
710
+
711
+ sage: KT = crystals.TensorProductOfKirillovReshetikhinTableaux(['C',2,1], [[2,4],[1,2]])
712
+ sage: t = KT(pathlist=[[2,1,2,1,-2,2,-1,-2],[2,-2]])
713
+ sage: rc = t.to_rigged_configuration(); rc
714
+ <BLANKLINE>
715
+ -1[ ][ ][ ]-1
716
+ 0[ ][ ]0
717
+ <BLANKLINE>
718
+ -1[ ][ ]-1
719
+ -1[ ]-1
720
+ -1[ ]-1
721
+ <BLANKLINE>
722
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[2,4]])
723
+ sage: RC(rc)
724
+ <BLANKLINE>
725
+ -1[ ][ ][ ]-1
726
+ 0[ ][ ]0
727
+ <BLANKLINE>
728
+ -1[ ][ ]-1
729
+ -1[ ]-1
730
+ -1[ ]-1
731
+ <BLANKLINE>
732
+
733
+ TESTS:
734
+
735
+ Check that :issue:`17054` is fixed::
736
+
737
+ sage: B = crystals.infinity.RiggedConfigurations(['A',2])
738
+ sage: RC = RiggedConfigurations(['A',2,1], [[1,1]]*4 + [[2,1]]*4)
739
+ sage: x = B.an_element().f_string([2,2,1,1,2,1,2,1])
740
+ sage: ascii_art(x)
741
+ -4[ ][ ][ ][ ]-4 -4[ ][ ][ ][ ]0
742
+ sage: ascii_art(RC(x))
743
+ 0[ ][ ][ ][ ]-4 0[ ][ ][ ][ ]0
744
+ sage: x == B.an_element().f_string([2,2,1,1,2,1,2,1])
745
+ True
746
+ """
747
+ if not lst:
748
+ return self.element_class(self, [], **options)
749
+
750
+ from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element import TensorProductOfKirillovReshetikhinTableauxElement
751
+ if isinstance(lst[0], TensorProductOfKirillovReshetikhinTableauxElement):
752
+ if self != lst[0].parent().rigged_configurations():
753
+ raise ValueError("incorrect bijection image")
754
+ return lst[0].to_rigged_configuration()
755
+
756
+ from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement
757
+ if isinstance(lst[0], TensorProductOfRegularCrystalsElement):
758
+ lst = lst[0]
759
+ from sage.combinat.crystals.kirillov_reshetikhin import KirillovReshetikhinGenericCrystalElement
760
+ if isinstance(lst[0], KirillovReshetikhinGenericCrystalElement):
761
+ KRT = self.tensor_product_of_kirillov_reshetikhin_tableaux()
762
+ krt_elt = KRT(*[x.to_kirillov_reshetikhin_tableau() for x in lst])
763
+ return krt_elt.to_rigged_configuration()
764
+
765
+ if isinstance(lst[0], (list, tuple)):
766
+ lst = lst[0]
767
+
768
+ if isinstance(lst[0], RiggedPartition):
769
+ lst = [p._clone() for p in lst] # Make a deep copy
770
+ elif isinstance(lst[0], RiggedConfigurationElement):
771
+ lst = [p._clone() for p in lst[0]] # Make a deep copy
772
+
773
+ return self.element_class(self, list(lst), **options)
774
+
775
+ def _calc_vacancy_number(self, partitions, a, i, **options):
776
+ r"""
777
+ Calculate the vacancy number `p_i^{(a)}` in ``self``.
778
+
779
+ This assumes that `\gamma_a = 1` for all `a` and `(\alpha_a \mid
780
+ \alpha_b ) = A_{ab}`.
781
+
782
+ INPUT:
783
+
784
+ - ``partitions`` -- the list of rigged partitions we are using
785
+
786
+ - ``a`` -- the rigged partition index
787
+
788
+ - ``i`` -- the row length
789
+
790
+ TESTS::
791
+
792
+ sage: RC = RiggedConfigurations(['A', 4, 1], [[2, 1]])
793
+ sage: elt = RC(partition_list=[[1], [1], [], []])
794
+ sage: RC._calc_vacancy_number(elt.nu(), 1, 1)
795
+ 0
796
+ """
797
+ vac_num = 0
798
+ if "B" in options:
799
+ for tab in options["B"]:
800
+ if len(tab) == self._rc_index[a]:
801
+ vac_num += min(i, len(tab[0]))
802
+ elif "L" in options:
803
+ L = options["L"]
804
+ if a in L:
805
+ for kvp in L[a].items():
806
+ vac_num += min(kvp[0], i) * kvp[1]
807
+ elif "dims" in options:
808
+ for dim in options["dims"]:
809
+ if dim[0] == self._rc_index[a]:
810
+ vac_num += min(dim[1], i)
811
+ else:
812
+ for dim in self.dims:
813
+ if dim[0] == self._rc_index[a]:
814
+ vac_num += min(dim[1], i)
815
+
816
+ if i == float('inf'):
817
+ vac_num -= sum(self._cartan_matrix[a,b] * sum(nu)
818
+ for b,nu in enumerate(partitions))
819
+ else:
820
+ vac_num -= sum(self._cartan_matrix[a,b] * nu.get_num_cells_to_column(i)
821
+ for b,nu in enumerate(partitions))
822
+
823
+ return vac_num
824
+
825
+ def kleber_tree(self):
826
+ r"""
827
+ Return the underlying Kleber tree used to generate all highest
828
+ weight rigged configurations.
829
+
830
+ EXAMPLES::
831
+
832
+ sage: RC = RiggedConfigurations(['A',3,1], [[1,1], [2,1]])
833
+ sage: RC.kleber_tree()
834
+ Kleber tree of Cartan type ['A', 3, 1] and B = ((1, 1), (2, 1))
835
+ """
836
+ return KleberTree(self._cartan_type, self.dims)
837
+
838
+ @cached_method
839
+ def tensor_product_of_kirillov_reshetikhin_tableaux(self):
840
+ """
841
+ Return the corresponding tensor product of Kirillov-Reshetikhin
842
+ tableaux.
843
+
844
+ EXAMPLES::
845
+
846
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2]])
847
+ sage: RC.tensor_product_of_kirillov_reshetikhin_tableaux()
848
+ Tensor product of Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and factor(s) ((3, 2), (1, 2))
849
+ """
850
+ from sage.combinat.rigged_configurations.tensor_product_kr_tableaux import TensorProductOfKirillovReshetikhinTableaux
851
+ return TensorProductOfKirillovReshetikhinTableaux(self._cartan_type, self.dims)
852
+
853
+ @cached_method
854
+ def tensor_product_of_kirillov_reshetikhin_crystals(self):
855
+ """
856
+ Return the corresponding tensor product of Kirillov-Reshetikhin
857
+ crystals.
858
+
859
+ EXAMPLES::
860
+
861
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3,1],[2,2]])
862
+ sage: RC.tensor_product_of_kirillov_reshetikhin_crystals()
863
+ Full tensor product of the crystals
864
+ [Kirillov-Reshetikhin crystal of type ['A', 3, 1] with (r,s)=(3,1),
865
+ Kirillov-Reshetikhin crystal of type ['A', 3, 1] with (r,s)=(2,2)]
866
+ """
867
+ return self.tensor_product_of_kirillov_reshetikhin_tableaux().tensor_product_of_kirillov_reshetikhin_crystals()
868
+
869
+ def fermionic_formula(self, q=None, only_highest_weight=False, weight=None):
870
+ r"""
871
+ Return the fermionic formula associated to ``self``.
872
+
873
+ Given a set of rigged configurations `RC(\lambda, L)`, the fermionic
874
+ formula is defined as:
875
+
876
+ .. MATH::
877
+
878
+ M(\lambda, L; q) = \sum_{(\nu,J)} q^{cc(\nu, J)}
879
+
880
+ where we sum over all (classically highest weight) rigged
881
+ configurations of weight `\lambda` where `cc` is the
882
+ :meth:`cocharge statistic
883
+ <sage.combinat.rigged_configurations.rigged_configuration_element.RiggedConfigurationElement.cc>`.
884
+ This is known to reduce to
885
+
886
+ .. MATH::
887
+
888
+ M(\lambda, L; q) = \sum_{\nu} q^{cc(\nu)} \prod_{(a,i) \in
889
+ I \times \ZZ} \begin{bmatrix} p_i^{(a)} + m_i^{(a)} \\ m_i^{(a)}
890
+ \end{bmatrix}_q.
891
+
892
+ The generating function of `M(\lambda, L; q)` in the weight algebra
893
+ subsumes all fermionic formulas:
894
+
895
+ .. MATH::
896
+
897
+ M(L; q) = \sum_{\lambda \in P} M(\lambda, L; q) \lambda.
898
+
899
+ This is conjecturally equal to the
900
+ :meth:`one dimensional configuration sum
901
+ <sage.combinat.crystals.tensor_product.CrystalOfWords.one_dimensional_configuration_sum>`
902
+ of the corresponding tensor product of Kirillov-Reshetikhin crystals, see [HKOTT2002]_.
903
+ This has been proven in general for type `A_n^{(1)}` [BijectionLRT]_,
904
+ single factors `B^{r,s}` in type `D_n^{(1)}` [OSS2011]_ with the result
905
+ from [Sakamoto13]_, as well as for a tensor product of single columns
906
+ [OSS2003]_, [BijectionDn]_ or a tensor product of single rows [OSS03]_
907
+ for all non-exceptional types.
908
+
909
+ INPUT:
910
+
911
+ - ``q`` -- the variable `q`
912
+ - ``only_highest_weight`` -- use only the classically highest weight
913
+ rigged configurations
914
+ - ``weight`` -- return the fermionic formula `M(\lambda, L; q)` where
915
+ `\lambda` is the classical weight ``weight``
916
+
917
+ REFERENCES:
918
+
919
+ .. [OSS2003] Masato Okado, Anne Schilling, and Mark Shimozono.
920
+ Virtual crystals and fermionic formulas of type `D_{n+1}^{(2)}`,
921
+ `A_{2n}^{(2)}`, and `C_n^{(1)}`. Representation Theory. **7** (2003)
922
+ :arxiv:`math.QA/0105017`.
923
+
924
+ .. [Sakamoto13] Reiho Sakamoto.
925
+ Rigged configurations and Kashiwara operators.
926
+ (2013) :arxiv:`1302.4562v1`.
927
+
928
+ EXAMPLES::
929
+
930
+ sage: RC = RiggedConfigurations(['A', 2, 1], [[1,1], [1,1]])
931
+ sage: RC.fermionic_formula()
932
+ B[-2*Lambda[1] + 2*Lambda[2]] + (q+1)*B[-Lambda[1]]
933
+ + (q+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]]
934
+ + B[-2*Lambda[2]] + (q+1)*B[Lambda[2]]
935
+ sage: t = QQ['t'].gen(0)
936
+ sage: RC.fermionic_formula(t)
937
+ B[-2*Lambda[1] + 2*Lambda[2]] + (t+1)*B[-Lambda[1]]
938
+ + (t+1)*B[Lambda[1] - Lambda[2]] + B[2*Lambda[1]]
939
+ + B[-2*Lambda[2]] + (t+1)*B[Lambda[2]]
940
+ sage: La = RC.weight_lattice_realization().classical().fundamental_weights()
941
+ sage: RC.fermionic_formula(weight=La[2])
942
+ q + 1
943
+ sage: RC.fermionic_formula(only_highest_weight=True, weight=La[2])
944
+ q
945
+
946
+ Only using the highest weight elements on other types::
947
+
948
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[3,1], [2,2]])
949
+ sage: RC.fermionic_formula(only_highest_weight=True)
950
+ q*B[Lambda[1] + Lambda[2]] + B[2*Lambda[2] + Lambda[3]]
951
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[3,1], [4,1], [2,1]])
952
+ sage: RC.fermionic_formula(only_highest_weight=True)
953
+ (q^4+q^3+q^2)*B[Lambda[1]] + (q^2+q)*B[Lambda[1] + Lambda[2]]
954
+ + q*B[Lambda[1] + 2*Lambda[3]] + q*B[Lambda[1] + 2*Lambda[4]]
955
+ + B[Lambda[2] + Lambda[3] + Lambda[4]] + (q^3+2*q^2+q)*B[Lambda[3] + Lambda[4]]
956
+ sage: RC = RiggedConfigurations(['E', 6, 1], [[2,2]])
957
+ sage: RC.fermionic_formula(only_highest_weight=True)
958
+ q^2*B[0] + q*B[Lambda[2]] + B[2*Lambda[2]]
959
+ sage: RC = RiggedConfigurations(['B', 3, 1], [[3,1], [2,2]])
960
+ sage: RC.fermionic_formula(only_highest_weight=True) # long time
961
+ q*B[Lambda[1] + Lambda[2] + Lambda[3]] + q^2*B[Lambda[1]
962
+ + Lambda[3]] + (q^2+q)*B[Lambda[2] + Lambda[3]] + B[2*Lambda[2]
963
+ + Lambda[3]] + (q^3+q^2)*B[Lambda[3]]
964
+ sage: RC = RiggedConfigurations(['C', 3, 1], [[3,1], [2,2]])
965
+ sage: RC.fermionic_formula(only_highest_weight=True) # long time
966
+ (q^3+q^2)*B[Lambda[1] + Lambda[2]] + q*B[Lambda[1] + 2*Lambda[2]]
967
+ + (q^2+q)*B[2*Lambda[1] + Lambda[3]] + B[2*Lambda[2] + Lambda[3]]
968
+ + (q^4+q^3+q^2)*B[Lambda[3]]
969
+ sage: RC = RiggedConfigurations(['D', 4, 2], [[3,1], [2,2]])
970
+ sage: RC.fermionic_formula(only_highest_weight=True) # long time
971
+ (q^2+q)*B[Lambda[1] + Lambda[2] + Lambda[3]] + (q^5+2*q^4+q^3)*B[Lambda[1]
972
+ + Lambda[3]] + (q^3+q^2)*B[2*Lambda[1] + Lambda[3]] + (q^4+q^3+q^2)*B[Lambda[2]
973
+ + Lambda[3]] + B[2*Lambda[2] + Lambda[3]] + (q^6+q^5+q^4)*B[Lambda[3]]
974
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,1],[2,2]])
975
+ sage: RC.fermionic_formula(only_highest_weight=True)
976
+ (q^3+q^2)*B[Lambda[1]] + (q^2+q)*B[Lambda[1] + 2*Lambda[2]]
977
+ + B[Lambda[1] + 4*Lambda[2]] + q*B[3*Lambda[1]] + q*B[4*Lambda[2]]
978
+
979
+ TESTS::
980
+
981
+ sage: RC = RiggedConfigurations(['A', 2, 1], [[1,1], [1,1]])
982
+ sage: KR = RC.tensor_product_of_kirillov_reshetikhin_crystals()
983
+ sage: RC.fermionic_formula() == KR.one_dimensional_configuration_sum()
984
+ True
985
+ sage: KT = RC.tensor_product_of_kirillov_reshetikhin_tableaux()
986
+ sage: RC.fermionic_formula() == KT.one_dimensional_configuration_sum()
987
+ True
988
+ sage: RC = RiggedConfigurations(['C', 2, 1], [[2,1], [2,1]])
989
+ sage: KR = RC.tensor_product_of_kirillov_reshetikhin_crystals()
990
+ sage: RC.fermionic_formula() == KR.one_dimensional_configuration_sum() # long time
991
+ True
992
+ sage: t = QQ['t'].gen(0)
993
+ sage: RC = RiggedConfigurations(['D', 4, 1], [[1,1], [2,1]])
994
+ sage: KR = RC.tensor_product_of_kirillov_reshetikhin_crystals()
995
+ sage: RC.fermionic_formula(t) == KR.one_dimensional_configuration_sum(t) # long time
996
+ True
997
+ """
998
+ if q is None:
999
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1000
+ q = PolynomialRing(QQ, 'q').gen(0)
1001
+
1002
+ if only_highest_weight:
1003
+ L = self.module_generators
1004
+ else:
1005
+ L = self
1006
+
1007
+ P = q.parent()
1008
+ WLR = self.weight_lattice_realization().classical()
1009
+
1010
+ if weight is not None:
1011
+ weight = WLR(weight)
1012
+ return P.sum(q**x.cc() for x in L if WLR(x.weight()) == weight)
1013
+
1014
+ B = WLR.algebra(P)
1015
+ return B.sum(q**x.cc() * B(WLR(x.weight())) for x in L)
1016
+
1017
+ def _test_bijection(self, **options):
1018
+ r"""
1019
+ Test function to make sure that the bijection between rigged
1020
+ configurations and Kirillov-Reshetikhin tableaux is correct.
1021
+
1022
+ EXAMPLES::
1023
+
1024
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1],[1,1]])
1025
+ sage: RC._test_bijection()
1026
+ """
1027
+ tester = self._tester(**options)
1028
+ rejects = []
1029
+ for x in self:
1030
+ y = x.to_tensor_product_of_kirillov_reshetikhin_tableaux()
1031
+ z = y.to_rigged_configuration()
1032
+ if z != x:
1033
+ rejects.append((x, z))
1034
+
1035
+ tester.assertEqual(len(rejects), 0, "Bijection is not correct: {}".format(rejects))
1036
+ if rejects:
1037
+ return rejects
1038
+
1039
+ def tensor(self, *crystals, **options):
1040
+ """
1041
+ Return the tensor product of ``self`` with ``crystals``.
1042
+
1043
+ If ``crystals`` is a list of rigged configurations of the same
1044
+ Cartan type, then this returns a new :class:`RiggedConfigurations`.
1045
+
1046
+ EXAMPLES::
1047
+
1048
+ sage: RC = RiggedConfigurations(['A', 3, 1], [[2,1],[1,3]])
1049
+ sage: RC2 = RiggedConfigurations(['A', 3, 1], [[1,1], [3,3]])
1050
+ sage: RC.tensor(RC2, RC2)
1051
+ Rigged configurations of type ['A', 3, 1]
1052
+ and factor(s) ((2, 1), (1, 3), (1, 1), (3, 3), (1, 1), (3, 3))
1053
+
1054
+ sage: K = crystals.KirillovReshetikhin(['A', 3, 1], 2, 2, model='KR')
1055
+ sage: RC.tensor(K)
1056
+ Full tensor product of the crystals
1057
+ [Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 1), (1, 3)),
1058
+ Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and shape (2, 2)]
1059
+ """
1060
+ ct = self._cartan_type
1061
+ if all(isinstance(B, RiggedConfigurations) and B.cartan_type() == ct for B in crystals):
1062
+ dims = self.dims
1063
+ for B in crystals:
1064
+ dims += B.dims
1065
+ return RiggedConfigurations(ct, dims)
1066
+ return super().tensor(*crystals, **options)
1067
+
1068
+ Element = KRRCSimplyLacedElement
1069
+
1070
+
1071
+ class RCNonSimplyLaced(RiggedConfigurations):
1072
+ r"""
1073
+ Rigged configurations in non-simply-laced types.
1074
+
1075
+ These are rigged configurations which lift to virtual rigged configurations
1076
+ in a simply-laced type.
1077
+
1078
+ For more on rigged configurations, see :class:`RiggedConfigurations`.
1079
+ """
1080
+ @staticmethod
1081
+ def __classcall_private__(cls, cartan_type, B):
1082
+ r"""
1083
+ Normalize the input arguments to ensure unique representation.
1084
+
1085
+ EXAMPLES::
1086
+
1087
+ sage: RC1 = RiggedConfigurations(CartanType(['A',4,2]), [[2,2]])
1088
+ sage: RC2 = RiggedConfigurations(['A',4,2], [(2,2)])
1089
+ sage: RC3 = RiggedConfigurations(['BC',2,2], ((2,2),))
1090
+ sage: RC2 is RC1, RC3 is RC1
1091
+ (True, True)
1092
+ """
1093
+ cartan_type = CartanType(cartan_type)
1094
+
1095
+ # Standardize B input into a tuple of tuples
1096
+ B = tuple(map(tuple, B))
1097
+ return super().__classcall__(cls, cartan_type, B)
1098
+
1099
+ def __init__(self, cartan_type, dims):
1100
+ """
1101
+ Initialize ``self``.
1102
+
1103
+ EXAMPLES::
1104
+
1105
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,1]])
1106
+ sage: TestSuite(RC).run()
1107
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[2,1]])
1108
+ sage: TestSuite(RC).run() # long time
1109
+ sage: RC = RiggedConfigurations(['B',3,1], [[3,1],[1,1]])
1110
+ sage: TestSuite(RC).run() # long time
1111
+ sage: RC = RiggedConfigurations(['D',4,2], [[2,1]])
1112
+ sage: TestSuite(RC).run() # long time
1113
+ sage: RC = RiggedConfigurations(['A',5,2], [[2,1]])
1114
+ sage: TestSuite(RC).run() # long time
1115
+ """
1116
+ self._folded_ct = cartan_type.as_folding()
1117
+ RiggedConfigurations.__init__(self, cartan_type, dims)
1118
+
1119
+ def _calc_vacancy_number(self, partitions, a, i, **options):
1120
+ r"""
1121
+ Calculate the vacancy number `p_i^{(a)}` in ``self``.
1122
+
1123
+ INPUT:
1124
+
1125
+ - ``partitions`` -- the list of rigged partitions we are using
1126
+
1127
+ - ``a`` -- the rigged partition index
1128
+
1129
+ - ``i`` -- the row length
1130
+
1131
+ TESTS::
1132
+
1133
+ sage: RC = RiggedConfigurations(['C', 4, 1], [[2, 1]])
1134
+ sage: elt = RC(partition_list=[[1], [2], [2], [1]])
1135
+ sage: RC._calc_vacancy_number(elt.nu(), 1, 2)
1136
+ 0
1137
+ """
1138
+ vac_num = 0
1139
+ if "B" in options:
1140
+ for tab in options["B"]:
1141
+ if len(tab) == self._rc_index[a]:
1142
+ vac_num += min(i, len(tab[0]))
1143
+ elif "L" in options:
1144
+ L = options["L"]
1145
+ if a in L:
1146
+ for kvp in L[a].items():
1147
+ vac_num += min(kvp[0], i) * kvp[1]
1148
+ elif "dims" in options:
1149
+ for dim in options["dims"]:
1150
+ if dim[0] == self._rc_index[a]:
1151
+ vac_num += min(dim[1], i)
1152
+ else:
1153
+ for dim in self.dims:
1154
+ if dim[0] == self._rc_index[a]:
1155
+ vac_num += min(dim[1], i)
1156
+
1157
+ if i == float('inf'):
1158
+ vac_num -= sum(self._cartan_matrix[a,b] * sum(nu)
1159
+ for b,nu in enumerate(partitions))
1160
+ else:
1161
+ gamma = self._folded_ct.scaling_factors()
1162
+ vac_num -= sum(self._cartan_matrix[a,b]
1163
+ * nu.get_num_cells_to_column(gamma[a+1]*i, gamma[b+1])
1164
+ // gamma[b+1]
1165
+ for b,nu in enumerate(partitions))
1166
+
1167
+ return vac_num
1168
+
1169
+ @lazy_attribute
1170
+ def module_generators(self):
1171
+ r"""
1172
+ Module generators for this set of rigged configurations.
1173
+
1174
+ Iterate over the highest weight rigged configurations by moving
1175
+ through the
1176
+ :class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree`
1177
+ and then setting appropriate values of the partitions.
1178
+
1179
+ EXAMPLES::
1180
+
1181
+ sage: RC = RiggedConfigurations(['C', 3, 1], [[1,2]])
1182
+ sage: for x in RC.module_generators: x
1183
+ <BLANKLINE>
1184
+ (/)
1185
+ <BLANKLINE>
1186
+ (/)
1187
+ <BLANKLINE>
1188
+ (/)
1189
+ <BLANKLINE>
1190
+ <BLANKLINE>
1191
+ 0[ ][ ]0
1192
+ <BLANKLINE>
1193
+ 0[ ][ ]0
1194
+ <BLANKLINE>
1195
+ 0[ ]0
1196
+ <BLANKLINE>
1197
+
1198
+ sage: RC = RiggedConfigurations(['D',4,3], [[1,1]])
1199
+ sage: RC.module_generators
1200
+ (
1201
+ <BLANKLINE>
1202
+ 0[ ]0
1203
+ (/) 0[ ]0
1204
+ <BLANKLINE>
1205
+ (/) 0[ ]0
1206
+ ,
1207
+ )
1208
+ """
1209
+ module_gens = []
1210
+ vec_len = len(self.kleber_tree().root.up_root.to_vector())
1211
+
1212
+ for tree_node in self.kleber_tree():
1213
+ shapes = []
1214
+ cur = tree_node
1215
+ path_lambda = [cur.up_root.to_vector()] # Build the lambda values
1216
+ # Note that these are not same lambda as in the paper,
1217
+ # but a less computational version.
1218
+ while cur.parent_node is not None:
1219
+ path_lambda.insert(0, (cur.parent_node.up_root - cur.up_root).to_vector())
1220
+ cur = cur.parent_node
1221
+
1222
+ for a in range(vec_len):
1223
+ shapes.append([])
1224
+ for i, cur_lambda in enumerate(path_lambda):
1225
+ for j in range(cur_lambda[a]):
1226
+ shapes[-1].insert(0, i)
1227
+
1228
+ # Convert from the virtual rigged configuration
1229
+ # As a special case, we do not need to do anything for type `A_{2n}^{(2)}`
1230
+ sigma = self._folded_ct.folding_orbit()
1231
+ vindex = self.virtual._rc_index
1232
+ shapes = [shapes[vindex.index(sigma[a][0])] for a in self._rc_index]
1233
+ if self._cartan_type.type() != 'BC':
1234
+ gamma = self._folded_ct.scaling_factors()
1235
+ for a,shape in enumerate(shapes):
1236
+ for i in range(len(shape)):
1237
+ shape[i] = shape[i] // gamma[self._rc_index[a]]
1238
+
1239
+ # Start with a base to calculate the vacancy numbers
1240
+ # Make a copy just to be safe
1241
+ base = self.element_class(self, partition_list=shapes[:])
1242
+
1243
+ # Build out the blocks for the partition values
1244
+ vac_nums = []
1245
+ blocks = []
1246
+ L = []
1247
+
1248
+ for partition in base:
1249
+ vac_nums.append(partition.vacancy_numbers)
1250
+ blocks.append([[]])
1251
+
1252
+ # If the partition is empty, there's nothing to do
1253
+ if not partition._list:
1254
+ L.append([[]])
1255
+ continue
1256
+
1257
+ # Setup the first block
1258
+ block_len = partition[0]
1259
+ for i, rowLen in enumerate(partition):
1260
+ # If we've gone to a different sized block, then update the
1261
+ # values which change when moving to a new block size
1262
+ if block_len != rowLen:
1263
+ blocks[-1].append([])
1264
+ block_len = rowLen
1265
+
1266
+ blocks[-1][-1].append(partition.vacancy_numbers[i])
1267
+
1268
+ L2 = []
1269
+ for block in blocks[-1]:
1270
+ L2.append(IterableFunctionCall(self._block_iterator, block))
1271
+ L.append(itertools.product(*L2))
1272
+
1273
+ C = itertools.product(*L)
1274
+ for cur_blocks in C:
1275
+ module_gens.append( self.element_class(self, KT_constructor=[shapes[:],
1276
+ self._blocks_to_values(cur_blocks[:]), vac_nums[:]]) )
1277
+
1278
+ return tuple(module_gens)
1279
+
1280
+ def kleber_tree(self):
1281
+ r"""
1282
+ Return the underlying (virtual) Kleber tree used to generate all
1283
+ highest weight rigged configurations.
1284
+
1285
+ EXAMPLES::
1286
+
1287
+ sage: RC = RiggedConfigurations(['C',3,1], [[1,1], [2,1]])
1288
+ sage: RC.kleber_tree()
1289
+ Virtual Kleber tree of Cartan type ['C', 3, 1] and B = ((1, 1), (2, 1))
1290
+ """
1291
+ return VirtualKleberTree(self._cartan_type, self.dims)
1292
+
1293
+ @lazy_attribute
1294
+ def virtual(self):
1295
+ """
1296
+ Return the corresponding virtual crystal.
1297
+
1298
+ EXAMPLES::
1299
+
1300
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
1301
+ sage: RC
1302
+ Rigged configurations of type ['C', 2, 1] and factor(s) ((1, 2), (1, 1), (2, 1))
1303
+ sage: RC.virtual
1304
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 2))
1305
+ """
1306
+ gamma = self._folded_ct.scaling_factors()
1307
+ sigma = self._folded_ct.folding_orbit()
1308
+ virtual_dims = []
1309
+ for r,s in self.dims:
1310
+ for a in sigma[r]:
1311
+ virtual_dims.append([a, s*gamma[r]])
1312
+ return RiggedConfigurations(self._folded_ct._folding, virtual_dims)
1313
+
1314
+ def to_virtual(self, rc):
1315
+ """
1316
+ Convert ``rc`` into a rigged configuration in the virtual crystal.
1317
+
1318
+ INPUT:
1319
+
1320
+ - ``rc`` -- a rigged configuration element
1321
+
1322
+ EXAMPLES::
1323
+
1324
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
1325
+ sage: elt = RC(partition_list=[[3],[2]]); elt
1326
+ <BLANKLINE>
1327
+ 0[ ][ ][ ]0
1328
+ <BLANKLINE>
1329
+ 0[ ][ ]0
1330
+ sage: velt = RC.to_virtual(elt); velt
1331
+ <BLANKLINE>
1332
+ 0[ ][ ][ ]0
1333
+ <BLANKLINE>
1334
+ 0[ ][ ][ ][ ]0
1335
+ <BLANKLINE>
1336
+ 0[ ][ ][ ]0
1337
+ sage: velt.parent()
1338
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 2))
1339
+ """
1340
+ gamma = self._folded_ct.scaling_factors()
1341
+ sigma = self._folded_ct.folding_orbit()
1342
+ n = len(self.virtual._rc_index)
1343
+ # +/- 1 for indexing
1344
+ partitions = [None] * n
1345
+ for a,rp in enumerate(rc):
1346
+ g = gamma[a+1]
1347
+ for i in sigma[a+1]:
1348
+ partitions[i-1] = RiggedPartition([row_len*g for row_len in rp._list],
1349
+ [rig_val*g for rig_val in rp.rigging],
1350
+ [vac_num*g for vac_num in rp.vacancy_numbers])
1351
+ return self.virtual.element_class(self.virtual, partitions, use_vacancy_numbers=True)
1352
+
1353
+ def from_virtual(self, vrc):
1354
+ """
1355
+ Convert ``vrc`` in the virtual crystal into a rigged configuration of
1356
+ the original Cartan type.
1357
+
1358
+ INPUT:
1359
+
1360
+ - ``vrc`` -- a virtual rigged configuration
1361
+
1362
+ EXAMPLES::
1363
+
1364
+ sage: RC = RiggedConfigurations(['C',2,1], [[1,2],[1,1],[2,1]])
1365
+ sage: elt = RC(partition_list=[[3],[2]])
1366
+ sage: vrc_elt = RC.to_virtual(elt)
1367
+ sage: ret = RC.from_virtual(vrc_elt); ret
1368
+ <BLANKLINE>
1369
+ 0[ ][ ][ ]0
1370
+ <BLANKLINE>
1371
+ 0[ ][ ]0
1372
+ sage: ret == elt
1373
+ True
1374
+ """
1375
+ gamma = self._folded_ct.scaling_factors()
1376
+ sigma = self._folded_ct.folding_orbit()
1377
+ n = len(self._rc_index)
1378
+ partitions = [None] * n
1379
+ # +/- 1 for indexing
1380
+ for a in range(n):
1381
+ rp = vrc[sigma[a+1][0] - 1]
1382
+ g = gamma[a+1]
1383
+ partitions[a] = RiggedPartition([row_len//g for row_len in rp._list],
1384
+ [rig_val//g for rig_val in rp.rigging],
1385
+ [vac_val//g for vac_val in rp.vacancy_numbers])
1386
+ return self.element_class(self, partitions, use_vacancy_numbers=True)
1387
+
1388
+ def _test_virtual_vacancy_numbers(self, **options):
1389
+ """
1390
+ Test to make sure that the vacancy numbers obtained from the virtual
1391
+ rigged configuration agree with the explicit computation of the
1392
+ vacancy numbers done here.
1393
+
1394
+ EXAMPLES::
1395
+
1396
+ sage: RC = RiggedConfigurations(['B', 3, 1], [[2,1]])
1397
+ sage: RC._test_virtual_vacancy_numbers()
1398
+ """
1399
+ tester = self._tester(**options)
1400
+ for x in self:
1401
+ parts_list = [p._list[:] for p in x]
1402
+ elt = self.element_class(self, partition_list=parts_list)
1403
+ for i, p in enumerate(elt):
1404
+ for j, vac_num in enumerate(p.vacancy_numbers):
1405
+ tester.assertEqual(vac_num, x[i].vacancy_numbers[j],
1406
+ "Incorrect vacancy number: {}\nComputed: {}\nFor: {}".format(
1407
+ x[i].vacancy_numbers[j], vac_num, x))
1408
+
1409
+ Element = KRRCNonSimplyLacedElement
1410
+
1411
+
1412
+ class RCTypeA2Even(RCNonSimplyLaced):
1413
+ """
1414
+ Rigged configurations for type `A_{2n}^{(2)}`.
1415
+
1416
+ For more on rigged configurations, see :class:`RiggedConfigurations`.
1417
+
1418
+ EXAMPLES::
1419
+
1420
+ sage: RC = RiggedConfigurations(['A',4,2], [[2,1], [1,2]])
1421
+ sage: RC.cardinality()
1422
+ 150
1423
+ sage: RC = RiggedConfigurations(['A',2,2], [[1,1]])
1424
+ sage: RC.cardinality()
1425
+ 3
1426
+ sage: RC = RiggedConfigurations(['A',2,2], [[1,2],[1,1]])
1427
+ sage: TestSuite(RC).run() # long time
1428
+ sage: RC = RiggedConfigurations(['A',4,2], [[2,1]])
1429
+ sage: TestSuite(RC).run() # long time
1430
+ """
1431
+
1432
+ def cardinality(self):
1433
+ """
1434
+ Return the cardinality of ``self``.
1435
+
1436
+ EXAMPLES::
1437
+
1438
+ sage: RC = RiggedConfigurations(['A',4,2], [[1,1], [2,2]])
1439
+ sage: RC.cardinality()
1440
+ 250
1441
+ """
1442
+ return self.tensor_product_of_kirillov_reshetikhin_tableaux().cardinality()
1443
+
1444
+ @lazy_attribute
1445
+ def virtual(self):
1446
+ """
1447
+ Return the corresponding virtual crystal.
1448
+
1449
+ EXAMPLES::
1450
+
1451
+ sage: RC = RiggedConfigurations(['A',4,2], [[1,2],[1,1],[2,1]])
1452
+ sage: RC
1453
+ Rigged configurations of type ['BC', 2, 2] and factor(s) ((1, 2), (1, 1), (2, 1))
1454
+ sage: RC.virtual
1455
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 1), (2, 1))
1456
+ """
1457
+ sigma = self._folded_ct.folding_orbit()
1458
+ n = len(sigma) - 1
1459
+ virtual_dims = []
1460
+ for r,s in self.dims:
1461
+ if r == n:
1462
+ virtual_dims.extend([[n, s], [n, s]])
1463
+ else:
1464
+ for a in sigma[r]:
1465
+ virtual_dims.append([a, s])
1466
+ return RiggedConfigurations(self._folded_ct._folding, virtual_dims)
1467
+
1468
+ def _calc_vacancy_number(self, partitions, a, i, **options):
1469
+ r"""
1470
+ Calculate the vacancy number `p_i^{(a)}` in ``self``.
1471
+
1472
+ This is a special implementation for type `A_{2n}^{(2)}`.
1473
+
1474
+ INPUT:
1475
+
1476
+ - ``partitions`` -- the list of rigged partitions we are using
1477
+
1478
+ - ``a`` -- the rigged partition index
1479
+
1480
+ - ``i`` -- the row length
1481
+
1482
+ TESTS::
1483
+
1484
+ sage: RC = RiggedConfigurations(['A', 4, 2], [[2, 1]])
1485
+ sage: elt = RC(partition_list=[[1], [2]])
1486
+ sage: RC._calc_vacancy_number(elt.nu(), 1, 2)
1487
+ 0
1488
+ """
1489
+ vac_num = 0
1490
+ if "B" in options:
1491
+ for tab in options["B"]:
1492
+ if len(tab) == self._rc_index[a]:
1493
+ vac_num += min(i, len(tab[0]))
1494
+ elif "L" in options:
1495
+ L = options["L"]
1496
+ if a in L:
1497
+ for kvp in L[a].items():
1498
+ vac_num += min(kvp[0], i) * kvp[1]
1499
+ elif "dims" in options:
1500
+ for dim in options["dims"]:
1501
+ if dim[0] == self._rc_index[a]:
1502
+ vac_num += min(dim[1], i)
1503
+ else:
1504
+ for dim in self.dims:
1505
+ if dim[0] == self._rc_index[a]:
1506
+ vac_num += min(dim[1], i)
1507
+
1508
+ gamma = self._folded_ct.scaling_factors()
1509
+ if i == float('inf'):
1510
+ vac_num -= sum(self._cartan_matrix[a,b] * sum(nu) // gamma[b+1]
1511
+ for b, nu in enumerate(partitions))
1512
+ else:
1513
+ vac_num -= sum(self._cartan_matrix[a,b] * nu.get_num_cells_to_column(i) // gamma[b+1]
1514
+ for b, nu in enumerate(partitions))
1515
+
1516
+ return vac_num
1517
+
1518
+ def to_virtual(self, rc):
1519
+ """
1520
+ Convert ``rc`` into a rigged configuration in the virtual crystal.
1521
+
1522
+ INPUT:
1523
+
1524
+ - ``rc`` -- a rigged configuration element
1525
+
1526
+ EXAMPLES::
1527
+
1528
+ sage: RC = RiggedConfigurations(['A',4,2], [[2,2]])
1529
+ sage: elt = RC(partition_list=[[1],[1]]); elt
1530
+ <BLANKLINE>
1531
+ -1[ ]-1
1532
+ <BLANKLINE>
1533
+ 1[ ]1
1534
+ <BLANKLINE>
1535
+ sage: velt = RC.to_virtual(elt); velt
1536
+ <BLANKLINE>
1537
+ -1[ ]-1
1538
+ <BLANKLINE>
1539
+ 2[ ]2
1540
+ <BLANKLINE>
1541
+ -1[ ]-1
1542
+ <BLANKLINE>
1543
+ sage: velt.parent()
1544
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 2), (2, 2))
1545
+ """
1546
+ gamma = self._folded_ct.scaling_factors()
1547
+ sigma = self._folded_ct.folding_orbit()
1548
+ n = len(self.virtual._rc_index)
1549
+ partitions = [None] * n
1550
+ for a,rp in enumerate(rc):
1551
+ g = gamma[a+1]
1552
+ for i in sigma[a+1]:
1553
+ partitions[i-1] = RiggedPartition(list(rp._list),
1554
+ [rig_val*g for rig_val in rp.rigging],
1555
+ [vac_num*g for vac_num in rp.vacancy_numbers])
1556
+ return self.virtual.element_class(self.virtual, partitions, use_vacancy_numbers=True)
1557
+
1558
+ def from_virtual(self, vrc):
1559
+ """
1560
+ Convert ``vrc`` in the virtual crystal into a rigged configuration of
1561
+ the original Cartan type.
1562
+
1563
+ INPUT:
1564
+
1565
+ - ``vrc`` -- a virtual rigged configuration element
1566
+
1567
+ EXAMPLES::
1568
+
1569
+ sage: RC = RiggedConfigurations(['A',4,2], [[2,2]])
1570
+ sage: elt = RC(partition_list=[[1],[1]])
1571
+ sage: velt = RC.to_virtual(elt)
1572
+ sage: ret = RC.from_virtual(velt); ret
1573
+ <BLANKLINE>
1574
+ -1[ ]-1
1575
+ <BLANKLINE>
1576
+ 1[ ]1
1577
+ <BLANKLINE>
1578
+ sage: ret == elt
1579
+ True
1580
+ """
1581
+ gamma = self._folded_ct.scaling_factors()
1582
+ sigma = self._folded_ct.folding_orbit()
1583
+ n = len(self._rc_index)
1584
+ partitions = [None] * n
1585
+ # +/- 1 for indexing
1586
+ for a in range(n):
1587
+ rp = vrc[sigma[a+1][0] - 1]
1588
+ g = gamma[a+1]
1589
+ partitions[a] = RiggedPartition(list(rp._list),
1590
+ [rig_val//g for rig_val in rp.rigging],
1591
+ [vac_val//g for vac_val in rp.vacancy_numbers])
1592
+ return self.element_class(self, partitions, use_vacancy_numbers=True)
1593
+
1594
+
1595
+ class RCTypeA2Dual(RCTypeA2Even):
1596
+ r"""
1597
+ Rigged configurations of type `A_{2n}^{(2)\dagger}`.
1598
+
1599
+ For more on rigged configurations, see :class:`RiggedConfigurations`.
1600
+
1601
+ EXAMPLES::
1602
+
1603
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[1,2],[1,1],[2,1]])
1604
+ sage: RC
1605
+ Rigged configurations of type ['BC', 2, 2]^* and factor(s) ((1, 2), (1, 1), (2, 1))
1606
+ sage: RC.cardinality()
1607
+ 750
1608
+ sage: RC.virtual
1609
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((1, 2), (3, 2), (1, 1), (3, 1), (2, 1), (2, 1))
1610
+ sage: RC = RiggedConfigurations(CartanType(['A',2,2]).dual(), [[1,1]])
1611
+ sage: RC.cardinality()
1612
+ 3
1613
+ sage: RC = RiggedConfigurations(CartanType(['A',2,2]).dual(), [[1,2],[1,1]])
1614
+ sage: TestSuite(RC).run() # long time
1615
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[2,1]])
1616
+ sage: TestSuite(RC).run() # long time
1617
+ """
1618
+
1619
+ def _calc_vacancy_number(self, partitions, a, i, **options):
1620
+ r"""
1621
+ Calculate the vacancy number `p_i^{(a)}` in ``self``. A special case
1622
+ is needed for the `n`-th partition for type `A_{2n}^{(2)\dagger}`.
1623
+
1624
+ INPUT:
1625
+
1626
+ - ``partitions`` -- the list of rigged partitions we are using
1627
+
1628
+ - ``a`` -- the rigged partition index
1629
+
1630
+ - ``i`` -- the row length
1631
+
1632
+ TESTS::
1633
+
1634
+ sage: RC = RiggedConfigurations(CartanType(['A', 6, 2]).dual(), [[2,1]])
1635
+ sage: elt = RC(partition_list=[[1], [2], [2]])
1636
+ sage: RC._calc_vacancy_number(elt.nu(), 0, 1)
1637
+ -1
1638
+ """
1639
+ if a != len(self._rc_index) - 1:
1640
+ return RCTypeA2Even._calc_vacancy_number(self, partitions, a, i, **options)
1641
+
1642
+ vac_num = 0
1643
+ if "B" in options:
1644
+ for tab in options["B"]:
1645
+ if len(tab) == self._rc_index[a]:
1646
+ vac_num += min(i, len(tab[0]))
1647
+ elif "L" in options:
1648
+ L = options["L"]
1649
+ if a in L:
1650
+ for kvp in L[a].items():
1651
+ vac_num += min(kvp[0], i) * kvp[1]
1652
+ elif "dims" in options:
1653
+ for dim in options["dims"]:
1654
+ if dim[0] == self._rc_index[a]:
1655
+ vac_num += min(dim[1], i)
1656
+ else:
1657
+ for dim in self.dims:
1658
+ if dim[0] == self._rc_index[a]:
1659
+ vac_num += min(dim[1], i)
1660
+
1661
+ if i == float('inf'):
1662
+ vac_num -= sum(self._cartan_matrix[a,b] * sum(nu) / 2
1663
+ for b,nu in enumerate(partitions))
1664
+ else:
1665
+ vac_num -= sum(self._cartan_matrix[a,b] * nu.get_num_cells_to_column(i) / 2
1666
+ for b,nu in enumerate(partitions))
1667
+
1668
+ return vac_num
1669
+
1670
+ @lazy_attribute
1671
+ def module_generators(self):
1672
+ r"""
1673
+ Module generators for rigged configurations of type
1674
+ `A_{2n}^{(2)\dagger}`.
1675
+
1676
+ Iterate over the highest weight rigged configurations by moving
1677
+ through the
1678
+ :class:`~sage.combinat.rigged_configurations.kleber_tree.KleberTree`
1679
+ and then setting appropriate values of the partitions. This also
1680
+ skips rigged configurations where `P_i^{(n)} < 1` when `i` is odd.
1681
+
1682
+ EXAMPLES::
1683
+
1684
+ sage: RC = RiggedConfigurations(CartanType(['A', 4, 2]).dual(), [[1,1]])
1685
+ sage: for x in RC.module_generators: x
1686
+ <BLANKLINE>
1687
+ (/)
1688
+ <BLANKLINE>
1689
+ (/)
1690
+ <BLANKLINE>
1691
+ """
1692
+ module_gens = []
1693
+ # This is for the non-simply-laced types
1694
+ vec_len = len(self.kleber_tree().root.up_root.to_vector())
1695
+
1696
+ for tree_node in self.kleber_tree():
1697
+ shapes = []
1698
+ cur = tree_node
1699
+ path_lambda = [cur.up_root.to_vector()] # Build the lambda values
1700
+ # Note that these are not same lambda as in the paper,
1701
+ # but a less computational version.
1702
+ while cur.parent_node is not None:
1703
+ path_lambda.insert(0, (cur.parent_node.up_root - cur.up_root).to_vector())
1704
+ cur = cur.parent_node
1705
+
1706
+ for a in range(vec_len):
1707
+ shapes.append([])
1708
+ for i, cur_lambda in enumerate(path_lambda):
1709
+ for j in range(cur_lambda[a]):
1710
+ shapes[-1].insert(0, i)
1711
+
1712
+ # We are not simply-laced, so convert from the virtual rigged configuration
1713
+ sigma = self._folded_ct.folding_orbit()
1714
+ vindex = self.virtual._rc_index
1715
+ shapes = [shapes[vindex.index(sigma[a][0])] for a in self._rc_index]
1716
+ # Nothing more to do since gamma[i] == 1 for all i >= 1
1717
+
1718
+ # Start with a base to calculate the vacancy numbers
1719
+ # Make a copy just to be safe
1720
+ base = self.element_class(self, partition_list=shapes[:])
1721
+
1722
+ # Check the special condition of odd rows in the n-th partition
1723
+ invalid_RC = False
1724
+ for i in range(len(base[-1]._list)):
1725
+ if base[-1]._list[i] % 2 == 1 and base[-1].vacancy_numbers[i] < 1:
1726
+ invalid_RC = True
1727
+ break
1728
+ # If it is invalid, skip it
1729
+ if invalid_RC:
1730
+ continue
1731
+
1732
+ # Build out the blocks for the partition values
1733
+ vac_nums = []
1734
+ blocks = []
1735
+ L = []
1736
+
1737
+ for partition in base[:-1]:
1738
+ vac_nums.append(partition.vacancy_numbers)
1739
+ blocks.append([[]])
1740
+
1741
+ # If the partition is empty, there's nothing to do
1742
+ if len(partition) <= 0:
1743
+ L.append([[]])
1744
+ continue
1745
+
1746
+ # Setup the first block
1747
+ block_len = partition[0]
1748
+ for i, row_len in enumerate(partition):
1749
+ # If we've gone to a different sized block, then update the
1750
+ # values which change when moving to a new block size
1751
+ if block_len != row_len:
1752
+ blocks[-1].append([])
1753
+ block_len = row_len
1754
+
1755
+ blocks[-1][-1].append(partition.vacancy_numbers[i])
1756
+
1757
+ L2 = []
1758
+ for block in blocks[-1]:
1759
+ L2.append(IterableFunctionCall(self._block_iterator, block))
1760
+ L.append(itertools.product(*L2))
1761
+
1762
+ # Special case for the final tableau
1763
+ partition = base[-1]
1764
+ vac_nums.append(partition.vacancy_numbers)
1765
+
1766
+ # If the partition is empty, there's nothing to do
1767
+ if len(partition) <= 0:
1768
+ L.append([[]])
1769
+ else:
1770
+ # Setup the first block
1771
+ block_len = partition[0]
1772
+ blocks = [[]]
1773
+ odd_block = []
1774
+ for i, row_len in enumerate(partition):
1775
+ # If we've gone to a different sized block, then update the
1776
+ # values which change when moving to a new block size
1777
+ if block_len != row_len:
1778
+ blocks.append([])
1779
+ odd_block.append(block_len % 2 == 1)
1780
+ block_len = row_len
1781
+
1782
+ blocks[-1].append(partition.vacancy_numbers[i])
1783
+ odd_block.append(block_len % 2 == 1)
1784
+
1785
+ L2 = []
1786
+ for i, block in enumerate(blocks):
1787
+ if odd_block[i]:
1788
+ L2.append(IterableFunctionCall(self._block_iterator_n_odd, block))
1789
+ else:
1790
+ L2.append(IterableFunctionCall(self._block_iterator, block))
1791
+ L.append(itertools.product(*L2))
1792
+
1793
+ C = itertools.product(*L)
1794
+ for curBlocks in C:
1795
+ module_gens.append( self.element_class(self, KT_constructor=[shapes[:],
1796
+ self._blocks_to_values(curBlocks[:]), vac_nums[:]]) )
1797
+
1798
+ return tuple(module_gens)
1799
+
1800
+ def _block_iterator_n_odd(self, container):
1801
+ r"""
1802
+ Iterate over all possible riggings for a block of odd length in the
1803
+ `n`-th rigged partition for type `A_{2n}^{(2)\dagger}`.
1804
+
1805
+ Helper iterator which iterates over all possible partitions of
1806
+ `\frac{2k+1}{2}` sizes contained within the container.
1807
+
1808
+ INPUT:
1809
+
1810
+ - ``container`` -- list the widths of the rows of the container
1811
+
1812
+ TESTS::
1813
+
1814
+ sage: RC = RiggedConfigurations(CartanType(['A', 4, 2]).dual(), [[2, 2]])
1815
+ sage: for x in RC._block_iterator_n_odd([]): x
1816
+ []
1817
+ sage: for x in RC._block_iterator_n_odd([2,2]): x
1818
+ [1/2, 1/2]
1819
+ [3/2, 1/2]
1820
+ [3/2, 3/2]
1821
+ """
1822
+ if len(container) == 0:
1823
+ yield []
1824
+ return
1825
+
1826
+ pos = 0
1827
+ length = len(container)
1828
+ ret_part = [-1] * length
1829
+ while pos >= 0:
1830
+ ret_part[pos] += 2
1831
+
1832
+ if ret_part[pos] > container[pos]*2 or (pos != 0 and ret_part[pos] > ret_part[pos - 1]):
1833
+ ret_part[pos] = -1
1834
+ pos -= 1
1835
+ else:
1836
+ pos += 1
1837
+
1838
+ if pos == length:
1839
+ yield [QQ(n) / QQ(2) for n in ret_part]
1840
+ pos -= 1
1841
+
1842
+ def to_virtual(self, rc):
1843
+ """
1844
+ Convert ``rc`` into a rigged configuration in the virtual crystal.
1845
+
1846
+ INPUT:
1847
+
1848
+ - ``rc`` -- a rigged configuration element
1849
+
1850
+ EXAMPLES::
1851
+
1852
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[2,2]])
1853
+ sage: elt = RC(partition_list=[[1],[1]]); elt
1854
+ <BLANKLINE>
1855
+ -1[ ]-1
1856
+ <BLANKLINE>
1857
+ 1[ ]1
1858
+ <BLANKLINE>
1859
+ sage: velt = RC.to_virtual(elt); velt
1860
+ <BLANKLINE>
1861
+ -1[ ]-1
1862
+ <BLANKLINE>
1863
+ 2[ ]2
1864
+ <BLANKLINE>
1865
+ -1[ ]-1
1866
+ <BLANKLINE>
1867
+ sage: velt.parent()
1868
+ Rigged configurations of type ['A', 3, 1] and factor(s) ((2, 2), (2, 2))
1869
+ """
1870
+ gammatilde = list(self._folded_ct.scaling_factors())
1871
+ gammatilde[-1] = 2
1872
+ sigma = self._folded_ct.folding_orbit()
1873
+ n = len(self.virtual._rc_index)
1874
+ partitions = [None] * n
1875
+ for a,rp in enumerate(rc):
1876
+ g = gammatilde[a+1]
1877
+ for i in sigma[a+1]:
1878
+ partitions[i-1] = RiggedPartition(list(rp._list),
1879
+ [rig_val*g for rig_val in rp.rigging])
1880
+ return self.virtual.element_class(self.virtual, partitions)
1881
+
1882
+ def from_virtual(self, vrc):
1883
+ """
1884
+ Convert ``vrc`` in the virtual crystal into a rigged configuration of
1885
+ the original Cartan type.
1886
+
1887
+ INPUT:
1888
+
1889
+ - ``vrc`` -- a virtual rigged configuration element
1890
+
1891
+ EXAMPLES::
1892
+
1893
+ sage: RC = RiggedConfigurations(CartanType(['A',4,2]).dual(), [[2,2]])
1894
+ sage: elt = RC(partition_list=[[1],[1]])
1895
+ sage: velt = RC.to_virtual(elt)
1896
+ sage: ret = RC.from_virtual(velt); ret
1897
+ <BLANKLINE>
1898
+ -1[ ]-1
1899
+ <BLANKLINE>
1900
+ 1[ ]1
1901
+ <BLANKLINE>
1902
+ sage: ret == elt
1903
+ True
1904
+ """
1905
+ gammatilde = list(self._folded_ct.scaling_factors())
1906
+ gammatilde[-1] = QQ(2)
1907
+ sigma = self._folded_ct.folding_orbit()
1908
+ n = len(self._rc_index)
1909
+ partitions = [None] * n
1910
+ # +/- 1 for indexing
1911
+ for a in range(n):
1912
+ rp = vrc[sigma[a+1][0] - 1]
1913
+ g = gammatilde[a+1]
1914
+ partitions[a] = RiggedPartition(list(rp._list),
1915
+ [rig_val/g for rig_val in rp.rigging])
1916
+ return self.element_class(self, partitions)
1917
+
1918
+ Element = KRRCTypeA2DualElement