passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_aarch64.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 (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,2774 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Finite Dimensional Lie Algebras With Basis
4
+
5
+ AUTHORS:
6
+
7
+ - Travis Scrimshaw (07-15-2013): Initial implementation
8
+ """
9
+
10
+ # ****************************************************************************
11
+ # Copyright (C) 2013-2024 Travis Scrimshaw <tcscrims at gmail.com>
12
+ #
13
+ # This program is free software: you can redistribute it and/or modify
14
+ # it under the terms of the GNU General Public License as published by
15
+ # the Free Software Foundation, either version 2 of the License, or
16
+ # (at your option) any later version.
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+
20
+ from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring
21
+ from sage.categories.lie_algebras import LieAlgebras
22
+ from sage.categories.subobjects import SubobjectsCategory
23
+ from sage.misc.abstract_method import abstract_method
24
+ from sage.misc.cachefunc import cached_method
25
+ from sage.misc.lazy_attribute import lazy_attribute
26
+ from sage.misc.lazy_import import LazyImport
27
+ from sage.rings.integer import Integer
28
+ from sage.sets.family import Family
29
+
30
+
31
+ def _ce_complex_key(self, M, d, s, n):
32
+ """
33
+ The key for caching the Chevalley-Eilenberg complex.
34
+
35
+ TESTS::
36
+
37
+ sage: # needs sage.combinat sage.modules
38
+ sage: from sage.categories.finite_dimensional_lie_algebras_with_basis import _ce_complex_key
39
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'y':1}})
40
+ sage: _ce_complex_key(L, None, False, True, 5)
41
+ (None, False, True)
42
+ sage: f = ({x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])})
43
+ sage: _ce_complex_key(L, f, False, True, 5)
44
+ (Representation of Lie algebra on 2 generators (x, y) over Rational Field defined by:
45
+ [1 0]
46
+ x |--> [0 0]
47
+ [0 1]
48
+ y |--> [0 0],
49
+ False,
50
+ True)
51
+ """
52
+ if isinstance(M, dict):
53
+ M = self.representation(M)
54
+ return (M, d, s)
55
+
56
+
57
+ class FiniteDimensionalLieAlgebrasWithBasis(CategoryWithAxiom_over_base_ring):
58
+ """
59
+ Category of finite dimensional Lie algebras with a basis.
60
+
61
+ .. TODO::
62
+
63
+ Many of these tests should use non-abelian Lie algebras and need to
64
+ be added after :issue:`16820`.
65
+ """
66
+ _base_category_class_and_axiom = (LieAlgebras.FiniteDimensional, "WithBasis")
67
+
68
+ def example(self, n=3):
69
+ """
70
+ Return an example of a finite dimensional Lie algebra with basis as per
71
+ :meth:`Category.example <sage.categories.category.Category.example>`.
72
+
73
+ EXAMPLES::
74
+
75
+ sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis()
76
+ sage: C.example() # needs sage.combinat sage.libs.singular sage.modules
77
+ An example of a finite dimensional Lie algebra with basis:
78
+ the 3-dimensional abelian Lie algebra over Rational Field
79
+
80
+ Other dimensions can be specified as an optional argument::
81
+
82
+ sage: C.example(5) # needs sage.combinat sage.libs.singular sage.modules
83
+ An example of a finite dimensional Lie algebra with basis:
84
+ the 5-dimensional abelian Lie algebra over Rational Field
85
+ """
86
+ from sage.categories.examples.finite_dimensional_lie_algebras_with_basis import Example
87
+ return Example(self.base_ring(), n)
88
+
89
+ Nilpotent = LazyImport('sage.categories.finite_dimensional_nilpotent_lie_algebras_with_basis',
90
+ 'FiniteDimensionalNilpotentLieAlgebrasWithBasis')
91
+
92
+ class ParentMethods:
93
+ @cached_method
94
+ def _construct_UEA(self):
95
+ r"""
96
+ Construct the universal enveloping algebra of ``self``.
97
+
98
+ EXAMPLES::
99
+
100
+ sage: # needs sage.combinat sage.libs.singular sage.modules
101
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
102
+ sage: UEA = L._construct_UEA(); UEA
103
+ Noncommutative Multivariate Polynomial Ring in b0, b1, b2
104
+ over Rational Field, nc-relations: {}
105
+ sage: UEA.relations(add_commutative=True)
106
+ {b1*b0: b0*b1, b2*b0: b0*b2, b2*b1: b1*b2}
107
+
108
+ ::
109
+
110
+ sage: # needs sage.combinat sage.libs.singular sage.modules
111
+ sage: L.<x,y,z> = LieAlgebra(QQ, {('x','y'): {'z':1},
112
+ ....: ('y','z'): {'x':1},
113
+ ....: ('z','x'):{'y':1}})
114
+ sage: UEA = L._construct_UEA(); UEA
115
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
116
+ nc-relations: {...}
117
+ sage: sorted(UEA.relations().items(), key=str)
118
+ [(y*x, x*y - z), (z*x, x*z + y), (z*y, y*z - x)]
119
+
120
+ Singular's ``nc_algebra`` does not work over `\ZZ/6\ZZ`,
121
+ so we fallback to the PBW basis in this case::
122
+
123
+ sage: L = lie_algebras.pwitt(Zmod(6), 6) # needs sage.combinat sage.graphs sage.modules
124
+ sage: L._construct_UEA() # needs sage.combinat sage.graphs sage.libs.singular sage.modules
125
+ Universal enveloping algebra of
126
+ The 6-Witt Lie algebra over Ring of integers modulo 6
127
+ in the Poincare-Birkhoff-Witt basis
128
+
129
+ Corner case for the trivial (0-dimensional) Lie algebra::
130
+
131
+ sage: # needs sage.combinat sage.modules
132
+ sage: L.<a,b,c> = LieAlgebra(QQ, abelian=True)
133
+ sage: I = L.product_space(L)
134
+ sage: I._construct_UEA()
135
+ Free Algebra on 0 generators () over Rational Field
136
+ """
137
+ from sage.algebras.free_algebra import FreeAlgebra
138
+
139
+ # Create the UEA relations
140
+ # We need to get names for the basis elements, not just the generators
141
+ I = self._basis_ordering
142
+ if not I: # trivial Lie algebra
143
+ return FreeAlgebra(self.base_ring(), [])
144
+ try:
145
+ names = [str(x) for x in I]
146
+
147
+ def names_map(x):
148
+ return x
149
+ F = FreeAlgebra(self.base_ring(), names)
150
+ except ValueError:
151
+ names = ['b{}'.format(i) for i in range(self.dimension())]
152
+ self._UEA_names_map = {g: names[i] for i, g in enumerate(I)}
153
+ names_map = self._UEA_names_map.__getitem__
154
+ F = FreeAlgebra(self.base_ring(), names)
155
+ # ``F`` is the free algebra over the basis of ``self``. The
156
+ # universal enveloping algebra of ``self`` will be constructed
157
+ # as a quotient of ``F``.
158
+ d = F.gens_dict()
159
+ rels = {}
160
+ S = self.structure_coefficients(True)
161
+ # Construct the map from indices to names of the UEA
162
+
163
+ def get_var(g):
164
+ return d[names_map(g)]
165
+ # The function ``get_var`` sends an element of the basis of
166
+ # ``self`` to the corresponding element of ``F``.
167
+ for k in S.keys():
168
+ g0 = get_var(k[0])
169
+ g1 = get_var(k[1])
170
+ if g0 < g1:
171
+ rels[g1*g0] = g0*g1 - F.sum(val*get_var(g) for g, val in S[k])
172
+ else:
173
+ rels[g0*g1] = g1*g0 + F.sum(val*get_var(g) for g, val in S[k])
174
+ try:
175
+ return F.g_algebra(rels)
176
+ except RuntimeError:
177
+ # Something went wrong with the computation, so fallback to
178
+ # the generic PBW basis implementation
179
+ return self.pbw_basis()
180
+
181
+ @lazy_attribute
182
+ def _basis_ordering(self):
183
+ """
184
+ Return the indices of the basis of ``self`` as a tuple in
185
+ a fixed order.
186
+
187
+ Override this attribute to get a specific ordering of the basis.
188
+
189
+ EXAMPLES::
190
+
191
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # needs sage.combinat sage.libs.singular sage.modules
192
+ sage: L._basis_ordering # needs sage.combinat sage.libs.singular sage.modules
193
+ (0, 1, 2)
194
+ """
195
+ return tuple(self.basis().keys())
196
+
197
+ @lazy_attribute
198
+ def _basis_key_inverse(self):
199
+ """
200
+ A dictionary for keys to their appropriate index given by
201
+ ``self._basis_ordering``.
202
+
203
+ EXAMPLES::
204
+
205
+ sage: # needs sage.combinat sage.groups sage.modules
206
+ sage: G = SymmetricGroup(3)
207
+ sage: S = GroupAlgebra(G, QQ)
208
+ sage: L = LieAlgebra(associative=S)
209
+ sage: [L._basis_key_inverse[k] for k in L._basis_ordering]
210
+ [0, 1, 2, 3, 4, 5]
211
+ """
212
+ return {k: i for i, k in enumerate(self._basis_ordering)}
213
+
214
+ def _basis_key(self, x):
215
+ """
216
+ Return a key for sorting for the index ``x``.
217
+
218
+ TESTS::
219
+
220
+ sage: # needs sage.graphs sage.groups sage.modules
221
+ sage: L = lie_algebras.three_dimensional_by_rank(QQ, 3,
222
+ ....: names=['E','F','H'])
223
+ sage: PBW = L.pbw_basis()
224
+ sage: PBW._basis_key('E') < PBW._basis_key('H')
225
+ True
226
+
227
+ ::
228
+
229
+ sage: # needs sage.graphs sage.groups sage.modules
230
+ sage: L = lie_algebras.sl(QQ, 2)
231
+ sage: def neg_key(x):
232
+ ....: return -L.basis().keys().index(x)
233
+ sage: PBW = L.pbw_basis(basis_key=neg_key)
234
+ sage: prod(PBW.gens()) # indirect doctest
235
+ PBW[-alpha[1]]*PBW[alphacheck[1]]*PBW[alpha[1]]
236
+ - 4*PBW[-alpha[1]]*PBW[alpha[1]] + PBW[alphacheck[1]]^2
237
+ - 2*PBW[alphacheck[1]]
238
+
239
+ Check that :issue:`23266` is fixed::
240
+
241
+ sage: # needs sage.graphs sage.groups sage.modules
242
+ sage: sl2 = lie_algebras.sl(QQ, 2, 'matrix')
243
+ sage: sl2.indices()
244
+ {'e1', 'f1', 'h1'}
245
+ sage: type(sl2.basis().keys())
246
+ <class 'list'>
247
+ sage: Usl2 = sl2.pbw_basis()
248
+ sage: Usl2._basis_key(2)
249
+ 2
250
+ sage: Usl2._basis_key(3)
251
+ Traceback (most recent call last):
252
+ ...
253
+ KeyError: 3
254
+ """
255
+ return self._basis_key_inverse[x]
256
+
257
+ def _dense_free_module(self, R=None):
258
+ """
259
+ Return a dense free module associated to ``self`` over ``R``.
260
+
261
+ EXAMPLES::
262
+
263
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # needs sage.combinat sage.libs.singular sage.modules
264
+ sage: L._dense_free_module() # needs sage.combinat sage.libs.singular sage.modules
265
+ Vector space of dimension 3 over Rational Field
266
+ """
267
+ if R is None:
268
+ R = self.base_ring()
269
+ from sage.modules.free_module import FreeModule
270
+ return FreeModule(R, self.dimension())
271
+
272
+ module = _dense_free_module
273
+
274
+ def from_vector(self, v, order=None):
275
+ """
276
+ Return the element of ``self`` corresponding to the
277
+ vector ``v`` in ``self.module()``.
278
+
279
+ Implement this if you implement :meth:`module`; see the
280
+ documentation of
281
+ :meth:`sage.categories.lie_algebras.LieAlgebras.module`
282
+ for how this is to be done.
283
+
284
+ EXAMPLES::
285
+
286
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # needs sage.combinat sage.libs.singular sage.modules
287
+ sage: u = L.from_vector(vector(QQ, (1, 0, 0))); u # needs sage.combinat sage.libs.singular sage.modules
288
+ (1, 0, 0)
289
+ sage: parent(u) is L # needs sage.combinat sage.libs.singular sage.modules
290
+ True
291
+ """
292
+ if order is None:
293
+ order = self._basis_ordering
294
+ B = self.basis()
295
+ return self.sum(v[i] * B[k] for i, k in enumerate(order) if v[i] != 0)
296
+
297
+ def killing_matrix(self, x, y):
298
+ r"""
299
+ Return the Killing matrix of ``x`` and ``y``, where ``x``
300
+ and ``y`` are two elements of ``self``.
301
+
302
+ The Killing matrix is defined as the matrix corresponding
303
+ to the action of
304
+ `\operatorname{ad}_x \circ \operatorname{ad}_y` in the
305
+ basis of ``self``.
306
+
307
+ EXAMPLES::
308
+
309
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # needs sage.combinat sage.libs.singular sage.modules
310
+ sage: a, b, c = L.lie_algebra_generators() # needs sage.combinat sage.libs.singular sage.modules
311
+ sage: L.killing_matrix(a, b) # needs sage.combinat sage.libs.singular sage.modules
312
+ [0 0 0]
313
+ [0 0 0]
314
+ [0 0 0]
315
+
316
+ ::
317
+
318
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}}) # needs sage.combinat sage.modules
319
+ sage: L.killing_matrix(y, x) # needs sage.combinat sage.modules
320
+ [ 0 -1]
321
+ [ 0 0]
322
+ """
323
+ return x.adjoint_matrix() * y.adjoint_matrix()
324
+
325
+ def killing_form(self, x, y):
326
+ r"""
327
+ Return the Killing form on ``x`` and ``y``, where ``x``
328
+ and ``y`` are two elements of ``self``.
329
+
330
+ The Killing form is defined as
331
+
332
+ .. MATH::
333
+
334
+ \langle x \mid y \rangle
335
+ = \operatorname{tr}\left( \operatorname{ad}_x
336
+ \circ \operatorname{ad}_y \right).
337
+
338
+ EXAMPLES::
339
+
340
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # needs sage.combinat sage.libs.singular sage.modules
341
+ sage: a, b, c = L.lie_algebra_generators() # needs sage.combinat sage.libs.singular sage.modules
342
+ sage: L.killing_form(a, b) # needs sage.combinat sage.libs.singular sage.modules
343
+ 0
344
+ """
345
+ return self.killing_matrix(x, y).trace()
346
+
347
+ @cached_method
348
+ def killing_form_matrix(self):
349
+ """
350
+ Return the matrix of the Killing form of ``self``.
351
+
352
+ The rows and the columns of this matrix are indexed by the
353
+ elements of the basis of ``self`` (in the order provided by
354
+ :meth:`basis`).
355
+
356
+ EXAMPLES::
357
+
358
+ sage: # needs sage.combinat sage.libs.singular sage.modules
359
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
360
+ sage: L.killing_form_matrix()
361
+ [0 0 0]
362
+ [0 0 0]
363
+ [0 0 0]
364
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example(0)
365
+ sage: m = L.killing_form_matrix(); m
366
+ []
367
+ sage: parent(m)
368
+ Full MatrixSpace of 0 by 0 dense matrices over Rational Field
369
+ """
370
+ from sage.matrix.constructor import matrix
371
+
372
+ B = self.basis()
373
+ m = matrix(self.base_ring(),
374
+ [[self.killing_form(x, y) for x in B] for y in B])
375
+ m.set_immutable()
376
+ return m
377
+
378
+ @cached_method
379
+ def structure_coefficients(self, include_zeros=False):
380
+ r"""
381
+ Return the structure coefficients of ``self``.
382
+
383
+ INPUT:
384
+
385
+ - ``include_zeros`` -- boolean (default: ``False``); if ``True``,
386
+ then include the `[x, y] = 0` pairs in the output
387
+
388
+ OUTPUT:
389
+
390
+ A dictionary whose keys are pairs of basis indices `(i, j)`
391
+ with `i < j`, and whose values are the corresponding
392
+ *elements* `[b_i, b_j]` in the Lie algebra.
393
+
394
+ EXAMPLES::
395
+
396
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() # needs sage.combinat sage.libs.singular sage.modules
397
+ sage: L.structure_coefficients() # needs sage.combinat sage.libs.singular sage.modules
398
+ Finite family {}
399
+ sage: L.structure_coefficients(True) # needs sage.combinat sage.libs.singular sage.modules
400
+ Finite family {(0, 1): (0, 0, 0), (0, 2): (0, 0, 0), (1, 2): (0, 0, 0)}
401
+
402
+ ::
403
+
404
+ sage: # needs sage.combinat sage.groups sage.modules
405
+ sage: G = SymmetricGroup(3)
406
+ sage: S = GroupAlgebra(G, QQ)
407
+ sage: L = LieAlgebra(associative=S)
408
+ sage: L.structure_coefficients()
409
+ Finite family {((2,3), (1,2)): (1,2,3) - (1,3,2),
410
+ ((2,3), (1,3)): -(1,2,3) + (1,3,2),
411
+ ((1,2,3), (2,3)): -(1,2) + (1,3),
412
+ ((1,2,3), (1,2)): (2,3) - (1,3),
413
+ ((1,2,3), (1,3)): -(2,3) + (1,2),
414
+ ((1,3,2), (2,3)): (1,2) - (1,3),
415
+ ((1,3,2), (1,2)): -(2,3) + (1,3),
416
+ ((1,3,2), (1,3)): (2,3) - (1,2),
417
+ ((1,3), (1,2)): -(1,2,3) + (1,3,2)}
418
+ """
419
+ d = {}
420
+ B = self.basis()
421
+ K = list(B.keys())
422
+ zero = self.zero()
423
+ for i, x in enumerate(K):
424
+ for y in K[i + 1:]:
425
+ bx = B[x]
426
+ by = B[y]
427
+ val = self.bracket(bx, by)
428
+ if not include_zeros and val == zero:
429
+ continue
430
+ if self._basis_key(x) > self._basis_key(y):
431
+ d[y, x] = -val
432
+ else:
433
+ d[x, y] = val
434
+ return Family(d)
435
+
436
+ def centralizer_basis(self, S):
437
+ """
438
+ Return a basis of the centralizer of ``S`` in ``self``.
439
+
440
+ INPUT:
441
+
442
+ - ``S`` -- a subalgebra of ``self`` or a list of elements that
443
+ represent generators for a subalgebra
444
+
445
+ .. SEEALSO::
446
+
447
+ :meth:`centralizer`
448
+
449
+ EXAMPLES::
450
+
451
+ sage: # needs sage.combinat sage.libs.singular sage.modules
452
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
453
+ sage: a, b, c = L.lie_algebra_generators()
454
+ sage: L.centralizer_basis([a + b, 2*a + c])
455
+ [(1, 0, 0), (0, 1, 0), (0, 0, 1)]
456
+
457
+ sage: # needs sage.combinat sage.graphs sage.modules
458
+ sage: H = lie_algebras.Heisenberg(QQ, 2)
459
+ sage: H.centralizer_basis(H)
460
+ [z]
461
+
462
+ sage: # needs sage.combinat sage.groups sage.modules
463
+ sage: D = DescentAlgebra(QQ, 4).D()
464
+ sage: L = LieAlgebra(associative=D)
465
+ sage: L.centralizer_basis(L)
466
+ [D{},
467
+ D{1} + D{1, 2} + D{2, 3} + D{3},
468
+ D{1, 2, 3} + D{1, 3} + D{2}]
469
+ sage: D.center_basis()
470
+ (D{},
471
+ D{1} + D{1, 2} + D{2, 3} + D{3},
472
+ D{1, 2, 3} + D{1, 3} + D{2})
473
+
474
+ sage: # needs sage.combinat sage.modules
475
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
476
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
477
+ ....: ('d','e'): {'c':1}}
478
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
479
+ sage: L.centralizer_basis([a, c])
480
+ [a, b, c]
481
+ sage: L.centralizer_basis([a, e])
482
+ [c]
483
+ """
484
+ from sage.matrix.constructor import matrix
485
+
486
+ # from sage.algebras.lie_algebras.subalgebra import LieSubalgebra
487
+ # if isinstance(S, LieSubalgebra) or S is self:
488
+ if S is self:
489
+ from sage.matrix.special import identity_matrix
490
+ m = identity_matrix(self.base_ring(), self.dimension())
491
+ elif isinstance(S, (list, tuple)):
492
+ m = matrix([v.to_vector() for v in self.echelon_form(S)])
493
+ else:
494
+ m = self.subalgebra(S).basis_matrix()
495
+
496
+ S = self.structure_coefficients()
497
+ sc = {}
498
+ for k in S.keys():
499
+ v = S[k].to_vector()
500
+ sc[k] = v
501
+ sc[k[1], k[0]] = -v
502
+ X = self.basis().keys()
503
+ d = len(X)
504
+ c_mat = matrix(self.base_ring(),
505
+ [[sum(m[i, j] * sc[x, xp][k] for j, xp in enumerate(X)
506
+ if (x, xp) in sc)
507
+ for x in X]
508
+ for i in range(m.nrows()) for k in range(d)])
509
+ C = c_mat.right_kernel().basis_matrix()
510
+ return [self.from_vector(c) for c in C]
511
+
512
+ def centralizer(self, S):
513
+ """
514
+ Return the centralizer of ``S`` in ``self``.
515
+
516
+ INPUT:
517
+
518
+ - ``S`` -- a subalgebra of ``self`` or a list of elements that
519
+ represent generators for a subalgebra
520
+
521
+ .. SEEALSO::
522
+
523
+ :meth:`centralizer_basis`
524
+
525
+ EXAMPLES::
526
+
527
+ sage: # needs sage.combinat sage.libs.singular sage.modules
528
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
529
+ sage: a, b, c = L.lie_algebra_generators()
530
+ sage: S = L.centralizer([a + b, 2*a + c]); S
531
+ An example of a finite dimensional Lie algebra with basis:
532
+ the 3-dimensional abelian Lie algebra over Rational Field
533
+ sage: S.basis_matrix()
534
+ [1 0 0]
535
+ [0 1 0]
536
+ [0 0 1]
537
+ """
538
+ return self.ideal(self.centralizer_basis(S))
539
+
540
+ @cached_method
541
+ def center(self):
542
+ """
543
+ Return the center of ``self``.
544
+
545
+ EXAMPLES::
546
+
547
+ sage: # needs sage.combinat sage.libs.singular sage.modules
548
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
549
+ sage: Z = L.center(); Z
550
+ An example of a finite dimensional Lie algebra with basis: the
551
+ 3-dimensional abelian Lie algebra over Rational Field
552
+ sage: Z.basis_matrix()
553
+ [1 0 0]
554
+ [0 1 0]
555
+ [0 0 1]
556
+ """
557
+ return self.centralizer(self)
558
+
559
+ def normalizer_basis(self, S):
560
+ r"""
561
+ Return a basis of the normalizer of ``S`` in ``self``.
562
+
563
+ INPUT:
564
+
565
+ - ``S`` -- a subalgebra of ``self`` or a list of elements that
566
+ represent generators for a subalgebra
567
+
568
+ .. SEEALSO::
569
+
570
+ :meth:`normalizer`
571
+
572
+ EXAMPLES::
573
+
574
+ sage: # needs sage.combinat sage.modules
575
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
576
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
577
+ ....: ('d','e'): {'c':1}}
578
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
579
+ sage: L.normalizer_basis([a, e])
580
+ [b, c]
581
+ sage: S = L.subalgebra([a, e])
582
+ sage: L.normalizer_basis(S)
583
+ [a, b, c, e]
584
+
585
+ When the subalgebra is the ambient Lie algebra, we return the
586
+ basis of the ambient Lie algebra::
587
+
588
+ sage: # needs sage.combinat sage.modules
589
+ sage: L.normalizer_basis(L)
590
+ Finite family {'a': a, 'b': b, 'c': c, 'd': d, 'e': e}
591
+ sage: L.normalizer_basis([a, b, c, a, d + e, a + e])
592
+ Finite family {'a': a, 'b': b, 'c': c, 'd': d, 'e': e}
593
+ """
594
+ from sage.matrix.constructor import matrix
595
+
596
+ if S is self:
597
+ return self.basis()
598
+ if isinstance(S, (list, tuple)):
599
+ m = matrix([v.to_vector() for v in self.echelon_form(S)])
600
+ else:
601
+ m = self.subalgebra(S).basis_matrix()
602
+
603
+ if m.nrows() == self.dimension():
604
+ return self.basis()
605
+
606
+ S = self.structure_coefficients()
607
+ sc = {}
608
+ for k in S.keys():
609
+ v = S[k].to_vector()
610
+ sc[k] = v
611
+ sc[k[1], k[0]] = -v
612
+ X = self.basis().keys()
613
+ d = len(X)
614
+ t = m.nrows()
615
+ c_mat = matrix(self.base_ring(),
616
+ [[sum(m[i, j] * sc[x, xp][k]
617
+ for j, xp in enumerate(X) if (x, xp) in sc)
618
+ for x in X]
619
+ + [0]*(i*t) + [-m[j, k] for j in range(t)]
620
+ + [0]*((t-i-1)*t)
621
+ for i in range(t) for k in range(d)])
622
+ C = c_mat.right_kernel().basis_matrix()
623
+ return [self.from_vector(c[:d]) for c in C]
624
+
625
+ def normalizer(self, S):
626
+ r"""
627
+ Return the normalizer of ``S`` in ``self``.
628
+
629
+ INPUT:
630
+
631
+ - ``S`` -- a subalgebra of ``self`` or a list of elements that
632
+ represent generators for a subalgebra
633
+
634
+ .. SEEALSO::
635
+
636
+ :meth:`normalizer_basis`
637
+
638
+ EXAMPLES::
639
+
640
+ sage: # needs sage.combinat sage.modules
641
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
642
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
643
+ ....: ('d','e'): {'c':1}}
644
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
645
+ sage: L.normalizer([a, e])
646
+ Subalgebra generated by (b, c) of Lie algebra on
647
+ 5 generators (a, b, c, d, e) over Rational Field
648
+ sage: L.normalizer([a, c, e])
649
+ Subalgebra generated by (b, c, d) of Lie algebra on
650
+ 5 generators (a, b, c, d, e) over Rational Field
651
+ """
652
+ return self.subalgebra(self.normalizer_basis(S))
653
+
654
+ @cached_method
655
+ def derivations_basis(self):
656
+ r"""
657
+ Return a basis for the Lie algebra of derivations
658
+ of ``self`` as matrices.
659
+
660
+ A derivation `D` of an algebra is an endomorphism of `A`
661
+ such that
662
+
663
+ .. MATH::
664
+
665
+ D([a, b]) = [D(a), b] + [a, D(b)]
666
+
667
+ for all `a, b \in A`. The set of all derivations
668
+ form a Lie algebra.
669
+
670
+ EXAMPLES:
671
+
672
+ We construct the derivations of the Heisenberg Lie algebra::
673
+
674
+ sage: # needs sage.combinat sage.graphs sage.modules
675
+ sage: H = lie_algebras.Heisenberg(QQ, 1)
676
+ sage: H.derivations_basis()
677
+ (
678
+ [1 0 0] [0 1 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0]
679
+ [0 0 0] [0 0 0] [1 0 0] [0 1 0] [0 0 0] [0 0 0]
680
+ [0 0 1], [0 0 0], [0 0 0], [0 0 1], [1 0 0], [0 1 0]
681
+ )
682
+
683
+ We construct the derivations of `\mathfrak{sl}_2`::
684
+
685
+ sage: # needs sage.combinat sage.graphs sage.modules
686
+ sage: sl2 = lie_algebras.sl(QQ, 2)
687
+ sage: sl2.derivations_basis()
688
+ (
689
+ [ 1 0 0] [ 0 1 0] [ 0 0 0]
690
+ [ 0 0 0] [ 0 0 -1/2] [ 1 0 0]
691
+ [ 0 0 -1], [ 0 0 0], [ 0 -2 0]
692
+ )
693
+
694
+ We verify these are derivations::
695
+
696
+ sage: # needs sage.combinat sage.graphs sage.modules
697
+ sage: D = [sl2.module_morphism(matrix=M, codomain=sl2)
698
+ ....: for M in sl2.derivations_basis()]
699
+ sage: all(d(a.bracket(b)) == d(a).bracket(b) + a.bracket(d(b))
700
+ ....: for a in sl2.basis() for b in sl2.basis() for d in D)
701
+ True
702
+
703
+ REFERENCES:
704
+
705
+ :wikipedia:`Derivation_(differential_algebra)`
706
+ """
707
+ from sage.matrix.constructor import matrix
708
+
709
+ R = self.base_ring()
710
+ B = self.basis()
711
+ keys = list(B.keys())
712
+ scoeffs = {(j, y, i): c for y in keys for i in keys
713
+ for j, c in self.bracket(B[y], B[i])
714
+ }
715
+ zero = R.zero()
716
+ data = {}
717
+ N = len(keys)
718
+ for ii, i in enumerate(keys):
719
+ for ij, j in enumerate(keys[ii+1:]):
720
+ ijp = ij + ii + 1
721
+ for il, l in enumerate(keys):
722
+ row = ii + N * il + N**2 * ij
723
+ for ik, k in enumerate(keys):
724
+ data[row, ik+N*il] = (data.get((row, ik+N*il), zero)
725
+ + scoeffs.get((k, i, j), zero))
726
+ data[row, ii+N*ik] = (data.get((row, ii+N*ik), zero)
727
+ - scoeffs.get((l, k, j), zero))
728
+ data[row, ijp+N*ik] = (data.get((row, ijp+N*ik), zero)
729
+ - scoeffs.get((l, i, k), zero))
730
+ mat = matrix(R, data, sparse=True)
731
+ return tuple([matrix(R, N, N, list(b)) for b in mat.right_kernel().basis()])
732
+
733
+ @cached_method
734
+ def inner_derivations_basis(self):
735
+ r"""
736
+ Return a basis for the Lie algebra of inner derivations
737
+ of ``self`` as matrices.
738
+
739
+ EXAMPLES::
740
+
741
+ sage: # needs sage.combinat sage.graphs sage.modules
742
+ sage: H = lie_algebras.Heisenberg(QQ, 1)
743
+ sage: H.inner_derivations_basis()
744
+ (
745
+ [0 0 0] [0 0 0]
746
+ [0 0 0] [0 0 0]
747
+ [1 0 0], [0 1 0]
748
+ )
749
+ """
750
+ from sage.matrix.constructor import matrix
751
+
752
+ R = self.base_ring()
753
+ IDer = matrix(R, [b.adjoint_matrix().list() for b in self.basis()])
754
+ N = self.dimension()
755
+ return tuple([matrix(R, N, N, list(b))
756
+ for b in IDer.row_module().basis()])
757
+
758
+ @cached_method
759
+ def nilradical_basis(self):
760
+ r"""
761
+ Return a basis of the nilradical of ``self``.
762
+
763
+ .. SEEALSO::
764
+
765
+ :meth:`nilradical`
766
+
767
+ EXAMPLES::
768
+
769
+ sage: # needs sage.combinat sage.libs.pari sage.modules
770
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
771
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
772
+ ....: ('d','e'): {'c':1}}
773
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
774
+ sage: L.nilradical_basis()
775
+ (a, b, c)
776
+ sage: L.is_nilpotent()
777
+ False
778
+
779
+ sage: # needs sage.combinat sage.graphs sage.libs.pari sage.modules
780
+ sage: sl3 = LieAlgebra(QQ, cartan_type=['A',2])
781
+ sage: sl3.nilradical_basis()
782
+ ()
783
+
784
+ sage: # needs sage.combinat sage.libs.pari sage.modules
785
+ sage: scoeffs = {('a','e'): {'a':1}, ('b','e'): {'a':1,'b':1},
786
+ ....: ('c','d'): {'a':1}, ('c','e'): {'c':1}}
787
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
788
+ sage: L.nilradical_basis()
789
+ (a, b, c, d)
790
+ sage: L.is_solvable()
791
+ True
792
+ sage: L.is_nilpotent()
793
+ False
794
+ sage: K1 = L.quotient([a])
795
+ sage: K1.nilradical_basis()
796
+ (b, c, d)
797
+ sage: SL = L.subalgebra([a,b,c,d]); SL
798
+ Subalgebra generated by (a, b, c, d) of
799
+ Lie algebra on 5 generators (a, b, c, d, e) over Rational Field
800
+ sage: SL.nilradical_basis()
801
+ (a, b, c, d)
802
+
803
+ sage: # needs sage.combinat sage.libs.pari sage.modules
804
+ sage: scoeffs = {('x','z'): {'x':1, 'y':1}, ('y','z'): {'y':1}}
805
+ sage: L.<x,y,z> = LieAlgebra(GF(3), scoeffs)
806
+ sage: L.nilradical_basis()
807
+ (x, y)
808
+
809
+ We check against the generic algorithm::
810
+
811
+
812
+ sage: # needs sage.combinat sage.libs.pari sage.modules
813
+ sage: L.<x,y,z> = LieAlgebra(QQ, {('x','z'): {'x':1,'y':1}, ('y','z'): {'y':1}})
814
+ sage: L.nilradical_basis()
815
+ (x, y)
816
+ sage: dim = L.dimension()
817
+ sage: MS = MatrixSpace(L.base_ring(), dim)
818
+ sage: gens = [b.adjoint_matrix() for b in L.basis()]
819
+ sage: A = MS.subalgebra(gens)
820
+ sage: RB = A.radical_basis()
821
+ sage: mat = matrix(L.base_ring(),
822
+ ....: [g._vector_() for g in gens]
823
+ ....: + [A.lift(r)._vector_() for r in RB])
824
+ sage: tuple([L.from_vector(w) for v in mat.right_kernel().basis()
825
+ ....: if (w := v[:dim])])
826
+ (x, y)
827
+
828
+ A positive characteristic example::
829
+
830
+ sage: # needs sage.combinat sage.libs.pari sage.modules
831
+ sage: scoeffs = {('x','z'): {'x':1,'y':1}, ('y','z'): {'y':1}}
832
+ sage: L.<x,y,z> = LieAlgebra(GF(3), scoeffs)
833
+ sage: L.nilradical_basis()
834
+ (x, y)
835
+ """
836
+ if self.base_ring().characteristic() == 0:
837
+ L = self.solvable_radical()
838
+ if not L.dimension():
839
+ return ()
840
+ P = L.ideal(list(L.product_space(L).basis()))
841
+
842
+ I = P.derived_subalgebra()
843
+ if I.dimension():
844
+ Q = L.quotient(I)
845
+ ret = [Q.lift(b) for b in Q.nilradical_basis()]
846
+ ret.extend(b.value for b in I.basis())
847
+ return tuple([self(L.lift(b)) for b in ret])
848
+
849
+ H = L.hypercenter()
850
+ if H.dimension():
851
+ # the hypercenter is everything, so we don't need to compute the quotient
852
+ if L.dimension() == H.dimension():
853
+ return tuple([self(H.lift(b)) for b in H.basis()])
854
+ Q = L.quotient(H)
855
+ ret = [Q.lift(b) for b in Q.nilradical_basis()]
856
+ ret.extend(b.value for b in H.basis())
857
+ return tuple([self(L.lift(b)) for b in ret])
858
+
859
+ from sage.matrix.constructor import matrix
860
+ s = P.dimension()
861
+ QP = L.quotient(P)
862
+ MP = P.module()
863
+ for b in QP.basis():
864
+ yi = QP.lift(b)
865
+ brackets = [yi.bracket(P.lift(b)) for b in P.basis()]
866
+ adj = matrix([MP.coordinate_vector(elt.to_vector())
867
+ for elt in brackets]).transpose()
868
+ if adj.rank() < s:
869
+ J = L.ideal(brackets)
870
+ QJ = L.quotient(J)
871
+ M = L.ideal([QJ.lift(b) for b in QJ.nilradical_basis()]
872
+ + list(J.basis()))
873
+ return tuple([self(L.lift(b.value)) for b in M.nilradical_basis()])
874
+
875
+ f = adj.minimal_polynomial()
876
+ if not f.is_squarefree():
877
+ poly_ring = f.parent()
878
+ g = poly_ring(f / f.gcd(f.diff()))
879
+ phi = P.module_morphism(codomain=P, matrix=g(adj))
880
+ I = L.ideal([phi(p) for p in P.basis()])
881
+ QI = L.quotient(I)
882
+ M = L.ideal([QI.lift(b) for b in QI.nilradical_basis()]
883
+ + list(I.basis()))
884
+ return tuple([self(L.lift(b.value)) for b in M.nilradical_basis()])
885
+ return tuple([self(L.lift(b.value)) for b in P.basis()])
886
+
887
+ # positive characteristic
888
+ if self.is_nilpotent():
889
+ return tuple(self.basis())
890
+
891
+ from sage.matrix.matrix_space import MatrixSpace
892
+ from sage.matrix.constructor import matrix
893
+ dim = self.dimension()
894
+ MS = MatrixSpace(self.base_ring(), dim)
895
+ gens = [b.adjoint_matrix() for b in self.basis()]
896
+ A = MS.subalgebra(gens)
897
+ RB = A.radical_basis()
898
+ mat = matrix(self.base_ring(),
899
+ [g._vector_() for g in gens]
900
+ + [A.lift(r)._vector_() for r in RB])
901
+ return tuple([self.from_vector(w) for v in mat.left_kernel().basis()
902
+ if (w := v[:dim])])
903
+
904
+ def nilradical(self):
905
+ r"""
906
+ Return the nilradical of ``self``.
907
+
908
+ The *nilradical* of a Lie algebra `L` is the largest
909
+ nilpotent ideal of `L`.
910
+
911
+ .. SEEALSO::
912
+
913
+ :meth:`nilradical_basis`
914
+
915
+ EXAMPLES::
916
+
917
+ sage: # needs sage.combinat sage.modules
918
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
919
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
920
+ ....: ('d','e'): {'c':1}}
921
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
922
+ sage: L.solvable_radical()
923
+ Ideal (a, b, c, d, e) of
924
+ Lie algebra on 5 generators (a, b, c, d, e) over Rational Field
925
+ """
926
+ return self.ideal(self.nilradical_basis())
927
+
928
+ @cached_method
929
+ def solvable_radical_basis(self):
930
+ r"""
931
+ Return a basis of the solvable radical of ``self``.
932
+
933
+ .. SEEALSO::
934
+
935
+ :meth:`solvable_radical`
936
+
937
+ EXAMPLES::
938
+
939
+ sage: # needs sage.combinat sage.modules
940
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
941
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
942
+ ....: ('d','e'): {'c':1}}
943
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
944
+ sage: L.solvable_radical_basis()
945
+ (a, b, c, d, e)
946
+ sage: L.is_solvable()
947
+ True
948
+
949
+ sage: # needs sage.combinat sage.graphs sage.modules
950
+ sage: sl3 = LieAlgebra(QQ, cartan_type=['A',2])
951
+ sage: sl3.solvable_radical_basis()
952
+ ()
953
+
954
+ sage: # needs sage.combinat sage.modules
955
+ sage: L.<x,y,z> = LieAlgebra(QQ, {('x','z'): {'x':1,'y':1}, ('y','z'): {'y':1}})
956
+ sage: S = L.subalgebra([x, y])
957
+ sage: S.solvable_radical_basis()
958
+ (x, y)
959
+ sage: S.is_solvable()
960
+ True
961
+
962
+ Positive characteristic examples::
963
+
964
+ sage: # needs sage.combinat sage.modules
965
+ sage: scoeffs = {('x','z'): {'x':1,'y':1}, ('y','z'): {'y':1}}
966
+ sage: L.<x,y,z> = LieAlgebra(GF(3), scoeffs)
967
+ sage: L.solvable_radical_basis()
968
+ (x, y, z)
969
+
970
+ sage: # needs sage.combinat sage.graphs sage.modules
971
+ sage: sl3 = LieAlgebra(GF(3), cartan_type=['A',2])
972
+ sage: sl3.solvable_radical_basis()
973
+ (2*h1 + h2,)
974
+ """
975
+ if self.base_ring().characteristic() == 0:
976
+ P = self.derived_subalgebra() # same ambient space as self
977
+ if not P.dimension():
978
+ return tuple(self.basis())
979
+ Bad = [b.adjoint_matrix() for b in self.basis()]
980
+ Pad = [self(p).adjoint_matrix() for p in P.basis()]
981
+ from sage.matrix.constructor import matrix
982
+ mat = matrix(self.base_ring(),
983
+ [[(B * P).trace() for B in Bad] for P in Pad])
984
+ return tuple([self.from_vector(c) for c in mat.right_kernel().basis_matrix()])
985
+
986
+ # positive characteristic
987
+ if not self.nilradical_basis():
988
+ return ()
989
+ dim = self.dimension()
990
+ R = self.nilradical()
991
+ while True:
992
+ Q = self.quotient(R)
993
+ RQ = Q.nilradical()
994
+ if not RQ.dimension(): # we did not add anything
995
+ return tuple([self(b) for b in R.basis()])
996
+ new_gens = [Q.lift(b.value) for b in RQ.basis()]
997
+ R = self.ideal(list(R.basis()) + new_gens)
998
+ if R.dimension() == dim:
999
+ return tuple(self.basis())
1000
+
1001
+ def solvable_radical(self):
1002
+ r"""
1003
+ Return the solvable radical of ``self``.
1004
+
1005
+ The *solvable radical* of a Lie algebra `L` is the largest
1006
+ solvable ideal of `L`.
1007
+
1008
+ .. SEEALSO::
1009
+
1010
+ :meth:`solvable_radical_basis`
1011
+
1012
+ EXAMPLES::
1013
+
1014
+ sage: # needs sage.combinat sage.modules
1015
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
1016
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
1017
+ ....: ('d','e'): {'c':1}}
1018
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
1019
+ sage: L.solvable_radical()
1020
+ Ideal (a, b, c, d, e) of Lie algebra on 5 generators (a, b, c, d, e) over Rational Field
1021
+ """
1022
+ return self.ideal(self.solvable_radical_basis())
1023
+
1024
+ def subalgebra(self, *gens, **kwds):
1025
+ r"""
1026
+ Return the subalgebra of ``self`` generated by ``gens``.
1027
+
1028
+ INPUT:
1029
+
1030
+ - ``gens`` -- list of generators of the subalgebra
1031
+ - ``category`` -- (optional) a subcategory of subobjects of finite
1032
+ dimensional Lie algebras with basis
1033
+
1034
+ EXAMPLES::
1035
+
1036
+ sage: # needs sage.combinat sage.graphs sage.modules
1037
+ sage: H = lie_algebras.Heisenberg(QQ, 2)
1038
+ sage: p1,p2,q1,q2,z = H.basis()
1039
+ sage: S = H.subalgebra([p1, q1])
1040
+ sage: S.basis().list()
1041
+ [p1, q1, z]
1042
+ sage: S.basis_matrix()
1043
+ [1 0 0 0 0]
1044
+ [0 0 1 0 0]
1045
+ [0 0 0 0 1]
1046
+
1047
+ Passing an extra category to a subalgebra::
1048
+
1049
+ sage: # needs sage.combinat sage.modules
1050
+ sage: L = LieAlgebra(QQ, 3, step=2)
1051
+ sage: x,y,z = L.homogeneous_component_basis(1)
1052
+ sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis()
1053
+ sage: C = C.Subobjects().Graded().Stratified()
1054
+ sage: S = L.subalgebra([x, y], category=C)
1055
+ sage: S.homogeneous_component_basis(2).list()
1056
+ [X_12]
1057
+ """
1058
+ from sage.algebras.lie_algebras.subalgebra import LieSubalgebra_finite_dimensional_with_basis
1059
+ if len(gens) == 1 and isinstance(gens[0], (list, tuple)):
1060
+ gens = gens[0]
1061
+ category = kwds.pop('category', None)
1062
+ return LieSubalgebra_finite_dimensional_with_basis(
1063
+ self, gens, category=category, **kwds)
1064
+
1065
+ def ideal(self, *gens, **kwds):
1066
+ r"""
1067
+ Return the ideal of ``self`` generated by ``gens``.
1068
+
1069
+ INPUT:
1070
+
1071
+ - ``gens`` -- list of generators of the ideal
1072
+ - ``category`` -- (optional) a subcategory of subobjects of finite
1073
+ dimensional Lie algebras with basis
1074
+
1075
+ EXAMPLES::
1076
+
1077
+ sage: # needs sage.combinat sage.graphs sage.modules
1078
+ sage: H = lie_algebras.Heisenberg(QQ, 2)
1079
+ sage: p1,p2,q1,q2,z = H.basis()
1080
+ sage: I = H.ideal([p1 - p2, q1 - q2])
1081
+ sage: I.basis().list()
1082
+ [-p1 + p2, -q1 + q2, z]
1083
+ sage: I.reduce(p1 + p2 + q1 + q2 + z)
1084
+ 2*p1 + 2*q1
1085
+
1086
+ Passing an extra category to an ideal::
1087
+
1088
+ sage: # needs sage.combinat sage.modules
1089
+ sage: L.<x,y,z> = LieAlgebra(QQ, abelian=True)
1090
+ sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis()
1091
+ sage: C = C.Subobjects().Graded().Stratified()
1092
+ sage: I = L.ideal(x, y, category=C)
1093
+ sage: I.homogeneous_component_basis(1).list()
1094
+ [x, y]
1095
+ """
1096
+ from sage.algebras.lie_algebras.subalgebra import LieSubalgebra_finite_dimensional_with_basis
1097
+ from sage.structure.element import parent, Element
1098
+ if len(gens) == 1 and not isinstance(gens[0], Element):
1099
+ gens = gens[0]
1100
+ category = kwds.pop('category', None)
1101
+ return LieSubalgebra_finite_dimensional_with_basis(
1102
+ self, gens, ideal_of=self, category=category, **kwds)
1103
+
1104
+ @cached_method
1105
+ def is_ideal(self, A):
1106
+ """
1107
+ Return if ``self`` is an ideal of ``A``.
1108
+
1109
+ EXAMPLES::
1110
+
1111
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1112
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1113
+ sage: a, b, c = L.lie_algebra_generators()
1114
+ sage: I = L.ideal([2*a - c, b + c])
1115
+ sage: I.is_ideal(L)
1116
+ True
1117
+
1118
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'):{'x':1}}) # needs sage.combinat sage.modules
1119
+ sage: L.is_ideal(L) # needs sage.combinat sage.modules
1120
+ True
1121
+
1122
+ sage: F = LieAlgebra(QQ, 'F', representation='polynomial') # needs sage.combinat sage.modules
1123
+ sage: L.is_ideal(F) # needs sage.combinat sage.modules
1124
+ Traceback (most recent call last):
1125
+ ...
1126
+ NotImplementedError: A must be a finite dimensional Lie algebra
1127
+ with basis
1128
+ """
1129
+ if A == self:
1130
+ return True
1131
+ if A not in LieAlgebras(self.base_ring()).FiniteDimensional().WithBasis():
1132
+ raise NotImplementedError("A must be a finite dimensional"
1133
+ " Lie algebra with basis")
1134
+
1135
+ from sage.matrix.constructor import matrix
1136
+
1137
+ B = self.basis()
1138
+ AB = A.basis()
1139
+ try:
1140
+ b_mat = matrix(A.base_ring(), [A.bracket(b, ab).to_vector()
1141
+ for b in B for ab in AB])
1142
+ except (ValueError, TypeError):
1143
+ return False
1144
+ return b_mat.row_space().is_submodule(self.module())
1145
+
1146
+ def quotient(self, I, names=None, category=None):
1147
+ r"""
1148
+ Return the quotient of ``self`` by the ideal ``I``.
1149
+
1150
+ A quotient Lie algebra.
1151
+
1152
+ INPUT:
1153
+
1154
+ - ``I`` -- an ideal or a list of generators of the ideal
1155
+ - ``names`` -- (optional) string or list of strings;
1156
+ names for the basis elements of the quotient. If ``names`` is a
1157
+ string, the basis will be named ``names_1``,...,``names_n``.
1158
+
1159
+ EXAMPLES:
1160
+
1161
+ The Engel Lie algebra as a quotient of the free nilpotent Lie algebra
1162
+ of step 3 with 2 generators::
1163
+
1164
+ sage: # needs sage.combinat sage.modules
1165
+ sage: L.<X,Y,Z,W,U> = LieAlgebra(QQ, 2, step=3)
1166
+ sage: E = L.quotient(U); E
1167
+ Lie algebra quotient L/I of dimension 4 over Rational Field where
1168
+ L: Free Nilpotent Lie algebra on 5 generators (X, Y, Z, W, U)
1169
+ over Rational Field
1170
+ I: Ideal (U)
1171
+ sage: E.basis().list()
1172
+ [X, Y, Z, W]
1173
+ sage: E(X).bracket(E(Y))
1174
+ Z
1175
+ sage: Y.bracket(Z)
1176
+ -U
1177
+ sage: E(Y).bracket(E(Z))
1178
+ 0
1179
+ sage: E(U)
1180
+ 0
1181
+
1182
+ Quotients when the base ring is not a field are not implemented::
1183
+
1184
+ sage: # needs sage.combinat sage.graphs sage.modules
1185
+ sage: L = lie_algebras.Heisenberg(ZZ, 1)
1186
+ sage: L.quotient(L.an_element())
1187
+ Traceback (most recent call last):
1188
+ ...
1189
+ NotImplementedError: quotients over non-fields not implemented
1190
+ """
1191
+ from sage.algebras.lie_algebras.quotient import LieQuotient_finite_dimensional_with_basis
1192
+ return LieQuotient_finite_dimensional_with_basis(self, I,
1193
+ names=names,
1194
+ category=category)
1195
+
1196
+ def product_space(self, L, submodule=False):
1197
+ r"""
1198
+ Return the product space ``[self, L]``.
1199
+
1200
+ INPUT:
1201
+
1202
+ - ``L`` -- a Lie subalgebra of ``self``
1203
+ - ``submodule`` -- boolean (default: ``False``); if ``True``, then
1204
+ the result is forced to be a submodule of ``self``
1205
+
1206
+ EXAMPLES::
1207
+
1208
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1209
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1210
+ sage: a,b,c = L.lie_algebra_generators()
1211
+ sage: X = L.subalgebra([a, b + c])
1212
+ sage: L.product_space(X)
1213
+ An example of a finite dimensional Lie algebra with basis:
1214
+ the 0-dimensional abelian Lie algebra over Rational Field
1215
+ with basis matrix: []
1216
+ sage: Y = L.subalgebra([a, 2*b - c])
1217
+ sage: X.product_space(Y)
1218
+ An example of a finite dimensional Lie algebra with basis:
1219
+ the 0-dimensional abelian Lie algebra over Rational Field
1220
+ with basis matrix: []
1221
+
1222
+ ::
1223
+
1224
+ sage: # needs sage.combinat sage.graphs sage.modules
1225
+ sage: H = lie_algebras.Heisenberg(ZZ, 4)
1226
+ sage: Hp = H.product_space(H, submodule=True).basis()
1227
+ sage: [H.from_vector(v) for v in Hp]
1228
+ [z]
1229
+
1230
+ ::
1231
+
1232
+ sage: # needs sage.combinat sage.modules
1233
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'):{'x':1}})
1234
+ sage: Lp = L.product_space(L) # not implemented
1235
+ sage: Lp # not implemented
1236
+ Subalgebra generated of
1237
+ Lie algebra on 2 generators (x, y) over Rational Field
1238
+ with basis: (x,)
1239
+ sage: Lp.product_space(L) # not implemented
1240
+ Subalgebra generated of
1241
+ Lie algebra on 2 generators (x, y) over Rational Field
1242
+ with basis: (x,)
1243
+ sage: L.product_space(Lp) # not implemented
1244
+ Subalgebra generated of
1245
+ Lie algebra on 2 generators (x, y) over Rational Field
1246
+ with basis: (x,)
1247
+ sage: Lp.product_space(Lp) # not implemented
1248
+ Subalgebra generated of
1249
+ Lie algebra on 2 generators (x, y) over Rational Field
1250
+ with basis: ()
1251
+ """
1252
+ from sage.matrix.constructor import matrix
1253
+
1254
+ # Make sure we lift everything to the ambient space
1255
+ if self in LieAlgebras(self.base_ring()).Subobjects():
1256
+ A = self.ambient()
1257
+ elif L in LieAlgebras(L.base_ring()).Subobjects():
1258
+ A = L.ambient()
1259
+ else:
1260
+ A = self
1261
+
1262
+ if L not in self.category():
1263
+ # L might be a submodule of A.module()
1264
+ LB = [self.from_vector(b) for b in L.basis()]
1265
+ else:
1266
+ LB = L.basis()
1267
+
1268
+ B = self.basis()
1269
+ b_mat = matrix(A.base_ring(), [A.bracket(b, lb).to_vector()
1270
+ for b in B for lb in LB])
1271
+ if submodule is True or not (self.is_ideal(A) and L.is_ideal(A)):
1272
+ return b_mat.row_space()
1273
+ # We echelonize the matrix here
1274
+ # TODO: Do we want to?
1275
+ b_mat.echelonize()
1276
+ r = b_mat.rank()
1277
+ gens = [A.from_vector(row) for row in b_mat.rows()[:r]]
1278
+ return A.ideal(gens)
1279
+
1280
+ @cached_method
1281
+ def derived_subalgebra(self):
1282
+ """
1283
+ Return the derived subalgebra of ``self``.
1284
+
1285
+ EXAMPLES::
1286
+
1287
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1288
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1289
+ sage: L.derived_subalgebra()
1290
+ An example of a finite dimensional Lie algebra with basis:
1291
+ the 0-dimensional abelian Lie algebra over Rational Field
1292
+ with basis matrix:
1293
+ []
1294
+
1295
+ If ``self`` is semisimple, then the derived subalgebra is ``self``::
1296
+
1297
+ sage: # needs sage.combinat sage.graphs sage.modules
1298
+ sage: sl3 = LieAlgebra(QQ, cartan_type=['A', 2])
1299
+ sage: sl3.derived_subalgebra()
1300
+ Lie algebra of ['A', 2] in the Chevalley basis
1301
+ sage: sl3 is sl3.derived_subalgebra()
1302
+ True
1303
+ """
1304
+ if self.is_semisimple():
1305
+ return self
1306
+ else:
1307
+ return self.product_space(self)
1308
+
1309
+ @cached_method
1310
+ def derived_series(self):
1311
+ r"""
1312
+ Return the derived series `(\mathfrak{g}^{(i)})_i` of ``self``
1313
+ where the rightmost
1314
+ `\mathfrak{g}^{(k)} = \mathfrak{g}^{(k+1)} = \cdots`.
1315
+
1316
+ We define the derived series of a Lie algebra `\mathfrak{g}`
1317
+ recursively by `\mathfrak{g}^{(0)} := \mathfrak{g}` and
1318
+
1319
+ .. MATH::
1320
+
1321
+ \mathfrak{g}^{(k+1)} =
1322
+ [\mathfrak{g}^{(k)}, \mathfrak{g}^{(k)}]
1323
+
1324
+ and recall that
1325
+ `\mathfrak{g}^{(k)} \supseteq \mathfrak{g}^{(k+1)}`.
1326
+ Alternatively we can express this as
1327
+
1328
+ .. MATH::
1329
+
1330
+ \mathfrak{g} \supseteq [\mathfrak{g}, \mathfrak{g}] \supseteq
1331
+ \bigl[ [\mathfrak{g}, \mathfrak{g}], [\mathfrak{g},
1332
+ \mathfrak{g}] \bigr] \supseteq
1333
+ \biggl[ \bigl[ [\mathfrak{g}, \mathfrak{g}], [\mathfrak{g},
1334
+ \mathfrak{g}] \bigr], \bigl[ [\mathfrak{g}, \mathfrak{g}],
1335
+ [\mathfrak{g}, \mathfrak{g}] \bigr] \biggr] \supseteq \cdots.
1336
+
1337
+ EXAMPLES::
1338
+
1339
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1340
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1341
+ sage: L.derived_series()
1342
+ (An example of a finite dimensional Lie algebra with basis:
1343
+ the 3-dimensional abelian Lie algebra over Rational Field,
1344
+ An example of a finite dimensional Lie algebra with basis:
1345
+ the 0-dimensional abelian Lie algebra over Rational Field
1346
+ with basis matrix: [])
1347
+
1348
+ ::
1349
+
1350
+ sage: # needs sage.combinat sage.modules
1351
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
1352
+ sage: L.derived_series()
1353
+ (Lie algebra on 2 generators (x, y) over Rational Field,
1354
+ Ideal (x) of Lie algebra on 2 generators (x, y) over Rational Field,
1355
+ Ideal () of Lie algebra on 2 generators (x, y) over Rational Field)
1356
+
1357
+ sage: # needs sage.combinat sage.modules
1358
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
1359
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
1360
+ ....: ('d','e'): {'c':1}}
1361
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
1362
+ sage: L.derived_series()
1363
+ (Lie algebra on 5 generators (a, b, c, d, e) over Rational Field,
1364
+ Ideal (a, b, c) of Lie algebra on 5 generators (a, b, c, d, e) over Rational Field,
1365
+ Ideal () of Lie algebra on 5 generators (a, b, c, d, e) over Rational Field)
1366
+ """
1367
+ L = [self]
1368
+ while L[-1].dimension() > 0:
1369
+ p = L[-1].derived_subalgebra()
1370
+ if L[-1].dimension() == p.dimension():
1371
+ break
1372
+ L.append(p)
1373
+ return tuple(L)
1374
+
1375
+ @cached_method
1376
+ def lower_central_series(self, submodule=False):
1377
+ r"""
1378
+ Return the lower central series `(\mathfrak{g}_{i})_i`
1379
+ of ``self`` where the rightmost
1380
+ `\mathfrak{g}_k = \mathfrak{g}_{k+1} = \cdots`.
1381
+
1382
+ INPUT:
1383
+
1384
+ - ``submodule`` -- boolean (default: ``False``); if ``True``, then
1385
+ the result is given as submodules of ``self``
1386
+
1387
+ We define the lower central series of a Lie algebra `\mathfrak{g}`
1388
+ recursively by `\mathfrak{g}_0 := \mathfrak{g}` and
1389
+
1390
+ .. MATH::
1391
+
1392
+ \mathfrak{g}_{k+1} = [\mathfrak{g}, \mathfrak{g}_{k}]
1393
+
1394
+ and recall that `\mathfrak{g}_{k} \supseteq \mathfrak{g}_{k+1}`.
1395
+ Alternatively we can express this as
1396
+
1397
+ .. MATH::
1398
+
1399
+ \mathfrak{g} \supseteq [\mathfrak{g}, \mathfrak{g}] \supseteq
1400
+ \bigl[ [\mathfrak{g}, \mathfrak{g}], \mathfrak{g} \bigr]
1401
+ \supseteq \Bigl[\bigl[ [\mathfrak{g}, \mathfrak{g}],
1402
+ \mathfrak{g} \bigr], \mathfrak{g}\Bigr] \supseteq \cdots.
1403
+
1404
+ EXAMPLES::
1405
+
1406
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1407
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1408
+ sage: L.derived_series()
1409
+ (An example of a finite dimensional Lie algebra with basis:
1410
+ the 3-dimensional abelian Lie algebra over Rational Field,
1411
+ An example of a finite dimensional Lie algebra with basis:
1412
+ the 0-dimensional abelian Lie algebra over Rational Field
1413
+ with basis matrix: [])
1414
+
1415
+ The lower central series as submodules::
1416
+
1417
+ sage: # needs sage.combinat sage.modules
1418
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
1419
+ sage: L.lower_central_series(submodule=True)
1420
+ (Sparse vector space of dimension 2 over Rational Field,
1421
+ Vector space of degree 2 and dimension 1 over Rational Field
1422
+ Basis matrix: [1 0])
1423
+
1424
+ ::
1425
+
1426
+ sage: # needs sage.combinat sage.modules
1427
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
1428
+ sage: L.lower_central_series()
1429
+ (Lie algebra on 2 generators (x, y) over Rational Field,
1430
+ Ideal (x) of Lie algebra on 2 generators (x, y) over Rational Field)
1431
+
1432
+ sage: # needs sage.combinat sage.modules
1433
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
1434
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
1435
+ ....: ('d','e'): {'c':1}}
1436
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
1437
+ sage: L.lower_central_series()
1438
+ (Lie algebra on 5 generators (a, b, c, d, e) over Rational Field,
1439
+ Ideal (a, b, c) of Lie algebra on 5 generators (a, b, c, d, e) over Rational Field,
1440
+ Ideal (a, b) of Lie algebra on 5 generators (a, b, c, d, e) over Rational Field)
1441
+ """
1442
+ if submodule:
1443
+ L = [self.module()]
1444
+ else:
1445
+ L = [self]
1446
+ while L[-1].dimension() > 0:
1447
+ s = self.product_space(L[-1], submodule=submodule)
1448
+ if L[-1].dimension() == s.dimension():
1449
+ break
1450
+ L.append(s)
1451
+ return tuple(L)
1452
+
1453
+ @cached_method
1454
+ def upper_central_series(self):
1455
+ r"""
1456
+ Return the upper central series `(Z_i(\mathfrak{g}))_i`
1457
+ of ``self`` where the rightmost
1458
+ `Z_k(\mathfrak{g}) = Z_{k+1}(\mathfrak{g}) = \cdots`.
1459
+
1460
+ The *upper central series* of a Lie algebra `\mathfrak{g}` is
1461
+ defined recursively by `Z_0(\mathfrak{g}) := Z(\mathfrak{g})` and
1462
+
1463
+ .. MATH::
1464
+
1465
+ Z_{k+1}(\mathfrak{g}) / Z_k(\mathfrak{g})
1466
+ = Z(\mathfrak{g} / Z_k(\mathfrak{g}),
1467
+
1468
+ and recall that `Z(\mathfrak{g})` is the :meth:`center`
1469
+ of `\mathfrak{g}`.
1470
+
1471
+ EXAMPLES::
1472
+
1473
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1474
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1475
+ sage: L.upper_central_series()
1476
+ [An example of a finite dimensional Lie algebra with basis:
1477
+ the 3-dimensional abelian Lie algebra over Rational Field]
1478
+
1479
+ sage: # needs sage.combinat sage.modules
1480
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
1481
+ sage: L.upper_central_series()
1482
+ [Ideal () of Lie algebra on 2 generators (x, y) over Rational Field]
1483
+
1484
+ sage: # needs sage.combinat sage.modules
1485
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
1486
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
1487
+ ....: ('d','e'): {'c':1}}
1488
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
1489
+ sage: L.upper_central_series()
1490
+ [Ideal (c) of Lie algebra on 5 generators (a, b, c, d, e) over Rational Field]
1491
+
1492
+ sage: # needs sage.combinat sage.graphs sage.modules
1493
+ sage: L = lie_algebras.Heisenberg(QQ, 3)
1494
+ sage: L.upper_central_series()
1495
+ [Ideal (z) of Heisenberg algebra of rank 3 over Rational Field,
1496
+ Heisenberg algebra of rank 3 over Rational Field]
1497
+ """
1498
+ I = self.center()
1499
+ if I.dimension() == 0:
1500
+ return [I]
1501
+ ret = [I]
1502
+ dim = self.dimension()
1503
+ while True:
1504
+ Q = self.quotient(I)
1505
+ Z = Q.center()
1506
+ if not Z.dimension(): # we did not add anything
1507
+ return ret
1508
+ new_gens = [Q.lift(b.value) for b in Z.basis()]
1509
+ I = self.ideal(list(I.basis()) + new_gens)
1510
+ if I.dimension() == dim:
1511
+ ret.append(self)
1512
+ return ret
1513
+ ret.append(I)
1514
+
1515
+ def hypercenter(self):
1516
+ r"""
1517
+ Return the hypercenter of ``self``.
1518
+
1519
+ EXAMPLES::
1520
+
1521
+ sage: # needs sage.combinat sage.groups
1522
+ sage: SGA3 = SymmetricGroup(3).algebra(QQ)
1523
+ sage: L = LieAlgebra(associative=SGA3)
1524
+ sage: L.hypercenter()
1525
+ Ideal ((), (1,2,3) + (1,3,2), (2,3) + (1,2) + (1,3)) of
1526
+ Lie algebra of Symmetric group algebra of order 3
1527
+ over Rational Field
1528
+
1529
+ sage: # needs sage.combinat sage.graphs sage.modules
1530
+ sage: L = lie_algebras.Heisenberg(QQ, 3)
1531
+ sage: L.hypercenter()
1532
+ Heisenberg algebra of rank 3 over Rational Field
1533
+ """
1534
+ return self.upper_central_series()[-1]
1535
+
1536
+ def is_abelian(self):
1537
+ """
1538
+ Return if ``self`` is an abelian Lie algebra.
1539
+
1540
+ EXAMPLES::
1541
+
1542
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1543
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1544
+ sage: L.is_abelian()
1545
+ True
1546
+
1547
+ ::
1548
+
1549
+ sage: # needs sage.combinat sage.modules
1550
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
1551
+ sage: L.is_abelian()
1552
+ False
1553
+ """
1554
+ return len(self.structure_coefficients()) == 0
1555
+ # TODO: boolean handling of empty family
1556
+ # return not self.structure_coefficients()
1557
+
1558
+ def is_solvable(self):
1559
+ r"""
1560
+ Return if ``self`` is a solvable Lie algebra.
1561
+
1562
+ A Lie algebra is solvable if the derived series eventually
1563
+ becomes `0`.
1564
+
1565
+ EXAMPLES::
1566
+
1567
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1568
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1569
+ sage: L.is_solvable()
1570
+ True
1571
+
1572
+ ::
1573
+
1574
+ sage: # needs sage.combinat sage.modules
1575
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
1576
+ sage: L.is_solvable() # not implemented
1577
+ False
1578
+ """
1579
+ return not self.derived_series()[-1].dimension()
1580
+
1581
+ def is_nilpotent(self):
1582
+ r"""
1583
+ Return if ``self`` is a nilpotent Lie algebra.
1584
+
1585
+ A Lie algebra is nilpotent if the lower central series eventually
1586
+ becomes `0`.
1587
+
1588
+ EXAMPLES::
1589
+
1590
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1591
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1592
+ sage: L.is_nilpotent()
1593
+ True
1594
+ """
1595
+ return not self.lower_central_series()[-1].dimension()
1596
+
1597
+ def is_semisimple(self):
1598
+ """
1599
+ Return if ``self`` if a semisimple Lie algebra.
1600
+
1601
+ A Lie algebra is semisimple if the solvable radical is zero. In
1602
+ characteristic 0, this is equivalent to saying the Killing form
1603
+ is non-degenerate.
1604
+
1605
+ EXAMPLES::
1606
+
1607
+ sage: # needs sage.combinat sage.libs.singular sage.modules
1608
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
1609
+ sage: L.is_semisimple()
1610
+ False
1611
+
1612
+ Positive characteristic examples::
1613
+
1614
+ sage: # needs sage.combinat sage.modules
1615
+ sage: L.<x,y,z> = LieAlgebra(GF(3), {('x','z'): {'x':1, 'y':1}, ('y','z'): {'y':1}})
1616
+ sage: L.is_semisimple()
1617
+ False
1618
+
1619
+ sage: # needs sage.combinat sage.graphs sage.modules
1620
+ sage: sp4 = LieAlgebra(GF(3), cartan_type=['C',2])
1621
+ sage: sp4.killing_form_matrix().det()
1622
+ 0
1623
+ sage: sp4.solvable_radical_basis() # long time
1624
+ ()
1625
+ sage: sp4.is_semisimple() # long time
1626
+ True
1627
+ """
1628
+ if self.base_ring().characteristic() == 0:
1629
+ return not self.killing_form_matrix().is_singular()
1630
+ if not self.killing_form_matrix().is_singular():
1631
+ return True
1632
+ return not self.solvable_radical_basis()
1633
+
1634
+ @cached_method(key=_ce_complex_key)
1635
+ def chevalley_eilenberg_complex(self, M=None, dual=False, sparse=True, ncpus=None):
1636
+ r"""
1637
+ Return the Chevalley-Eilenberg complex of ``self``.
1638
+
1639
+ Let `\mathfrak{g}` be a Lie algebra and `M` be a right
1640
+ `\mathfrak{g}`-module. The *Chevalley-Eilenberg complex*
1641
+ is the chain complex on
1642
+
1643
+ .. MATH::
1644
+
1645
+ C_{\bullet}(\mathfrak{g}, M) =
1646
+ M \otimes \bigwedge\nolimits^{\bullet} \mathfrak{g},
1647
+
1648
+ where the differential is given by
1649
+
1650
+ .. MATH::
1651
+
1652
+ d(m \otimes g_1 \wedge \cdots \wedge g_p) =
1653
+ \sum_{i=1}^p (-1)^{i+1}
1654
+ (m g_i) \otimes g_1 \wedge \cdots \wedge
1655
+ \hat{g}_i \wedge \cdots \wedge g_p +
1656
+ \sum_{1 \leq i < j \leq p} (-1)^{i+j}
1657
+ m \otimes [g_i, g_j] \wedge
1658
+ g_1 \wedge \cdots \wedge \hat{g}_i
1659
+ \wedge \cdots \wedge \hat{g}_j
1660
+ \wedge \cdots \wedge g_p.
1661
+
1662
+ INPUT:
1663
+
1664
+ - ``M`` -- (default: the trivial 1-dimensional module)
1665
+ one of the following:
1666
+
1667
+ * a module `M` with an action of ``self``
1668
+ * a dictionary whose keys are basis elements and values
1669
+ are matrices representing a Lie algebra homomorphism
1670
+ defining the representation
1671
+
1672
+ - ``dual`` -- boolean (default: ``False``); if ``True``, causes
1673
+ the dual of the complex to be computed
1674
+ - ``sparse`` -- boolean (default: ``True``); whether to use sparse
1675
+ or dense matrices
1676
+ - ``ncpus`` -- (optional) how many cpus to use
1677
+
1678
+ EXAMPLES::
1679
+
1680
+ sage: # needs sage.combinat sage.graphs sage.modules
1681
+ sage: L = lie_algebras.sl(ZZ, 2)
1682
+ sage: C = L.chevalley_eilenberg_complex(); C
1683
+ Chain complex with at most 4 nonzero terms over Integer Ring
1684
+ sage: ascii_art(C)
1685
+ [-2 0 0] [0]
1686
+ [ 0 1 0] [0]
1687
+ [0 0 0] [ 0 0 -2] [0]
1688
+ 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0
1689
+
1690
+ sage: # needs sage.combinat sage.graphs sage.modules
1691
+ sage: L = LieAlgebra(QQ, cartan_type=['C',2])
1692
+ sage: C = L.chevalley_eilenberg_complex() # long time
1693
+ sage: [C.free_module_rank(i) for i in range(11)] # long time
1694
+ [1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
1695
+
1696
+ sage: # needs sage.combinat sage.modules
1697
+ sage: g = lie_algebras.sl(QQ, 2)
1698
+ sage: E, F, H = g.basis()
1699
+ sage: n = g.subalgebra([F, H])
1700
+ sage: ascii_art(n.chevalley_eilenberg_complex())
1701
+ [ 0]
1702
+ [0 0] [-2]
1703
+ 0 <-- C_0 <------ C_1 <----- C_2 <-- 0
1704
+
1705
+ sage: # needs sage.combinat sage.modules
1706
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'y':1}})
1707
+ sage: f = ({x: Matrix([[1,0],[0,0]]), y: Matrix([[0,1],[0,0]])})
1708
+ sage: C = L.chevalley_eilenberg_complex(f); C
1709
+ Chain complex with at most 3 nonzero terms over Rational Field
1710
+ sage: ascii_art(C)
1711
+ [ 0 -1]
1712
+ [ 2 0]
1713
+ [1 0 0 1] [ 0 0]
1714
+ [0 0 0 0] [ 0 1]
1715
+ 0 <-- C_0 <---------- C_1 <-------- C_2 <-- 0
1716
+ sage: ascii_art(L.chevalley_eilenberg_complex(f, sparse=False))
1717
+ [ 0 -1]
1718
+ [ 2 0]
1719
+ [1 0 0 1] [ 0 0]
1720
+ [0 0 0 0] [ 0 1]
1721
+ 0 <-- C_0 <---------- C_1 <-------- C_2 <-- 0
1722
+
1723
+ REFERENCES:
1724
+
1725
+ - :wikipedia:`Lie_algebra_cohomology#Chevalley-Eilenberg_complex`
1726
+ - [Wei1994]_ Chapter 7
1727
+ """
1728
+ if dual:
1729
+ return self.chevalley_eilenberg_complex(M, dual=False,
1730
+ sparse=sparse,
1731
+ ncpus=ncpus).dual()
1732
+
1733
+ from itertools import combinations, product
1734
+ from sage.matrix.matrix_space import MatrixSpace
1735
+ from sage.algebras.lie_algebras.representation import Representation_abstract
1736
+ R = self.base_ring()
1737
+ zero = R.zero()
1738
+ mone = -R.one()
1739
+
1740
+ # Make sure we specify the ordering of the basis
1741
+ LB = self.basis()
1742
+ LK = list(LB.keys())
1743
+ LB = [LB[k] for k in LK]
1744
+ LI = list(range(len(LK)))
1745
+ Lmod = self.module()
1746
+ ambient = Lmod.is_ambient()
1747
+
1748
+ if M is not None:
1749
+ if not isinstance(M, Representation_abstract):
1750
+ M = self.representation(M)
1751
+
1752
+ MB = M.basis()
1753
+ MK = list(MB.keys())
1754
+ MB = [MB[k] for k in MK]
1755
+ MI = list(range(len(MK)))
1756
+
1757
+ def sgn(k, X):
1758
+ """
1759
+ Insert a new entry ``k`` into a strictly increasing
1760
+ list ``X`` in such a way that the resulting list is
1761
+ still strictly increasing.
1762
+ The return value is the pair ``(s, Y)``, where ``Y``
1763
+ is the resulting list (as tuple) and ``s`` is the
1764
+ Koszul sign incurred by the insertion (with the
1765
+ understanding that ``k`` originally stood to the
1766
+ left of the list).
1767
+ If ``k`` is already in ``X``, then the return value
1768
+ is ``(zero, None)``.
1769
+ """
1770
+ Y = list(X)
1771
+ for i in range(len(X)-1, -1, -1):
1772
+ val = X[i]
1773
+ if val == k:
1774
+ return zero, None
1775
+ if k > val:
1776
+ Y.insert(i+1, k)
1777
+ return mone**(i+1), tuple(Y)
1778
+ Y.insert(0, k)
1779
+ return R.one(), tuple(Y)
1780
+
1781
+ from sage.parallel.decorate import parallel
1782
+ from sage.matrix.constructor import matrix
1783
+
1784
+ @parallel(ncpus=ncpus)
1785
+ def compute_diff(k):
1786
+ """
1787
+ Build the ``k``-th differential (in parallel).
1788
+ """
1789
+ # The indices for the exterior algebra
1790
+ ext_ind = {tuple(X): i for i, X in enumerate(combinations(LI, k-1))}
1791
+
1792
+ # Compute the part independent of the module first ("part 2" of the computation)
1793
+ if sparse:
1794
+ p2_data = {}
1795
+ row = 0
1796
+ else:
1797
+ p2_data = []
1798
+ if not sparse:
1799
+ zv = [zero] * len(ext_ind)
1800
+ for X in combinations(LI, k):
1801
+ if not sparse:
1802
+ ret = list(zv)
1803
+ for i in range(k):
1804
+ Y = list(X)
1805
+ Y.pop(i)
1806
+ # This is where we would do the action on
1807
+ # the coefficients module
1808
+ # ret[indices[tuple(Y)]] += mone**i * zero
1809
+ for j in range(i + 1, k):
1810
+ # We shift j by 1 because we already removed
1811
+ # an earlier element from X.
1812
+ Z = tuple(Y[:j-1] + Y[j:])
1813
+ elt = mone**(i+j+1) * LB[X[i]].bracket(LB[X[j]])
1814
+ if not elt:
1815
+ continue
1816
+ if ambient:
1817
+ vec = elt.to_vector()
1818
+ else:
1819
+ vec = Lmod.coordinate_vector(elt.to_vector())
1820
+ for key, coeff in vec.iteritems():
1821
+ if not coeff:
1822
+ continue
1823
+ s, A = sgn(key, Z)
1824
+ if A is None:
1825
+ continue
1826
+ if sparse:
1827
+ coords = (row, ext_ind[A])
1828
+ if coords in p2_data:
1829
+ p2_data[coords] += s * coeff
1830
+ else:
1831
+ p2_data[coords] = s * coeff
1832
+ else:
1833
+ ret[ext_ind[A]] += s * coeff
1834
+ if sparse:
1835
+ row += 1
1836
+ else:
1837
+ p2_data.append(ret)
1838
+
1839
+ lenLI = Integer(len(LI))
1840
+ nrows = lenLI.binomial(k)
1841
+ ncols = lenLI.binomial(k - 1)
1842
+ MS = MatrixSpace(R, nrows, ncols, sparse=sparse)
1843
+ if M is None:
1844
+ p2 = MS(p2_data).transpose()
1845
+ p2.set_immutable()
1846
+ return p2
1847
+ p2 = matrix.identity(len(MI)).tensor_product(MS(p2_data)).transpose()
1848
+
1849
+ ten_ind = {tuple(Y): i for i, Y in enumerate(product(MI, ext_ind))}
1850
+
1851
+ # Now compute the part from the module ("part 1")
1852
+ if sparse:
1853
+ p1_data = {}
1854
+ row = 0
1855
+ else:
1856
+ p1_data = []
1857
+ if not sparse:
1858
+ zv = [zero] * len(ten_ind)
1859
+ for v, X in product(MI, combinations(LI, k)):
1860
+ if not sparse:
1861
+ ret = list(zv)
1862
+ for i in range(k):
1863
+ # We do mone**i because we are 0-based
1864
+ elt = mone**i * LB[X[i]] * MB[v]
1865
+ if not elt:
1866
+ continue
1867
+ Y = X[:i] + X[i+1:]
1868
+ for j in MI:
1869
+ coeff = elt[MK[j]]
1870
+ if not coeff:
1871
+ continue
1872
+ if sparse:
1873
+ coords = (row, ten_ind[j, Y])
1874
+ if coords in p1_data:
1875
+ p1_data[coords] += coeff
1876
+ else:
1877
+ p1_data[coords] = coeff
1878
+ else:
1879
+ ret[ten_ind[j, Y]] += coeff
1880
+ if sparse:
1881
+ row += 1
1882
+ else:
1883
+ p1_data.append(ret)
1884
+
1885
+ nrows = len(MI) * Integer(len(LI)).binomial(k)
1886
+ ncols = len(ten_ind)
1887
+ MS = MatrixSpace(R, nrows, ncols, sparse=sparse)
1888
+ ret = MS(p1_data).transpose() + p2
1889
+ ret.set_immutable()
1890
+ return ret
1891
+
1892
+ from sage.homology.chain_complex import ChainComplex
1893
+ ind = list(range(1, len(LI) + 1))
1894
+ chain_data = {X[0][0]: M for X, M in compute_diff(ind)}
1895
+ return ChainComplex(chain_data, degree_of_differential=-1)
1896
+
1897
+ def homology(self, deg=None, M=None, sparse=True, ncpus=None):
1898
+ r"""
1899
+ Return the Lie algebra homology of ``self``.
1900
+
1901
+ The Lie algebra homology is the homology of the
1902
+ Chevalley-Eilenberg chain complex.
1903
+
1904
+ INPUT:
1905
+
1906
+ - ``deg`` -- the degree of the homology (optional)
1907
+ - ``M`` -- (default: the trivial module) a right module
1908
+ of ``self``
1909
+ - ``sparse`` -- boolean (default: ``True``); whether to use sparse
1910
+ matrices for the Chevalley-Eilenberg chain complex
1911
+ - ``ncpus`` -- (optional) how many cpus to use when
1912
+ computing the Chevalley-Eilenberg chain complex
1913
+
1914
+ EXAMPLES::
1915
+
1916
+ sage: # needs sage.combinat sage.graphs sage.modules
1917
+ sage: L = lie_algebras.cross_product(QQ)
1918
+ sage: L.homology()
1919
+ {0: Vector space of dimension 1 over Rational Field,
1920
+ 1: Vector space of dimension 0 over Rational Field,
1921
+ 2: Vector space of dimension 0 over Rational Field,
1922
+ 3: Vector space of dimension 1 over Rational Field}
1923
+
1924
+ sage: # needs sage.combinat sage.modules
1925
+ sage: L = lie_algebras.pwitt(GF(5), 5)
1926
+ sage: L.homology()
1927
+ {0: Vector space of dimension 1 over Finite Field of size 5,
1928
+ 1: Vector space of dimension 0 over Finite Field of size 5,
1929
+ 2: Vector space of dimension 1 over Finite Field of size 5,
1930
+ 3: Vector space of dimension 1 over Finite Field of size 5,
1931
+ 4: Vector space of dimension 0 over Finite Field of size 5,
1932
+ 5: Vector space of dimension 1 over Finite Field of size 5}
1933
+
1934
+ sage: # needs sage.combinat sage.modules
1935
+ sage: d = {('x', 'y'): {'y': 2}}
1936
+ sage: L.<x,y> = LieAlgebra(ZZ, d)
1937
+ sage: L.homology()
1938
+ {0: Z, 1: Z x C2, 2: 0}
1939
+
1940
+ .. SEEALSO::
1941
+
1942
+ :meth:`chevalley_eilenberg_complex`
1943
+ """
1944
+ C = self.chevalley_eilenberg_complex(M=M, sparse=sparse,
1945
+ ncpus=ncpus)
1946
+ return C.homology(deg=deg)
1947
+
1948
+ def cohomology(self, deg=None, M=None, sparse=True, ncpus=None):
1949
+ r"""
1950
+ Return the Lie algebra cohomology of ``self``.
1951
+
1952
+ The Lie algebra cohomology is the cohomology of the
1953
+ Chevalley-Eilenberg cochain complex (which is the dual
1954
+ of the Chevalley-Eilenberg chain complex).
1955
+
1956
+ Let `\mathfrak{g}` be a Lie algebra and `M` a left
1957
+ `\mathfrak{g}`-module. It is known that `H^0(\mathfrak{g}; M)`
1958
+ is the subspace of `\mathfrak{g}`-invariants of `M`:
1959
+
1960
+ .. MATH::
1961
+
1962
+ H^0(\mathfrak{g}; M) = M^{\mathfrak{g}}
1963
+ = \{ m \in M \mid g m = 0
1964
+ \text{ for all } g \in \mathfrak{g} \}.
1965
+
1966
+ Additionally, `H^1(\mathfrak{g}; M)` is the space of
1967
+ derivations `\mathfrak{g} \to M`
1968
+ modulo the space of inner derivations, and
1969
+ `H^2(\mathfrak{g}; M)` is the space of equivalence classes
1970
+ of Lie algebra extensions of `\mathfrak{g}` by `M`.
1971
+
1972
+ INPUT:
1973
+
1974
+ - ``deg`` -- the degree of the homology (optional)
1975
+ - ``M`` -- (default: the trivial module) a right module
1976
+ of ``self``
1977
+ - ``sparse`` -- boolean (default: ``True``); whether to use sparse
1978
+ matrices for the Chevalley-Eilenberg chain complex
1979
+ - ``ncpus`` -- (optional) how many cpus to use when
1980
+ computing the Chevalley-Eilenberg chain complex
1981
+
1982
+ EXAMPLES::
1983
+
1984
+ sage: # needs sage.combinat sage.graphs sage.modules
1985
+ sage: L = lie_algebras.so(QQ, 4)
1986
+ sage: L.cohomology()
1987
+ {0: Vector space of dimension 1 over Rational Field,
1988
+ 1: Vector space of dimension 0 over Rational Field,
1989
+ 2: Vector space of dimension 0 over Rational Field,
1990
+ 3: Vector space of dimension 2 over Rational Field,
1991
+ 4: Vector space of dimension 0 over Rational Field,
1992
+ 5: Vector space of dimension 0 over Rational Field,
1993
+ 6: Vector space of dimension 1 over Rational Field}
1994
+
1995
+ sage: # needs sage.combinat sage.graphs sage.modules
1996
+ sage: L = lie_algebras.Heisenberg(QQ, 2)
1997
+ sage: L.cohomology()
1998
+ {0: Vector space of dimension 1 over Rational Field,
1999
+ 1: Vector space of dimension 4 over Rational Field,
2000
+ 2: Vector space of dimension 5 over Rational Field,
2001
+ 3: Vector space of dimension 5 over Rational Field,
2002
+ 4: Vector space of dimension 4 over Rational Field,
2003
+ 5: Vector space of dimension 1 over Rational Field}
2004
+
2005
+ sage: # needs sage.combinat sage.modules
2006
+ sage: d = {('x', 'y'): {'y': 2}}
2007
+ sage: L.<x,y> = LieAlgebra(ZZ, d)
2008
+ sage: L.cohomology()
2009
+ {0: Z, 1: Z, 2: C2}
2010
+
2011
+ .. SEEALSO::
2012
+
2013
+ :meth:`chevalley_eilenberg_complex`
2014
+
2015
+ REFERENCES:
2016
+
2017
+ - :wikipedia:`Lie_algebra_cohomology`
2018
+ """
2019
+ C = self.chevalley_eilenberg_complex(M=M, dual=True, sparse=sparse,
2020
+ ncpus=ncpus)
2021
+ return C.homology(deg=deg)
2022
+
2023
+ def as_finite_dimensional_algebra(self):
2024
+ """
2025
+ Return ``self`` as a :class:`FiniteDimensionalAlgebra`.
2026
+
2027
+ EXAMPLES::
2028
+
2029
+ sage: # needs sage.combinat sage.graphs sage.modules
2030
+ sage: L = lie_algebras.cross_product(QQ)
2031
+ sage: x, y, z = L.basis()
2032
+ sage: F = L.as_finite_dimensional_algebra()
2033
+ sage: X, Y, Z = F.basis()
2034
+ sage: x.bracket(y)
2035
+ Z
2036
+ sage: X * Y
2037
+ Z
2038
+ """
2039
+ from sage.matrix.constructor import matrix
2040
+
2041
+ K = self._basis_ordering
2042
+ mats = []
2043
+ R = self.base_ring()
2044
+ S = dict(self.structure_coefficients())
2045
+ V = self._dense_free_module()
2046
+ zero_vec = V.zero()
2047
+ for k in K:
2048
+ M = []
2049
+ for kp in K:
2050
+ if (k, kp) in S:
2051
+ M.append(-S[k, kp].to_vector())
2052
+ elif (kp, k) in S:
2053
+ M.append(S[kp, k].to_vector())
2054
+ else:
2055
+ M.append(zero_vec)
2056
+ mats.append(matrix(R, M))
2057
+ from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra
2058
+ return FiniteDimensionalAlgebra(R, mats, names=self._names)
2059
+
2060
+ def morphism(self, on_generators, codomain=None, base_map=None, check=True):
2061
+ r"""
2062
+ Return a Lie algebra morphism defined by images of a Lie
2063
+ generating subset of ``self``.
2064
+
2065
+ INPUT:
2066
+
2067
+ - ``on_generators`` -- dictionary ``{X: Y}`` of the images `Y`
2068
+ in ``codomain`` of elements `X` of ``domain``
2069
+ - ``codomain`` -- a Lie algebra (optional); this is inferred
2070
+ from the values of ``on_generators`` if not given
2071
+ - ``base_map`` -- a homomorphism from the base ring to something
2072
+ coercing into the codomain
2073
+ - ``check`` -- boolean (default: ``True``); if ``False`` the
2074
+ values on the Lie brackets implied by ``on_generators`` will
2075
+ not be checked for contradictory values
2076
+
2077
+ .. NOTE::
2078
+
2079
+ The keys of ``on_generators`` need to generate ``domain``
2080
+ as a Lie algebra.
2081
+
2082
+ .. SEEALSO::
2083
+
2084
+ :class:`sage.algebras.lie_algebras.morphism.LieAlgebraMorphism_from_generators`
2085
+
2086
+ EXAMPLES:
2087
+
2088
+ A quotient type Lie algebra morphism ::
2089
+
2090
+ sage: # needs sage.combinat sage.modules
2091
+ sage: L.<X,Y,Z,W> = LieAlgebra(QQ, {('X','Y'): {'Z': 1},
2092
+ ....: ('X','Z'): {'W': 1}})
2093
+ sage: K.<A,B> = LieAlgebra(QQ, abelian=True)
2094
+ sage: L.morphism({X: A, Y: B})
2095
+ Lie algebra morphism:
2096
+ From: Lie algebra on 4 generators (X, Y, Z, W) over Rational Field
2097
+ To: Abelian Lie algebra on 2 generators (A, B) over Rational Field
2098
+ Defn: X |--> A
2099
+ Y |--> B
2100
+ Z |--> 0
2101
+ W |--> 0
2102
+
2103
+ The reverse map `A \mapsto X`, `B \mapsto Y` does not define a Lie
2104
+ algebra morphism, since `[A,B] = 0`, but `[X,Y] \neq 0`::
2105
+
2106
+ sage: # needs sage.combinat sage.modules
2107
+ sage: K.morphism({A:X, B: Y})
2108
+ Traceback (most recent call last):
2109
+ ...
2110
+ ValueError: this does not define a Lie algebra morphism;
2111
+ contradictory values for brackets of length 2
2112
+
2113
+ However, it is still possible to create a morphism that acts nontrivially
2114
+ on the coefficients, even though it's not a Lie algebra morphism
2115
+ (since it isn't linear)::
2116
+
2117
+ sage: # needs sage.combinat sage.modules sage.rings.number_field
2118
+ sage: R.<x> = ZZ[]
2119
+ sage: K.<i> = NumberField(x^2 + 1)
2120
+ sage: cc = K.hom([-i])
2121
+ sage: L.<X,Y,Z,W> = LieAlgebra(K, {('X','Y'): {'Z': 1},
2122
+ ....: ('X','Z'): {'W': 1}})
2123
+ sage: M.<A,B> = LieAlgebra(K, abelian=True)
2124
+ sage: phi = L.morphism({X: A, Y: B}, base_map=cc)
2125
+ sage: phi(X)
2126
+ A
2127
+ sage: phi(i*X)
2128
+ -i*A
2129
+ """
2130
+ from sage.algebras.lie_algebras.morphism import LieAlgebraMorphism_from_generators
2131
+ return LieAlgebraMorphism_from_generators(on_generators, domain=self,
2132
+ codomain=codomain, base_map=base_map, check=check)
2133
+
2134
+ @cached_method
2135
+ def universal_polynomials(self):
2136
+ r"""
2137
+ Return the family of universal polynomials of ``self``.
2138
+
2139
+ The *universal polynomials* of a Lie algebra `L` with
2140
+ basis `\{e_i\}_{i \in I}` and structure coefficients
2141
+ `[e_i, e_j] = \tau_{ij}^a e_a` is given by
2142
+
2143
+ .. MATH::
2144
+
2145
+ P_{aij} = \sum_{u \in I} \tau_{ij}^u X_{au}
2146
+ - \sum_{s,t \in I} \tau_{st}^a X_{si} X_{tj},
2147
+
2148
+ where `a,i,j \in I`.
2149
+
2150
+ REFERENCES:
2151
+
2152
+ - [AM2020]_
2153
+
2154
+ EXAMPLES::
2155
+
2156
+ sage: # needs sage.combinat sage.modules
2157
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
2158
+ sage: L.universal_polynomials()
2159
+ Finite family {('x', 'x', 'y'): X01*X10 - X00*X11 + X00,
2160
+ ('y', 'x', 'y'): X10}
2161
+
2162
+ sage: # needs sage.combinat sage.graphs sage.modules
2163
+ sage: L = LieAlgebra(QQ, cartan_type=['A',1])
2164
+ sage: list(L.universal_polynomials())
2165
+ [-2*X01*X10 + 2*X00*X11 - 2*X00,
2166
+ -2*X02*X10 + 2*X00*X12 + X01,
2167
+ -2*X02*X11 + 2*X01*X12 - 2*X02,
2168
+ X01*X20 - X00*X21 - 2*X10,
2169
+ X02*X20 - X00*X22 + X11,
2170
+ X02*X21 - X01*X22 - 2*X12,
2171
+ -2*X11*X20 + 2*X10*X21 - 2*X20,
2172
+ -2*X12*X20 + 2*X10*X22 + X21,
2173
+ -2*X12*X21 + 2*X11*X22 - 2*X22]
2174
+
2175
+ sage: # long time, needs sage.combinat sage.graphs sage.modules
2176
+ sage: L = LieAlgebra(QQ, cartan_type=['B', 2])
2177
+ sage: al = RootSystem(['B', 2]).root_lattice().simple_roots()
2178
+ sage: k = list(L.basis().keys())[0]
2179
+ sage: UP = L.universal_polynomials()
2180
+ sage: len(UP)
2181
+ 450
2182
+ sage: UP[al[2], al[1], -al[1]]
2183
+ X0_7*X4_1 - X0_1*X4_7 - 2*X0_7*X5_1 + 2*X0_1*X5_7 + X2_7*X7_1
2184
+ - X2_1*X7_7 - X3_7*X8_1 + X3_1*X8_7 + X0_4
2185
+ """
2186
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
2187
+ I = self.basis().keys()
2188
+ n = len(I)
2189
+ s_coeffs = self.structure_coefficients(True)
2190
+ zero = self.base_ring().zero()
2191
+
2192
+ def sc(i, j):
2193
+ if i == j:
2194
+ return zero
2195
+ if i > j:
2196
+ return -s_coeffs[I[j], I[i]]
2197
+ return s_coeffs[I[i], I[j]]
2198
+ d = {}
2199
+ keys = []
2200
+ if n >= 10:
2201
+ vs = 'X{}_{}'
2202
+ else:
2203
+ vs = 'X{}{}'
2204
+ R = PolynomialRing(self.base_ring(), ','.join(vs.format(i, j)
2205
+ for i in range(n)
2206
+ for j in range(n)))
2207
+ X = [[R.gen(i+n*j) for i in range(n)] for j in range(n)]
2208
+ for a in range(n):
2209
+ for i in range(n):
2210
+ for j in range(i+1, n):
2211
+ k = (I[a], I[i], I[j])
2212
+ keys.append(k)
2213
+ if i != j:
2214
+ s = sc(i, j)
2215
+ d[k] = (R.sum(s[I[u]] * X[a][u] for u in range(n))
2216
+ - R.sum(sc(s, t)[I[a]] * X[s][i] * X[t][j]
2217
+ for s in range(n) for t in range(n) if s != t))
2218
+ else:
2219
+ d[k] = -R.sum(sc(s, t)[I[a]] * X[s][i] * X[t][j]
2220
+ for s in range(n) for t in range(n) if s != t)
2221
+ return Family(keys, d.__getitem__)
2222
+
2223
+ @cached_method
2224
+ def universal_commutative_algebra(self):
2225
+ r"""
2226
+ Return the universal commutative algebra associated to ``self``.
2227
+
2228
+ Let `I` be the index set of the basis of ``self``. Let
2229
+ `\mathcal{P} = \{P_{a,i,j}\}_{a,i,j \in I}` denote the
2230
+ universal polynomials of a Lie algebra `L`. The *universal
2231
+ commutative algebra* associated to `L` is the quotient
2232
+ ring `R[X_{ij}]_{i,j \in I} / (\mathcal{P})`.
2233
+
2234
+ EXAMPLES::
2235
+
2236
+ sage: # needs sage.combinat sage.libs.singular sage.modules
2237
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
2238
+ sage: A = L.universal_commutative_algebra()
2239
+ sage: a, b, c, d = A.gens()
2240
+ sage: a, b, c, d
2241
+ (X00bar, X01bar, 0, X11bar)
2242
+ sage: a*d - a
2243
+ 0
2244
+ """
2245
+ P = list(self.universal_polynomials())
2246
+ R = P[0].parent()
2247
+ return R.quotient(P)
2248
+
2249
+ def casimir_element(self, order=2, UEA=None, force_generic=False, basis=False):
2250
+ r"""
2251
+ Return a Casimir element of order ``order`` in the universal
2252
+ enveloping algebra of ``self``.
2253
+
2254
+ A *Casimir element* of order `k` is a distinguished basis element
2255
+ for the center of `U(\mathfrak{g})` of homogeneous degree `k`
2256
+ (that is, it is an element of `U_k \setminus U_{k-1}`, where
2257
+ `\{U_i\}_{i=0}^{\infty}` is the natural filtration of
2258
+ `U(\mathfrak{g})`). When `\mathfrak{g}` is a simple Lie algebra,
2259
+ then this spans `Z(U(\mathfrak{g}))_k`.
2260
+
2261
+ INPUT:
2262
+
2263
+ - ``order`` -- (default: ``2``) the order of the Casimir element
2264
+ - ``UEA`` -- (optional) the universal enveloping algebra
2265
+ implementation to return the result in
2266
+ - ``force_generic`` -- boolean (default: ``False``); if ``True``
2267
+ for the quadratic order, then this uses the default algorithm
2268
+ (otherwise this is ignored)
2269
+ - ``basis`` -- boolean (default: ``False``); if ``True``, this
2270
+ returns a basis of all Casimir elements of order ``order`` as a
2271
+ list
2272
+
2273
+ ALGORITHM:
2274
+
2275
+ For the quadratic order (i.e., ``order=2``), then this uses
2276
+ `K^{ij}`, the inverse of the Killing form matrix, to compute
2277
+ `C_{(2)} = \sum_{i,j} K^{ij} X_i \cdots X_j`, where `\{X_1, \ldots,
2278
+ X_n\}` is a basis for `\mathfrak{g}`. Otherwise this solves the
2279
+ system of equations
2280
+
2281
+ .. MATH::
2282
+
2283
+ f_{aj}^b \kappa^{jc\cdots d} + f_{aj}^c \kappa^{cj\cdots d}
2284
+ \cdots + f_{aj}^d \kappa^{bc \cdots j}
2285
+
2286
+ for the symmetric tensor `\kappa^{i_1 \cdots i_k}`, where `k` is
2287
+ the ``order``. This system comes from `[X_i, C_{(k)}] = 0` with
2288
+
2289
+ .. MATH::
2290
+
2291
+ C_{(k)} = \sum_{i_1, \ldots, i_k}^n
2292
+ \kappa^{i_1 \cdots i_k} X_{i_1} \cdots X_{i_k}.
2293
+
2294
+ EXAMPLES::
2295
+
2296
+ sage: # needs sage.combinat sage.graphs sage.modules
2297
+ sage: L = LieAlgebra(QQ, cartan_type=['A', 1])
2298
+ sage: C = L.casimir_element(); C
2299
+ 1/8*b1^2 + 1/2*b0*b2 - 1/4*b1
2300
+ sage: U = L.universal_enveloping_algebra()
2301
+ sage: all(g * C == C * g for g in U.gens())
2302
+ True
2303
+ sage: U = L.pbw_basis()
2304
+ sage: C = L.casimir_element(UEA=U); C
2305
+ 1/2*PBW[alpha[1]]*PBW[-alpha[1]] + 1/8*PBW[alphacheck[1]]^2
2306
+ - 1/4*PBW[alphacheck[1]]
2307
+ sage: all(g * C == C * g for g in U.algebra_generators())
2308
+ True
2309
+
2310
+ sage: # needs sage.combinat sage.graphs sage.modules
2311
+ sage: L = LieAlgebra(QQ, cartan_type=['B', 2])
2312
+ sage: U = L.pbw_basis()
2313
+ sage: C = L.casimir_element(UEA=U)
2314
+ sage: all(g * C == C * g for g in U.algebra_generators())
2315
+ True
2316
+
2317
+ sage: # needs sage.combinat sage.graphs sage.modules
2318
+ sage: L = LieAlgebra(QQ, cartan_type=['C', 3])
2319
+ sage: U = L.pbw_basis()
2320
+ sage: C = L.casimir_element(UEA=U)
2321
+ sage: all(g * C == C * g for g in U.algebra_generators())
2322
+ True
2323
+
2324
+ sage: # needs sage.combinat sage.graphs sage.modules
2325
+ sage: L = LieAlgebra(QQ, cartan_type=['A', 1])
2326
+ sage: C4 = L.casimir_element(order=4, UEA=L.pbw_basis()); C4
2327
+ 4*PBW[alpha[1]]^2*PBW[-alpha[1]]^2
2328
+ + 2*PBW[alpha[1]]*PBW[alphacheck[1]]^2*PBW[-alpha[1]]
2329
+ + 1/4*PBW[alphacheck[1]]^4 - PBW[alphacheck[1]]^3
2330
+ - 4*PBW[alpha[1]]*PBW[-alpha[1]] + 2*PBW[alphacheck[1]]
2331
+ sage: all(g * C4 == C4 * g for g in L.pbw_basis().algebra_generators())
2332
+ True
2333
+
2334
+ sage: # needs sage.combinat sage.graphs sage.modules
2335
+ sage: L = lie_algebras.Heisenberg(QQ, 2)
2336
+ sage: L.casimir_element()
2337
+ 0
2338
+
2339
+ sage: # needs sage.combinat sage.graphs sage.modules
2340
+ sage: g = LieAlgebra(QQ, cartan_type=['D',2])
2341
+ sage: U = g.pbw_basis()
2342
+ sage: U.casimir_element(2, basis=True)
2343
+ [2*PBW[alpha[2]]*PBW[-alpha[2]] + 1/2*PBW[alphacheck[2]]^2 - PBW[alphacheck[2]],
2344
+ 2*PBW[alpha[1]]*PBW[-alpha[1]] + 1/2*PBW[alphacheck[1]]^2 - PBW[alphacheck[1]]]
2345
+
2346
+ TESTS::
2347
+
2348
+ sage: # needs sage.combinat sage.graphs sage.modules
2349
+ sage: L = LieAlgebra(QQ, cartan_type=['A', 1])
2350
+ sage: L.casimir_element(1)
2351
+ Traceback (most recent call last):
2352
+ ...
2353
+ ValueError: invalid order
2354
+ sage: 4 * L.casimir_element() == L.casimir_element(force_generic=True)
2355
+ True
2356
+
2357
+ .. TODO::
2358
+
2359
+ Use the symmetry of the tensor to reduce the number of
2360
+ equations and/or variables to solve.
2361
+ """
2362
+ if order < 2:
2363
+ raise ValueError("invalid order")
2364
+
2365
+ if UEA is None:
2366
+ UEA = self.universal_enveloping_algebra()
2367
+
2368
+ B = self.basis()
2369
+
2370
+ if order == 2 and not force_generic and not basis:
2371
+ # Special case for the quadratic using the Killing form
2372
+ try:
2373
+ K = self.killing_form_matrix().inverse()
2374
+ return UEA.sum(K[i, j] * UEA(x) * UEA(y) for i, x in enumerate(B)
2375
+ for j, y in enumerate(B) if K[i, j])
2376
+ except (ValueError, TypeError, ZeroDivisionError):
2377
+ # fall back to finding solutions to the system of equations
2378
+ pass
2379
+
2380
+ keys = self.get_order()
2381
+ dim = len(keys)
2382
+ s_coeffs = dict(self.structure_coefficients())
2383
+ for k in list(s_coeffs.keys()):
2384
+ s_coeffs[k[1], k[0]] = -s_coeffs[k]
2385
+
2386
+ # setup the equations
2387
+ from sage.matrix.constructor import matrix
2388
+ from itertools import product
2389
+ eqns = matrix.zero(self.base_ring(), dim**(order+1), dim**order, sparse=True)
2390
+ for ii, p in enumerate(product(range(dim), repeat=order+1)):
2391
+ i = p[0]
2392
+ a = keys[i]
2393
+ for j, b in enumerate(keys):
2394
+ if (a, b) not in s_coeffs:
2395
+ continue
2396
+ sc_val = s_coeffs[a, b]
2397
+ for k in range(order):
2398
+ c = keys[p[k+1]]
2399
+ if not sc_val[c]:
2400
+ continue
2401
+ pp = list(p[1:])
2402
+ pp[k] = j
2403
+ jj = sum(dim**m * pp[m] for m in range(order))
2404
+ eqns[ii, jj] += sc_val[c]
2405
+
2406
+ ker = eqns.right_kernel()
2407
+ if ker.dimension() == 0:
2408
+ return self.zero()
2409
+
2410
+ del eqns # no need to hold onto the matrix
2411
+
2412
+ def to_prod(vec, index):
2413
+ coeff = vec[index]
2414
+ p = [0] * order
2415
+ base = dim ** (order-1)
2416
+ for i in range(order):
2417
+ p[i] = index // base
2418
+ index %= base
2419
+ base //= dim
2420
+ p.reverse()
2421
+ return coeff * UEA.prod(UEA(B[keys[i]]) for i in p)
2422
+
2423
+ tens = ker.basis()
2424
+
2425
+ if not basis:
2426
+ vec = tens[0]
2427
+ return UEA.sum(to_prod(vec, index) for index in vec.support())
2428
+
2429
+ return [UEA.sum(to_prod(vec, index) for index in vec.support())
2430
+ for vec in tens]
2431
+
2432
+ def faithful_representation(self, algorithm=None):
2433
+ r"""
2434
+ Return a faithful representation of ``self``.
2435
+
2436
+ By Ado's and Iwasawa's theorems, every finite dimensional
2437
+ Lie algebra has a faithful finite dimensional representation.
2438
+
2439
+ INPUT:
2440
+
2441
+ - ``algorithm`` -- one of the following depending on the
2442
+ classification of the Lie algebra:
2443
+
2444
+ Nilpotent:
2445
+
2446
+ * ``'regular'`` -- use the universal enveloping algebra quotient
2447
+ :class:`~sage.algebras.lie_algebras.representation.FaithfulRepresentationNilpotentPBW`
2448
+ * ``'minimal'`` -- construct the minimal representation (for
2449
+ precise details, see the documentation of
2450
+ :class:`~sage.algebras.lie_algebras.representation.FaithfulRepresentationNilpotentPBW`)
2451
+
2452
+ Solvable:
2453
+
2454
+ * Not implemented
2455
+
2456
+ Semisimple:
2457
+
2458
+ * Not implemented
2459
+
2460
+ General case
2461
+
2462
+ * ``'generic'`` -- generic algorithm (only implemented currently
2463
+ for positive characteristic)
2464
+
2465
+ Note that the algorithm for any more generic cases can be used
2466
+ in the specialized cases. For instance, using ``'generic'`` for
2467
+ any Lie algebra (e.g., even if nilpotent) will use the generic
2468
+ implementation.
2469
+
2470
+ EXAMPLES::
2471
+
2472
+ sage: # needs sage.combinat sage.graphs sage.modules
2473
+ sage: H2 = lie_algebras.Heisenberg(QQ, 2)
2474
+ sage: H2.is_nilpotent()
2475
+ True
2476
+ sage: F = H2.faithful_representation(); F
2477
+ Faithful 16 dimensional representation of
2478
+ Heisenberg algebra of rank 2 over Rational Field
2479
+ sage: M = H2.faithful_representation(algorithm='minimal'); M
2480
+ Minimal faithful representation of
2481
+ Heisenberg algebra of rank 2 over Rational Field
2482
+ sage: M.dimension()
2483
+ 4
2484
+ sage: H2.faithful_representation(algorithm='invalid')
2485
+ Traceback (most recent call last):
2486
+ ...
2487
+ ValueError: invalid algorithm 'invalid'
2488
+
2489
+ sage: # needs sage.combinat sage.modules
2490
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
2491
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
2492
+ ....: ('d','e'): {'c':1}}
2493
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
2494
+ sage: L.is_nilpotent()
2495
+ False
2496
+ sage: L.is_solvable()
2497
+ True
2498
+ sage: L.faithful_representation()
2499
+ Traceback (most recent call last):
2500
+ ...
2501
+ NotImplementedError: only implemented for nilpotent Lie algebras
2502
+
2503
+ sage: # needs sage.combinat sage.graphs sage.modules
2504
+ sage: sl3 = LieAlgebra(QQ, cartan_type=['A', 2])
2505
+ sage: sl3.is_semisimple()
2506
+ True
2507
+ sage: sl3.faithful_representation()
2508
+ Traceback (most recent call last):
2509
+ ...
2510
+ NotImplementedError: only implemented for nilpotent Lie algebras
2511
+ """
2512
+ if self.is_nilpotent():
2513
+ if algorithm is None:
2514
+ algorithm = "regular"
2515
+ if algorithm == "regular":
2516
+ from sage.algebras.lie_algebras.representation import FaithfulRepresentationNilpotentPBW
2517
+ return FaithfulRepresentationNilpotentPBW(self, minimal=False)
2518
+ if algorithm == "minimal":
2519
+ from sage.algebras.lie_algebras.representation import FaithfulRepresentationNilpotentPBW
2520
+ return FaithfulRepresentationNilpotentPBW(self, minimal=True)
2521
+ if algorithm is None or algorithm == "generic":
2522
+ if self.base_ring().characteristic() > 0:
2523
+ from sage.algebras.lie_algebras.representation import FaithfulRepresentationPBWPosChar
2524
+ return FaithfulRepresentationPBWPosChar(self)
2525
+ raise NotImplementedError("only implemented for nilpotent Lie algebras")
2526
+ raise ValueError("invalid algorithm '{}'".format(algorithm))
2527
+
2528
+ class ElementMethods:
2529
+ def adjoint_matrix(self, sparse=False):
2530
+ # In #11111 (more or less) by using matrix of a morphism
2531
+ """
2532
+ Return the matrix of the adjoint action of ``self``.
2533
+
2534
+ EXAMPLES::
2535
+
2536
+ sage: # needs sage.combinat sage.libs.singular sage.modules
2537
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
2538
+ sage: L.an_element().adjoint_matrix()
2539
+ [0 0 0]
2540
+ [0 0 0]
2541
+ [0 0 0]
2542
+ sage: L.an_element().adjoint_matrix(sparse=True).is_sparse()
2543
+ True
2544
+
2545
+ ::
2546
+
2547
+ sage: # needs sage.combinat sage.modules
2548
+ sage: L.<x,y> = LieAlgebra(QQ, {('x','y'): {'x':1}})
2549
+ sage: x.adjoint_matrix()
2550
+ [0 1]
2551
+ [0 0]
2552
+ sage: y.adjoint_matrix()
2553
+ [-1 0]
2554
+ [ 0 0]
2555
+
2556
+ We verify that this forms a representation::
2557
+
2558
+ sage: # needs sage.combinat sage.modules
2559
+ sage: sl3 = lie_algebras.sl(QQ, 3)
2560
+ sage: e1, e2 = sl3.e(1), sl3.e(2)
2561
+ sage: e12 = e1.bracket(e2)
2562
+ sage: E1, E2 = e1.adjoint_matrix(), e2.adjoint_matrix()
2563
+ sage: E1 * E2 - E2 * E1 == e12.adjoint_matrix()
2564
+ True
2565
+
2566
+ TESTS::
2567
+
2568
+ sage: # needs sage.combinat sage.modules
2569
+ sage: scoeffs = {('a','d'): {'a':1}, ('a','e'): {'b':-1},
2570
+ ....: ('b','d'): {'b':1}, ('b','e'): {'a':1},
2571
+ ....: ('d','e'): {'c':1}}
2572
+ sage: L.<a,b,c,d,e> = LieAlgebra(QQ, scoeffs)
2573
+ sage: S = L.solvable_radical()
2574
+ sage: elt = S.derived_subalgebra().an_element()
2575
+ sage: elt.adjoint_matrix()
2576
+ [0 0 0]
2577
+ [0 0 0]
2578
+ [0 0 0]
2579
+ """
2580
+ from sage.matrix.constructor import matrix
2581
+
2582
+ P = self.parent()
2583
+ basis = P.basis()
2584
+ return matrix(self.base_ring(),
2585
+ [P.bracket(self, b).to_vector(sparse=sparse) for b in basis],
2586
+ sparse=sparse).transpose()
2587
+
2588
+ def to_vector(self, sparse=False, order=None):
2589
+ r"""
2590
+ Return the vector in ``g.module()`` corresponding to the
2591
+ element ``self`` of ``g`` (where ``g`` is the parent of
2592
+ ``self``).
2593
+
2594
+ Implement this if you implement ``g.module()``.
2595
+ See :meth:`sage.categories.lie_algebras.LieAlgebras.module`
2596
+ for how this is to be done.
2597
+
2598
+ EXAMPLES::
2599
+
2600
+ sage: # needs sage.combinat sage.libs.singular sage.modules
2601
+ sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
2602
+ sage: L.an_element().to_vector()
2603
+ (0, 0, 0)
2604
+ sage: L.an_element().to_vector(sparse=True)
2605
+ (0, 0, 0)
2606
+
2607
+ sage: # needs sage.combinat sage.groupssage.modules
2608
+ sage: D = DescentAlgebra(QQ, 4).D()
2609
+ sage: L = LieAlgebra(associative=D)
2610
+ sage: L.an_element().to_vector()
2611
+ (1, 1, 1, 1, 1, 1, 1, 1)
2612
+
2613
+ TESTS:
2614
+
2615
+ Check that the error raised agrees with the one
2616
+ from ``monomial_coefficients()`` (see :issue:`25007`)::
2617
+
2618
+ sage: # needs sage.combinat sage.modules
2619
+ sage: L = lie_algebras.sp(QQ, 4, representation='matrix')
2620
+ sage: x = L.an_element()
2621
+ sage: x.monomial_coefficients()
2622
+ Traceback (most recent call last):
2623
+ ...
2624
+ NotImplementedError: the basis is not defined
2625
+ sage: x.to_vector()
2626
+ Traceback (most recent call last):
2627
+ ...
2628
+ NotImplementedError: the basis is not defined
2629
+ """
2630
+ mc = self.monomial_coefficients(copy=False)
2631
+ if sparse:
2632
+ from sage.modules.free_module import FreeModule
2633
+ M = FreeModule(self.parent().base_ring(), self.dimension(), sparse=True)
2634
+ if order is None:
2635
+ order = {b: i for i, b in enumerate(self.parent()._basis_ordering)}
2636
+ return M({order[k]: c for k, c in mc.items()})
2637
+ else:
2638
+ M = self.parent().module()
2639
+ B = M.basis()
2640
+ if order is None:
2641
+ order = self.parent()._basis_ordering
2642
+ return M.sum(mc[k] * B[i] for i, k in enumerate(order) if k in mc)
2643
+
2644
+ _vector_ = to_vector
2645
+
2646
+ class Subobjects(SubobjectsCategory):
2647
+ """
2648
+ A category for subalgebras of a finite dimensional Lie algebra
2649
+ with basis.
2650
+ """
2651
+ class ParentMethods:
2652
+ @abstract_method
2653
+ def ambient(self):
2654
+ """
2655
+ Return the ambient Lie algebra of ``self``.
2656
+
2657
+ EXAMPLES::
2658
+
2659
+ sage: # needs sage.combinat sage.libs.singular sage.modules
2660
+ sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis()
2661
+ sage: L = C.example()
2662
+ sage: a, b, c = L.lie_algebra_generators()
2663
+ sage: S = L.subalgebra([2*a + b, b + c])
2664
+ sage: S.ambient() == L
2665
+ True
2666
+ """
2667
+
2668
+ @abstract_method
2669
+ def basis_matrix(self):
2670
+ """
2671
+ Return the basis matrix of ``self``.
2672
+
2673
+ EXAMPLES::
2674
+
2675
+ sage: # needs sage.combinat sage.libs.singular sage.modules
2676
+ sage: C = LieAlgebras(QQ).FiniteDimensional().WithBasis()
2677
+ sage: L = C.example()
2678
+ sage: a, b, c = L.lie_algebra_generators()
2679
+ sage: S = L.subalgebra([2*a + b, b + c])
2680
+ sage: S.basis_matrix()
2681
+ [ 1 0 -1/2]
2682
+ [ 0 1 1]
2683
+ """
2684
+
2685
+ def reduce(self, X):
2686
+ r"""
2687
+ Reduce an element of the ambient Lie algebra modulo the
2688
+ ideal ``self``.
2689
+
2690
+ INPUT:
2691
+
2692
+ - ``X`` -- an element of the ambient Lie algebra
2693
+
2694
+ OUTPUT:
2695
+
2696
+ An element `Y` of the ambient Lie algebra that is contained
2697
+ in a fixed complementary submodule `V` to ``self`` such that
2698
+ `X = Y` mod ``self``.
2699
+
2700
+ When the base ring of ``self`` is a field, the complementary
2701
+ submodule `V` is spanned by the elements of the basis that
2702
+ are not the leading supports of the basis of ``self``.
2703
+
2704
+ EXAMPLES:
2705
+
2706
+ An example reduction in a 6 dimensional Lie algebra::
2707
+
2708
+ sage: # needs sage.combinat sage.modules
2709
+ sage: sc = {('a','b'): {'d': 1}, ('a','c'): {'e': 1},
2710
+ ....: ('b','c'): {'f': 1}}
2711
+ sage: L.<a,b,c,d,e,f> = LieAlgebra(QQ, sc)
2712
+ sage: I = L.ideal(c)
2713
+ sage: I.reduce(a + b + c + d + e + f)
2714
+ a + b + d
2715
+
2716
+ The reduction of an element is zero if and only if the
2717
+ element belongs to the subalgebra::
2718
+
2719
+ sage: # needs sage.combinat sage.modules
2720
+ sage: I.reduce(c + e)
2721
+ 0
2722
+ sage: c + e in I
2723
+ True
2724
+
2725
+ Over non-fields, the complementary submodule may not be spanned
2726
+ by a subset of the basis of the ambient Lie algebra::
2727
+
2728
+ sage: # needs sage.combinat sage.libs.singular sage.modules
2729
+ sage: L.<X,Y,Z> = LieAlgebra(ZZ, {('X','Y'): {'Z': 3}})
2730
+ sage: I = L.ideal(Y)
2731
+ sage: I.basis()
2732
+ Finite family {'Y': Y, 'Z': 3*Z}
2733
+ sage: I.reduce(3*Z)
2734
+ 0
2735
+ sage: I.reduce(Y + 14*Z)
2736
+ 2*Z
2737
+
2738
+ We can reduce elements of a subalgebra `A` by an ideal `B`
2739
+ (:issue:`40137`)::
2740
+
2741
+ sage: # needs sage.combinat sage.modules
2742
+ sage: L.<a,b,c,d> = LieAlgebra(QQ, {('a','b'): {'c': 1, 'd':1}, ('a','c'): {'b':1}})
2743
+ sage: A = L.ideal([b, c, d])
2744
+ sage: B = L.ideal([c+d])
2745
+ sage: [B.reduce(v) for v in A.basis()]
2746
+ [0, c, -c]
2747
+ sage: A.basis()
2748
+ Finite family {'b': b, 'c': c, 'd': d}
2749
+ sage: B.basis()
2750
+ Finite family {'b': b, 'd': c + d}
2751
+ sage: all(B.reduce(v).parent() is A for v in A.basis())
2752
+ True
2753
+ """
2754
+ R = self.base_ring()
2755
+ from sage.categories.fields import Fields
2756
+ is_field = R in Fields()
2757
+ P = X.parent()
2758
+ X = self.ambient()(X) # make sure it is in the ambient space
2759
+ for Y in self.basis():
2760
+ Y = self.lift(Y)
2761
+ k, c = Y.leading_item(key=self._order)
2762
+ if not X[k]: # scalar will be 0
2763
+ continue
2764
+
2765
+ if is_field:
2766
+ X -= (X[k] / c) * Y
2767
+ else:
2768
+ try:
2769
+ q, _ = X[k].quo_rem(c)
2770
+ X -= q * Y
2771
+ except AttributeError:
2772
+ break
2773
+
2774
+ return P(X) # bring it back to the parent we started with