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,1773 @@
1
+ # sage_setup: distribution = sagemath-combinat
2
+ # sage.doctest: needs sage.combinat sage.modules
3
+ r"""
4
+ Jordan Algebras
5
+
6
+ AUTHORS:
7
+
8
+ - Travis Scrimshaw (2014-04-02): initial version
9
+ - Travis Scrimshaw (2023-05-09): added the 27 dimensional exceptional
10
+ Jordan algebra
11
+ """
12
+
13
+ #*****************************************************************************
14
+ # Copyright (C) 2014, 2023 Travis Scrimshaw <tscrim at ucdavis.edu>
15
+ #
16
+ # Distributed under the terms of the GNU General Public License (GPL)
17
+ # https://www.gnu.org/licenses/
18
+ #*****************************************************************************
19
+
20
+ from sage.structure.parent import Parent
21
+ from sage.structure.unique_representation import UniqueRepresentation
22
+ from sage.structure.element import AlgebraElement
23
+ from sage.structure.richcmp import richcmp
24
+ from sage.categories.magmatic_algebras import MagmaticAlgebras
25
+ from sage.misc.cachefunc import cached_method
26
+ from sage.structure.element import Matrix
27
+ from sage.modules.free_module import FreeModule
28
+ from sage.matrix.constructor import matrix
29
+ from sage.sets.family import Family
30
+
31
+
32
+ class JordanAlgebra(UniqueRepresentation, Parent):
33
+ r"""
34
+ A Jordan algebra.
35
+
36
+ A *Jordan algebra* is a magmatic algebra (over a commutative ring
37
+ `R`) whose multiplication satisfies the following axioms:
38
+
39
+ - `xy = yx`, and
40
+ - `(xy)(xx) = x(y(xx))` (the Jordan identity).
41
+
42
+ See [Ja1971]_, [Ch2012]_, and [McC1978]_, for example.
43
+
44
+ These axioms imply that a Jordan algebra is power-associative and the
45
+ following generalization of Jordan's identity holds [Al1947]_:
46
+ `(x^m y) x^n = x^m (y x^n)` for all `m, n \in \ZZ_{>0}`.
47
+
48
+ Let `A` be an associative algebra over a ring `R` in which `2` is
49
+ invertible. We construct a Jordan algebra `A^+` with ground set `A`
50
+ by defining the multiplication as
51
+
52
+ .. MATH::
53
+
54
+ x \circ y = \frac{xy + yx}{2}.
55
+
56
+ Often the multiplication is written as `x \circ y` to avoid confusion
57
+ with the product in the associative algebra `A`. We note that if `A` is
58
+ commutative then this reduces to the usual multiplication in `A`.
59
+
60
+ Jordan algebras constructed in this fashion, or their subalgebras,
61
+ are called *special*. All other Jordan algebras are called *exceptional*.
62
+
63
+ Jordan algebras can also be constructed from a module `M` over `R` with
64
+ a symmetric bilinear form `(\cdot, \cdot) : M \times M \to R`.
65
+ We begin with the module `M^* = R \oplus M` and define multiplication
66
+ in `M^*` by
67
+
68
+ .. MATH::
69
+
70
+ (\alpha + x) \circ (\beta + y) =
71
+ \underbrace{\alpha \beta + (x,y)}_{\in R}
72
+ + \underbrace{\beta x + \alpha y}_{\in M},
73
+
74
+ where `\alpha, \beta \in R` and `x,y \in M`.
75
+
76
+ INPUT:
77
+
78
+ Can be either an associative algebra `A` or a symmetric bilinear
79
+ form given as a matrix (possibly followed by, or preceded by, a base
80
+ ring argument).
81
+
82
+ EXAMPLES:
83
+
84
+ We let the base algebra `A` be the free algebra on 3 generators::
85
+
86
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
87
+ sage: J = JordanAlgebra(F); J
88
+ Jordan algebra of Free Algebra on 3 generators (x, y, z) over Rational Field
89
+ sage: a,b,c = map(J, F.gens())
90
+ sage: a*b
91
+ 1/2*x*y + 1/2*y*x
92
+ sage: b*a
93
+ 1/2*x*y + 1/2*y*x
94
+
95
+ Jordan algebras are typically non-associative::
96
+
97
+ sage: (a*b)*c
98
+ 1/4*x*y*z + 1/4*y*x*z + 1/4*z*x*y + 1/4*z*y*x
99
+ sage: a*(b*c)
100
+ 1/4*x*y*z + 1/4*x*z*y + 1/4*y*z*x + 1/4*z*y*x
101
+
102
+ We check the Jordan identity::
103
+
104
+ sage: (a*b)*(a*a) == a*(b*(a*a))
105
+ True
106
+ sage: x = a + c
107
+ sage: y = b - 2*a
108
+ sage: (x*y)*(x*x) == x*(y*(x*x))
109
+ True
110
+
111
+ Next we construct a Jordan algebra from a symmetric bilinear form::
112
+
113
+ sage: m = matrix([[-2,3],[3,4]])
114
+ sage: J.<a,b,c> = JordanAlgebra(m); J
115
+ Jordan algebra over Integer Ring given by the symmetric bilinear form:
116
+ [-2 3]
117
+ [ 3 4]
118
+ sage: a
119
+ 1 + (0, 0)
120
+ sage: b
121
+ 0 + (1, 0)
122
+ sage: x = 3*a - 2*b + c; x
123
+ 3 + (-2, 1)
124
+
125
+ We again show that Jordan algebras are usually non-associative::
126
+
127
+ sage: (x*b)*b
128
+ -6 + (7, 0)
129
+ sage: x*(b*b)
130
+ -6 + (4, -2)
131
+
132
+ We verify the Jordan identity::
133
+
134
+ sage: y = -a + 4*b - c
135
+ sage: (x*y)*(x*x) == x*(y*(x*x))
136
+ True
137
+
138
+ The base ring, while normally inferred from the matrix, can also
139
+ be explicitly specified::
140
+
141
+ sage: J.<a,b,c> = JordanAlgebra(m, QQ); J
142
+ Jordan algebra over Rational Field given by the symmetric bilinear form:
143
+ [-2 3]
144
+ [ 3 4]
145
+ sage: J.<a,b,c> = JordanAlgebra(QQ, m); J # either order work
146
+ Jordan algebra over Rational Field given by the symmetric bilinear form:
147
+ [-2 3]
148
+ [ 3 4]
149
+
150
+ REFERENCES:
151
+
152
+ - :wikipedia:`Jordan_algebra`
153
+ - [Ja1971]_
154
+ - [Ch2012]_
155
+ - [McC1978]_
156
+ - [Al1947]_
157
+ """
158
+ @staticmethod
159
+ def __classcall_private__(self, arg0, arg1=None, names=None):
160
+ """
161
+ Choose the correct parent based upon input.
162
+
163
+ TESTS:
164
+
165
+ We check arguments with passing in an associative algebra::
166
+
167
+ sage: cat = Algebras(QQ).WithBasis().FiniteDimensional()
168
+ sage: C = CombinatorialFreeModule(QQ, ['x','y','z'], category=cat)
169
+ sage: J1 = JordanAlgebra(C, names=['a','b','c'])
170
+ sage: J2.<a,b,c> = JordanAlgebra(C)
171
+ sage: J1 is J2
172
+ True
173
+
174
+ We check with passing in a symmetric bilinear form::
175
+
176
+ sage: m = matrix([[0,1],[1,1]])
177
+ sage: J1 = JordanAlgebra(m)
178
+ sage: J2 = JordanAlgebra(QQ, m)
179
+ sage: J3 = JordanAlgebra(m, QQ)
180
+ sage: J1 is J2
181
+ False
182
+ sage: J2 is J3
183
+ True
184
+ sage: J4 = JordanAlgebra(ZZ, m)
185
+ sage: J1 is J4
186
+ True
187
+ sage: m = matrix(QQ, [[0,1],[1,1]])
188
+ sage: J1 = JordanAlgebra(m)
189
+ sage: J1 is J2
190
+ True
191
+ """
192
+ if names is not None:
193
+ if isinstance(names, str):
194
+ names = names.split(',')
195
+ names = tuple(names)
196
+
197
+ if arg1 is None:
198
+ if not isinstance(arg0, Matrix):
199
+ from sage.algebras.octonion_algebra import OctonionAlgebra
200
+ if isinstance(arg0, OctonionAlgebra):
201
+ return ExceptionalJordanAlgebra(arg0)
202
+ if arg0.base_ring().characteristic() == 2:
203
+ raise ValueError("the base ring cannot have characteristic 2")
204
+ return SpecialJordanAlgebra(arg0, names)
205
+ arg0, arg1 = arg0.base_ring(), arg0
206
+ elif isinstance(arg0, Matrix):
207
+ arg0, arg1 = arg1, arg0
208
+
209
+ # arg0 is the base ring and arg1 is a matrix
210
+ if not arg1.is_symmetric():
211
+ raise ValueError("the bilinear form is not symmetric")
212
+
213
+ arg1 = arg1.change_ring(arg0) # This makes a copy
214
+ arg1.set_immutable()
215
+ return JordanAlgebraSymmetricBilinear(arg0, arg1, names=names)
216
+
217
+ def _test_jordan_relations(self, **options):
218
+ r"""
219
+ Test the Jordan algebra relations.
220
+
221
+ The Jordan algebra relations are
222
+
223
+ - `xy = yx`, and
224
+ - `(xy)(xx) = x(y(xx))` (the Jordan identity).
225
+
226
+ EXAMPLES::
227
+
228
+ sage: O = OctonionAlgebra(GF(7), 1, 3, 4)
229
+ sage: J = JordanAlgebra(O)
230
+ sage: J._test_jordan_relations()
231
+ """
232
+ tester = self._tester(**options)
233
+ S = tester.some_elements()
234
+ from sage.misc.misc import some_tuples
235
+ for x, y in some_tuples(S, 2, tester._max_runs):
236
+ tester.assertEqual(x * y, y * x)
237
+ tester.assertEqual((x * y) * (x * x), x * (y * (x * x)))
238
+
239
+
240
+ class SpecialJordanAlgebra(JordanAlgebra):
241
+ r"""
242
+ A (special) Jordan algebra `A^+` from an associative algebra `A`.
243
+ """
244
+ def __init__(self, A, names=None):
245
+ """
246
+ Initialize ``self``.
247
+
248
+ TESTS::
249
+
250
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
251
+ sage: J = JordanAlgebra(F)
252
+ sage: TestSuite(J).run()
253
+ sage: J.category()
254
+ Category of commutative unital algebras with basis over Rational Field
255
+ """
256
+ R = A.base_ring()
257
+ C = MagmaticAlgebras(R)
258
+ if A not in C.Associative():
259
+ raise ValueError("A is not an associative algebra")
260
+
261
+ self._A = A
262
+ cat = C.Commutative()
263
+ if A in C.Unital():
264
+ cat = cat.Unital()
265
+ if A in C.WithBasis():
266
+ cat = cat.WithBasis()
267
+ if A in C.FiniteDimensional():
268
+ cat = cat.FiniteDimensional()
269
+
270
+ Parent.__init__(self, base=R, names=names, category=cat)
271
+
272
+ def _repr_(self):
273
+ """
274
+ Return a string representation of ``self``.
275
+
276
+ EXAMPLES::
277
+
278
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
279
+ sage: JordanAlgebra(F)
280
+ Jordan algebra of Free Algebra on 3 generators (x, y, z) over Rational Field
281
+ """
282
+ return "Jordan algebra of {}".format(self._A)
283
+
284
+ def _element_constructor_(self, x):
285
+ """
286
+ Construct an element of ``self`` from ``x``.
287
+
288
+ EXAMPLES::
289
+
290
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
291
+ sage: J = JordanAlgebra(F)
292
+ sage: J(5)
293
+ 5
294
+ sage: elt = J(x + 2*x*y); elt
295
+ x + 2*x*y
296
+ sage: elt.parent() is J
297
+ True
298
+ """
299
+ return self.element_class(self, self._A(x))
300
+
301
+ def _an_element_(self):
302
+ """
303
+ Return an element of ``self``.
304
+
305
+ EXAMPLES::
306
+
307
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
308
+ sage: J = JordanAlgebra(F)
309
+ sage: J.an_element()
310
+ 2 + 2*x + 3*y
311
+ """
312
+ return self.element_class(self, self._A.an_element())
313
+
314
+ @cached_method
315
+ def basis(self):
316
+ """
317
+ Return the basis of ``self``.
318
+
319
+ EXAMPLES::
320
+
321
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
322
+ sage: J = JordanAlgebra(F)
323
+ sage: J.basis()
324
+ Lazy family (Term map(i))_{i in Free monoid on 3 generators (x, y, z)}
325
+ """
326
+ B = self._A.basis()
327
+ return Family(B.keys(), lambda x: self.element_class(self, B[x]), name="Term map")
328
+
329
+ algebra_generators = basis
330
+
331
+ # TODO: Keep this until we can better handle R.<...> shorthand
332
+ def gens(self) -> tuple:
333
+ """
334
+ Return the generators of ``self``.
335
+
336
+ EXAMPLES::
337
+
338
+ sage: cat = Algebras(QQ).WithBasis().FiniteDimensional()
339
+ sage: C = CombinatorialFreeModule(QQ, ['x','y','z'], category=cat)
340
+ sage: J = JordanAlgebra(C)
341
+ sage: J.gens()
342
+ (B['x'], B['y'], B['z'])
343
+
344
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
345
+ sage: J = JordanAlgebra(F)
346
+ sage: J.gens()
347
+ Traceback (most recent call last):
348
+ ...
349
+ NotImplementedError: infinite set
350
+ """
351
+ return tuple(self.algebra_generators())
352
+
353
+ @cached_method
354
+ def zero(self):
355
+ """
356
+ Return the element `0`.
357
+
358
+ EXAMPLES::
359
+
360
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
361
+ sage: J = JordanAlgebra(F)
362
+ sage: J.zero()
363
+ 0
364
+ """
365
+ return self.element_class(self, self._A.zero())
366
+
367
+ @cached_method
368
+ def one(self):
369
+ """
370
+ Return the element `1` if it exists.
371
+
372
+ EXAMPLES::
373
+
374
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
375
+ sage: J = JordanAlgebra(F)
376
+ sage: J.one()
377
+ 1
378
+ """
379
+ return self.element_class(self, self._A.one())
380
+
381
+ class Element(AlgebraElement):
382
+ """
383
+ An element of a special Jordan algebra.
384
+ """
385
+ def __init__(self, parent, x):
386
+ """
387
+ Initialize ``self``.
388
+
389
+ EXAMPLES::
390
+
391
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
392
+ sage: J = JordanAlgebra(F)
393
+ sage: a,b,c = map(J, F.gens())
394
+ sage: TestSuite(a + 2*b - c).run()
395
+ """
396
+ self._x = x
397
+ AlgebraElement.__init__(self, parent)
398
+
399
+ def _repr_(self):
400
+ """
401
+ Return a string representation of ``self``.
402
+
403
+ EXAMPLES::
404
+
405
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
406
+ sage: J = JordanAlgebra(F)
407
+ sage: a,b,c = map(J, F.gens())
408
+ sage: a + 2*b - c
409
+ x + 2*y - z
410
+ """
411
+ return repr(self._x)
412
+
413
+ def _latex_(self):
414
+ """
415
+ Return a latex representation of ``self``.
416
+
417
+ EXAMPLES::
418
+
419
+ sage: F.<x0,x1,x2> = FreeAlgebra(QQ)
420
+ sage: J = JordanAlgebra(F)
421
+ sage: a,b,c = map(J, F.gens())
422
+ sage: latex(a + 2*b - c)
423
+ x_{0} + 2 x_{1} - x_{2}
424
+ """
425
+ from sage.misc.latex import latex
426
+ return latex(self._x)
427
+
428
+ def __bool__(self) -> bool:
429
+ """
430
+ Return if ``self`` is nonzero.
431
+
432
+ EXAMPLES::
433
+
434
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
435
+ sage: J = JordanAlgebra(F)
436
+ sage: a,b,c = map(J, F.gens())
437
+ sage: bool(a + 2*b - c)
438
+ True
439
+ """
440
+ return bool(self._x)
441
+
442
+ def __eq__(self, other):
443
+ """
444
+ Check equality.
445
+
446
+ EXAMPLES::
447
+
448
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
449
+ sage: J = JordanAlgebra(F)
450
+ sage: a,b,c = map(J, F.gens())
451
+ sage: elt = a + 2*b - c
452
+ sage: elt == elt
453
+ True
454
+ sage: elt == x
455
+ False
456
+ sage: elt == 2*b
457
+ False
458
+ """
459
+ if not isinstance(other, SpecialJordanAlgebra.Element):
460
+ return False
461
+ if other.parent() != self.parent():
462
+ return False
463
+ return self._x == other._x
464
+
465
+ def __ne__(self, other):
466
+ """
467
+ Check inequality.
468
+
469
+ EXAMPLES::
470
+
471
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
472
+ sage: J = JordanAlgebra(F)
473
+ sage: a,b,c = map(J, F.gens())
474
+ sage: elt = a + 2*b - c
475
+ sage: elt != elt
476
+ False
477
+ sage: elt != x
478
+ True
479
+ sage: elt != 2*b
480
+ True
481
+ """
482
+ return not self == other
483
+
484
+ def _add_(self, other):
485
+ """
486
+ Add ``self`` and ``other``.
487
+
488
+ EXAMPLES::
489
+
490
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
491
+ sage: J = JordanAlgebra(F)
492
+ sage: a,b,c = map(J, F.gens())
493
+ sage: a + 2*b
494
+ x + 2*y
495
+ """
496
+ return self.__class__(self.parent(), self._x + other._x)
497
+
498
+ def _neg_(self):
499
+ """
500
+ Negate ``self``.
501
+
502
+ EXAMPLES::
503
+
504
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
505
+ sage: J = JordanAlgebra(F)
506
+ sage: a,b,c = map(J, F.gens())
507
+ sage: -(a + 2*b)
508
+ -x - 2*y
509
+ """
510
+ return self.__class__(self.parent(), -self._x)
511
+
512
+ def _sub_(self, other):
513
+ """
514
+ Subtract ``other`` from ``self``.
515
+
516
+ EXAMPLES::
517
+
518
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
519
+ sage: J = JordanAlgebra(F)
520
+ sage: a,b,c = map(J, F.gens())
521
+ sage: a - 2*b
522
+ x - 2*y
523
+ """
524
+ return self.__class__(self.parent(), self._x - other._x)
525
+
526
+ def _mul_(self, other):
527
+ """
528
+ Multiply ``self`` and ``other``.
529
+
530
+ EXAMPLES::
531
+
532
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
533
+ sage: J = JordanAlgebra(F)
534
+ sage: a,b,c = map(J, F.gens())
535
+ sage: (a + 2*b) * (c - b)
536
+ -1/2*x*y + 1/2*x*z - 1/2*y*x - 2*y^2 + y*z + 1/2*z*x + z*y
537
+
538
+ sage: F.<x,y,z> = FreeAlgebra(GF(3))
539
+ sage: J = JordanAlgebra(F)
540
+ sage: a,b,c = map(J, F.gens())
541
+ sage: (a + 2*b) * (c - b)
542
+ x*y + 2*x*z + y*x + y^2 + y*z + 2*z*x + z*y
543
+ """
544
+ x = self._x
545
+ y = other._x
546
+ # This is safer than dividing by 2
547
+ R = self.parent().base_ring()
548
+ return self.__class__(self.parent(), (x*y + y*x) * ~R(2))
549
+
550
+ def _lmul_(self, other):
551
+ """
552
+ Multiply ``self`` by the scalar ``other`` on the left.
553
+
554
+ EXAMPLES::
555
+
556
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
557
+ sage: J = JordanAlgebra(F)
558
+ sage: a,b,c = map(J, F.gens())
559
+ sage: (a + b) * 2
560
+ 2*x + 2*y
561
+ """
562
+ return self.__class__(self.parent(), self._x * other)
563
+
564
+ def _rmul_(self, other):
565
+ """
566
+ Multiply ``self`` and the scalar ``other`` by the right
567
+ action.
568
+
569
+ EXAMPLES::
570
+
571
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
572
+ sage: J = JordanAlgebra(F)
573
+ sage: a,b,c = map(J, F.gens())
574
+ sage: 2 * (a + b)
575
+ 2*x + 2*y
576
+ """
577
+ return self.__class__(self.parent(), other * self._x)
578
+
579
+ def monomial_coefficients(self, copy=True):
580
+ """
581
+ Return a dictionary whose keys are indices of basis elements in
582
+ the support of ``self`` and whose values are the corresponding
583
+ coefficients.
584
+
585
+ INPUT:
586
+
587
+ - ``copy`` -- boolean (default: ``True``); if ``self`` is
588
+ internally represented by a dictionary ``d``, then make a copy of
589
+ ``d``; if ``False``, then this can cause undesired behavior by
590
+ mutating ``d``
591
+
592
+ EXAMPLES::
593
+
594
+ sage: F.<x,y,z> = FreeAlgebra(QQ)
595
+ sage: J = JordanAlgebra(F)
596
+ sage: a,b,c = map(J, F.gens())
597
+ sage: elt = a + 2*b - c
598
+ sage: elt.monomial_coefficients()
599
+ {x: 1, y: 2, z: -1}
600
+ """
601
+ return self._x.monomial_coefficients(copy)
602
+
603
+
604
+ class JordanAlgebraSymmetricBilinear(JordanAlgebra):
605
+ r"""
606
+ A Jordan algebra given by a symmetric bilinear form `m`.
607
+ """
608
+ def __init__(self, R, form, names=None):
609
+ """
610
+ Initialize ``self``.
611
+
612
+ TESTS::
613
+
614
+ sage: m = matrix([[-2,3],[3,4]])
615
+ sage: J = JordanAlgebra(m)
616
+ sage: TestSuite(J).run()
617
+ """
618
+ self._form = form
619
+ self._M = FreeModule(R, form.ncols())
620
+ cat = MagmaticAlgebras(R).Commutative().Unital().FiniteDimensional().WithBasis()
621
+ Parent.__init__(self, base=R, names=names, category=cat)
622
+
623
+ def _repr_(self):
624
+ """
625
+ Return a string representation of ``self``.
626
+
627
+ EXAMPLES::
628
+
629
+ sage: m = matrix([[-2,3],[3,4]])
630
+ sage: JordanAlgebra(m)
631
+ Jordan algebra over Integer Ring given by the symmetric bilinear form:
632
+ [-2 3]
633
+ [ 3 4]
634
+ """
635
+ return "Jordan algebra over {} given by the symmetric bilinear" \
636
+ " form:\n{}".format(self.base_ring(), self._form)
637
+
638
+ def _element_constructor_(self, *args):
639
+ """
640
+ Construct an element of ``self`` from ``s``.
641
+
642
+ Here ``s`` can be a pair of an element of `R` and an
643
+ element of `M`, or an element of `R`, or an element of
644
+ `M`, or an element of a(nother) Jordan algebra given
645
+ by a symmetric bilinear form.
646
+
647
+ EXAMPLES::
648
+
649
+ sage: m = matrix([[0,1],[1,1]])
650
+ sage: J = JordanAlgebra(m)
651
+ sage: J(2)
652
+ 2 + (0, 0)
653
+ sage: J((-4, (2, 5)))
654
+ -4 + (2, 5)
655
+ sage: J((-4, (ZZ^2)((2, 5))))
656
+ -4 + (2, 5)
657
+ sage: J(2, (-2, 3))
658
+ 2 + (-2, 3)
659
+ sage: J(2, (ZZ^2)((-2, 3)))
660
+ 2 + (-2, 3)
661
+ sage: J(-1, 1, 0)
662
+ -1 + (1, 0)
663
+ sage: J((ZZ^2)((1, 3)))
664
+ 0 + (1, 3)
665
+
666
+ sage: m = matrix([[2]])
667
+ sage: J = JordanAlgebra(m)
668
+ sage: J(2)
669
+ 2 + (0)
670
+ sage: J((-4, (2,)))
671
+ -4 + (2)
672
+ sage: J(2, (-2,))
673
+ 2 + (-2)
674
+ sage: J(-1, 1)
675
+ -1 + (1)
676
+ sage: J((ZZ^1)((3,)))
677
+ 0 + (3)
678
+
679
+ sage: m = Matrix(QQ, [])
680
+ sage: J = JordanAlgebra(m)
681
+ sage: J(2)
682
+ 2 + ()
683
+ sage: J((-4, ()))
684
+ -4 + ()
685
+ sage: J(2, ())
686
+ 2 + ()
687
+ sage: J(-1)
688
+ -1 + ()
689
+ sage: J((ZZ^0)(()))
690
+ 0 + ()
691
+ """
692
+ R = self.base_ring()
693
+ if len(args) == 1:
694
+ s = args[0]
695
+
696
+ if isinstance(s, JordanAlgebraSymmetricBilinear.Element):
697
+ if s.parent() is self:
698
+ return s
699
+ return self.element_class(self, R(s._s), self._M(s._v))
700
+
701
+ if isinstance(s, (list, tuple)):
702
+ if len(s) != 2:
703
+ raise ValueError("must be length 2")
704
+ return self.element_class(self, R(s[0]), self._M(s[1]))
705
+
706
+ if s in self._M:
707
+ return self.element_class(self, R.zero(), self._M(s))
708
+
709
+ return self.element_class(self, R(s), self._M.zero())
710
+
711
+ if len(args) == 2 and (isinstance(args[1], (list, tuple)) or args[1] in self._M):
712
+ return self.element_class(self, R(args[0]), self._M(args[1]))
713
+
714
+ if len(args) == self._form.ncols() + 1:
715
+ return self.element_class(self, R(args[0]), self._M(args[1:]))
716
+
717
+ raise ValueError("unable to construct an element from the given data")
718
+
719
+ def _coerce_map_from_base_ring(self):
720
+ """
721
+ Return a coercion map from the base ring of ``self``.
722
+
723
+ TESTS::
724
+
725
+ sage: J = JordanAlgebra(Matrix([[0, 1], [1, 1]]))
726
+ sage: J._coerce_map_from_base_ring()
727
+ Conversion map:
728
+ From: Integer Ring
729
+ To: Jordan algebra over Integer Ring given by the symmetric bilinear form:
730
+ [0 1]
731
+ [1 1]
732
+ sage: J.coerce_map_from(ZZ)
733
+ Coercion map:
734
+ From: Integer Ring
735
+ To: Jordan algebra over Integer Ring given by the symmetric bilinear form:
736
+ [0 1]
737
+ [1 1]
738
+ """
739
+ # Return a DefaultConvertMap_unique; this can pass additional
740
+ # arguments to _element_constructor_, unlike the map returned
741
+ # by UnitalAlgebras.ParentMethods._coerce_map_from_base_ring.
742
+ return self._generic_coerce_map(self.base_ring())
743
+
744
+ @cached_method
745
+ def basis(self):
746
+ """
747
+ Return a basis of ``self``.
748
+
749
+ The basis returned begins with the unity of `R` and continues with
750
+ the standard basis of `M`.
751
+
752
+ EXAMPLES::
753
+
754
+ sage: m = matrix([[0,1],[1,1]])
755
+ sage: J = JordanAlgebra(m)
756
+ sage: J.basis()
757
+ Family (1 + (0, 0), 0 + (1, 0), 0 + (0, 1))
758
+ """
759
+ R = self.base_ring()
760
+ ret = (self.element_class(self, R.one(), self._M.zero()),)
761
+ ret += tuple(self.element_class(self, R.zero(), x)
762
+ for x in self._M.basis())
763
+ return Family(ret)
764
+
765
+ algebra_generators = basis
766
+
767
+ def gens(self) -> tuple:
768
+ """
769
+ Return the generators of ``self``.
770
+
771
+ EXAMPLES::
772
+
773
+ sage: m = matrix([[0,1],[1,1]])
774
+ sage: J = JordanAlgebra(m)
775
+ sage: J.gens()
776
+ (1 + (0, 0), 0 + (1, 0), 0 + (0, 1))
777
+ """
778
+ return tuple(self.algebra_generators())
779
+
780
+ @cached_method
781
+ def zero(self):
782
+ """
783
+ Return the element 0.
784
+
785
+ EXAMPLES::
786
+
787
+ sage: m = matrix([[0,1],[1,1]])
788
+ sage: J = JordanAlgebra(m)
789
+ sage: J.zero()
790
+ 0 + (0, 0)
791
+ """
792
+ return self.element_class(self, self.base_ring().zero(), self._M.zero())
793
+
794
+ @cached_method
795
+ def one(self):
796
+ """
797
+ Return the element 1 if it exists.
798
+
799
+ EXAMPLES::
800
+
801
+ sage: m = matrix([[0,1],[1,1]])
802
+ sage: J = JordanAlgebra(m)
803
+ sage: J.one()
804
+ 1 + (0, 0)
805
+ """
806
+ return self.element_class(self, self.base_ring().one(), self._M.zero())
807
+
808
+ class Element(AlgebraElement):
809
+ """
810
+ An element of a Jordan algebra defined by a symmetric bilinear form.
811
+ """
812
+ def __init__(self, parent, s, v):
813
+ """
814
+ Initialize ``self``.
815
+
816
+ TESTS::
817
+
818
+ sage: m = matrix([[0,1],[1,1]])
819
+ sage: J.<a,b,c> = JordanAlgebra(m)
820
+ sage: TestSuite(a + 2*b - c).run()
821
+ """
822
+ self._s = s
823
+ self._v = v
824
+ AlgebraElement.__init__(self, parent)
825
+
826
+ def _repr_(self):
827
+ """
828
+ Return a string representation of ``self``.
829
+
830
+ EXAMPLES::
831
+
832
+ sage: m = matrix([[0,1],[1,1]])
833
+ sage: J.<a,b,c> = JordanAlgebra(m)
834
+ sage: a + 2*b - c
835
+ 1 + (2, -1)
836
+ """
837
+ return "{} + {}".format(self._s, self._v)
838
+
839
+ def _latex_(self):
840
+ r"""
841
+ Return a latex representation of ``self``.
842
+
843
+ EXAMPLES::
844
+
845
+ sage: m = matrix([[0,1],[1,1]])
846
+ sage: J.<a,b,c> = JordanAlgebra(m)
847
+ sage: latex(a + 2*b - c)
848
+ 1 + \left(2,\,-1\right)
849
+ """
850
+ from sage.misc.latex import latex
851
+ return "{} + {}".format(latex(self._s), latex(self._v))
852
+
853
+ def __bool__(self) -> bool:
854
+ """
855
+ Return if ``self`` is nonzero.
856
+
857
+ TESTS::
858
+
859
+ sage: m = matrix([[0,1],[1,1]])
860
+ sage: J.<a,b,c> = JordanAlgebra(m)
861
+ sage: bool(1)
862
+ True
863
+ sage: bool(b)
864
+ True
865
+ sage: bool(a + 2*b - c)
866
+ True
867
+ """
868
+ return bool(self._s) or bool(self._v)
869
+
870
+ def __eq__(self, other):
871
+ """
872
+ Check equality.
873
+
874
+ EXAMPLES::
875
+
876
+ sage: m = matrix([[0,1],[1,1]])
877
+ sage: J.<a,b,c> = JordanAlgebra(m)
878
+ sage: x = 4*a - b + 3*c
879
+ sage: x == J((4, (-1, 3)))
880
+ True
881
+ sage: a == x
882
+ False
883
+
884
+ sage: m = matrix([[-2,3],[3,4]])
885
+ sage: J.<a,b,c> = JordanAlgebra(m)
886
+ sage: 4*a - b + 3*c == x
887
+ False
888
+ """
889
+ if not isinstance(other, JordanAlgebraSymmetricBilinear.Element):
890
+ return False
891
+ if other.parent() != self.parent():
892
+ return False
893
+ return self._s == other._s and self._v == other._v
894
+
895
+ def __ne__(self, other):
896
+ """
897
+ Check inequality.
898
+
899
+ EXAMPLES::
900
+
901
+ sage: m = matrix([[0,1],[1,1]])
902
+ sage: J.<a,b,c> = JordanAlgebra(m)
903
+ sage: x = 4*a - b + 3*c
904
+ sage: x != J((4, (-1, 3)))
905
+ False
906
+ sage: a != x
907
+ True
908
+
909
+ sage: m = matrix([[-2,3],[3,4]])
910
+ sage: J.<a,b,c> = JordanAlgebra(m)
911
+ sage: 4*a - b + 3*c != x
912
+ True
913
+ """
914
+ return not self == other
915
+
916
+ def _add_(self, other):
917
+ """
918
+ Add ``self`` and ``other``.
919
+
920
+ EXAMPLES::
921
+
922
+ sage: m = matrix([[0,1],[1,1]])
923
+ sage: J.<a,b,c> = JordanAlgebra(m)
924
+ sage: a + b
925
+ 1 + (1, 0)
926
+ sage: b + c
927
+ 0 + (1, 1)
928
+ """
929
+ return self.__class__(self.parent(), self._s + other._s, self._v + other._v)
930
+
931
+ def _neg_(self):
932
+ """
933
+ Negate ``self``.
934
+
935
+ EXAMPLES::
936
+
937
+ sage: m = matrix([[0,1],[1,1]])
938
+ sage: J.<a,b,c> = JordanAlgebra(m)
939
+ sage: -(a + b - 2*c)
940
+ -1 + (-1, 2)
941
+ """
942
+ return self.__class__(self.parent(), -self._s, -self._v)
943
+
944
+ def _sub_(self, other):
945
+ """
946
+ Subtract ``other`` from ``self``.
947
+
948
+ EXAMPLES::
949
+
950
+ sage: m = matrix([[0,1],[1,1]])
951
+ sage: J.<a,b,c> = JordanAlgebra(m)
952
+ sage: a - b
953
+ 1 + (-1, 0)
954
+ sage: b - c
955
+ 0 + (1, -1)
956
+ """
957
+ return self.__class__(self.parent(), self._s - other._s, self._v - other._v)
958
+
959
+ def _mul_(self, other):
960
+ """
961
+ Multiply ``self`` and ``other``.
962
+
963
+ EXAMPLES::
964
+
965
+ sage: m = matrix([[0,1],[1,1]])
966
+ sage: J.<a,b,c> = JordanAlgebra(m)
967
+ sage: (4*a - b + 3*c)*(2*a + 2*b - c)
968
+ 12 + (6, 2)
969
+
970
+ sage: m = matrix([[-2,3],[3,4]])
971
+ sage: J.<a,b,c> = JordanAlgebra(m)
972
+ sage: (4*a - b + 3*c)*(2*a + 2*b - c)
973
+ 21 + (6, 2)
974
+ """
975
+ P = self.parent()
976
+ return self.__class__(P,
977
+ self._s * other._s
978
+ + (self._v * P._form * other._v.column())[0],
979
+ other._s * self._v + self._s * other._v)
980
+
981
+ def _lmul_(self, other):
982
+ """
983
+ Multiply ``self`` by the scalar ``other`` on the left.
984
+
985
+ EXAMPLES::
986
+
987
+ sage: m = matrix([[0,1],[1,1]])
988
+ sage: J.<a,b,c> = JordanAlgebra(m)
989
+ sage: (a + b - c) * 2
990
+ 2 + (2, -2)
991
+ """
992
+ return self.__class__(self.parent(), self._s * other, self._v * other)
993
+
994
+ def _rmul_(self, other):
995
+ """
996
+ Multiply ``self`` with the scalar ``other`` by the right
997
+ action.
998
+
999
+ EXAMPLES::
1000
+
1001
+ sage: m = matrix([[0,1],[1,1]])
1002
+ sage: J.<a,b,c> = JordanAlgebra(m)
1003
+ sage: 2 * (a + b - c)
1004
+ 2 + (2, -2)
1005
+ """
1006
+ return self.__class__(self.parent(), other * self._s, other * self._v)
1007
+
1008
+ def monomial_coefficients(self, copy=True):
1009
+ """
1010
+ Return a dictionary whose keys are indices of basis elements in
1011
+ the support of ``self`` and whose values are the corresponding
1012
+ coefficients.
1013
+
1014
+ INPUT:
1015
+
1016
+ - ``copy`` -- ignored
1017
+
1018
+ EXAMPLES::
1019
+
1020
+ sage: m = matrix([[0,1],[1,1]])
1021
+ sage: J.<a,b,c> = JordanAlgebra(m)
1022
+ sage: elt = a + 2*b - c
1023
+ sage: elt.monomial_coefficients()
1024
+ {0: 1, 1: 2, 2: -1}
1025
+ """
1026
+ d = {0: self._s}
1027
+ for i,c in enumerate(self._v):
1028
+ d[i+1] = c
1029
+ return d
1030
+
1031
+ def trace(self):
1032
+ r"""
1033
+ Return the trace of ``self``.
1034
+
1035
+ The trace of an element `\alpha + x \in M^*` is given by
1036
+ `t(\alpha + x) = 2 \alpha`.
1037
+
1038
+ EXAMPLES::
1039
+
1040
+ sage: m = matrix([[0,1],[1,1]])
1041
+ sage: J.<a,b,c> = JordanAlgebra(m)
1042
+ sage: x = 4*a - b + 3*c
1043
+ sage: x.trace()
1044
+ 8
1045
+ """
1046
+ return 2 * self._s
1047
+
1048
+ def norm(self):
1049
+ r"""
1050
+ Return the norm of ``self``.
1051
+
1052
+ The norm of an element `\alpha + x \in M^*` is given by
1053
+ `n(\alpha + x) = \alpha^2 - (x, x)`.
1054
+
1055
+ EXAMPLES::
1056
+
1057
+ sage: m = matrix([[0,1],[1,1]])
1058
+ sage: J.<a,b,c> = JordanAlgebra(m)
1059
+ sage: x = 4*a - b + 3*c; x
1060
+ 4 + (-1, 3)
1061
+ sage: x.norm()
1062
+ 13
1063
+ """
1064
+ return self._s * self._s - (self._v * self.parent()._form
1065
+ * self._v.column())[0]
1066
+
1067
+ def bar(self):
1068
+ r"""
1069
+ Return the result of the bar involution of ``self``.
1070
+
1071
+ The bar involution `\bar{\cdot}` is the `R`-linear
1072
+ endomorphism of `M^*` defined by `\bar{1} = 1` and
1073
+ `\bar{x} = -x` for `x \in M`.
1074
+
1075
+ EXAMPLES::
1076
+
1077
+ sage: m = matrix([[0,1],[1,1]])
1078
+ sage: J.<a,b,c> = JordanAlgebra(m)
1079
+ sage: x = 4*a - b + 3*c
1080
+ sage: x.bar()
1081
+ 4 + (1, -3)
1082
+
1083
+ We check that it is an algebra morphism::
1084
+
1085
+ sage: y = 2*a + 2*b - c
1086
+ sage: x.bar() * y.bar() == (x*y).bar()
1087
+ True
1088
+ """
1089
+ return self.__class__(self.parent(), self._s, -self._v)
1090
+
1091
+
1092
+ class ExceptionalJordanAlgebra(JordanAlgebra):
1093
+ r"""
1094
+ The exceptional `27` dimensional Jordan algebra as self-adjoint
1095
+ `3 \times 3` matrix over an octonion algebra.
1096
+
1097
+ Let `\mathbf{O}` be the :class:`OctonionAlgebra` over a commutative
1098
+ ring `R` of characteristic not equal to `2`. The *exceptional Jordan
1099
+ algebra* `\mathfrak{h}_3(\mathbf{O})` is a `27` dimensional free
1100
+ `R`-module spanned by the matrices
1101
+
1102
+ .. MATH::
1103
+
1104
+ \begin{bmatrix}
1105
+ \alpha & x & y \\
1106
+ x^* & \beta & z \\
1107
+ y^* & z^* & \gamma
1108
+ \end{bmatrix}
1109
+
1110
+ for `\alpha, \beta, \gamma \in R` and `x, y, z \in \mathbf{O}`,
1111
+ with multiplication given by the usual symmetrizer operation
1112
+ `X \circ Y = \frac{1}{2}(XY + YX)`.
1113
+
1114
+ These are also known as *Albert algebras* due to the work of
1115
+ Abraham Adrian Albert on these algebras over `\RR`.
1116
+
1117
+ EXAMPLES:
1118
+
1119
+ We construct an exceptional Jordan algebra over `\QQ` and perform
1120
+ some basic computations::
1121
+
1122
+ sage: O = OctonionAlgebra(QQ)
1123
+ sage: J = JordanAlgebra(O)
1124
+ sage: gens = J.gens()
1125
+ sage: gens[1]
1126
+ [0 0 0]
1127
+ [0 1 0]
1128
+ [0 0 0]
1129
+ sage: gens[3]
1130
+ [0 1 0]
1131
+ [1 0 0]
1132
+ [0 0 0]
1133
+ sage: gens[1] * gens[3]
1134
+ [ 0 1/2 0]
1135
+ [1/2 0 0]
1136
+ [ 0 0 0]
1137
+
1138
+ The Lie algebra of derivations of the exceptional Jordan algebra
1139
+ is isomorphic to the simple Lie algebra of type `F_4`. We verify
1140
+ that we the derivation module has the correct dimension::
1141
+
1142
+ sage: len(J.derivations_basis()) # long time
1143
+ 52
1144
+ sage: LieAlgebra(QQ, cartan_type='F4').dimension() # needs sage.graphs
1145
+ 52
1146
+
1147
+ REFERENCES:
1148
+
1149
+ - :wikipedia:`Albert_algebra`
1150
+ - :wikipedia:`Jordan_algebra#Examples`
1151
+ - :wikipedia:`Hurwitz's_theorem_(composition_algebras)#Applications_to_Jordan_algebras`
1152
+ - `<https://math.ucr.edu/home/baez/octonions/octonions.pdf>`_
1153
+ """
1154
+ def __init__(self, O):
1155
+ r"""
1156
+ Initialize ``self``.
1157
+
1158
+ EXAMPLES::
1159
+
1160
+ sage: O = OctonionAlgebra(QQ)
1161
+ sage: J = JordanAlgebra(O)
1162
+ sage: TestSuite(J).run() # long time
1163
+
1164
+ sage: O = OctonionAlgebra(QQ, 1, -2, 9)
1165
+ sage: J = JordanAlgebra(O)
1166
+ sage: TestSuite(J).run() # long time
1167
+
1168
+ sage: R.<x, y> = GF(11)[]
1169
+ sage: O = OctonionAlgebra(R, 1, x + y, 9)
1170
+ sage: J = JordanAlgebra(O)
1171
+ sage: TestSuite(J).run() # long time
1172
+
1173
+ sage: O = OctonionAlgebra(ZZ)
1174
+ sage: J = JordanAlgebra(O)
1175
+ Traceback (most recent call last):
1176
+ ...
1177
+ ValueError: 2 must be invertible
1178
+ """
1179
+ self._O = O
1180
+ R = O.base_ring()
1181
+
1182
+ if not R(2).is_unit():
1183
+ raise ValueError("2 must be invertible")
1184
+ self._half = R(2).inverse_of_unit()
1185
+
1186
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
1187
+ Onames = list(O.variable_names())
1188
+ Onames.extend(Onames[3] + Onames[i] for i in range(3))
1189
+ self._repr_poly_ring = PolynomialRing(R, Onames)
1190
+
1191
+ cat = MagmaticAlgebras(R).Unital().FiniteDimensional().WithBasis()
1192
+ Parent.__init__(self, base=R, category=cat)
1193
+
1194
+ def _repr_(self):
1195
+ r"""
1196
+ Return a string representation of ``self``.
1197
+
1198
+ EXAMPLES::
1199
+
1200
+ sage: O = OctonionAlgebra(QQ)
1201
+ sage: JordanAlgebra(O)
1202
+ Exceptional Jordan algebra constructed from Octonion algebra
1203
+ over Rational Field
1204
+ """
1205
+ return "Exceptional Jordan algebra constructed from {}".format(self._O)
1206
+
1207
+ def _element_constructor_(self, x):
1208
+ r"""
1209
+ Construct an element of ``self`` from ``s``.
1210
+
1211
+ EXAMPLES::
1212
+
1213
+ sage: O = OctonionAlgebra(QQ)
1214
+ sage: J = JordanAlgebra(O)
1215
+ sage: J(2)
1216
+ [2 0 0]
1217
+ [0 2 0]
1218
+ [0 0 2]
1219
+ sage: J([2, 3, 0, -1, O.basis()[3], 2])
1220
+ [ 2 -1 k]
1221
+ [-1 3 2]
1222
+ [-k 2 0]
1223
+ """
1224
+ R = self.base_ring()
1225
+ try:
1226
+ x = R(x)
1227
+ zero = self._O.zero()
1228
+ return self.element_class(self, [x, x, x, zero, zero, zero])
1229
+ except (ValueError, TypeError):
1230
+ pass
1231
+ x = list(x)
1232
+ if len(x) != 6:
1233
+ raise ValueError("invalid data to construct an element")
1234
+ R = self.base_ring()
1235
+ for i in range(3):
1236
+ x[i] = R(x[i])
1237
+ x[3+i] = self._O(x[3+i])
1238
+ return self.element_class(self, x)
1239
+
1240
+ def _test_multiplication_self_adjoint(self, **options):
1241
+ r"""
1242
+ Test that `(XY + YX) / 2` is self-adjoint.
1243
+
1244
+ EXAMPLES::
1245
+
1246
+ sage: O = OctonionAlgebra(GF(7), 1, 3, 4)
1247
+ sage: J = JordanAlgebra(O)
1248
+ sage: J._test_multiplication_self_adjoint()
1249
+ """
1250
+ tester = self._tester(**options)
1251
+ S = tester.some_elements()
1252
+ data_pairs = [(0, 0), (1, 1), (2, 2), (0, 1), (0, 2), (1, 2)]
1253
+ zerO = self._O.zero()
1254
+ from sage.misc.misc import some_tuples
1255
+ for x, y in some_tuples(S, 2, tester._max_runs):
1256
+ SD = x._data
1257
+ OD = y._data
1258
+ X = [[SD[0], SD[3], SD[4]],
1259
+ [SD[3].conjugate(), SD[1], SD[5]],
1260
+ [SD[4].conjugate(), SD[5].conjugate(), SD[2]]]
1261
+ Y = [[OD[0], OD[3], OD[4]],
1262
+ [OD[3].conjugate(), OD[1], OD[5]],
1263
+ [OD[4].conjugate(), OD[5].conjugate(), OD[2]]]
1264
+ for r, c in data_pairs:
1265
+ if r != c:
1266
+ val = sum(X[r][i] * Y[i][c] + Y[r][i] * X[i][c] for i in range(3)) * self._half
1267
+ val_opp = sum(X[c][i] * Y[i][r] + Y[c][i] * X[i][r] for i in range(3)) * self._half
1268
+ tester.assertEqual(val, val_opp.conjugate())
1269
+ else:
1270
+ val = sum(X[r][i] * Y[i][c] + Y[r][i] * X[i][c] for i in range(3)) * self._half
1271
+ tester.assertEqual(val.imag_part(), zerO)
1272
+
1273
+ @cached_method
1274
+ def basis(self):
1275
+ r"""
1276
+ Return a basis of ``self``.
1277
+
1278
+ EXAMPLES::
1279
+
1280
+ sage: O = OctonionAlgebra(QQ)
1281
+ sage: J = JordanAlgebra(O)
1282
+ sage: B = J.basis()
1283
+ sage: B[::6]
1284
+ ([1 0 0]
1285
+ [0 0 0]
1286
+ [0 0 0],
1287
+ [ 0 k 0]
1288
+ [-k 0 0]
1289
+ [ 0 0 0],
1290
+ [ 0 0 i]
1291
+ [ 0 0 0]
1292
+ [-i 0 0],
1293
+ [ 0 0 lk]
1294
+ [ 0 0 0]
1295
+ [-lk 0 0],
1296
+ [ 0 0 0]
1297
+ [ 0 0 li]
1298
+ [ 0 -li 0])
1299
+ sage: len(B)
1300
+ 27
1301
+ """
1302
+ R = self.base_ring()
1303
+ OB = self._O.basis()
1304
+ base = [R.zero()] * 3 + [self._O.zero()] * 3
1305
+ ret = []
1306
+ for i in range(3):
1307
+ temp = list(base)
1308
+ temp[i] = R.one()
1309
+ ret.append(self.element_class(self, temp))
1310
+ for i in range(3):
1311
+ for b in OB:
1312
+ temp = list(base)
1313
+ temp[3+i] = b
1314
+ ret.append(self.element_class(self, temp))
1315
+ return Family(ret)
1316
+
1317
+ algebra_generators = basis
1318
+
1319
+ def gens(self) -> tuple:
1320
+ """
1321
+ Return the generators of ``self``.
1322
+
1323
+ EXAMPLES::
1324
+
1325
+ sage: O = OctonionAlgebra(QQ)
1326
+ sage: J = JordanAlgebra(O)
1327
+ sage: G = J.gens()
1328
+ sage: G[0]
1329
+ [1 0 0]
1330
+ [0 0 0]
1331
+ [0 0 0]
1332
+ sage: G[5]
1333
+ [ 0 j 0]
1334
+ [-j 0 0]
1335
+ [ 0 0 0]
1336
+ sage: G[22]
1337
+ [ 0 0 0]
1338
+ [ 0 0 k]
1339
+ [ 0 -k 0]
1340
+ """
1341
+ return tuple(self.algebra_generators())
1342
+
1343
+ @cached_method
1344
+ def zero(self):
1345
+ r"""
1346
+ Return the additive identity.
1347
+
1348
+ EXAMPLES::
1349
+
1350
+ sage: O = OctonionAlgebra(QQ)
1351
+ sage: J = JordanAlgebra(O)
1352
+ sage: J.zero()
1353
+ [0 0 0]
1354
+ [0 0 0]
1355
+ [0 0 0]
1356
+ """
1357
+ Rz = self.base_ring().zero()
1358
+ Oz = self._O.zero()
1359
+ return self.element_class(self, (Rz, Rz, Rz, Oz, Oz, Oz))
1360
+
1361
+ @cached_method
1362
+ def one(self):
1363
+ r"""
1364
+ Return multiplicative identity.
1365
+
1366
+ EXAMPLES::
1367
+
1368
+ sage: O = OctonionAlgebra(QQ)
1369
+ sage: J = JordanAlgebra(O)
1370
+ sage: J.one()
1371
+ [1 0 0]
1372
+ [0 1 0]
1373
+ [0 0 1]
1374
+ sage: all(J.one() * b == b for b in J.basis())
1375
+ True
1376
+ """
1377
+ one = self.base_ring().one()
1378
+ zero = self._O.zero()
1379
+ return self.element_class(self, (one, one, one, zero, zero, zero))
1380
+
1381
+ def some_elements(self):
1382
+ r"""
1383
+ Return some elements of ``self``.
1384
+
1385
+ EXAMPLES::
1386
+
1387
+ sage: O = OctonionAlgebra(QQ)
1388
+ sage: J = JordanAlgebra(O)
1389
+ sage: J.some_elements()
1390
+ [[6/5 0 0]
1391
+ [ 0 6/5 0]
1392
+ [ 0 0 6/5],
1393
+ [1 0 0]
1394
+ [0 1 0]
1395
+ [0 0 1],
1396
+ [0 0 0]
1397
+ [0 0 0]
1398
+ [0 0 0],
1399
+ [0 0 0]
1400
+ [0 1 0]
1401
+ [0 0 0],
1402
+ [ 0 j 0]
1403
+ [-j 0 0]
1404
+ [ 0 0 0],
1405
+ [ 0 0 lj]
1406
+ [ 0 0 0]
1407
+ [-lj 0 0],
1408
+ [ 0 0 0]
1409
+ [ 0 1 1/2*lj]
1410
+ [ 0 -1/2*lj 0],
1411
+ [ 1 0 j + 2*li]
1412
+ [ 0 1 0]
1413
+ [-j - 2*li 0 1],
1414
+ [ 1 j + lk l]
1415
+ [-j - lk 0 i + lj]
1416
+ [ -l -i - lj 0],
1417
+ [ 1 3/2*l 2*k]
1418
+ [-3/2*l 0 5/2*j]
1419
+ [ -2*k -5/2*j 0]]
1420
+
1421
+ sage: O = OctonionAlgebra(GF(3))
1422
+ sage: J = JordanAlgebra(O)
1423
+ sage: J.some_elements()
1424
+ [[-1 0 0]
1425
+ [ 0 -1 0]
1426
+ [ 0 0 -1],
1427
+ [1 0 0]
1428
+ [0 1 0]
1429
+ [0 0 1],
1430
+ [0 0 0]
1431
+ [0 0 0]
1432
+ [0 0 0],
1433
+ [0 0 0]
1434
+ [0 1 0]
1435
+ [0 0 0],
1436
+ [ 0 j 0]
1437
+ [-j 0 0]
1438
+ [ 0 0 0],
1439
+ [ 0 0 lj]
1440
+ [ 0 0 0]
1441
+ [-lj 0 0],
1442
+ [ 0 0 0]
1443
+ [ 0 1 -lj]
1444
+ [ 0 lj 0],
1445
+ [ 1 0 j - li]
1446
+ [ 0 1 0]
1447
+ [-j + li 0 1],
1448
+ [ 1 j + lk l]
1449
+ [-j - lk 0 i + lj]
1450
+ [ -l -i - lj 0],
1451
+ [ 1 0 -k]
1452
+ [ 0 0 j]
1453
+ [ k -j 0]]
1454
+ """
1455
+ B = self.basis()
1456
+ S = [self.an_element(), self.one(), self.zero(),
1457
+ B[1], B[5], B[17], B[1] + self._half*B[25],
1458
+ self.one() + B[13] + 2*B[16]]
1459
+ S.append(sum(B[::5]))
1460
+ S.append(sum(self._half * ind * b for ind, b in enumerate(B[::7], start=2)))
1461
+ return S
1462
+
1463
+ class Element(AlgebraElement):
1464
+ r"""
1465
+ An element of an exceptional Jordan algebra.
1466
+ """
1467
+ def __init__(self, parent, data):
1468
+ """
1469
+ Initialize ``self``.
1470
+
1471
+ TESTS::
1472
+
1473
+ sage: O = OctonionAlgebra(QQ)
1474
+ sage: J = JordanAlgebra(O)
1475
+ sage: elt = sum(J.basis())
1476
+ sage: TestSuite(elt).run()
1477
+ """
1478
+ self._data = tuple(data)
1479
+ AlgebraElement.__init__(self, parent)
1480
+
1481
+ def _to_print_matrix(self):
1482
+ r"""
1483
+ Return ``self`` as a matrix for printing.
1484
+
1485
+ EXAMPLES::
1486
+
1487
+ sage: O = OctonionAlgebra(QQ)
1488
+ sage: J = JordanAlgebra(O)
1489
+ sage: elt = J([2, 3, 0, -1 + O.basis()[2], O.basis()[3], -O.basis()[5] + 5*O.basis()[7]])
1490
+ sage: elt._to_print_matrix()
1491
+ [ 2 j - 1 k]
1492
+ [ -j - 1 3 -li + 5*lk]
1493
+ [ -k li - 5*lk 0]
1494
+ """
1495
+ PR = self.parent()._repr_poly_ring
1496
+ gens = [PR.one()] + list(PR.gens())
1497
+ data = [PR(self._data[i]) for i in range(3)]
1498
+ data.extend(PR.sum(c * g for c, g in zip(self._data[3+i].vector(), gens))
1499
+ for i in range(3))
1500
+ # add the conjugates
1501
+ for i in range(1, 8):
1502
+ gens[i] = -gens[i]
1503
+ data.extend(PR.sum(c * g for c, g in zip(self._data[3+i].vector(), gens))
1504
+ for i in range(3))
1505
+ return matrix(PR, [[data[0], data[3], data[4]], [data[6], data[1], data[5]], [data[7], data[8], data[2]]])
1506
+
1507
+ def _repr_(self):
1508
+ r"""
1509
+ Return a string representation of ``self``.
1510
+
1511
+ EXAMPLES::
1512
+
1513
+ sage: O = OctonionAlgebra(QQ)
1514
+ sage: J = JordanAlgebra(O)
1515
+ sage: J.an_element()
1516
+ [6/5 0 0]
1517
+ [ 0 6/5 0]
1518
+ [ 0 0 6/5]
1519
+ """
1520
+ return repr(self._to_print_matrix())
1521
+
1522
+ def _latex_(self):
1523
+ r"""
1524
+ Return a latex representation of ``self``.
1525
+
1526
+ EXAMPLES::
1527
+
1528
+ sage: O = OctonionAlgebra(QQ)
1529
+ sage: J = JordanAlgebra(O)
1530
+ sage: latex(J.an_element())
1531
+ \left(\begin{array}{rrr}
1532
+ \frac{6}{5} & 0 & 0 \\
1533
+ 0 & \frac{6}{5} & 0 \\
1534
+ 0 & 0 & \frac{6}{5}
1535
+ \end{array}\right)
1536
+ """
1537
+ from sage.misc.latex import latex
1538
+ return latex(self._to_print_matrix())
1539
+
1540
+ def _ascii_art_(self):
1541
+ r"""
1542
+ Return an ascii art representation of ``self``.
1543
+
1544
+ EXAMPLES::
1545
+
1546
+ sage: O = OctonionAlgebra(QQ)
1547
+ sage: J = JordanAlgebra(O)
1548
+ sage: ascii_art(J.an_element())
1549
+ [6/5 0 0]
1550
+ [ 0 6/5 0]
1551
+ [ 0 0 6/5]
1552
+ """
1553
+ from sage.typeset.ascii_art import ascii_art
1554
+ return ascii_art(self._to_print_matrix())
1555
+
1556
+ def _unicode_art_(self):
1557
+ r"""
1558
+ Return a unicode art representation of ``self``.
1559
+
1560
+ EXAMPLES::
1561
+
1562
+ sage: O = OctonionAlgebra(QQ)
1563
+ sage: J = JordanAlgebra(O)
1564
+ sage: unicode_art(J.an_element())
1565
+ ⎛6/5 0 0⎞
1566
+ ⎜ 0 6/5 0⎟
1567
+ ⎝ 0 0 6/5⎠
1568
+ """
1569
+ from sage.typeset.unicode_art import unicode_art
1570
+ return unicode_art(self._to_print_matrix())
1571
+
1572
+ def __bool__(self) -> bool:
1573
+ """
1574
+ Return if ``self`` is nonzero.
1575
+
1576
+ TESTS::
1577
+
1578
+ sage: O = OctonionAlgebra(QQ)
1579
+ sage: J = JordanAlgebra(O)
1580
+ sage: all(bool(b) for b in J.basis())
1581
+ True
1582
+ sage: bool(J.zero())
1583
+ False
1584
+ """
1585
+ return any(d for d in self._data)
1586
+
1587
+ def _richcmp_(self, other, op):
1588
+ r"""
1589
+ Rich comparison of ``self`` with ``other`` by ``op``.
1590
+
1591
+ EXAMPLES::
1592
+
1593
+ sage: O = OctonionAlgebra(QQ)
1594
+ sage: J = JordanAlgebra(O)
1595
+ sage: x = sum(J.basis()[::6])
1596
+ sage: y = sum(J.basis()[::5])
1597
+ sage: x == x
1598
+ True
1599
+ sage: x == y
1600
+ False
1601
+ sage: x < y
1602
+ True
1603
+ sage: x != J.zero()
1604
+ True
1605
+ """
1606
+ return richcmp(self._data, other._data, op)
1607
+
1608
+ def _add_(self, other):
1609
+ """
1610
+ Add ``self`` and ``other``.
1611
+
1612
+ EXAMPLES::
1613
+
1614
+ sage: O = OctonionAlgebra(QQ)
1615
+ sage: J = JordanAlgebra(O)
1616
+ sage: x = sum(J.basis()[::6])
1617
+ sage: y = sum(J.basis()[::5])
1618
+ sage: x + x
1619
+ [ 2 2*k 2*i + 2*lk]
1620
+ [ -2*k 0 2*li]
1621
+ [-2*i - 2*lk -2*li 0]
1622
+ sage: x + y
1623
+ [ 2 j + k + lk i + l + lk]
1624
+ [ -j - k - lk 0 i + li + lj]
1625
+ [ -i - l - lk -i - li - lj 0]
1626
+ """
1627
+ return self.__class__(self.parent(), [a + b for a, b in zip(self._data, other._data)])
1628
+
1629
+ def _neg_(self):
1630
+ """
1631
+ Negate ``self``.
1632
+
1633
+ EXAMPLES::
1634
+
1635
+ sage: O = OctonionAlgebra(QQ)
1636
+ sage: J = JordanAlgebra(O)
1637
+ sage: x = sum(J.basis()[::6])
1638
+ sage: -x
1639
+ [ -1 -k -i - lk]
1640
+ [ k 0 -li]
1641
+ [ i + lk li 0]
1642
+ """
1643
+ return self.__class__(self.parent(), [-c for c in self._data])
1644
+
1645
+ def _sub_(self, other):
1646
+ r"""
1647
+ Subtract ``other`` from ``self``.
1648
+
1649
+ EXAMPLES::
1650
+
1651
+ sage: O = OctonionAlgebra(QQ)
1652
+ sage: J = JordanAlgebra(O)
1653
+ sage: x = sum(J.basis()[::6])
1654
+ sage: y = sum(J.basis()[::5])
1655
+ sage: x - x
1656
+ [0 0 0]
1657
+ [0 0 0]
1658
+ [0 0 0]
1659
+ sage: x - y
1660
+ [ 0 -j + k - lk i - l + lk]
1661
+ [ j - k + lk 0 -i + li - lj]
1662
+ [ -i + l - lk i - li + lj 0]
1663
+ """
1664
+ return self.__class__(self.parent(), [a - b for a, b in zip(self._data, other._data)])
1665
+
1666
+ def _mul_(self, other):
1667
+ """
1668
+ Multiply ``self`` and ``other``.
1669
+
1670
+ EXAMPLES::
1671
+
1672
+ sage: O = OctonionAlgebra(QQ)
1673
+ sage: J = JordanAlgebra(O)
1674
+ sage: x = sum(J.basis()[::7])
1675
+ sage: y = sum(J.basis()[::11])
1676
+ sage: x * y
1677
+ [ 1 -1/2*j + 1/2*l + 1/2 1/2*k + 1/2*lk + 1/2]
1678
+ [ 1/2*j - 1/2*l + 1/2 0 -1/2*l]
1679
+ [-1/2*k - 1/2*lk + 1/2 1/2*l 0]
1680
+ """
1681
+ P = self.parent()
1682
+ SD = self._data
1683
+ OD = other._data
1684
+ X = [[SD[0], SD[3], SD[4]],
1685
+ [SD[3].conjugate(), SD[1], SD[5]],
1686
+ [SD[4].conjugate(), SD[5].conjugate(), SD[2]]]
1687
+ Y = [[OD[0], OD[3], OD[4]],
1688
+ [OD[3].conjugate(), OD[1], OD[5]],
1689
+ [OD[4].conjugate(), OD[5].conjugate(), OD[2]]]
1690
+ # we do a simplified multiplication for the diagonal entries since
1691
+ # we have, e.g., \alpha * \alpha' + (x (x')^* + x' x^* + y (y')^* + y' y^*) / 2
1692
+ ret = [X[0][0] * Y[0][0] + (X[0][1] * Y[1][0]).real_part() + (X[0][2] * Y[2][0]).real_part(),
1693
+ X[1][1] * Y[1][1] + (X[1][0] * Y[0][1]).real_part() + (X[1][2] * Y[2][1]).real_part(),
1694
+ X[2][2] * Y[2][2] + (X[2][0] * Y[0][2]).real_part() + (X[2][1] * Y[1][2]).real_part()]
1695
+ ret += [sum(X[r][i] * Y[i][c] + Y[r][i] * X[i][c] for i in range(3)) * P._half
1696
+ for r, c in [(0, 1), (0, 2), (1, 2)]]
1697
+ return self.__class__(P, ret)
1698
+
1699
+ def _lmul_(self, other):
1700
+ r"""
1701
+ Multiply ``self`` by the scalar ``other`` on the left.
1702
+
1703
+ EXAMPLES::
1704
+
1705
+ sage: O = OctonionAlgebra(QQ)
1706
+ sage: J = JordanAlgebra(O)
1707
+ sage: elt = sum(2 * b for b in J.basis()[::6]); elt
1708
+ [ 2 2*k 2*i + 2*lk]
1709
+ [ -2*k 0 2*li]
1710
+ [-2*i - 2*lk -2*li 0]
1711
+ sage: elt * 2
1712
+ [ 4 4*k 4*i + 4*lk]
1713
+ [ -4*k 0 4*li]
1714
+ [-4*i - 4*lk -4*li 0]
1715
+ """
1716
+ return self.__class__(self.parent(), [c * other for c in self._data])
1717
+
1718
+ def _rmul_(self, other):
1719
+ r"""
1720
+ Multiply ``self`` with the scalar ``other`` by the right
1721
+ action.
1722
+
1723
+ EXAMPLES::
1724
+
1725
+ sage: O = OctonionAlgebra(QQ)
1726
+ sage: J = JordanAlgebra(O)
1727
+ sage: elt = sum(b * 2 for b in J.basis()[::6]); elt
1728
+ [ 2 2*k 2*i + 2*lk]
1729
+ [ -2*k 0 2*li]
1730
+ [-2*i - 2*lk -2*li 0]
1731
+ sage: (1/2) * elt
1732
+ [ 1 k i + lk]
1733
+ [ -k 0 li]
1734
+ [-i - lk -li 0]
1735
+ """
1736
+ return self.__class__(self.parent(), [other * c for c in self._data])
1737
+
1738
+ def monomial_coefficients(self, copy=True):
1739
+ r"""
1740
+ Return a dictionary whose keys are indices of basis elements in
1741
+ the support of ``self`` and whose values are the corresponding
1742
+ coefficients.
1743
+
1744
+ INPUT:
1745
+
1746
+ - ``copy`` -- ignored
1747
+
1748
+ EXAMPLES::
1749
+
1750
+ sage: O = OctonionAlgebra(QQ)
1751
+ sage: J = JordanAlgebra(O)
1752
+ sage: elt = sum(~QQ(ind) * b for ind, b in enumerate(J.basis()[::6], start=1)); elt
1753
+ [ 1 1/2*k 1/3*i + 1/4*lk]
1754
+ [ -1/2*k 0 1/5*li]
1755
+ [-1/3*i - 1/4*lk -1/5*li 0]
1756
+ sage: elt.monomial_coefficients()
1757
+ {0: 1, 6: 1/2, 12: 1/3, 18: 1/4, 24: 1/5}
1758
+
1759
+ TESTS::
1760
+
1761
+ sage: O = OctonionAlgebra(QQ)
1762
+ sage: J = JordanAlgebra(O)
1763
+ sage: all(b.monomial_coefficients() == {i: 1} for i,b in enumerate(J.basis()))
1764
+ True
1765
+ """
1766
+ ret = {}
1767
+ for i in range(3):
1768
+ if self._data[i]:
1769
+ ret[i] = self._data[i]
1770
+ mc = self._data[3+i].monomial_coefficients()
1771
+ for k, coeff in mc.items():
1772
+ ret[3+i*8+k] = coeff
1773
+ return ret