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,959 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.libs.singular sage.modules
3
+ r"""
4
+ Quantum Clifford Algebras
5
+
6
+ AUTHORS:
7
+
8
+ - Travis Scrimshaw (2021-05): initial version
9
+ """
10
+
11
+ #*****************************************************************************
12
+ # Copyright (C) 2021 Travis Scrimshaw <tcscrims at gmail.com>
13
+ #
14
+ # This program is free software: you can redistribute it and/or modify
15
+ # it under the terms of the GNU General Public License as published by
16
+ # the Free Software Foundation, either version 2 of the License, or
17
+ # (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ #*****************************************************************************
20
+
21
+ from sage.misc.cachefunc import cached_method
22
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
23
+ from sage.rings.integer_ring import ZZ
24
+ from sage.categories.algebras import Algebras
25
+ from sage.categories.fields import Fields
26
+ from sage.combinat.free_module import CombinatorialFreeModule
27
+ from sage.categories.cartesian_product import cartesian_product
28
+ from sage.sets.family import Family
29
+ from sage.rings.fraction_field import FractionField
30
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
31
+ from itertools import product
32
+ from sage.combinat.subset import powerset
33
+
34
+
35
+ class QuantumCliffordAlgebra(CombinatorialFreeModule):
36
+ r"""
37
+ The quantum Clifford algebra.
38
+
39
+ The *quantum Clifford algebra*, or `q`-Clifford algebra,
40
+ of rank `n` and twist `k` is the unital associative algebra
41
+ `\mathrm{Cl}_{q}(n, k)` over a field `F` with generators
42
+ `\psi_a, \psi_a^*, \omega_a` for `a = 1, \ldots, n` that
43
+ satisfy the following relations:
44
+
45
+ .. MATH::
46
+
47
+ \begin{aligned}
48
+ \omega_a \omega_b & = \omega_b \omega_a,
49
+ & \omega_a^{4k} & = (1 + q^{-2k}) \omega_a^{2k} - q^{-2k},
50
+ \\ \omega_a \psi_b & = q^{\delta_{ab}} \psi_b \omega_a,
51
+ & \omega_a \psi^*_b & = \psi^*_b \omega_a,
52
+ \\ \psi_a \psi_b & + \psi_b \psi_a = 0,
53
+ & \psi^*_a \psi^*_b & + \psi^*_b \psi^*_a = 0,
54
+ \\ \psi_a \psi^*_a & + q^k \psi^*_a \psi_a = \omega_a^{-k},
55
+ & \psi^*_a \psi_a & + q^{-k} \psi^*_a \psi_a = \omega_a^k,
56
+ \\ \psi_a \psi^*_b & + \psi_b^* \psi_a = 0
57
+ & & \text{if } a \neq b.
58
+ \end{aligned}
59
+
60
+ When `k = 2`, we recover the original definition given by Hayashi in
61
+ [Hayashi1990]_. The `k = 1` version was used in [Kwon2014]_.
62
+
63
+ INPUT:
64
+
65
+ - ``n`` -- positive integer; the rank
66
+ - ``k`` -- positive integer (default: 1); the twist
67
+ - ``q`` -- (optional) the parameter `q`
68
+ - ``F`` -- (default: `\QQ(q)`) the base field that contains ``q``
69
+
70
+ EXAMPLES:
71
+
72
+ We construct the rank 3 and twist 1 `q`-Clifford algebra::
73
+
74
+ sage: Cl = algebras.QuantumClifford(3)
75
+ sage: Cl
76
+ Quantum Clifford algebra of rank 3 and twist 1 with q=q over
77
+ Fraction Field of Univariate Polynomial Ring in q over Integer Ring
78
+ sage: q = Cl.q()
79
+
80
+ Some sample computations::
81
+
82
+ sage: p0, p1, p2, d0, d1, d2, w0, w1, w2 = Cl.gens()
83
+ sage: p0 * p1
84
+ psi0*psi1
85
+ sage: p1 * p0
86
+ -psi0*psi1
87
+ sage: p0 * w0 * p1 * d0 * w2
88
+ (1/(q^3-q))*psi1*w2 + (-q/(q^2-1))*psi1*w0^2*w2
89
+ sage: w0^4
90
+ -1/q^2 + ((q^2+1)/q^2)*w0^2
91
+
92
+ We construct the homomorphism from `U_q(\mathfrak{sl}_3)` to
93
+ `\mathrm{Cl}(3, 1)` given in (3.17) of [Hayashi1990]_::
94
+
95
+ sage: e1 = p0*d1; e2 = p1*d2
96
+ sage: f1 = p1*d0; f2 = p2*d1
97
+ sage: k1 = w0*~w1; k2 = w1*~w2
98
+ sage: k1i = w1*~w0; k2i = w2*~w1
99
+ sage: (e1, e2, f1, f2, k1, k2, k1i, k2i)
100
+ (psi0*psid1, psi1*psid2,
101
+ -psid0*psi1, -psid1*psi2,
102
+ (q^2+1)*w0*w1 - q^2*w0*w1^3, (q^2+1)*w1*w2 - q^2*w1*w2^3,
103
+ (q^2+1)*w0*w1 - q^2*w0^3*w1, (q^2+1)*w1*w2 - q^2*w1^3*w2)
104
+
105
+ We check that `k_i` and `k_i^{-1}` are inverses::
106
+
107
+ sage: k1 * k1i
108
+ 1
109
+ sage: k2 * k2i
110
+ 1
111
+
112
+ The relations between `e_i`, `f_i`, and `k_i`::
113
+
114
+ sage: k1 * f1 == q^-2 * f1 * k1
115
+ True
116
+ sage: k2 * f1 == q^1 * f1 * k2
117
+ True
118
+ sage: k2 * e1 == q^-1 * e1 * k2
119
+ True
120
+ sage: k1 * e1 == q^2 * e1 * k1
121
+ True
122
+ sage: e1 * f1 - f1 * e1 == (k1 - k1i)/(q-q^-1)
123
+ True
124
+ sage: e2 * f1 - f1 * e2
125
+ 0
126
+
127
+ The `q`-Serre relations::
128
+
129
+ sage: e1 * e1 * e2 - (q^1 + q^-1) * e1 * e2 * e1 + e2 * e1 * e1
130
+ 0
131
+ sage: f1 * f1 * f2 - (q^1 + q^-1) * f1 * f2 * f1 + f2 * f1 * f1
132
+ 0
133
+
134
+ This also can be constructed at the special point when `q^{2k} = 1`,
135
+ but the basis used is different::
136
+
137
+ sage: Cl = algebras.QuantumClifford(1, 1, -1)
138
+ sage: Cl.inject_variables()
139
+ Defining psi0, psid0, w0
140
+ sage: psi0 * psid0
141
+ psi0*psid0
142
+ sage: psid0 * psi0
143
+ -w0 + psi0*psid0
144
+ sage: w0^2
145
+ 1
146
+ """
147
+ @staticmethod
148
+ def __classcall_private__(cls, n, k=1, q=None, F=None):
149
+ r"""
150
+ Standardize input to ensure a unique representation.
151
+
152
+ TESTS::
153
+
154
+ sage: Cl1 = algebras.QuantumClifford(3)
155
+ sage: q = PolynomialRing(ZZ, 'q').fraction_field().gen()
156
+ sage: Cl2 = algebras.QuantumClifford(3, q=q)
157
+ sage: Cl3 = algebras.QuantumClifford(3, 1, q, q.parent())
158
+ sage: Cl1 is Cl2 and Cl2 is Cl3
159
+ True
160
+ """
161
+ if q is None:
162
+ q = PolynomialRing(ZZ, 'q').fraction_field().gen()
163
+ if F is None:
164
+ F = q.parent()
165
+ q = F(q)
166
+ if F not in Fields():
167
+ F = FractionField(F)
168
+ q = F(q)
169
+
170
+ if bool(q**(2*k) == 1):
171
+ return QuantumCliffordAlgebraRootUnity(n, k, q, F)
172
+ return QuantumCliffordAlgebraGeneric(n, k, q, F)
173
+
174
+ def __init__(self, n, k, q, F, psi, indices):
175
+ r"""
176
+ Initialize ``self``.
177
+
178
+ EXAMPLES::
179
+
180
+ sage: Cl = algebras.QuantumClifford(1, 2)
181
+ sage: TestSuite(Cl).run(elements=Cl.basis())
182
+ """
183
+ self._n = n
184
+ self._k = k
185
+ self._q = q
186
+ self._w_poly = PolynomialRing(F, n, 'w')
187
+ self._psi = psi
188
+ indices = FiniteEnumeratedSet(indices)
189
+
190
+ cat = Algebras(F).FiniteDimensional().Semisimple().WithBasis()
191
+ CombinatorialFreeModule.__init__(self, F, indices, category=cat)
192
+ self._assign_names(self.algebra_generators().keys())
193
+
194
+ def _repr_(self):
195
+ r"""
196
+ Return a string representation of ``self``.
197
+
198
+ EXAMPLES::
199
+
200
+ sage: algebras.QuantumClifford(3)
201
+ Quantum Clifford algebra of rank 3 and twist 1 with q=q over
202
+ Fraction Field of Univariate Polynomial Ring in q over Integer Ring
203
+ """
204
+ return "Quantum Clifford algebra of rank {} and twist {} with q={} over {}".format(
205
+ self._n, self._k, self._q, self.base_ring())
206
+
207
+ def _latex_(self):
208
+ r"""
209
+ Return a latex representation of ``self``.
210
+
211
+ EXAMPLES::
212
+
213
+ sage: Cl = algebras.QuantumClifford(3)
214
+ sage: latex(Cl)
215
+ \operatorname{Cl}_{q}(3, 1)
216
+ """
217
+ return "\\operatorname{Cl}_{%s}(%s, %s)" % (self._q, self._n, self._k)
218
+
219
+ def q(self):
220
+ r"""
221
+ Return the `q` of ``self``.
222
+
223
+ EXAMPLES::
224
+
225
+ sage: Cl = algebras.QuantumClifford(3)
226
+ sage: Cl.q()
227
+ q
228
+
229
+ sage: Cl = algebras.QuantumClifford(3, q=QQ(-5))
230
+ sage: Cl.q()
231
+ -5
232
+ """
233
+ return self._q
234
+
235
+ def twist(self):
236
+ r"""
237
+ Return the twist `k` of ``self``.
238
+
239
+ EXAMPLES::
240
+
241
+ sage: Cl = algebras.QuantumClifford(3, 2)
242
+ sage: Cl.twist()
243
+ 2
244
+ """
245
+ return self._k
246
+
247
+ def rank(self):
248
+ r"""
249
+ Return the rank `k` of ``self``.
250
+
251
+ EXAMPLES::
252
+
253
+ sage: Cl = algebras.QuantumClifford(3, 2)
254
+ sage: Cl.rank()
255
+ 3
256
+ """
257
+ return self._n
258
+
259
+ def dimension(self):
260
+ r"""
261
+ Return the dimension of ``self``.
262
+
263
+ EXAMPLES::
264
+
265
+ sage: Cl = algebras.QuantumClifford(3)
266
+ sage: Cl.dimension()
267
+ 512
268
+
269
+ sage: Cl = algebras.QuantumClifford(4, 2) # long time
270
+ sage: Cl.dimension() # long time
271
+ 65536
272
+ """
273
+ return ZZ(8*self._k) ** self._n
274
+
275
+ @cached_method
276
+ def algebra_generators(self):
277
+ r"""
278
+ Return the algebra generators of ``self``.
279
+
280
+ EXAMPLES::
281
+
282
+ sage: Cl = algebras.QuantumClifford(3)
283
+ sage: Cl.algebra_generators()
284
+ Finite family {'psi0': psi0, 'psi1': psi1, 'psi2': psi2,
285
+ 'psid0': psid0, 'psid1': psid1, 'psid2': psid2,
286
+ 'w0': w0, 'w1': w1, 'w2': w2}
287
+ """
288
+ one = (0,) * self._n # one in the corresponding free abelian group
289
+ zero = [0] * self._n
290
+ d = {}
291
+ for i in range(self._n):
292
+ r = list(zero) # Make a copy
293
+ r[i] = 1
294
+ d['psi%s' % i] = self.monomial((self._psi(r), one))
295
+ r[i] = -1
296
+ d['psid%s' % i] = self.monomial((self._psi(r), one))
297
+ zero = self._psi(zero)
298
+ for i in range(self._n):
299
+ temp = list(zero) # Make a copy
300
+ temp[i] = 1
301
+ d['w%s' % i] = self.monomial((zero, tuple(temp)))
302
+ return Family(sorted(d), lambda i: d[i])
303
+
304
+ @cached_method
305
+ def gens(self) -> tuple:
306
+ r"""
307
+ Return the generators of ``self``.
308
+
309
+ EXAMPLES::
310
+
311
+ sage: Cl = algebras.QuantumClifford(3)
312
+ sage: Cl.gens()
313
+ (psi0, psi1, psi2, psid0, psid1, psid2, w0, w1, w2)
314
+ """
315
+ return tuple(self.algebra_generators())
316
+
317
+ @cached_method
318
+ def one_basis(self):
319
+ r"""
320
+ Return the index of the basis element of `1`.
321
+
322
+ EXAMPLES::
323
+
324
+ sage: Cl = algebras.QuantumClifford(3)
325
+ sage: Cl.one_basis()
326
+ ((0, 0, 0), (0, 0, 0))
327
+ """
328
+ return (self._psi([0]*self._n), (0,)*self._n)
329
+
330
+
331
+ class QuantumCliffordAlgebraGeneric(QuantumCliffordAlgebra):
332
+ r"""
333
+ The quantum Clifford algebra when `q^{2k} \neq 1`.
334
+
335
+ The *quantum Clifford algebra*, or `q`-Clifford algebra,
336
+ of rank `n` and twist `k` is the unital associative algebra
337
+ `\mathrm{Cl}_{q}(n, k)` over a field `F` with generators
338
+ `\psi_a, \psi_a^*, \omega_a` for `a = 1, \ldots, n` that
339
+ satisfy the following relations:
340
+
341
+ .. MATH::
342
+
343
+ \begin{aligned}
344
+ \omega_a \omega_b & = \omega_b \omega_a,
345
+ & \omega_a^{4k} & = (1 + q^{-2k}) \omega_a^{2k} - q^{-2k},
346
+ \\ \omega_a \psi_b & = q^{\delta_{ab}} \psi_b \omega_a,
347
+ & \omega_a \psi^*_b & = \psi^*_b \omega_a,
348
+ \\ \psi_a \psi_b & + \psi_b \psi_a = 0,
349
+ & \psi^*_a \psi^*_b & + \psi^*_b \psi^*_a = 0,
350
+ \\ \psi_a \psi^*_a & = \frac{q^k \omega_a^{3k} - q^{-k} \omega_a^k}{q^k - q^{-k}},
351
+ & \psi^*_a \psi_a & = \frac{q^{2k} (\omega_a - \omega_a^{3k})}{q^k - q^{-k}},
352
+ \\ \psi_a \psi^*_b & + \psi_b^* \psi_a = 0
353
+ & & \text{if } a \neq b,
354
+ \end{aligned}
355
+
356
+ where `q \in F` such that `q^{2k} \neq 1`.
357
+
358
+ When `k = 2`, we recover the original definition given by Hayashi in
359
+ [Hayashi1990]_. The `k = 1` version was used in [Kwon2014]_.
360
+ """
361
+ def __init__(self, n, k, q, F):
362
+ r"""
363
+ Initialize ``self``.
364
+
365
+ TESTS::
366
+
367
+ sage: Cl = algebras.QuantumClifford(1,3)
368
+ sage: TestSuite(Cl).run(elements=Cl.basis()) # long time
369
+
370
+ sage: Cl = algebras.QuantumClifford(3)
371
+ sage: elts = Cl.some_elements() + list(Cl.algebra_generators())
372
+ sage: TestSuite(Cl).run(elements=elts) # long time
373
+
374
+ sage: Cl = algebras.QuantumClifford(2, 4)
375
+ sage: elts = Cl.some_elements() + list(Cl.algebra_generators())
376
+ sage: TestSuite(Cl).run(elements=elts) # long time
377
+ """
378
+ psi = cartesian_product([(-1,0,1)]*n)
379
+ indices = [(tuple(p), tuple(w))
380
+ for p in psi
381
+ for w in product(*[list(range((4-2*abs(p[i]))*k)) for i in range(n)])]
382
+ super().__init__(n, k, q, F, psi, indices)
383
+
384
+ def _repr_term(self, m):
385
+ r"""
386
+ Return a string representation of the basis element indexed by ``m``.
387
+
388
+ EXAMPLES::
389
+
390
+ sage: Cl = algebras.QuantumClifford(3, 3)
391
+ sage: Cl._repr_term( ((1, 0, -1), (0, 2, 5)) )
392
+ 'psi0*psid2*w1^2*w2^5'
393
+ sage: Cl._repr_term( ((1, 0, -1), (0, 0, 0)) )
394
+ 'psi0*psid2'
395
+ sage: Cl._repr_term( ((0, 0, 0), (0, 2, 5)) )
396
+ 'w1^2*w2^5'
397
+ sage: Cl._repr_term( ((0, 0, 0), (0, 0, 0)) )
398
+ '1'
399
+
400
+ sage: Cl(5)
401
+ 5
402
+ """
403
+ p, v = m
404
+ rp = '*'.join('psi%s' % i if p[i] > 0 else 'psid%s' % i
405
+ for i in range(self._n) if p[i] != 0)
406
+ gen_str = lambda e: '' if e == 1 else '^%s' % e
407
+ rv = '*'.join('w%s' % i + gen_str(v[i]) for i in range(self._n) if v[i] != 0)
408
+ if rp:
409
+ if rv:
410
+ return rp + '*' + rv
411
+ return rp
412
+ if rv:
413
+ return rv
414
+ return '1'
415
+
416
+ def _latex_term(self, m):
417
+ r"""
418
+ Return a latex representation for the basis element indexed by ``m``.
419
+
420
+ EXAMPLES::
421
+
422
+ sage: Cl = algebras.QuantumClifford(3, 3)
423
+ sage: Cl._latex_term( ((1, 0, -1), (0, -2, 5)) )
424
+ '\\psi_{0}\\psi^{\\dagger}_{2}\\omega_{1}^{-2}\\omega_{2}^{5}'
425
+ sage: Cl._latex_term( ((1, 0, -1), (0, 0, 0)) )
426
+ '\\psi_{0}\\psi^{\\dagger}_{2}'
427
+ sage: Cl._latex_term( ((0, 0, 0), (0, -2, 5)) )
428
+ '\\omega_{1}^{-2}\\omega_{2}^{5}'
429
+ sage: Cl._latex_term( ((0, 0, 0), (0, 0, 0)) )
430
+ '1'
431
+
432
+ sage: latex(Cl(5))
433
+ 5
434
+ """
435
+ p, v = m
436
+ rp = ''.join('\\psi_{%s}' % i if p[i] > 0 else '\\psi^{\\dagger}_{%s}' % i
437
+ for i in range(self._n) if p[i] != 0)
438
+ gen_str = lambda e: '' if e == 1 else '^{%s}' % e
439
+ rv = ''.join('\\omega_{%s}' % i + gen_str(v[i])
440
+ for i in range(self._n) if v[i] != 0)
441
+ if not rp and not rv:
442
+ return '1'
443
+ return rp + rv
444
+
445
+ @cached_method
446
+ def product_on_basis(self, m1, m2):
447
+ r"""
448
+ Return the product of the basis elements indexed by ``m1`` and ``m2``.
449
+
450
+ EXAMPLES::
451
+
452
+ sage: Cl = algebras.QuantumClifford(3)
453
+ sage: Cl.inject_variables()
454
+ Defining psi0, psi1, psi2, psid0, psid1, psid2, w0, w1, w2
455
+ sage: psi0^2 # indirect doctest
456
+ 0
457
+ sage: psid0^2
458
+ 0
459
+ sage: w0 * psi0
460
+ q*psi0*w0
461
+ sage: w0 * psid0
462
+ 1/q*psid0*w0
463
+ sage: w2 * w0
464
+ w0*w2
465
+ sage: w0^4
466
+ -1/q^2 + ((q^2+1)/q^2)*w0^2
467
+ """
468
+ p1, w1 = m1
469
+ p2, w2 = m2
470
+
471
+ # Check for \psi_i^2 == 0 and for the dagger version
472
+ if any(p1[i] != 0 and p1[i] == p2[i] for i in range(self._n)):
473
+ return self.zero()
474
+
475
+ # \psi_i is represented by a 1 in p1[i] and p2[i]
476
+ # \psi_i^{\dagger} is represented by a -1 in p1[i] and p2[i]
477
+
478
+ k = self._k
479
+ q_power = 0
480
+ sign = 1
481
+ pairings = []
482
+ supported = []
483
+ p = [0] * self._n
484
+ # Move w1 * p2 to q^q_power * p2 * w1
485
+ # Also find pairs \psi_i \psi_i^{\dagger} (or vice versa)
486
+ for i in range(self._n):
487
+ if p2[i] != 0:
488
+ supported.append(i)
489
+ q_power += w1[i] * p2[i]
490
+ if p1[i] != 0:
491
+ # We make pairings 1-based because we cannot distinguish 0 and -0
492
+ pairings.append((i+1) * p1[i])
493
+ # we know p1[i] != p2[i] if nonzero, so their sum is -1, 0, 1
494
+ p[i] = p1[i] + p2[i]
495
+
496
+ supported.append(self._n-1) # To get between the last support and the end
497
+ # Get the sign of moving \psi_i and \psi_i^{\dagger} into position
498
+ for i in reversed(range(1, len(supported))):
499
+ if i % 2 != 0:
500
+ for j in reversed(range(supported[i-1]+1, supported[i]+1)):
501
+ if p1[j] != 0:
502
+ sign = (-1)**i * sign
503
+
504
+ # We move the pairs \psi_i \psi_i^{\dagger} (or the reverse) to the
505
+ # end of the \psi part. This does not change the sign because they
506
+ # move in pairs.
507
+ # We take the products.
508
+ vp = self._w_poly.gens()
509
+ poly = self._w_poly.one()
510
+ q = self._q
511
+ for i in pairings:
512
+ if i < 0:
513
+ i = -i - 1 # Go back to 0-based
514
+ vpik = -q**(2*k) * vp[i]**(3*k) + (1 + q**(2*k)) * vp[i]**k
515
+ poly *= -(vp[i]**k - vpik) / (q**k - q**(-k))
516
+ else:
517
+ i -= 1 # Go back to 0-based
518
+ vpik = -q**(2*k) * vp[i]**(3*k) + (1 + q**(2*k)) * vp[i]**k
519
+ poly *= (q**k * vp[i]**k - q**(-k) * vpik) / (q**k - q**(-k))
520
+
521
+ v = list(w1)
522
+ for i in range(self._n):
523
+ v[i] += w2[i]
524
+
525
+ # For all \psi_i v_i^k, convert this to either k = 0, 1
526
+ # and same for \psi_i^{\dagger}
527
+ for i in range(self._n):
528
+ if p[i] > 0 and v[i] != 0:
529
+ q_power -= 2 * k * (v[i] // (2*k))
530
+ v[i] = v[i] % (2*k)
531
+ if p[i] < 0 and v[i] != 0:
532
+ v[i] = v[i] % (2*k)
533
+
534
+ poly *= self._w_poly.monomial(*v)
535
+ poly = poly.reduce([vp[i]**(4*k) - (1 + q**(-2*k)) * vp[i]**(2*k) + q**(-2*k)
536
+ for i in range(self._n)])
537
+ pdict = poly.monomial_coefficients()
538
+ ret = {(self._psi(p), tuple(e)): pdict[e] * q**q_power * sign
539
+ for e in pdict}
540
+
541
+ return self._from_dict(ret)
542
+
543
+ class Element(CombinatorialFreeModule.Element):
544
+ def inverse(self):
545
+ r"""
546
+ Return the inverse if ``self`` is a basis element.
547
+
548
+ EXAMPLES::
549
+
550
+ sage: Cl = algebras.QuantumClifford(2)
551
+ sage: Cl.inject_variables()
552
+ Defining psi0, psi1, psid0, psid1, w0, w1
553
+ sage: w0^-1
554
+ (q^2+1)*w0 - q^2*w0^3
555
+ sage: w0^-1 * w0
556
+ 1
557
+ sage: w0^-2
558
+ (q^2+1) - q^2*w0^2
559
+ sage: w0^-2 * w0^2
560
+ 1
561
+ sage: w0^-2 * w0 == w0^-1
562
+ True
563
+ sage: w = w0 * w1
564
+ sage: w^-1
565
+ (q^4+2*q^2+1)*w0*w1 + (-q^4-q^2)*w0*w1^3
566
+ + (-q^4-q^2)*w0^3*w1 + q^4*w0^3*w1^3
567
+ sage: w^-1 * w
568
+ 1
569
+ sage: w * w^-1
570
+ 1
571
+
572
+ sage: (2*w0)^-1
573
+ ((q^2+1)/2)*w0 - q^2/2*w0^3
574
+
575
+ sage: (w0 + w1)^-1
576
+ Traceback (most recent call last):
577
+ ...
578
+ ValueError: cannot invert self (= w1 + w0)
579
+ sage: (psi0 * w0)^-1
580
+ Traceback (most recent call last):
581
+ ...
582
+ ValueError: cannot invert self (= psi0*w0)
583
+
584
+ sage: Cl = algebras.QuantumClifford(1, 2)
585
+ sage: Cl.inject_variables()
586
+ Defining psi0, psid0, w0
587
+ sage: (psi0 + psid0).inverse()
588
+ psid0*w0^2 + q^2*psi0*w0^2
589
+
590
+ sage: Cl = algebras.QuantumClifford(2, 2)
591
+ sage: Cl.inject_variables()
592
+ Defining psi0, psi1, psid0, psid1, w0, w1
593
+ sage: w0^-1
594
+ (q^4+1)*w0^3 - q^4*w0^7
595
+ sage: w0 * w0^-1
596
+ 1
597
+ """
598
+ if not self:
599
+ raise ZeroDivisionError
600
+ if len(self) != 1:
601
+ return super().__invert__()
602
+ Cl = self.parent()
603
+ ((p, w), coeff), = list(self._monomial_coefficients.items())
604
+ if any(p[i] != 0 for i in range(Cl._n)):
605
+ return super().__invert__()
606
+ poly = Cl._w_poly.monomial(*w)
607
+ wp = Cl._w_poly.gens()
608
+ q = Cl._q
609
+ k = Cl._k
610
+ poly = poly.subs({wi: -q**(2*k) * wi**(4*k-1) + (1 + q**(2*k)) * wi**(2*k-1)
611
+ for wi in wp})
612
+ poly = poly.reduce([wi**(4*k) - (1 + q**(-2*k)) * wi**(2*k) + q**(-2*k)
613
+ for wi in wp])
614
+ pdict = poly.monomial_coefficients()
615
+ coeff = coeff.inverse_of_unit()
616
+ ret = {(p, tuple(e)): coeff * c for e, c in pdict.items()}
617
+ return Cl.element_class(Cl, ret)
618
+
619
+ __invert__ = inverse
620
+
621
+
622
+ class QuantumCliffordAlgebraRootUnity(QuantumCliffordAlgebra):
623
+ r"""
624
+ The quantum Clifford algebra when `q^{2k} = 1`.
625
+
626
+ The *quantum Clifford algebra*, or `q`-Clifford algebra,
627
+ of rank `n` and twist `k` is the unital associative algebra
628
+ `\mathrm{Cl}_{q}(n, k)` over a field `F` with generators
629
+ `\psi_a, \psi_a^*, \omega_a` for `a = 1, \ldots, n` that
630
+ satisfy the following relations:
631
+
632
+ .. MATH::
633
+
634
+ \begin{aligned}
635
+ \omega_a \omega_b & = \omega_b \omega_a,
636
+ & \omega_a^{2k} & = 1,
637
+ \\ \omega_a \psi_b & = q^{\delta_{ab}} \psi_b \omega_a,
638
+ & \omega_a \psi^*_b & = \psi^*_b \omega_a,
639
+ \\ \psi_a \psi_b & + \psi_b \psi_a = 0,
640
+ & \psi^*_a \psi^*_b & + \psi^*_b \psi^*_a = 0,
641
+ \\ \psi_a \psi^*_a & + q^k \psi^*_a \psi_a = \omega_a^k
642
+ & \psi_a \psi^*_b & + \psi_b^* \psi_a = 0 \quad (a \neq b),
643
+ \end{aligned}
644
+
645
+ where `q \in F` such that `q^{2k} = 1`. This has further relations of
646
+
647
+ .. MATH::
648
+
649
+ \begin{aligned}
650
+ \psi^*_a \psi_a \psi^*_a & = \psi^*_a \omega_a^k,
651
+ \\
652
+ \psi_a \psi^*_a \psi_a & = q^k \psi_a \omega_a^k,
653
+ \\
654
+ (\psi_a \psi^*_a)^2 & = \psi_a \psi^*_a \omega_a^k.
655
+ \end{aligned}
656
+ """
657
+ def __init__(self, n, k, q, F):
658
+ r"""
659
+ Initialize ``self``.
660
+
661
+ EXAMPLES::
662
+
663
+ sage: Cl = algebras.QuantumClifford(1,2,-1)
664
+ sage: TestSuite(Cl).run(elements=Cl.basis())
665
+
666
+ sage: z = CyclotomicField(3).gen()
667
+ sage: Cl = algebras.QuantumClifford(1,3,z)
668
+ sage: TestSuite(Cl).run(elements=Cl.basis())
669
+
670
+ sage: Cl = algebras.QuantumClifford(3,1,-1)
671
+ sage: elts = Cl.some_elements() + list(Cl.algebra_generators())
672
+ sage: TestSuite(Cl).run(elements=elts) # long time
673
+
674
+ sage: Cl = algebras.QuantumClifford(2,4,-1)
675
+ sage: elts = Cl.some_elements() + list(Cl.algebra_generators())
676
+ sage: TestSuite(Cl).run(elements=elts) # long time
677
+ """
678
+ psi = cartesian_product([(-1,0,1,2)]*n)
679
+ indices = [(tuple(p), tuple(w))
680
+ for p in psi
681
+ for w in product(list(range(2*k)), repeat=n)]
682
+ super().__init__(n, k, q, F, psi, indices)
683
+
684
+ def _repr_term(self, m):
685
+ r"""
686
+ Return a string representation of the basis element indexed by ``m``.
687
+
688
+ EXAMPLES::
689
+
690
+ sage: Cl = algebras.QuantumClifford(3, 3, -1)
691
+ sage: Cl._repr_term( ((1, 0, -1), (0, 2, 5)) )
692
+ 'psi0*psid2*w1^2*w2^5'
693
+ sage: Cl._repr_term( ((1, 0, 2), (0, 0, 0)) )
694
+ 'psi0*psi2*psid2'
695
+ sage: Cl._repr_term( ((0, 0, 0), (0, 2, 5)) )
696
+ 'w1^2*w2^5'
697
+ sage: Cl._repr_term( ((0, 0, 0), (0, 0, 0)) )
698
+ '1'
699
+
700
+ sage: Cl(5)
701
+ 5
702
+ """
703
+ p, v = m
704
+
705
+ def ppr(i):
706
+ val = p[i]
707
+ if val == -1:
708
+ return 'psid%s' % i
709
+ elif val == 1:
710
+ return 'psi%s' % i
711
+ elif val == 2:
712
+ return 'psi%s*psid%s' % (i,i)
713
+
714
+ rp = '*'.join(ppr(i) for i in range(self._n) if p[i] != 0)
715
+ gen_str = lambda e: '' if e == 1 else '^%s' % e
716
+ rv = '*'.join('w%s' % i + gen_str(v[i]) for i in range(self._n) if v[i] != 0)
717
+ if rp:
718
+ if rv:
719
+ return rp + '*' + rv
720
+ return rp
721
+ if rv:
722
+ return rv
723
+ return '1'
724
+
725
+ def _latex_term(self, m):
726
+ r"""
727
+ Return a latex representation for the basis element indexed by ``m``.
728
+
729
+ EXAMPLES::
730
+
731
+ sage: Cl = algebras.QuantumClifford(3, 3, -1)
732
+ sage: Cl._latex_term( ((1, 0, -1), (0, 2, 5)) )
733
+ '\\psi_{0}\\psi^{\\dagger}_{2}\\omega_{1}^{2}\\omega_{2}^{5}'
734
+ sage: Cl._latex_term( ((1, 0, 2), (0, 0, 0)) )
735
+ '\\psi_{0}\\psi_{2}\\psi^{\\dagger}_{2}'
736
+ sage: Cl._latex_term( ((0, 0, 0), (0, 2, 5)) )
737
+ '\\omega_{1}^{2}\\omega_{2}^{5}'
738
+ sage: Cl._latex_term( ((0, 0, 0), (0, 0, 0)) )
739
+ '1'
740
+
741
+ sage: latex(Cl(5))
742
+ 5
743
+ """
744
+ p, v = m
745
+
746
+ def ppr(i):
747
+ val = p[i]
748
+ if val == -1:
749
+ return '\\psi^{\\dagger}_{%s}' % i
750
+ elif val == 1:
751
+ return '\\psi_{%s}' % i
752
+ elif val == 2:
753
+ return '\\psi_{%s}\\psi^{\\dagger}_{%s}' % (i, i)
754
+
755
+ rp = ''.join(ppr(i) for i in range(self._n) if p[i] != 0)
756
+ gen_str = lambda e: '' if e == 1 else '^{%s}' % e
757
+ rv = ''.join('\\omega_{%s}' % i + gen_str(v[i])
758
+ for i in range(self._n) if v[i] != 0)
759
+ if not rp and not rv:
760
+ return '1'
761
+ return rp + rv
762
+
763
+ @cached_method
764
+ def product_on_basis(self, m1, m2):
765
+ r"""
766
+ Return the product of the basis elements indexed by ``m1`` and ``m2``.
767
+
768
+ EXAMPLES::
769
+
770
+ sage: z = CyclotomicField(3).gen()
771
+ sage: Cl = algebras.QuantumClifford(3, 3, z)
772
+ sage: Cl.inject_variables()
773
+ Defining psi0, psi1, psi2, psid0, psid1, psid2, w0, w1, w2
774
+ sage: psi0^2 # indirect doctest
775
+ 0
776
+ sage: psid0^2
777
+ 0
778
+ sage: w0 * psi0
779
+ -(-zeta3)*psi0*w0
780
+ sage: w0 * psid0
781
+ -(zeta3+1)*psid0*w0
782
+ sage: psi0 * psid0
783
+ psi0*psid0
784
+ sage: psid0 * psi0
785
+ w0^3 - psi0*psid0
786
+ sage: w2 * w0
787
+ w0*w2
788
+ sage: w0^6
789
+ 1
790
+ sage: psi0 * psi1
791
+ psi0*psi1
792
+ sage: psi1 * psi0
793
+ -psi0*psi1
794
+ sage: psi1 * (psi0 * psi2)
795
+ -psi0*psi1*psi2
796
+
797
+ sage: z = CyclotomicField(6).gen()
798
+ sage: Cl = algebras.QuantumClifford(3, 3, z)
799
+ sage: Cl.inject_variables()
800
+ Defining psi0, psi1, psi2, psid0, psid1, psid2, w0, w1, w2
801
+
802
+ sage: psid1 * (psi1 * psid1)
803
+ psid1*w1^3
804
+ sage: (psi1* psid1) * (psi1 * psid1)
805
+ psi1*psid1*w1^3
806
+ sage: (psi1 * psid1) * psi1
807
+ -psi1*w1^3
808
+ """
809
+ p1, w1 = m1
810
+ p2, w2 = m2
811
+ k = self._k
812
+ tk = 2 * k
813
+
814
+ # \psi_i is represented by a 1 in p1[i] and p2[i]
815
+ # \psi_i^{\dagger} is represented by a -1 in p1[i] and p2[i]
816
+ # \psi_i \psi_i^{\dagger} is a 2 in p1[i] and p2[i]
817
+
818
+ # Check for \psi_i^2 == 0 and for the dagger version
819
+ if any((p1[i] % 2 != 0 and p1[i] == p2[i])
820
+ or (p1[i] == 2 and p2[i] == -1) or (p2[i] == 2 and p1[i] == 1)
821
+ for i in range(self._n)):
822
+ return self.zero()
823
+
824
+ # Reduce any v_i^{2k} = 1
825
+ v = [(w1[i] + w2[i]) % tk for i in range(self._n)]
826
+
827
+ q_power = 0
828
+ sign = 1
829
+ pairings = []
830
+ p = [0] * self._n
831
+ # Move w1 * p2 to q^q_power * p2 * w1
832
+ # Also find pairs \psi_i \psi_i^{\dagger} (or vice versa) and
833
+ # count the sign from moving \psi_i and \psi_i^{\dagger} into position
834
+ num_cross = 0
835
+ total_cross = 0
836
+ for i in range(self._n):
837
+ num_cross += p2[i]
838
+ if p2[i] == 2:
839
+ # By the above check, we cannot have p1[i] == 1
840
+ if p1[i] != 0:
841
+ v[i] = (v[i] + k) % tk
842
+ p[i] = p1[i]
843
+ else:
844
+ p[i] = p2[i]
845
+ elif p2[i] != 0: # == +1, -1
846
+ q_power += w1[i] * p2[i]
847
+ # By the above check, we cannot have p1[i] == p2[i]
848
+ if p1[i] == -1:
849
+ pairings.append(i)
850
+ total_cross -= 1 # correction
851
+ p[i] = None
852
+ elif p1[i] == 1:
853
+ total_cross -= 1 # correction
854
+ p[i] = 2
855
+ elif p1[i] == 2:
856
+ q_power += k
857
+ v[i] = (v[i] + k) % tk
858
+ p[i] = p2[i]
859
+ else:
860
+ p[i] = p2[i]
861
+ else:
862
+ p[i] = p1[i] # since p2[i] == 0
863
+
864
+ if abs(p1[i]) == 1:
865
+ total_cross += num_cross
866
+
867
+ # total_cross does not need to actually be the total number of crossings; just correct mod 2
868
+ if total_cross % 2:
869
+ sign = -sign
870
+
871
+ # Replace \psi_i^{\dagger} \psi_i = q^k ( w^k - \psi_i \psi_i^{\dagger} )
872
+ def key(X):
873
+ e = list(v) # Make a copy
874
+ for i in pairings:
875
+ if i in X:
876
+ p[i] = 2
877
+ else:
878
+ p[i] = 0
879
+ e[i] = (e[i] + k) % tk
880
+ return (self._psi(p), tuple(e))
881
+
882
+ q = self._q
883
+ ret = {key(X): (-1)**len(X) * sign * q**(q_power+k*(len(pairings) % 2))
884
+ for X in powerset(pairings)}
885
+
886
+ return self._from_dict(ret)
887
+
888
+ class Element(QuantumCliffordAlgebra.Element):
889
+ def inverse(self):
890
+ r"""
891
+ Return the inverse if ``self`` is a basis element.
892
+
893
+ EXAMPLES::
894
+
895
+ sage: Cl = algebras.QuantumClifford(3, 3, -1)
896
+ sage: Cl.inject_variables()
897
+ Defining psi0, psi1, psi2, psid0, psid1, psid2, w0, w1, w2
898
+ sage: w0^-1
899
+ w0^5
900
+ sage: w0^-1 * w0
901
+ 1
902
+ sage: w0^-2
903
+ w0^4
904
+ sage: w0^-2 * w0^2
905
+ 1
906
+ sage: w0^-2 * w0 == w0^-1
907
+ True
908
+ sage: w = w0 * w1^3
909
+ sage: w^-1
910
+ w0^5*w1^3
911
+ sage: w^-1 * w
912
+ 1
913
+ sage: w * w^-1
914
+ 1
915
+
916
+ sage: (2*w0)^-1
917
+ 1/2*w0^5
918
+
919
+ sage: Cl = algebras.QuantumClifford(3, 1, -1)
920
+ sage: Cl.inject_variables()
921
+ Defining psi0, psi1, psi2, psid0, psid1, psid2, w0, w1, w2
922
+
923
+ sage: (w0 + w1)^-1
924
+ Traceback (most recent call last):
925
+ ...
926
+ ValueError: cannot invert self (= w1 + w0)
927
+ sage: (psi0 * w0)^-1
928
+ Traceback (most recent call last):
929
+ ...
930
+ ValueError: cannot invert self (= psi0*w0)
931
+
932
+ sage: z = CyclotomicField(6).gen()
933
+ sage: Cl = algebras.QuantumClifford(1, 3, z)
934
+ sage: Cl.inject_variables()
935
+ Defining psi0, psid0, w0
936
+ sage: (psi0 + psid0).inverse()
937
+ psid0*w0^3 - psi0*w0^3
938
+
939
+ sage: Cl = algebras.QuantumClifford(2, 2, -1)
940
+ sage: Cl.inject_variables()
941
+ Defining psi0, psi1, psid0, psid1, w0, w1
942
+ sage: w0^-1
943
+ w0^3
944
+ sage: w0 * w0^-1
945
+ 1
946
+ """
947
+ if not self:
948
+ raise ZeroDivisionError
949
+ if len(self) != 1:
950
+ return super().__invert__()
951
+ Cl = self.parent()
952
+ ((p, w), coeff), = list(self._monomial_coefficients.items())
953
+ if any(p[i] != 0 for i in range(Cl._n)):
954
+ return super().__invert__()
955
+ tk = 2 * Cl._k
956
+ w = tuple([tk - val if val else 0 for val in w])
957
+ return Cl.element_class(Cl, {(p, w): coeff.inverse_of_unit()})
958
+
959
+ __invert__ = inverse