passagemath-modules 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_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.

Potentially problematic release.


This version of passagemath-modules might be problematic. Click here for more details.

Files changed (806) hide show
  1. passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
  2. passagemath_modules-10.6.31rc3.dist-info/RECORD +806 -0
  3. passagemath_modules-10.6.31rc3.dist-info/WHEEL +6 -0
  4. passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_modules.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  6. passagemath_modules.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
  7. passagemath_modules.libs/libgsl-e3525837.so.28.0.0 +0 -0
  8. passagemath_modules.libs/libmpc-c5c421e1.so.3.3.1 +0 -0
  9. passagemath_modules.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
  10. passagemath_modules.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  11. sage/algebras/all__sagemath_modules.py +20 -0
  12. sage/algebras/catalog.py +148 -0
  13. sage/algebras/clifford_algebra.py +3107 -0
  14. sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  15. sage/algebras/clifford_algebra_element.pxd +16 -0
  16. sage/algebras/clifford_algebra_element.pyx +997 -0
  17. sage/algebras/commutative_dga.py +4252 -0
  18. sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-gnu.so +0 -0
  19. sage/algebras/exterior_algebra_groebner.pxd +55 -0
  20. sage/algebras/exterior_algebra_groebner.pyx +727 -0
  21. sage/algebras/finite_dimensional_algebras/all.py +2 -0
  22. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
  23. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  24. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
  25. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
  26. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
  27. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
  28. sage/algebras/finite_gca.py +528 -0
  29. sage/algebras/group_algebra.py +232 -0
  30. sage/algebras/lie_algebras/abelian.py +197 -0
  31. sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
  32. sage/algebras/lie_algebras/all.py +25 -0
  33. sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
  34. sage/algebras/lie_algebras/bch.py +177 -0
  35. sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
  36. sage/algebras/lie_algebras/bgg_resolution.py +232 -0
  37. sage/algebras/lie_algebras/center_uea.py +767 -0
  38. sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
  39. sage/algebras/lie_algebras/examples.py +683 -0
  40. sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
  41. sage/algebras/lie_algebras/heisenberg.py +820 -0
  42. sage/algebras/lie_algebras/lie_algebra.py +1562 -0
  43. sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  44. sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
  45. sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
  46. sage/algebras/lie_algebras/morphism.py +661 -0
  47. sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
  48. sage/algebras/lie_algebras/onsager.py +1324 -0
  49. sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
  50. sage/algebras/lie_algebras/quotient.py +462 -0
  51. sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
  52. sage/algebras/lie_algebras/representation.py +1040 -0
  53. sage/algebras/lie_algebras/structure_coefficients.py +459 -0
  54. sage/algebras/lie_algebras/subalgebra.py +967 -0
  55. sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
  56. sage/algebras/lie_algebras/verma_module.py +1630 -0
  57. sage/algebras/lie_algebras/virasoro.py +1186 -0
  58. sage/algebras/octonion_algebra.cpython-314-aarch64-linux-gnu.so +0 -0
  59. sage/algebras/octonion_algebra.pxd +20 -0
  60. sage/algebras/octonion_algebra.pyx +987 -0
  61. sage/algebras/orlik_solomon.py +907 -0
  62. sage/algebras/orlik_terao.py +779 -0
  63. sage/algebras/steenrod/all.py +7 -0
  64. sage/algebras/steenrod/steenrod_algebra.py +4258 -0
  65. sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
  66. sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
  67. sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
  68. sage/algebras/weyl_algebra.py +1126 -0
  69. sage/all__sagemath_modules.py +62 -0
  70. sage/calculus/all__sagemath_modules.py +19 -0
  71. sage/calculus/expr.py +205 -0
  72. sage/calculus/integration.cpython-314-aarch64-linux-gnu.so +0 -0
  73. sage/calculus/integration.pyx +698 -0
  74. sage/calculus/interpolation.cpython-314-aarch64-linux-gnu.so +0 -0
  75. sage/calculus/interpolation.pxd +13 -0
  76. sage/calculus/interpolation.pyx +387 -0
  77. sage/calculus/interpolators.cpython-314-aarch64-linux-gnu.so +0 -0
  78. sage/calculus/interpolators.pyx +326 -0
  79. sage/calculus/ode.cpython-314-aarch64-linux-gnu.so +0 -0
  80. sage/calculus/ode.pxd +5 -0
  81. sage/calculus/ode.pyx +610 -0
  82. sage/calculus/riemann.cpython-314-aarch64-linux-gnu.so +0 -0
  83. sage/calculus/riemann.pyx +1521 -0
  84. sage/calculus/test_sympy.py +201 -0
  85. sage/calculus/transforms/all.py +7 -0
  86. sage/calculus/transforms/dft.py +844 -0
  87. sage/calculus/transforms/dwt.cpython-314-aarch64-linux-gnu.so +0 -0
  88. sage/calculus/transforms/dwt.pxd +7 -0
  89. sage/calculus/transforms/dwt.pyx +160 -0
  90. sage/calculus/transforms/fft.cpython-314-aarch64-linux-gnu.so +0 -0
  91. sage/calculus/transforms/fft.pxd +12 -0
  92. sage/calculus/transforms/fft.pyx +487 -0
  93. sage/calculus/wester.py +662 -0
  94. sage/coding/abstract_code.py +1108 -0
  95. sage/coding/ag_code.py +868 -0
  96. sage/coding/ag_code_decoders.cpython-314-aarch64-linux-gnu.so +0 -0
  97. sage/coding/ag_code_decoders.pyx +2639 -0
  98. sage/coding/all.py +15 -0
  99. sage/coding/bch_code.py +494 -0
  100. sage/coding/binary_code.cpython-314-aarch64-linux-gnu.so +0 -0
  101. sage/coding/binary_code.pxd +124 -0
  102. sage/coding/binary_code.pyx +4139 -0
  103. sage/coding/bounds_catalog.py +43 -0
  104. sage/coding/channel.py +819 -0
  105. sage/coding/channels_catalog.py +29 -0
  106. sage/coding/code_bounds.py +755 -0
  107. sage/coding/code_constructions.py +804 -0
  108. sage/coding/codes_catalog.py +111 -0
  109. sage/coding/cyclic_code.py +1329 -0
  110. sage/coding/databases.py +316 -0
  111. sage/coding/decoder.py +373 -0
  112. sage/coding/decoders_catalog.py +88 -0
  113. sage/coding/delsarte_bounds.py +709 -0
  114. sage/coding/encoder.py +390 -0
  115. sage/coding/encoders_catalog.py +64 -0
  116. sage/coding/extended_code.py +468 -0
  117. sage/coding/gabidulin_code.py +1058 -0
  118. sage/coding/golay_code.py +404 -0
  119. sage/coding/goppa_code.py +441 -0
  120. sage/coding/grs_code.py +2371 -0
  121. sage/coding/guava.py +107 -0
  122. sage/coding/guruswami_sudan/all.py +1 -0
  123. sage/coding/guruswami_sudan/gs_decoder.py +897 -0
  124. sage/coding/guruswami_sudan/interpolation.py +409 -0
  125. sage/coding/guruswami_sudan/utils.py +176 -0
  126. sage/coding/hamming_code.py +176 -0
  127. sage/coding/information_set_decoder.py +1032 -0
  128. sage/coding/kasami_codes.cpython-314-aarch64-linux-gnu.so +0 -0
  129. sage/coding/kasami_codes.pyx +351 -0
  130. sage/coding/linear_code.py +3067 -0
  131. sage/coding/linear_code_no_metric.py +1354 -0
  132. sage/coding/linear_rank_metric.py +961 -0
  133. sage/coding/parity_check_code.py +353 -0
  134. sage/coding/punctured_code.py +719 -0
  135. sage/coding/reed_muller_code.py +999 -0
  136. sage/coding/self_dual_codes.py +942 -0
  137. sage/coding/source_coding/all.py +2 -0
  138. sage/coding/source_coding/huffman.py +553 -0
  139. sage/coding/subfield_subcode.py +423 -0
  140. sage/coding/two_weight_db.py +399 -0
  141. sage/combinat/all__sagemath_modules.py +7 -0
  142. sage/combinat/cartesian_product.py +347 -0
  143. sage/combinat/family.py +11 -0
  144. sage/combinat/free_module.py +1977 -0
  145. sage/combinat/root_system/all.py +147 -0
  146. sage/combinat/root_system/ambient_space.py +527 -0
  147. sage/combinat/root_system/associahedron.py +471 -0
  148. sage/combinat/root_system/braid_move_calculator.py +143 -0
  149. sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-gnu.so +0 -0
  150. sage/combinat/root_system/braid_orbit.pyx +144 -0
  151. sage/combinat/root_system/branching_rules.py +2301 -0
  152. sage/combinat/root_system/cartan_matrix.py +1245 -0
  153. sage/combinat/root_system/cartan_type.py +3069 -0
  154. sage/combinat/root_system/coxeter_group.py +162 -0
  155. sage/combinat/root_system/coxeter_matrix.py +1261 -0
  156. sage/combinat/root_system/coxeter_type.py +681 -0
  157. sage/combinat/root_system/dynkin_diagram.py +900 -0
  158. sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
  159. sage/combinat/root_system/fundamental_group.py +795 -0
  160. sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
  161. sage/combinat/root_system/integrable_representations.py +1227 -0
  162. sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
  163. sage/combinat/root_system/pieri_factors.py +1147 -0
  164. sage/combinat/root_system/plot.py +1615 -0
  165. sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
  166. sage/combinat/root_system/root_lattice_realizations.py +4628 -0
  167. sage/combinat/root_system/root_space.py +487 -0
  168. sage/combinat/root_system/root_system.py +882 -0
  169. sage/combinat/root_system/type_A.py +348 -0
  170. sage/combinat/root_system/type_A_affine.py +227 -0
  171. sage/combinat/root_system/type_A_infinity.py +241 -0
  172. sage/combinat/root_system/type_B.py +347 -0
  173. sage/combinat/root_system/type_BC_affine.py +287 -0
  174. sage/combinat/root_system/type_B_affine.py +216 -0
  175. sage/combinat/root_system/type_C.py +317 -0
  176. sage/combinat/root_system/type_C_affine.py +188 -0
  177. sage/combinat/root_system/type_D.py +357 -0
  178. sage/combinat/root_system/type_D_affine.py +208 -0
  179. sage/combinat/root_system/type_E.py +641 -0
  180. sage/combinat/root_system/type_E_affine.py +231 -0
  181. sage/combinat/root_system/type_F.py +387 -0
  182. sage/combinat/root_system/type_F_affine.py +137 -0
  183. sage/combinat/root_system/type_G.py +293 -0
  184. sage/combinat/root_system/type_G_affine.py +132 -0
  185. sage/combinat/root_system/type_H.py +105 -0
  186. sage/combinat/root_system/type_I.py +110 -0
  187. sage/combinat/root_system/type_Q.py +150 -0
  188. sage/combinat/root_system/type_affine.py +509 -0
  189. sage/combinat/root_system/type_dual.py +704 -0
  190. sage/combinat/root_system/type_folded.py +301 -0
  191. sage/combinat/root_system/type_marked.py +748 -0
  192. sage/combinat/root_system/type_reducible.py +601 -0
  193. sage/combinat/root_system/type_relabel.py +730 -0
  194. sage/combinat/root_system/type_super_A.py +837 -0
  195. sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
  196. sage/combinat/root_system/weight_space.py +639 -0
  197. sage/combinat/root_system/weyl_characters.py +2238 -0
  198. sage/crypto/__init__.py +4 -0
  199. sage/crypto/all.py +28 -0
  200. sage/crypto/block_cipher/all.py +7 -0
  201. sage/crypto/block_cipher/des.py +1065 -0
  202. sage/crypto/block_cipher/miniaes.py +2171 -0
  203. sage/crypto/block_cipher/present.py +909 -0
  204. sage/crypto/block_cipher/sdes.py +1527 -0
  205. sage/crypto/boolean_function.cpython-314-aarch64-linux-gnu.so +0 -0
  206. sage/crypto/boolean_function.pxd +10 -0
  207. sage/crypto/boolean_function.pyx +1487 -0
  208. sage/crypto/cipher.py +78 -0
  209. sage/crypto/classical.py +3668 -0
  210. sage/crypto/classical_cipher.py +569 -0
  211. sage/crypto/cryptosystem.py +387 -0
  212. sage/crypto/key_exchange/all.py +7 -0
  213. sage/crypto/key_exchange/catalog.py +24 -0
  214. sage/crypto/key_exchange/diffie_hellman.py +323 -0
  215. sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
  216. sage/crypto/lattice.py +312 -0
  217. sage/crypto/lfsr.py +295 -0
  218. sage/crypto/lwe.py +840 -0
  219. sage/crypto/mq/__init__.py +4 -0
  220. sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
  221. sage/crypto/mq/rijndael_gf.py +2345 -0
  222. sage/crypto/mq/sbox.py +7 -0
  223. sage/crypto/mq/sr.py +3344 -0
  224. sage/crypto/public_key/all.py +5 -0
  225. sage/crypto/public_key/blum_goldwasser.py +776 -0
  226. sage/crypto/sbox.cpython-314-aarch64-linux-gnu.so +0 -0
  227. sage/crypto/sbox.pyx +2090 -0
  228. sage/crypto/sboxes.py +2090 -0
  229. sage/crypto/stream.py +390 -0
  230. sage/crypto/stream_cipher.py +297 -0
  231. sage/crypto/util.py +519 -0
  232. sage/ext/all__sagemath_modules.py +1 -0
  233. sage/ext/interpreters/__init__.py +1 -0
  234. sage/ext/interpreters/all__sagemath_modules.py +2 -0
  235. sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-gnu.so +0 -0
  236. sage/ext/interpreters/wrapper_cc.pxd +30 -0
  237. sage/ext/interpreters/wrapper_cc.pyx +252 -0
  238. sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-gnu.so +0 -0
  239. sage/ext/interpreters/wrapper_cdf.pxd +26 -0
  240. sage/ext/interpreters/wrapper_cdf.pyx +245 -0
  241. sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-gnu.so +0 -0
  242. sage/ext/interpreters/wrapper_rdf.pxd +23 -0
  243. sage/ext/interpreters/wrapper_rdf.pyx +221 -0
  244. sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-gnu.so +0 -0
  245. sage/ext/interpreters/wrapper_rr.pxd +28 -0
  246. sage/ext/interpreters/wrapper_rr.pyx +335 -0
  247. sage/geometry/all__sagemath_modules.py +5 -0
  248. sage/geometry/toric_lattice.py +1745 -0
  249. sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-gnu.so +0 -0
  250. sage/geometry/toric_lattice_element.pyx +432 -0
  251. sage/groups/abelian_gps/abelian_group.py +1925 -0
  252. sage/groups/abelian_gps/abelian_group_element.py +164 -0
  253. sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
  254. sage/groups/abelian_gps/dual_abelian_group.py +421 -0
  255. sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
  256. sage/groups/abelian_gps/element_base.py +341 -0
  257. sage/groups/abelian_gps/values.py +488 -0
  258. sage/groups/additive_abelian/additive_abelian_group.py +476 -0
  259. sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
  260. sage/groups/additive_abelian/all.py +4 -0
  261. sage/groups/additive_abelian/qmodnz.py +231 -0
  262. sage/groups/additive_abelian/qmodnz_element.py +349 -0
  263. sage/groups/affine_gps/affine_group.py +535 -0
  264. sage/groups/affine_gps/all.py +1 -0
  265. sage/groups/affine_gps/catalog.py +17 -0
  266. sage/groups/affine_gps/euclidean_group.py +246 -0
  267. sage/groups/affine_gps/group_element.py +562 -0
  268. sage/groups/all__sagemath_modules.py +12 -0
  269. sage/groups/galois_group.py +479 -0
  270. sage/groups/matrix_gps/all.py +4 -0
  271. sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
  272. sage/groups/matrix_gps/catalog.py +26 -0
  273. sage/groups/matrix_gps/coxeter_group.py +927 -0
  274. sage/groups/matrix_gps/finitely_generated.py +487 -0
  275. sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-gnu.so +0 -0
  276. sage/groups/matrix_gps/group_element.pxd +11 -0
  277. sage/groups/matrix_gps/group_element.pyx +431 -0
  278. sage/groups/matrix_gps/linear.py +440 -0
  279. sage/groups/matrix_gps/matrix_group.py +617 -0
  280. sage/groups/matrix_gps/named_group.py +296 -0
  281. sage/groups/matrix_gps/orthogonal.py +544 -0
  282. sage/groups/matrix_gps/symplectic.py +251 -0
  283. sage/groups/matrix_gps/unitary.py +436 -0
  284. sage/groups/misc_gps/all__sagemath_modules.py +1 -0
  285. sage/groups/misc_gps/argument_groups.py +1905 -0
  286. sage/groups/misc_gps/imaginary_groups.py +479 -0
  287. sage/groups/perm_gps/all__sagemath_modules.py +1 -0
  288. sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
  289. sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-gnu.so +0 -0
  290. sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
  291. sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
  292. sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-gnu.so +0 -0
  293. sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
  294. sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
  295. sage/homology/algebraic_topological_model.py +595 -0
  296. sage/homology/all.py +2 -0
  297. sage/homology/all__sagemath_modules.py +8 -0
  298. sage/homology/chain_complex.py +2148 -0
  299. sage/homology/chain_complex_homspace.py +165 -0
  300. sage/homology/chain_complex_morphism.py +629 -0
  301. sage/homology/chain_homotopy.py +604 -0
  302. sage/homology/chains.py +653 -0
  303. sage/homology/free_resolution.py +923 -0
  304. sage/homology/graded_resolution.py +567 -0
  305. sage/homology/hochschild_complex.py +756 -0
  306. sage/homology/homology_group.py +188 -0
  307. sage/homology/homology_morphism.py +422 -0
  308. sage/homology/homology_vector_space_with_basis.py +1454 -0
  309. sage/homology/koszul_complex.py +169 -0
  310. sage/homology/matrix_utils.py +205 -0
  311. sage/libs/all__sagemath_modules.py +1 -0
  312. sage/libs/gsl/__init__.py +1 -0
  313. sage/libs/gsl/airy.pxd +56 -0
  314. sage/libs/gsl/all.pxd +66 -0
  315. sage/libs/gsl/array.cpython-314-aarch64-linux-gnu.so +0 -0
  316. sage/libs/gsl/array.pxd +5 -0
  317. sage/libs/gsl/array.pyx +102 -0
  318. sage/libs/gsl/bessel.pxd +208 -0
  319. sage/libs/gsl/blas.pxd +116 -0
  320. sage/libs/gsl/blas_types.pxd +34 -0
  321. sage/libs/gsl/block.pxd +52 -0
  322. sage/libs/gsl/chebyshev.pxd +37 -0
  323. sage/libs/gsl/clausen.pxd +12 -0
  324. sage/libs/gsl/combination.pxd +47 -0
  325. sage/libs/gsl/complex.pxd +151 -0
  326. sage/libs/gsl/coulomb.pxd +30 -0
  327. sage/libs/gsl/coupling.pxd +21 -0
  328. sage/libs/gsl/dawson.pxd +12 -0
  329. sage/libs/gsl/debye.pxd +24 -0
  330. sage/libs/gsl/dilog.pxd +14 -0
  331. sage/libs/gsl/eigen.pxd +46 -0
  332. sage/libs/gsl/elementary.pxd +12 -0
  333. sage/libs/gsl/ellint.pxd +48 -0
  334. sage/libs/gsl/elljac.pxd +8 -0
  335. sage/libs/gsl/erf.pxd +32 -0
  336. sage/libs/gsl/errno.pxd +26 -0
  337. sage/libs/gsl/exp.pxd +44 -0
  338. sage/libs/gsl/expint.pxd +44 -0
  339. sage/libs/gsl/fermi_dirac.pxd +44 -0
  340. sage/libs/gsl/fft.pxd +121 -0
  341. sage/libs/gsl/fit.pxd +50 -0
  342. sage/libs/gsl/gamma.pxd +94 -0
  343. sage/libs/gsl/gegenbauer.pxd +26 -0
  344. sage/libs/gsl/histogram.pxd +176 -0
  345. sage/libs/gsl/hyperg.pxd +52 -0
  346. sage/libs/gsl/integration.pxd +69 -0
  347. sage/libs/gsl/interp.pxd +109 -0
  348. sage/libs/gsl/laguerre.pxd +24 -0
  349. sage/libs/gsl/lambert.pxd +16 -0
  350. sage/libs/gsl/legendre.pxd +90 -0
  351. sage/libs/gsl/linalg.pxd +185 -0
  352. sage/libs/gsl/log.pxd +26 -0
  353. sage/libs/gsl/math.pxd +43 -0
  354. sage/libs/gsl/matrix.pxd +143 -0
  355. sage/libs/gsl/matrix_complex.pxd +130 -0
  356. sage/libs/gsl/min.pxd +67 -0
  357. sage/libs/gsl/monte.pxd +56 -0
  358. sage/libs/gsl/ntuple.pxd +32 -0
  359. sage/libs/gsl/odeiv.pxd +70 -0
  360. sage/libs/gsl/permutation.pxd +78 -0
  361. sage/libs/gsl/poly.pxd +40 -0
  362. sage/libs/gsl/pow_int.pxd +12 -0
  363. sage/libs/gsl/psi.pxd +28 -0
  364. sage/libs/gsl/qrng.pxd +29 -0
  365. sage/libs/gsl/random.pxd +257 -0
  366. sage/libs/gsl/rng.pxd +100 -0
  367. sage/libs/gsl/roots.pxd +72 -0
  368. sage/libs/gsl/sort.pxd +36 -0
  369. sage/libs/gsl/statistics.pxd +59 -0
  370. sage/libs/gsl/sum.pxd +55 -0
  371. sage/libs/gsl/synchrotron.pxd +16 -0
  372. sage/libs/gsl/transport.pxd +24 -0
  373. sage/libs/gsl/trig.pxd +58 -0
  374. sage/libs/gsl/types.pxd +137 -0
  375. sage/libs/gsl/vector.pxd +101 -0
  376. sage/libs/gsl/vector_complex.pxd +83 -0
  377. sage/libs/gsl/wavelet.pxd +49 -0
  378. sage/libs/gsl/zeta.pxd +28 -0
  379. sage/libs/mpc/__init__.pxd +114 -0
  380. sage/libs/mpc/types.pxd +28 -0
  381. sage/libs/mpfr/__init__.pxd +299 -0
  382. sage/libs/mpfr/types.pxd +26 -0
  383. sage/libs/mpmath/__init__.py +1 -0
  384. sage/libs/mpmath/all.py +27 -0
  385. sage/libs/mpmath/all__sagemath_modules.py +1 -0
  386. sage/libs/mpmath/utils.cpython-314-aarch64-linux-gnu.so +0 -0
  387. sage/libs/mpmath/utils.pxd +4 -0
  388. sage/libs/mpmath/utils.pyx +319 -0
  389. sage/matrix/action.cpython-314-aarch64-linux-gnu.so +0 -0
  390. sage/matrix/action.pxd +26 -0
  391. sage/matrix/action.pyx +596 -0
  392. sage/matrix/all.py +9 -0
  393. sage/matrix/args.cpython-314-aarch64-linux-gnu.so +0 -0
  394. sage/matrix/args.pxd +144 -0
  395. sage/matrix/args.pyx +1668 -0
  396. sage/matrix/benchmark.py +1258 -0
  397. sage/matrix/berlekamp_massey.py +95 -0
  398. sage/matrix/compute_J_ideal.py +926 -0
  399. sage/matrix/constructor.cpython-314-aarch64-linux-gnu.so +0 -0
  400. sage/matrix/constructor.pyx +750 -0
  401. sage/matrix/docs.py +430 -0
  402. sage/matrix/echelon_matrix.cpython-314-aarch64-linux-gnu.so +0 -0
  403. sage/matrix/echelon_matrix.pyx +155 -0
  404. sage/matrix/matrix.pxd +2 -0
  405. sage/matrix/matrix0.cpython-314-aarch64-linux-gnu.so +0 -0
  406. sage/matrix/matrix0.pxd +68 -0
  407. sage/matrix/matrix0.pyx +6324 -0
  408. sage/matrix/matrix1.cpython-314-aarch64-linux-gnu.so +0 -0
  409. sage/matrix/matrix1.pxd +8 -0
  410. sage/matrix/matrix1.pyx +2851 -0
  411. sage/matrix/matrix2.cpython-314-aarch64-linux-gnu.so +0 -0
  412. sage/matrix/matrix2.pxd +25 -0
  413. sage/matrix/matrix2.pyx +20181 -0
  414. sage/matrix/matrix_cdv.cpython-314-aarch64-linux-gnu.so +0 -0
  415. sage/matrix/matrix_cdv.pxd +4 -0
  416. sage/matrix/matrix_cdv.pyx +93 -0
  417. sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  418. sage/matrix/matrix_complex_double_dense.pxd +5 -0
  419. sage/matrix/matrix_complex_double_dense.pyx +98 -0
  420. sage/matrix/matrix_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  421. sage/matrix/matrix_dense.pxd +5 -0
  422. sage/matrix/matrix_dense.pyx +343 -0
  423. sage/matrix/matrix_domain_dense.pxd +5 -0
  424. sage/matrix/matrix_domain_sparse.pxd +5 -0
  425. sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  426. sage/matrix/matrix_double_dense.pxd +7 -0
  427. sage/matrix/matrix_double_dense.pyx +3906 -0
  428. sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  429. sage/matrix/matrix_double_sparse.pxd +6 -0
  430. sage/matrix/matrix_double_sparse.pyx +248 -0
  431. sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  432. sage/matrix/matrix_generic_dense.pxd +7 -0
  433. sage/matrix/matrix_generic_dense.pyx +354 -0
  434. sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  435. sage/matrix/matrix_generic_sparse.pxd +7 -0
  436. sage/matrix/matrix_generic_sparse.pyx +461 -0
  437. sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  438. sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
  439. sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
  440. sage/matrix/matrix_misc.py +313 -0
  441. sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  442. sage/matrix/matrix_numpy_dense.pxd +14 -0
  443. sage/matrix/matrix_numpy_dense.pyx +450 -0
  444. sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  445. sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
  446. sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
  447. sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  448. sage/matrix/matrix_polynomial_dense.pxd +5 -0
  449. sage/matrix/matrix_polynomial_dense.pyx +5341 -0
  450. sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  451. sage/matrix/matrix_real_double_dense.pxd +7 -0
  452. sage/matrix/matrix_real_double_dense.pyx +122 -0
  453. sage/matrix/matrix_space.py +2848 -0
  454. sage/matrix/matrix_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  455. sage/matrix/matrix_sparse.pxd +5 -0
  456. sage/matrix/matrix_sparse.pyx +1222 -0
  457. sage/matrix/matrix_window.cpython-314-aarch64-linux-gnu.so +0 -0
  458. sage/matrix/matrix_window.pxd +37 -0
  459. sage/matrix/matrix_window.pyx +242 -0
  460. sage/matrix/misc_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  461. sage/matrix/misc_mpfr.pyx +80 -0
  462. sage/matrix/operation_table.py +1182 -0
  463. sage/matrix/special.py +3666 -0
  464. sage/matrix/strassen.cpython-314-aarch64-linux-gnu.so +0 -0
  465. sage/matrix/strassen.pyx +851 -0
  466. sage/matrix/symplectic_basis.py +541 -0
  467. sage/matrix/template.pxd +6 -0
  468. sage/matrix/tests.py +71 -0
  469. sage/matroids/advanced.py +77 -0
  470. sage/matroids/all.py +13 -0
  471. sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  472. sage/matroids/basis_exchange_matroid.pxd +96 -0
  473. sage/matroids/basis_exchange_matroid.pyx +2344 -0
  474. sage/matroids/basis_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  475. sage/matroids/basis_matroid.pxd +45 -0
  476. sage/matroids/basis_matroid.pyx +1217 -0
  477. sage/matroids/catalog.py +44 -0
  478. sage/matroids/chow_ring.py +473 -0
  479. sage/matroids/chow_ring_ideal.py +849 -0
  480. sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  481. sage/matroids/circuit_closures_matroid.pxd +16 -0
  482. sage/matroids/circuit_closures_matroid.pyx +559 -0
  483. sage/matroids/circuits_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  484. sage/matroids/circuits_matroid.pxd +38 -0
  485. sage/matroids/circuits_matroid.pyx +947 -0
  486. sage/matroids/constructor.py +1086 -0
  487. sage/matroids/database_collections.py +365 -0
  488. sage/matroids/database_matroids.py +5338 -0
  489. sage/matroids/dual_matroid.py +583 -0
  490. sage/matroids/extension.cpython-314-aarch64-linux-gnu.so +0 -0
  491. sage/matroids/extension.pxd +34 -0
  492. sage/matroids/extension.pyx +519 -0
  493. sage/matroids/flats_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  494. sage/matroids/flats_matroid.pxd +28 -0
  495. sage/matroids/flats_matroid.pyx +715 -0
  496. sage/matroids/gammoid.py +600 -0
  497. sage/matroids/graphic_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  498. sage/matroids/graphic_matroid.pxd +39 -0
  499. sage/matroids/graphic_matroid.pyx +2024 -0
  500. sage/matroids/lean_matrix.cpython-314-aarch64-linux-gnu.so +0 -0
  501. sage/matroids/lean_matrix.pxd +126 -0
  502. sage/matroids/lean_matrix.pyx +3667 -0
  503. sage/matroids/linear_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  504. sage/matroids/linear_matroid.pxd +180 -0
  505. sage/matroids/linear_matroid.pyx +6649 -0
  506. sage/matroids/matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  507. sage/matroids/matroid.pxd +243 -0
  508. sage/matroids/matroid.pyx +8759 -0
  509. sage/matroids/matroids_catalog.py +190 -0
  510. sage/matroids/matroids_plot_helpers.py +890 -0
  511. sage/matroids/minor_matroid.py +480 -0
  512. sage/matroids/minorfix.h +9 -0
  513. sage/matroids/named_matroids.py +5 -0
  514. sage/matroids/rank_matroid.py +268 -0
  515. sage/matroids/set_system.cpython-314-aarch64-linux-gnu.so +0 -0
  516. sage/matroids/set_system.pxd +38 -0
  517. sage/matroids/set_system.pyx +800 -0
  518. sage/matroids/transversal_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  519. sage/matroids/transversal_matroid.pxd +14 -0
  520. sage/matroids/transversal_matroid.pyx +893 -0
  521. sage/matroids/union_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  522. sage/matroids/union_matroid.pxd +20 -0
  523. sage/matroids/union_matroid.pyx +331 -0
  524. sage/matroids/unpickling.cpython-314-aarch64-linux-gnu.so +0 -0
  525. sage/matroids/unpickling.pyx +843 -0
  526. sage/matroids/utilities.py +809 -0
  527. sage/misc/all__sagemath_modules.py +20 -0
  528. sage/misc/c3.cpython-314-aarch64-linux-gnu.so +0 -0
  529. sage/misc/c3.pyx +238 -0
  530. sage/misc/compat.py +87 -0
  531. sage/misc/element_with_label.py +173 -0
  532. sage/misc/func_persist.py +79 -0
  533. sage/misc/pickle_old.cpython-314-aarch64-linux-gnu.so +0 -0
  534. sage/misc/pickle_old.pyx +19 -0
  535. sage/misc/proof.py +7 -0
  536. sage/misc/replace_dot_all.py +472 -0
  537. sage/misc/sagedoc_conf.py +168 -0
  538. sage/misc/sphinxify.py +167 -0
  539. sage/misc/test_class_pickling.py +85 -0
  540. sage/modules/all.py +42 -0
  541. sage/modules/complex_double_vector.py +25 -0
  542. sage/modules/diamond_cutting.py +380 -0
  543. sage/modules/fg_pid/all.py +1 -0
  544. sage/modules/fg_pid/fgp_element.py +456 -0
  545. sage/modules/fg_pid/fgp_module.py +2091 -0
  546. sage/modules/fg_pid/fgp_morphism.py +550 -0
  547. sage/modules/filtered_vector_space.py +1271 -0
  548. sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-gnu.so +0 -0
  549. sage/modules/finite_submodule_iter.pxd +27 -0
  550. sage/modules/finite_submodule_iter.pyx +452 -0
  551. sage/modules/fp_graded/all.py +1 -0
  552. sage/modules/fp_graded/element.py +346 -0
  553. sage/modules/fp_graded/free_element.py +298 -0
  554. sage/modules/fp_graded/free_homspace.py +53 -0
  555. sage/modules/fp_graded/free_module.py +1060 -0
  556. sage/modules/fp_graded/free_morphism.py +217 -0
  557. sage/modules/fp_graded/homspace.py +563 -0
  558. sage/modules/fp_graded/module.py +1340 -0
  559. sage/modules/fp_graded/morphism.py +1990 -0
  560. sage/modules/fp_graded/steenrod/all.py +1 -0
  561. sage/modules/fp_graded/steenrod/homspace.py +65 -0
  562. sage/modules/fp_graded/steenrod/module.py +477 -0
  563. sage/modules/fp_graded/steenrod/morphism.py +404 -0
  564. sage/modules/fp_graded/steenrod/profile.py +241 -0
  565. sage/modules/free_module.py +8447 -0
  566. sage/modules/free_module_element.cpython-314-aarch64-linux-gnu.so +0 -0
  567. sage/modules/free_module_element.pxd +22 -0
  568. sage/modules/free_module_element.pyx +5445 -0
  569. sage/modules/free_module_homspace.py +369 -0
  570. sage/modules/free_module_integer.py +896 -0
  571. sage/modules/free_module_morphism.py +823 -0
  572. sage/modules/free_module_pseudohomspace.py +352 -0
  573. sage/modules/free_module_pseudomorphism.py +578 -0
  574. sage/modules/free_quadratic_module.py +1706 -0
  575. sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
  576. sage/modules/matrix_morphism.py +1745 -0
  577. sage/modules/misc.py +103 -0
  578. sage/modules/module_functors.py +192 -0
  579. sage/modules/multi_filtered_vector_space.py +719 -0
  580. sage/modules/ore_module.py +2208 -0
  581. sage/modules/ore_module_element.py +178 -0
  582. sage/modules/ore_module_homspace.py +147 -0
  583. sage/modules/ore_module_morphism.py +968 -0
  584. sage/modules/quotient_module.py +699 -0
  585. sage/modules/real_double_vector.py +22 -0
  586. sage/modules/submodule.py +255 -0
  587. sage/modules/tensor_operations.py +567 -0
  588. sage/modules/torsion_quadratic_module.py +1352 -0
  589. sage/modules/tutorial_free_modules.py +248 -0
  590. sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  591. sage/modules/vector_complex_double_dense.pxd +6 -0
  592. sage/modules/vector_complex_double_dense.pyx +117 -0
  593. sage/modules/vector_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  594. sage/modules/vector_double_dense.pxd +6 -0
  595. sage/modules/vector_double_dense.pyx +604 -0
  596. sage/modules/vector_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  597. sage/modules/vector_integer_dense.pxd +15 -0
  598. sage/modules/vector_integer_dense.pyx +361 -0
  599. sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  600. sage/modules/vector_integer_sparse.pxd +29 -0
  601. sage/modules/vector_integer_sparse.pyx +406 -0
  602. sage/modules/vector_modn_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  603. sage/modules/vector_modn_dense.pxd +12 -0
  604. sage/modules/vector_modn_dense.pyx +394 -0
  605. sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  606. sage/modules/vector_modn_sparse.pxd +21 -0
  607. sage/modules/vector_modn_sparse.pyx +298 -0
  608. sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  609. sage/modules/vector_numpy_dense.pxd +15 -0
  610. sage/modules/vector_numpy_dense.pyx +304 -0
  611. sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  612. sage/modules/vector_numpy_integer_dense.pxd +7 -0
  613. sage/modules/vector_numpy_integer_dense.pyx +54 -0
  614. sage/modules/vector_rational_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  615. sage/modules/vector_rational_dense.pxd +15 -0
  616. sage/modules/vector_rational_dense.pyx +387 -0
  617. sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  618. sage/modules/vector_rational_sparse.pxd +30 -0
  619. sage/modules/vector_rational_sparse.pyx +413 -0
  620. sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  621. sage/modules/vector_real_double_dense.pxd +6 -0
  622. sage/modules/vector_real_double_dense.pyx +126 -0
  623. sage/modules/vector_space_homspace.py +430 -0
  624. sage/modules/vector_space_morphism.py +989 -0
  625. sage/modules/with_basis/all.py +15 -0
  626. sage/modules/with_basis/cell_module.py +494 -0
  627. sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-gnu.so +0 -0
  628. sage/modules/with_basis/indexed_element.pxd +13 -0
  629. sage/modules/with_basis/indexed_element.pyx +1058 -0
  630. sage/modules/with_basis/invariant.py +1075 -0
  631. sage/modules/with_basis/morphism.py +1636 -0
  632. sage/modules/with_basis/representation.py +2939 -0
  633. sage/modules/with_basis/subquotient.py +685 -0
  634. sage/numerical/all__sagemath_modules.py +6 -0
  635. sage/numerical/gauss_legendre.cpython-314-aarch64-linux-gnu.so +0 -0
  636. sage/numerical/gauss_legendre.pyx +381 -0
  637. sage/numerical/optimize.py +910 -0
  638. sage/probability/all.py +10 -0
  639. sage/probability/probability_distribution.cpython-314-aarch64-linux-gnu.so +0 -0
  640. sage/probability/probability_distribution.pyx +1242 -0
  641. sage/probability/random_variable.py +411 -0
  642. sage/quadratic_forms/all.py +4 -0
  643. sage/quadratic_forms/all__sagemath_modules.py +15 -0
  644. sage/quadratic_forms/binary_qf.py +2042 -0
  645. sage/quadratic_forms/bqf_class_group.py +748 -0
  646. sage/quadratic_forms/constructions.py +93 -0
  647. sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-gnu.so +0 -0
  648. sage/quadratic_forms/count_local_2.pyx +365 -0
  649. sage/quadratic_forms/extras.py +195 -0
  650. sage/quadratic_forms/quadratic_form.py +1753 -0
  651. sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
  652. sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
  653. sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-gnu.so +0 -0
  654. sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
  655. sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
  656. sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
  657. sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
  658. sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
  659. sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
  660. sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
  661. sage/quadratic_forms/quadratic_form__theta.py +352 -0
  662. sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
  663. sage/quadratic_forms/random_quadraticform.py +209 -0
  664. sage/quadratic_forms/ternary.cpython-314-aarch64-linux-gnu.so +0 -0
  665. sage/quadratic_forms/ternary.pyx +1154 -0
  666. sage/quadratic_forms/ternary_qf.py +2027 -0
  667. sage/rings/all__sagemath_modules.py +28 -0
  668. sage/rings/asymptotic/all__sagemath_modules.py +1 -0
  669. sage/rings/asymptotic/misc.py +1252 -0
  670. sage/rings/cc.py +4 -0
  671. sage/rings/cfinite_sequence.py +1306 -0
  672. sage/rings/complex_conversion.cpython-314-aarch64-linux-gnu.so +0 -0
  673. sage/rings/complex_conversion.pxd +8 -0
  674. sage/rings/complex_conversion.pyx +23 -0
  675. sage/rings/complex_double.cpython-314-aarch64-linux-gnu.so +0 -0
  676. sage/rings/complex_double.pxd +21 -0
  677. sage/rings/complex_double.pyx +2654 -0
  678. sage/rings/complex_mpc.cpython-314-aarch64-linux-gnu.so +0 -0
  679. sage/rings/complex_mpc.pxd +21 -0
  680. sage/rings/complex_mpc.pyx +2576 -0
  681. sage/rings/complex_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  682. sage/rings/complex_mpfr.pxd +18 -0
  683. sage/rings/complex_mpfr.pyx +3602 -0
  684. sage/rings/derivation.py +2334 -0
  685. sage/rings/finite_rings/all__sagemath_modules.py +1 -0
  686. sage/rings/finite_rings/maps_finite_field.py +191 -0
  687. sage/rings/function_field/all__sagemath_modules.py +8 -0
  688. sage/rings/function_field/derivations.py +102 -0
  689. sage/rings/function_field/derivations_rational.py +132 -0
  690. sage/rings/function_field/differential.py +853 -0
  691. sage/rings/function_field/divisor.py +1107 -0
  692. sage/rings/function_field/drinfeld_modules/action.py +199 -0
  693. sage/rings/function_field/drinfeld_modules/all.py +1 -0
  694. sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
  695. sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
  696. sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
  697. sage/rings/function_field/drinfeld_modules/homset.py +420 -0
  698. sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
  699. sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-gnu.so +0 -0
  700. sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
  701. sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-gnu.so +0 -0
  702. sage/rings/function_field/khuri_makdisi.pyx +935 -0
  703. sage/rings/invariants/all.py +4 -0
  704. sage/rings/invariants/invariant_theory.py +4597 -0
  705. sage/rings/invariants/reconstruction.py +395 -0
  706. sage/rings/polynomial/all__sagemath_modules.py +17 -0
  707. sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
  708. sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-gnu.so +0 -0
  709. sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
  710. sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
  711. sage/rings/polynomial/ore_function_element.py +952 -0
  712. sage/rings/polynomial/ore_function_field.py +1028 -0
  713. sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-gnu.so +0 -0
  714. sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
  715. sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
  716. sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
  717. sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  718. sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
  719. sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
  720. sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-gnu.so +0 -0
  721. sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
  722. sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
  723. sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-gnu.so +0 -0
  724. sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
  725. sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
  726. sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-gnu.so +0 -0
  727. sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
  728. sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
  729. sage/rings/polynomial/skew_polynomial_ring.py +908 -0
  730. sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-gnu.so +0 -0
  731. sage/rings/real_double_element_gsl.pxd +8 -0
  732. sage/rings/real_double_element_gsl.pyx +794 -0
  733. sage/rings/real_field.py +58 -0
  734. sage/rings/real_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  735. sage/rings/real_mpfr.pxd +29 -0
  736. sage/rings/real_mpfr.pyx +6122 -0
  737. sage/rings/ring_extension.cpython-314-aarch64-linux-gnu.so +0 -0
  738. sage/rings/ring_extension.pxd +42 -0
  739. sage/rings/ring_extension.pyx +2779 -0
  740. sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-gnu.so +0 -0
  741. sage/rings/ring_extension_conversion.pxd +16 -0
  742. sage/rings/ring_extension_conversion.pyx +462 -0
  743. sage/rings/ring_extension_element.cpython-314-aarch64-linux-gnu.so +0 -0
  744. sage/rings/ring_extension_element.pxd +21 -0
  745. sage/rings/ring_extension_element.pyx +1635 -0
  746. sage/rings/ring_extension_homset.py +64 -0
  747. sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-gnu.so +0 -0
  748. sage/rings/ring_extension_morphism.pxd +35 -0
  749. sage/rings/ring_extension_morphism.pyx +920 -0
  750. sage/schemes/all__sagemath_modules.py +1 -0
  751. sage/schemes/projective/all__sagemath_modules.py +1 -0
  752. sage/schemes/projective/coherent_sheaf.py +300 -0
  753. sage/schemes/projective/cohomology.py +510 -0
  754. sage/stats/all.py +15 -0
  755. sage/stats/basic_stats.py +489 -0
  756. sage/stats/distributions/all.py +7 -0
  757. sage/stats/distributions/catalog.py +34 -0
  758. sage/stats/distributions/dgs.h +50 -0
  759. sage/stats/distributions/dgs.pxd +111 -0
  760. sage/stats/distributions/dgs_bern.h +400 -0
  761. sage/stats/distributions/dgs_gauss.h +614 -0
  762. sage/stats/distributions/dgs_misc.h +104 -0
  763. sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-gnu.so +0 -0
  764. sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
  765. sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
  766. sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
  767. sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
  768. sage/stats/hmm/all.py +15 -0
  769. sage/stats/hmm/chmm.cpython-314-aarch64-linux-gnu.so +0 -0
  770. sage/stats/hmm/chmm.pyx +1595 -0
  771. sage/stats/hmm/distributions.cpython-314-aarch64-linux-gnu.so +0 -0
  772. sage/stats/hmm/distributions.pxd +29 -0
  773. sage/stats/hmm/distributions.pyx +531 -0
  774. sage/stats/hmm/hmm.cpython-314-aarch64-linux-gnu.so +0 -0
  775. sage/stats/hmm/hmm.pxd +17 -0
  776. sage/stats/hmm/hmm.pyx +1388 -0
  777. sage/stats/hmm/util.cpython-314-aarch64-linux-gnu.so +0 -0
  778. sage/stats/hmm/util.pxd +7 -0
  779. sage/stats/hmm/util.pyx +165 -0
  780. sage/stats/intlist.cpython-314-aarch64-linux-gnu.so +0 -0
  781. sage/stats/intlist.pxd +14 -0
  782. sage/stats/intlist.pyx +588 -0
  783. sage/stats/r.py +49 -0
  784. sage/stats/time_series.cpython-314-aarch64-linux-gnu.so +0 -0
  785. sage/stats/time_series.pxd +6 -0
  786. sage/stats/time_series.pyx +2546 -0
  787. sage/tensor/all.py +2 -0
  788. sage/tensor/modules/all.py +8 -0
  789. sage/tensor/modules/alternating_contr_tensor.py +761 -0
  790. sage/tensor/modules/comp.py +5598 -0
  791. sage/tensor/modules/ext_pow_free_module.py +824 -0
  792. sage/tensor/modules/finite_rank_free_module.py +3589 -0
  793. sage/tensor/modules/format_utilities.py +333 -0
  794. sage/tensor/modules/free_module_alt_form.py +858 -0
  795. sage/tensor/modules/free_module_automorphism.py +1207 -0
  796. sage/tensor/modules/free_module_basis.py +1074 -0
  797. sage/tensor/modules/free_module_element.py +284 -0
  798. sage/tensor/modules/free_module_homset.py +652 -0
  799. sage/tensor/modules/free_module_linear_group.py +564 -0
  800. sage/tensor/modules/free_module_morphism.py +1581 -0
  801. sage/tensor/modules/free_module_tensor.py +3289 -0
  802. sage/tensor/modules/reflexive_module.py +386 -0
  803. sage/tensor/modules/tensor_free_module.py +780 -0
  804. sage/tensor/modules/tensor_free_submodule.py +538 -0
  805. sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
  806. sage/tensor/modules/tensor_with_indices.py +1043 -0
@@ -0,0 +1,3107 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ # sage.doctest: needs sage.modules
3
+ r"""
4
+ Clifford Algebras
5
+
6
+ AUTHORS:
7
+
8
+ - Travis Scrimshaw (2013-09-06): Initial version
9
+ - Trevor K. Karn (2022-07-27): Rewrite basis indexing using FrozenBitset
10
+ """
11
+ # ****************************************************************************
12
+ # Copyright (C) 2013-2022 Travis Scrimshaw <tcscrims at gmail.com>
13
+ # (C) 2022 Trevor Karn <karnx018 at umn.edu>
14
+ #
15
+ # This program is free software: you can redistribute it and/or modify
16
+ # it under the terms of the GNU General Public License as published by
17
+ # the Free Software Foundation, either version 2 of the License, or
18
+ # (at your option) any later version.
19
+ # https://www.gnu.org/licenses/
20
+ # ****************************************************************************
21
+ from sage.misc.cachefunc import cached_method
22
+ from sage.structure.unique_representation import UniqueRepresentation
23
+ from sage.structure.parent import Parent
24
+ from sage.structure.element import Element
25
+ from sage.structure.richcmp import (richcmp_method, op_EQ, op_NE,
26
+ op_LT, op_GT, op_LE, op_GE, rich_to_bool)
27
+ from sage.data_structures.bitset import Bitset, FrozenBitset
28
+
29
+ from sage.algebras.clifford_algebra_element import CliffordAlgebraElement, ExteriorAlgebraElement
30
+ from sage.categories.algebras_with_basis import AlgebrasWithBasis
31
+ from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis
32
+ from sage.categories.fields import Fields
33
+ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
34
+ from sage.modules.with_basis.morphism import ModuleMorphismByLinearity
35
+ from sage.categories.poor_man_map import PoorManMap
36
+ from sage.rings.integer_ring import ZZ
37
+ from sage.rings.noncommutative_ideals import Ideal_nc
38
+ from sage.modules.free_module import FreeModule, FreeModule_generic
39
+ from sage.matrix.constructor import Matrix
40
+ from sage.matrix.args import MatrixArgs
41
+ from sage.sets.family import Family
42
+ from sage.combinat.free_module import CombinatorialFreeModule
43
+ from sage.quadratic_forms.quadratic_form import QuadraticForm
44
+ from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass
45
+ from sage.typeset.ascii_art import ascii_art
46
+ from sage.typeset.unicode_art import unicode_art
47
+ import unicodedata
48
+
49
+
50
+ class CliffordAlgebraIndices(UniqueRepresentation, Parent):
51
+ r"""
52
+ A facade parent for the indices of Clifford algebra.
53
+ Users should not create instances of this class directly.
54
+ """
55
+ def __init__(self, Qdim, degree=None):
56
+ r"""
57
+ Initialize ``self``.
58
+
59
+ EXAMPLES::
60
+
61
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
62
+ sage: idx = CliffordAlgebraIndices(7)
63
+ sage: idx._nbits
64
+ 7
65
+ sage: idx._cardinality
66
+ 128
67
+ sage: i = idx.an_element(); i
68
+ 1111
69
+ sage: type(i)
70
+ <class 'sage.data_structures.bitset.FrozenBitset'>
71
+
72
+ sage: idx = CliffordAlgebraIndices(7, 3)
73
+ sage: idx._nbits
74
+ 7
75
+ sage: idx._degree
76
+ 3
77
+ sage: idx._cardinality
78
+ 35
79
+
80
+ sage: idx = CliffordAlgebraIndices(7, 0)
81
+ sage: idx._nbits
82
+ 7
83
+ sage: idx._degree
84
+ 0
85
+ sage: idx._cardinality
86
+ 1
87
+ """
88
+ self._nbits = Qdim
89
+ if degree is None:
90
+ self._cardinality = 2 ** Qdim
91
+ else:
92
+ from sage.arith.misc import binomial
93
+ self._cardinality = binomial(Qdim, degree)
94
+ self._degree = degree
95
+ # the if statement here is in case Qdim is 0.
96
+ category = FiniteEnumeratedSets().Facade()
97
+ Parent.__init__(self, category=category, facade=True)
98
+
99
+ def _element_constructor_(self, x):
100
+ r"""
101
+ Construct an element of ``self``.
102
+
103
+ EXAMPLES::
104
+
105
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
106
+ sage: idx = CliffordAlgebraIndices(7)
107
+ sage: idx([1,3,6])
108
+ 0101001
109
+ sage: for i in range(7): print(idx(i))
110
+ 1
111
+ 01
112
+ 001
113
+ 0001
114
+ 00001
115
+ 000001
116
+ 0000001
117
+
118
+ sage: idx = CliffordAlgebraIndices(0)
119
+ sage: idx([])
120
+ 0
121
+ """
122
+ if isinstance(x, (list, tuple, set, frozenset)):
123
+ if len(x) > self._nbits:
124
+ raise ValueError(f"{x=} is too long")
125
+ if not x:
126
+ return FrozenBitset()
127
+ return FrozenBitset(x)
128
+
129
+ if isinstance(x, int):
130
+ return FrozenBitset((x,))
131
+
132
+ def __call__(self, el):
133
+ r"""
134
+ EXAMPLES::
135
+
136
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
137
+ sage: idx = CliffordAlgebraIndices(7)
138
+ sage: idx([1,3,6])
139
+ 0101001
140
+ sage: E = ExteriorAlgebra(QQ, 7)
141
+ sage: B = E.basis()
142
+ """
143
+ if not isinstance(el, Element):
144
+ return self._element_constructor_(el)
145
+ else:
146
+ return Parent.__call__(self, el)
147
+
148
+ def cardinality(self):
149
+ r"""
150
+ Return the cardinality of ``self``.
151
+
152
+ EXAMPLES::
153
+
154
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
155
+ sage: idx = CliffordAlgebraIndices(7)
156
+ sage: idx.cardinality() == 2^7
157
+ True
158
+ sage: len(idx) == 2^7
159
+ True
160
+
161
+ sage: idx = CliffordAlgebraIndices(7, 3)
162
+ sage: idx.cardinality() == binomial(7, 3)
163
+ True
164
+ sage: len(idx) == binomial(7, 3)
165
+ True
166
+ """
167
+ return self._cardinality
168
+
169
+ __len__ = cardinality
170
+
171
+ def _repr_(self):
172
+ r"""
173
+ Return a string representation of ``self``.
174
+
175
+ EXAMPLES::
176
+
177
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
178
+ sage: CliffordAlgebraIndices(7)
179
+ Subsets of {0,1,...,6}
180
+ sage: CliffordAlgebraIndices(0)
181
+ Subsets of {}
182
+ sage: CliffordAlgebraIndices(1)
183
+ Subsets of {0}
184
+ sage: CliffordAlgebraIndices(2)
185
+ Subsets of {0,1}
186
+ sage: CliffordAlgebraIndices(5, 3)
187
+ Subsets of {0,1,...,4} of size 3
188
+ """
189
+ if self._degree is not None:
190
+ extra = f" of size {self._degree}"
191
+ else:
192
+ extra = ""
193
+ if self._nbits == 0:
194
+ return "Subsets of {}" + extra
195
+ if self._nbits == 1:
196
+ return "Subsets of {0}" + extra
197
+ if self._nbits == 2:
198
+ return "Subsets of {0,1}" + extra
199
+ return f"Subsets of {{0,1,...,{self._nbits-1}}}" + extra
200
+
201
+ def _latex_(self):
202
+ r"""
203
+ Return a latex representation of ``self``.
204
+
205
+ EXAMPLES::
206
+
207
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
208
+ sage: latex(CliffordAlgebraIndices(7))
209
+ \mathcal{P}(\{0,1,\ldots,6\})
210
+ sage: latex(CliffordAlgebraIndices(0))
211
+ \mathcal{P}(\emptyset)
212
+ sage: latex(CliffordAlgebraIndices(1))
213
+ \mathcal{P}(\{0\})
214
+ sage: latex(CliffordAlgebraIndices(2))
215
+ \mathcal{P}(\{0,1\})
216
+ sage: latex(CliffordAlgebraIndices(2, 1))
217
+ \mathcal{P}(\{0,1\}, 1)
218
+ """
219
+ if self._degree is not None:
220
+ extra = f", {self._degree}"
221
+ else:
222
+ extra = ""
223
+ if self._nbits == 0:
224
+ return f"\\mathcal{{P}}(\\emptyset{extra})"
225
+ if self._nbits == 1:
226
+ return f"\\mathcal{{P}}(\\{{0\\}}{extra})"
227
+ if self._nbits == 2:
228
+ return f"\\mathcal{{P}}(\\{{0,1\\}}{extra})"
229
+ return f"\\mathcal{{P}}(\\{{0,1,\\ldots,{self._nbits-1}\\}}{extra})"
230
+
231
+ def __iter__(self):
232
+ r"""
233
+ Iterate over ``self``.
234
+
235
+ EXAMPLES::
236
+
237
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
238
+ sage: idx = CliffordAlgebraIndices(3)
239
+ sage: for i in idx:
240
+ ....: print(i)
241
+ 0
242
+ 1
243
+ 01
244
+ 001
245
+ 11
246
+ 101
247
+ 011
248
+ 111
249
+
250
+ sage: idx = CliffordAlgebraIndices(5, 3)
251
+ sage: list(idx)
252
+ [111, 1101, 11001, 1011, 10101, 10011, 0111, 01101, 01011, 00111]
253
+
254
+ sage: idx = CliffordAlgebraIndices(7, 0)
255
+ sage: list(idx)
256
+ [0]
257
+ """
258
+ import itertools
259
+ n = self._nbits
260
+ if self._degree is not None:
261
+ if self._degree == 0: # special corner case
262
+ yield FrozenBitset()
263
+ return
264
+ for C in itertools.combinations(range(n), self._degree):
265
+ yield FrozenBitset(C)
266
+ return
267
+
268
+ yield FrozenBitset()
269
+ k = 1
270
+ while k <= n:
271
+ for C in itertools.combinations(range(n), k):
272
+ yield FrozenBitset(C)
273
+ k += 1
274
+
275
+ def __contains__(self, elt):
276
+ r"""
277
+ Check containment of ``elt`` in ``self``.
278
+
279
+ EXAMPLES::
280
+
281
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
282
+ sage: idx = CliffordAlgebraIndices(3)
283
+ sage: int(8) in idx # representing the set {4}
284
+ False
285
+ sage: int(5) in idx # representing the set {1,3}
286
+ True
287
+ sage: FrozenBitset('1') in idx
288
+ True
289
+ sage: FrozenBitset('000001') in idx
290
+ False
291
+
292
+ sage: idx = CliffordAlgebraIndices(6, 3)
293
+ sage: FrozenBitset('01011') in idx
294
+ True
295
+ sage: FrozenBitset('00011') in idx
296
+ False
297
+ sage: int(7) in idx
298
+ True
299
+ sage: int(8) in idx
300
+ False
301
+
302
+ sage: idx = CliffordAlgebraIndices(7, 0)
303
+ sage: FrozenBitset() in idx
304
+ True
305
+ sage: FrozenBitset('01') in idx
306
+ False
307
+ sage: int(0) in idx
308
+ True
309
+ sage: int(5) in idx
310
+ False
311
+ """
312
+ if isinstance(elt, int):
313
+ if self._degree is not None and sum(ZZ(elt).bits()) != self._degree:
314
+ return False
315
+ return elt < self._cardinality and elt >= 0
316
+ if not isinstance(elt, FrozenBitset):
317
+ return False
318
+ if self._degree is not None and len(elt) != self._degree:
319
+ return False
320
+ return elt.capacity() <= self._nbits
321
+
322
+ def _an_element_(self):
323
+ r"""
324
+ Return an element of ``self``.
325
+
326
+ EXAMPLES::
327
+
328
+ sage: from sage.algebras.clifford_algebra import CliffordAlgebraIndices
329
+ sage: idx = CliffordAlgebraIndices(0)
330
+ sage: idx._an_element_()
331
+ 0
332
+ sage: idx = CliffordAlgebraIndices(1)
333
+ sage: idx._an_element_()
334
+ 1
335
+ sage: idx = CliffordAlgebraIndices(2)
336
+ sage: idx._an_element_()
337
+ 01
338
+ sage: idx = CliffordAlgebraIndices(3)
339
+ sage: idx._an_element_()
340
+ 11
341
+ sage: idx = CliffordAlgebraIndices(5, 3)
342
+ sage: idx._an_element_()
343
+ 111
344
+ sage: idx = CliffordAlgebraIndices(7, 0)
345
+ sage: idx._an_element_()
346
+ 0
347
+ """
348
+ if not self._nbits:
349
+ return FrozenBitset()
350
+
351
+ if self._degree is not None:
352
+ if self._degree == 0: # special corner case
353
+ return FrozenBitset()
354
+ return FrozenBitset(range(self._degree))
355
+
356
+ from sage.combinat.subset import SubsetsSorted
357
+ X = SubsetsSorted(range(self._nbits))
358
+ return FrozenBitset(X.an_element())
359
+
360
+
361
+ class CliffordAlgebra(CombinatorialFreeModule):
362
+ r"""
363
+ The Clifford algebra of a quadratic form.
364
+
365
+ Let `Q : V \to \mathbf{k}` denote a quadratic form on a vector space `V`
366
+ over a field `\mathbf{k}`. The Clifford algebra `Cl(V, Q)` is defined as
367
+ `T(V) / I_Q` where `T(V)` is the tensor algebra of `V` and `I_Q` is the
368
+ two-sided ideal generated by all elements of the form `v \otimes v - Q(v)`
369
+ for all `v \in V`.
370
+
371
+ We abuse notation to denote the projection of a pure tensor
372
+ `x_1 \otimes x_2 \otimes \cdots \otimes x_m \in T(V)` onto
373
+ `T(V) / I_Q = Cl(V, Q)` by `x_1 \wedge x_2 \wedge \cdots \wedge x_m`.
374
+ This is motivated by the fact that `Cl(V, Q)` is the exterior algebra
375
+ `\wedge V` when `Q = 0` (one can also think of a Clifford algebra as
376
+ a quantization of the exterior algebra). See :class:`ExteriorAlgebra`
377
+ for the concept of an exterior algebra.
378
+
379
+ From the definition, a basis of `Cl(V, Q)` is given by monomials of
380
+ the form
381
+
382
+ .. MATH::
383
+
384
+ \{ e_{i_1} \wedge \cdots \wedge e_{i_k} \mid 1 \leq i_1 < \cdots <
385
+ i_k \leq n \},
386
+
387
+ where `n = \dim(V)` and where `\{ e_1, e_2, \cdots, e_n \}` is any
388
+ fixed basis of `V`. Hence
389
+
390
+ .. MATH::
391
+
392
+ \dim(Cl(V, Q)) = \sum_{k=0}^n \binom{n}{k} = 2^n.
393
+
394
+ .. NOTE::
395
+
396
+ The algebra `Cl(V, Q)` is a `\ZZ / 2\ZZ`-graded algebra, but not
397
+ (in general) `\ZZ`-graded (in a reasonable way).
398
+
399
+ This construction satisfies the following universal property. Let
400
+ `i : V \to Cl(V, Q)` denote the natural inclusion (which is an
401
+ embedding). Then for every associative `\mathbf{k}`-algebra `A`
402
+ and any `\mathbf{k}`-linear map `j : V \to A` satisfying
403
+
404
+ .. MATH::
405
+
406
+ j(v)^2 = Q(v) \cdot 1_A
407
+
408
+ for all `v \in V`, there exists a unique `\mathbf{k}`-algebra
409
+ homomorphism `f : Cl(V, Q) \to A` such that `f \circ i = j`.
410
+ This property determines the Clifford algebra uniquely up to
411
+ canonical isomorphism. The inclusion `i` is commonly used to
412
+ identify `V` with a vector subspace of `Cl(V)`.
413
+
414
+ The Clifford algebra `Cl(V, Q)` is a `\ZZ_2`-graded algebra
415
+ (where `\ZZ_2 = \ZZ / 2 \ZZ`); this grading is determined by
416
+ placing all elements of `V` in degree `1`. It is also an
417
+ `\NN`-filtered algebra, with the filtration too being defined
418
+ by placing all elements of `V` in degree `1`. The :meth:`degree` gives
419
+ the `\NN`-*filtration* degree, and to get the super degree use instead
420
+ :meth:`~sage.categories.super_modules.SuperModules.ElementMethods.is_even_odd`.
421
+
422
+ The Clifford algebra also can be considered as a covariant functor
423
+ from the category of vector spaces equipped with quadratic forms
424
+ to the category of algebras. In fact, if `(V, Q)` and `(W, R)`
425
+ are two vector spaces endowed with quadratic forms, and if
426
+ `g : W \to V` is a linear map preserving the quadratic form,
427
+ then we can define an algebra morphism
428
+ `Cl(g) : Cl(W, R) \to Cl(V, Q)` by requiring that it send every
429
+ `w \in W` to `g(w) \in V`. Since the quadratic form `R` on `W`
430
+ is uniquely determined by the quadratic form `Q` on `V` (due to
431
+ the assumption that `g` preserves the quadratic form), this fact
432
+ can be rewritten as follows: If `(V, Q)` is a vector space with a
433
+ quadratic form, and `W` is another vector space, and
434
+ `\phi : W \to V` is any linear map, then we obtain an algebra
435
+ morphism `Cl(\phi) : Cl(W, \phi(Q)) \to Cl(V, Q)` where
436
+ `\phi(Q) = \phi^T \cdot Q \cdot \phi` (we consider `\phi` as a
437
+ matrix) is the quadratic form `Q` pulled back to `W`. In fact, the
438
+ map `\phi` preserves the quadratic form because of
439
+
440
+ .. MATH::
441
+
442
+ \phi(Q)(x) = x^T \cdot \phi^T \cdot Q \cdot \phi \cdot x
443
+ = (\phi \cdot x)^T \cdot Q \cdot (\phi \cdot x) = Q(\phi(x)).
444
+
445
+ Hence we have `\phi(w)^2 = Q(\phi(w)) = \phi(Q)(w)` for all `w \in W`.
446
+
447
+ REFERENCES:
448
+
449
+ - :wikipedia:`Clifford_algebra`
450
+
451
+ INPUT:
452
+
453
+ - ``Q`` -- a quadratic form
454
+ - ``names`` -- (default: ``'e'``) the generator names
455
+
456
+ EXAMPLES:
457
+
458
+ To create a Clifford algebra, all one needs to do is specify a
459
+ quadratic form::
460
+
461
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
462
+ sage: Cl = CliffordAlgebra(Q)
463
+ sage: Cl
464
+ The Clifford algebra of the Quadratic form in 3 variables
465
+ over Integer Ring with coefficients:
466
+ [ 1 2 3 ]
467
+ [ * 4 5 ]
468
+ [ * * 6 ]
469
+
470
+ We can also explicitly name the generators. In this example, the
471
+ Clifford algebra we construct is an exterior algebra (since we
472
+ choose the quadratic form to be zero)::
473
+
474
+ sage: Q = QuadraticForm(ZZ, 4, [0]*10)
475
+ sage: Cl.<a,b,c,d> = CliffordAlgebra(Q)
476
+ sage: a*d
477
+ a*d
478
+ sage: d*c*b*a + a + 4*b*c
479
+ a*b*c*d + 4*b*c + a
480
+ """
481
+ @staticmethod
482
+ def __classcall_private__(cls, Q, names=None):
483
+ """
484
+ Normalize arguments to ensure a unique representation.
485
+
486
+ EXAMPLES::
487
+
488
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
489
+ sage: Cl1.<e0,e1,e2> = CliffordAlgebra(Q)
490
+ sage: Cl2 = CliffordAlgebra(Q)
491
+ sage: Cl3 = CliffordAlgebra(Q, ['e0','e1','e2'])
492
+ sage: Cl1 is Cl2 and Cl2 is Cl3
493
+ True
494
+ """
495
+ if not isinstance(Q, QuadraticForm):
496
+ raise ValueError("{} is not a quadratic form".format(Q))
497
+ if names is None:
498
+ names = 'e'
499
+ names = tuple(names)
500
+ if len(names) != Q.dim():
501
+ if len(names) == 1:
502
+ names = tuple('{}{}'.format(names[0], i) for i in range(Q.dim()))
503
+ else:
504
+ raise ValueError("the number of variables does not match the number of generators")
505
+ return super().__classcall__(cls, Q, names)
506
+
507
+ def __init__(self, Q, names, category=None):
508
+ r"""
509
+ Initialize ``self``.
510
+
511
+ EXAMPLES::
512
+
513
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
514
+ sage: Cl = CliffordAlgebra(Q)
515
+ sage: Cl.category()
516
+ Category of finite dimensional super algebras with basis over
517
+ (Dedekind domains and euclidean domains
518
+ and noetherian rings
519
+ and infinite enumerated sets and metric spaces)
520
+ sage: TestSuite(Cl).run()
521
+
522
+ TESTS:
523
+
524
+ We check that the basis elements are indeed indexed by
525
+ *strictly increasing* tuples::
526
+
527
+ sage: Q = QuadraticForm(ZZ, 9)
528
+ sage: Cl = CliffordAlgebra(Q)
529
+ sage: ba = Cl.basis().keys()
530
+ sage: all(FrozenBitset(format(i,'b')[::-1]) in ba for i in range(2**9))
531
+ True
532
+ """
533
+ self._quadratic_form = Q
534
+ R = Q.base_ring()
535
+ category = AlgebrasWithBasis(R.category()).Super().Filtered().FiniteDimensional().or_subcategory(category)
536
+ indices = CliffordAlgebraIndices(Q.dim())
537
+ CombinatorialFreeModule.__init__(self, R, indices, category=category, sorting_key=tuple)
538
+ self._assign_names(names)
539
+
540
+ def _repr_(self):
541
+ r"""
542
+ Return a string representation of ``self``.
543
+
544
+ EXAMPLES::
545
+
546
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
547
+ sage: CliffordAlgebra(Q)
548
+ The Clifford algebra of the Quadratic form in 3 variables
549
+ over Integer Ring with coefficients:
550
+ [ 1 2 3 ]
551
+ [ * 4 5 ]
552
+ [ * * 6 ]
553
+ """
554
+ return "The Clifford algebra of the {}".format(self._quadratic_form)
555
+
556
+ def _repr_term(self, m):
557
+ """
558
+ Return a string representation of the basis element indexed by ``m``.
559
+
560
+ EXAMPLES::
561
+
562
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
563
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
564
+ sage: Cl._repr_term((0,2))
565
+ 'x*z'
566
+ sage: Cl._repr_term(FrozenBitset('101'))
567
+ 'x*z'
568
+ sage: Cl._repr_term(())
569
+ '1'
570
+ sage: Cl._repr_term((1,))
571
+ 'y'
572
+ """
573
+ if not m:
574
+ return '1'
575
+ term = ''
576
+ for i in m:
577
+ if term:
578
+ term += '*'
579
+ term += self.variable_names()[i]
580
+ return term
581
+
582
+ def _latex_term(self, m):
583
+ r"""
584
+ Return a `\LaTeX` representation of the basis element indexed
585
+ by ``m``.
586
+
587
+ EXAMPLES::
588
+
589
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
590
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
591
+ sage: Cl._latex_term((0,2))
592
+ ' x z'
593
+ """
594
+ if not m:
595
+ return '1'
596
+ term = ''
597
+ for i in m:
598
+ term += ' ' + self.latex_variable_names()[i]
599
+ return term
600
+
601
+ def _coerce_map_from_(self, V):
602
+ """
603
+ Return if there is a coerce map from ``V`` into ``self``.
604
+
605
+ The things which coerce into ``self`` are:
606
+
607
+ - Clifford algebras with the same generator names and an equal
608
+ quadratic form over a ring which coerces into the base
609
+ ring of ``self``.
610
+ - The underlying free module of ``self``.
611
+ - The base ring of ``self``.
612
+
613
+ EXAMPLES::
614
+
615
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
616
+ sage: Qp = QuadraticForm(QQ, 3, [1,2,3,4,5,6])
617
+ sage: Cl = CliffordAlgebra(Q)
618
+ sage: Clp = CliffordAlgebra(Qp)
619
+ sage: Cl.has_coerce_map_from(Clp)
620
+ False
621
+ sage: Clp.has_coerce_map_from(Cl)
622
+ True
623
+
624
+ Check that we preserve the multiplicative structure::
625
+
626
+ sage: all(Clp(b)*Clp(b) == Clp(b*b) for b in Cl.basis())
627
+ True
628
+
629
+ Check from the underlying free module::
630
+
631
+ sage: M = ZZ^3
632
+ sage: Mp = QQ^3
633
+ sage: Cl.has_coerce_map_from(M)
634
+ True
635
+ sage: Cl.has_coerce_map_from(Mp)
636
+ False
637
+ sage: Clp.has_coerce_map_from(M)
638
+ True
639
+ sage: Clp.has_coerce_map_from(Mp)
640
+ True
641
+
642
+ Names matter::
643
+
644
+ sage: Cln = CliffordAlgebra(Q, names=['x','y','z'])
645
+ sage: Cln.has_coerce_map_from(Cl)
646
+ False
647
+ sage: Cl.has_coerce_map_from(Cln)
648
+ False
649
+
650
+ Non-injective homomorphisms of base rings don't cause zero
651
+ values in the coordinate dictionary (this had to be manually
652
+ ensured)::
653
+
654
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
655
+ sage: Qp = QuadraticForm(Integers(3), 3, [1,2,3,4,5,6])
656
+ sage: Cl = CliffordAlgebra(Q)
657
+ sage: Clp = CliffordAlgebra(Qp)
658
+ sage: a = Cl.basis()[(1,2)]
659
+ sage: a
660
+ e1*e2
661
+ sage: Clp(a) # so far so good
662
+ e1*e2
663
+ sage: Clp(3*a) # but now
664
+ 0
665
+ sage: Clp(3*a) == 0
666
+ True
667
+ sage: b = Cl.basis()[(0,2)]
668
+ sage: Clp(3*a-4*b)
669
+ 2*e0*e2
670
+ """
671
+ if isinstance(V, CliffordAlgebra):
672
+ Q = self._quadratic_form
673
+ try:
674
+ return (V.variable_names() == self.variable_names() and
675
+ V._quadratic_form.change_ring(self.base_ring()) == Q)
676
+ except (TypeError, AttributeError):
677
+ return False
678
+
679
+ if self.free_module().has_coerce_map_from(V):
680
+ return True
681
+
682
+ return super()._coerce_map_from_(V)
683
+
684
+ def _element_constructor_(self, x):
685
+ """
686
+ Construct an element of ``self`` from ``x``.
687
+
688
+ EXAMPLES::
689
+
690
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
691
+ sage: Qp = QuadraticForm(QQ, 3, [1,2,3,4,5,6])
692
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
693
+ sage: Clp = CliffordAlgebra(Qp, names=['x','y','z'])
694
+ sage: M = ZZ^3
695
+ sage: Mp = QQ^3
696
+ sage: Cl(2/3)
697
+ Traceback (most recent call last):
698
+ ...
699
+ TypeError: do not know how to make x=2/3 an element of self
700
+ sage: Clp(2/3)
701
+ 2/3
702
+ sage: Clp(x)
703
+ x
704
+ sage: M = ZZ^3
705
+ sage: Clp( M((1,-3,2)) )
706
+ x - 3*y + 2*z
707
+
708
+ Zero coordinates are handled appropriately::
709
+
710
+ sage: Q3 = QuadraticForm(Integers(3), 3, [1,2,3,4,5,6])
711
+ sage: Cl3 = CliffordAlgebra(Q3, names='xyz') # different syntax for a change
712
+ sage: Cl3( M((1,-3,2)) )
713
+ x + 2*z
714
+ """
715
+ # This is the natural lift morphism of the underlying free module
716
+ if x in self.free_module():
717
+ R = self.base_ring()
718
+ if x.parent().base_ring() is R:
719
+ return self.element_class(self, {FrozenBitset((i,)): c for i, c in x.items()})
720
+ # if the base ring is different, attempt to coerce it into R
721
+ return self.element_class(self, {FrozenBitset((i,)): R(c) for i, c in x.items() if R(c) != R.zero()})
722
+
723
+ if (isinstance(x, CliffordAlgebraElement)
724
+ and self.has_coerce_map_from(x.parent())):
725
+ R = self.base_ring()
726
+ return self.element_class(self, {i: R(c) for i, c in x if R(c) != R.zero()})
727
+
728
+ if isinstance(x, tuple):
729
+ R = self.base_ring()
730
+ return self.element_class(self, {FrozenBitset((i,)): R.one() for i in x})
731
+
732
+ try:
733
+ return super()._element_constructor_(x)
734
+ except TypeError:
735
+ raise TypeError(f'do not know how to make {x=} an element of self')
736
+
737
+ def _basis_index_function(self, x):
738
+ """
739
+ Given an integer indexing the basis, return the correct
740
+ bitset.
741
+
742
+ For backwards compatibility, tuples are also accepted.
743
+
744
+ EXAMPLES::
745
+
746
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
747
+ sage: Cl = CliffordAlgebra(Q)
748
+ sage: Cl._basis_index_function(7)
749
+ 111
750
+ sage: Cl._basis_index_function(5)
751
+ 101
752
+ sage: Cl._basis_index_function(4)
753
+ 001
754
+
755
+ sage: Cl._basis_index_function((0, 1, 2))
756
+ 111
757
+ sage: Cl._basis_index_function((0, 2))
758
+ 101
759
+ sage: Cl._basis_index_function((2,))
760
+ 001
761
+ """
762
+ Q = self._quadratic_form
763
+ format_style = f"0{Q.dim()}b"
764
+
765
+ # if the input is a tuple, assume that it has
766
+ # entries in {0, ..., 2**Q.dim()-1}
767
+ if isinstance(x, tuple):
768
+ return FrozenBitset(x, capacity=Q.dim())
769
+
770
+ # slice the output of format in order to make conventions
771
+ # of format and FrozenBitset agree.
772
+ return FrozenBitset(format(x, format_style)[::-1], capacity=Q.dim())
773
+
774
+ def gen(self, i):
775
+ """
776
+ Return the ``i``-th standard generator of the algebra ``self``.
777
+
778
+ This is the ``i``-th basis vector of the vector space on which
779
+ the quadratic form defining ``self`` is defined, regarded as an
780
+ element of ``self``.
781
+
782
+ EXAMPLES::
783
+
784
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
785
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
786
+ sage: [Cl.gen(i) for i in range(3)]
787
+ [x, y, z]
788
+ """
789
+ return self._from_dict({FrozenBitset((i,)): self.base_ring().one()}, remove_zeros=False)
790
+
791
+ def algebra_generators(self) -> Family:
792
+ """
793
+ Return the algebra generators of ``self``.
794
+
795
+ EXAMPLES::
796
+
797
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
798
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
799
+ sage: Cl.algebra_generators()
800
+ Finite family {'x': x, 'y': y, 'z': z}
801
+ """
802
+ d = {x: self.gen(i) for i, x in enumerate(self.variable_names())}
803
+ return Family(self.variable_names(), lambda x: d[x])
804
+
805
+ def gens(self) -> tuple:
806
+ r"""
807
+ Return the generators of ``self`` (as an algebra).
808
+
809
+ EXAMPLES::
810
+
811
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
812
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
813
+ sage: Cl.gens()
814
+ (x, y, z)
815
+ """
816
+ return tuple(self.algebra_generators())
817
+
818
+ @cached_method
819
+ def ngens(self):
820
+ """
821
+ Return the number of algebra generators of ``self``.
822
+
823
+ EXAMPLES::
824
+
825
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
826
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
827
+ sage: Cl.ngens()
828
+ 3
829
+ """
830
+ return self._quadratic_form.dim()
831
+
832
+ @cached_method
833
+ def one_basis(self):
834
+ """
835
+ Return the basis index of the element ``1``. The element ``1``
836
+ is indexed by the emptyset, which is represented by the
837
+ :class:`sage.data_structures.bitset.Bitset` ``0``.
838
+
839
+ EXAMPLES::
840
+
841
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
842
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
843
+ sage: Cl.one_basis()
844
+ 0
845
+ """
846
+ return FrozenBitset()
847
+
848
+ def is_commutative(self) -> bool:
849
+ """
850
+ Check if ``self`` is a commutative algebra.
851
+
852
+ EXAMPLES::
853
+
854
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
855
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
856
+ sage: Cl.is_commutative()
857
+ False
858
+ """
859
+ return self._quadratic_form.dim() < 2
860
+
861
+ def quadratic_form(self):
862
+ """
863
+ Return the quadratic form of ``self``.
864
+
865
+ This is the quadratic form used to define ``self``. The
866
+ quadratic form on ``self`` is yet to be implemented.
867
+
868
+ EXAMPLES::
869
+
870
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
871
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
872
+ sage: Cl.quadratic_form()
873
+ Quadratic form in 3 variables over Integer Ring with coefficients:
874
+ [ 1 2 3 ]
875
+ [ * 4 5 ]
876
+ [ * * 6 ]
877
+ """
878
+ return self._quadratic_form
879
+
880
+ def degree_on_basis(self, m):
881
+ r"""
882
+ Return the degree of the monomial indexed by ``m``.
883
+
884
+ We are considering the Clifford algebra to be `\NN`-filtered,
885
+ and the degree of the monomial ``m`` is the length of ``m``.
886
+
887
+ EXAMPLES::
888
+
889
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
890
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
891
+ sage: Cl.degree_on_basis((0,))
892
+ 1
893
+ sage: Cl.degree_on_basis((0,1))
894
+ 2
895
+ """
896
+ return ZZ(len(m))
897
+
898
+ def graded_algebra(self):
899
+ """
900
+ Return the associated graded algebra of ``self``.
901
+
902
+ EXAMPLES::
903
+
904
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
905
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
906
+ sage: Cl.graded_algebra()
907
+ The exterior algebra of rank 3 over Integer Ring
908
+ """
909
+ return ExteriorAlgebra(self.base_ring(), self.variable_names())
910
+
911
+ @cached_method
912
+ def free_module(self):
913
+ """
914
+ Return the underlying free module `V` of ``self``.
915
+
916
+ This is the free module on which the quadratic form that was
917
+ used to construct ``self`` is defined.
918
+
919
+ EXAMPLES::
920
+
921
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
922
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
923
+ sage: Cl.free_module()
924
+ Ambient free module of rank 3 over the principal ideal domain Integer Ring
925
+ """
926
+ return FreeModule(self.base_ring(), self._quadratic_form.dim())
927
+
928
+ def dimension(self):
929
+ """
930
+ Return the rank of ``self`` as a free module.
931
+
932
+ Let `V` be a free `R`-module of rank `n`; then, `Cl(V, Q)` is a
933
+ free `R`-module of rank `2^n`.
934
+
935
+ EXAMPLES::
936
+
937
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
938
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
939
+ sage: Cl.dimension()
940
+ 8
941
+ """
942
+ return ZZ(2)**self._quadratic_form.dim()
943
+
944
+ def pseudoscalar(self):
945
+ r"""
946
+ Return the unit pseudoscalar of ``self``.
947
+
948
+ Given the basis `e_1, e_2, \ldots, e_n` of the underlying
949
+ `R`-module, the unit pseudoscalar is defined as
950
+ `e_1 \cdot e_2 \cdots e_n`.
951
+
952
+ This depends on the choice of basis.
953
+
954
+ EXAMPLES::
955
+
956
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
957
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
958
+ sage: Cl.pseudoscalar()
959
+ x*y*z
960
+
961
+ sage: Q = QuadraticForm(ZZ, 0, [])
962
+ sage: Cl = CliffordAlgebra(Q)
963
+ sage: Cl.pseudoscalar()
964
+ 1
965
+
966
+ REFERENCES:
967
+
968
+ - :wikipedia:`Classification_of_Clifford_algebras#Unit_pseudoscalar`
969
+ """
970
+ d = self._quadratic_form.dim()
971
+ return self.element_class(self, {tuple(range(d)): self.base_ring().one()})
972
+
973
+ def lift_module_morphism(self, m, names=None):
974
+ r"""
975
+ Lift the matrix ``m`` to an algebra morphism of Clifford algebras.
976
+
977
+ Given a linear map `m : W \to V` (here represented by a matrix
978
+ acting on column vectors), this method returns the algebra
979
+ morphism `Cl(m) : Cl(W, m(Q)) \to Cl(V, Q)`, where `Cl(V, Q)`
980
+ is the Clifford algebra ``self`` and where `m(Q)` is the pullback
981
+ of the quadratic form `Q` to `W`. See the documentation
982
+ of :class:`CliffordAlgebra` for how this pullback and the
983
+ morphism `Cl(m)` are defined.
984
+
985
+ .. NOTE::
986
+
987
+ This is a map into ``self``.
988
+
989
+ INPUT:
990
+
991
+ - ``m`` -- a matrix
992
+ - ``names`` -- (default: ``'e'``) the names of the generators of the
993
+ Clifford algebra of the domain of (the map represented by) ``m``
994
+
995
+ OUTPUT: the algebra morphism `Cl(m)` from `Cl(W, m(Q))` to ``self``
996
+
997
+ EXAMPLES::
998
+
999
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
1000
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1001
+ sage: m = matrix([[1,-1,-1],[0,1,-1],[1,1,1]])
1002
+ sage: phi = Cl.lift_module_morphism(m, 'abc')
1003
+ sage: phi
1004
+ Generic morphism:
1005
+ From: The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients:
1006
+ [ 10 17 3 ]
1007
+ [ * 11 0 ]
1008
+ [ * * 5 ]
1009
+ To: The Clifford algebra of the Quadratic form in 3 variables over Integer Ring with coefficients:
1010
+ [ 1 2 3 ]
1011
+ [ * 4 5 ]
1012
+ [ * * 6 ]
1013
+ sage: a,b,c = phi.domain().gens()
1014
+ sage: phi(a)
1015
+ x + z
1016
+ sage: phi(b)
1017
+ -x + y + z
1018
+ sage: phi(c)
1019
+ -x - y + z
1020
+ sage: phi(a + 3*b)
1021
+ -2*x + 3*y + 4*z
1022
+ sage: phi(a) + 3*phi(b)
1023
+ -2*x + 3*y + 4*z
1024
+ sage: phi(a*b)
1025
+ x*y + 2*x*z - y*z + 7
1026
+ sage: phi(b*a)
1027
+ -x*y - 2*x*z + y*z + 10
1028
+ sage: phi(a*b + c)
1029
+ x*y + 2*x*z - y*z - x - y + z + 7
1030
+ sage: phi(a*b) + phi(c)
1031
+ x*y + 2*x*z - y*z - x - y + z + 7
1032
+
1033
+ We check that the map is an algebra morphism::
1034
+
1035
+ sage: phi(a)*phi(b)
1036
+ x*y + 2*x*z - y*z + 7
1037
+ sage: phi(a*b)
1038
+ x*y + 2*x*z - y*z + 7
1039
+ sage: phi(a*a)
1040
+ 10
1041
+ sage: phi(a)*phi(a)
1042
+ 10
1043
+ sage: phi(b*a)
1044
+ -x*y - 2*x*z + y*z + 10
1045
+ sage: phi(b) * phi(a)
1046
+ -x*y - 2*x*z + y*z + 10
1047
+ sage: phi((a + b)*(a + c)) == phi(a + b) * phi(a + c)
1048
+ True
1049
+
1050
+ We can also lift arbitrary linear maps::
1051
+
1052
+ sage: m = matrix([[1,1],[0,1],[1,1]])
1053
+ sage: phi = Cl.lift_module_morphism(m, 'ab')
1054
+ sage: a,b = phi.domain().gens()
1055
+ sage: phi(a)
1056
+ x + z
1057
+ sage: phi(b)
1058
+ x + y + z
1059
+ sage: phi(a*b)
1060
+ x*y - y*z + 15
1061
+ sage: phi(a)*phi(b)
1062
+ x*y - y*z + 15
1063
+ sage: phi(b*a)
1064
+ -x*y + y*z + 12
1065
+ sage: phi(b)*phi(a)
1066
+ -x*y + y*z + 12
1067
+
1068
+ sage: m = matrix([[1,1,1,2], [0,1,1,1], [0,1,1,1]])
1069
+ sage: phi = Cl.lift_module_morphism(m, 'abcd')
1070
+ sage: a,b,c,d = phi.domain().gens()
1071
+ sage: phi(a)
1072
+ x
1073
+ sage: phi(b)
1074
+ x + y + z
1075
+ sage: phi(c)
1076
+ x + y + z
1077
+ sage: phi(d)
1078
+ 2*x + y + z
1079
+ sage: phi(a*b*c + d*a)
1080
+ -x*y - x*z + 21*x + 7
1081
+ sage: phi(a*b*c*d)
1082
+ 21*x*y + 21*x*z + 42
1083
+
1084
+ TESTS:
1085
+
1086
+ Check that the resulting morphism knows it is for
1087
+ finite-dimensional algebras (:issue:`25339`)::
1088
+
1089
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
1090
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1091
+ sage: m = matrix([[1,-1,-1],[0,1,-1],[1,1,1]])
1092
+ sage: phi = Cl.lift_module_morphism(m, 'abc')
1093
+ sage: phi.category_for()
1094
+ Category of finite dimensional super algebras with basis over
1095
+ (Dedekind domains and euclidean domains
1096
+ and noetherian rings
1097
+ and infinite enumerated sets and metric spaces)
1098
+ sage: phi.matrix()
1099
+ [ 1 0 0 0 7 -3 -7 0]
1100
+ [ 0 1 -1 -1 0 0 0 -17]
1101
+ [ 0 0 1 -1 0 0 0 -4]
1102
+ [ 0 1 1 1 0 0 0 3]
1103
+ [ 0 0 0 0 1 -1 2 0]
1104
+ [ 0 0 0 0 2 2 0 0]
1105
+ [ 0 0 0 0 -1 1 2 0]
1106
+ [ 0 0 0 0 0 0 0 4]
1107
+ """
1108
+ Q = self._quadratic_form(m)
1109
+ # If R is a quadratic form and m is a matrix, then R(m) returns
1110
+ # the quadratic form m^t R m.
1111
+
1112
+ if Q == self._quadratic_form and names is None:
1113
+ Cl = self
1114
+ else:
1115
+ Cl = CliffordAlgebra(Q, names)
1116
+
1117
+ n = self._quadratic_form.dim()
1118
+ f = lambda x: self.prod(self._from_dict({FrozenBitset((j, )): m[j, i] for j in range(n)},
1119
+ remove_zeros=True) for i in x)
1120
+ cat = AlgebrasWithBasis(self.category().base_ring()).Super().FiniteDimensional()
1121
+ return Cl.module_morphism(on_basis=f, codomain=self, category=cat)
1122
+
1123
+ def lift_isometry(self, m, names=None):
1124
+ r"""
1125
+ Lift an invertible isometry ``m`` of the quadratic form of
1126
+ ``self`` to a Clifford algebra morphism.
1127
+
1128
+ Given an invertible linear map `m : V \to W` (here represented by
1129
+ a matrix acting on column vectors), this method returns the
1130
+ algebra morphism `Cl(m)` from `Cl(V, Q)` to `Cl(W, m^{-1}(Q))`,
1131
+ where `Cl(V, Q)` is the Clifford algebra ``self`` and where
1132
+ `m^{-1}(Q)` is the pullback of the quadratic form `Q` to `W` along
1133
+ the inverse map `m^{-1} : W \to V`. See the documentation of
1134
+ :class:`CliffordAlgebra` for how this pullback and the morphism
1135
+ `Cl(m)` are defined.
1136
+
1137
+ INPUT:
1138
+
1139
+ - ``m`` -- an isometry of the quadratic form of ``self``
1140
+ - ``names`` -- (default: ``'e'``) the names of the generators of
1141
+ the Clifford algebra of the codomain of (the map represented by)
1142
+ ``m``
1143
+
1144
+ OUTPUT: the algebra morphism `Cl(m)` from ``self`` to `Cl(W, m^{-1}(Q))`
1145
+
1146
+ EXAMPLES::
1147
+
1148
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
1149
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1150
+ sage: m = matrix([[1,1,2],[0,1,1],[0,0,1]])
1151
+ sage: phi = Cl.lift_isometry(m, 'abc')
1152
+ sage: phi(x)
1153
+ a
1154
+ sage: phi(y)
1155
+ a + b
1156
+ sage: phi(x*y)
1157
+ a*b + 1
1158
+ sage: phi(x) * phi(y)
1159
+ a*b + 1
1160
+ sage: phi(z*y)
1161
+ a*b - a*c - b*c
1162
+ sage: phi(z) * phi(y)
1163
+ a*b - a*c - b*c
1164
+ sage: phi(x + z) * phi(y + z) == phi((x + z) * (y + z))
1165
+ True
1166
+
1167
+ TESTS:
1168
+
1169
+ Check that the resulting morphism knows it is for
1170
+ finite-dimensional algebras (:issue:`25339`)::
1171
+
1172
+ sage: Q = QuadraticForm(ZZ, 3, [1,2,3,4,5,6])
1173
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1174
+ sage: m = matrix([[1,1,2],[0,1,1],[0,0,1]])
1175
+ sage: phi = Cl.lift_isometry(m, 'abc')
1176
+ sage: phi.category_for()
1177
+ Category of finite dimensional super algebras with basis over
1178
+ (Dedekind domains and euclidean domains
1179
+ and noetherian rings
1180
+ and infinite enumerated sets and metric spaces)
1181
+ sage: phi.matrix()
1182
+ [ 1 0 0 0 1 2 5 0]
1183
+ [ 0 1 1 2 0 0 0 5]
1184
+ [ 0 0 1 1 0 0 0 -1]
1185
+ [ 0 0 0 1 0 0 0 1]
1186
+ [ 0 0 0 0 1 1 -1 0]
1187
+ [ 0 0 0 0 0 1 1 0]
1188
+ [ 0 0 0 0 0 0 1 0]
1189
+ [ 0 0 0 0 0 0 0 1]
1190
+ """
1191
+ MS = m.parent()
1192
+ if not m.is_invertible():
1193
+ raise ValueError('{} is not invertible')
1194
+ Q = self._quadratic_form(MS(m.inverse()))
1195
+
1196
+ if Q == self._quadratic_form and names is None:
1197
+ Cl = self
1198
+ else:
1199
+ if names is None:
1200
+ names = 'e'
1201
+ Cl = CliffordAlgebra(Q, names)
1202
+
1203
+ n = Q.dim()
1204
+
1205
+ f = lambda x: Cl.prod(Cl._from_dict({FrozenBitset((j, )): m[j, i] for j in range(n)},
1206
+ remove_zeros=True) for i in x)
1207
+ cat = AlgebrasWithBasis(self.category().base_ring()).Super().FiniteDimensional()
1208
+ return self.module_morphism(on_basis=f, codomain=Cl, category=cat)
1209
+
1210
+ # This is a general method for finite dimensional algebras with bases
1211
+ # and should be moved to the corresponding category once there is
1212
+ # a category level method for getting the indexing set of the basis;
1213
+ # similar to #15289 but on a category level.
1214
+ @cached_method
1215
+ def center_basis(self):
1216
+ """
1217
+ Return a list of elements which correspond to a basis for the center
1218
+ of ``self``.
1219
+
1220
+ This assumes that the ground ring can be used to compute the
1221
+ kernel of a matrix.
1222
+
1223
+ .. SEEALSO::
1224
+
1225
+ :meth:`supercenter_basis`,
1226
+ http://math.stackexchange.com/questions/129183/center-of-clifford-algebra-depending-on-the-parity-of-dim-v
1227
+
1228
+ .. TODO::
1229
+
1230
+ Deprecate this in favor of a method called `center()` once
1231
+ subalgebras are properly implemented in Sage.
1232
+
1233
+ EXAMPLES::
1234
+
1235
+ sage: Q = QuadraticForm(QQ, 3, [1,2,3,4,5,6])
1236
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1237
+ sage: Z = Cl.center_basis(); Z
1238
+ (1, -2/5*x*y*z + x - 3/5*y + 2/5*z)
1239
+ sage: all(z*b - b*z == 0 for z in Z for b in Cl.basis())
1240
+ True
1241
+
1242
+ sage: Q = QuadraticForm(QQ, 3, [1,-2,-3, 4, 2, 1])
1243
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1244
+ sage: Z = Cl.center_basis(); Z
1245
+ (1, -x*y*z + x + 3/2*y - z)
1246
+ sage: all(z*b - b*z == 0 for z in Z for b in Cl.basis())
1247
+ True
1248
+
1249
+ sage: Q = QuadraticForm(QQ, 2, [1,-2,-3])
1250
+ sage: Cl.<x,y> = CliffordAlgebra(Q)
1251
+ sage: Cl.center_basis()
1252
+ (1,)
1253
+
1254
+ sage: Q = QuadraticForm(QQ, 2, [-1,1,-3])
1255
+ sage: Cl.<x,y> = CliffordAlgebra(Q)
1256
+ sage: Cl.center_basis()
1257
+ (1,)
1258
+
1259
+ A degenerate case::
1260
+
1261
+ sage: Q = QuadraticForm(QQ, 3, [4,4,-4,1,-2,1])
1262
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1263
+ sage: Cl.center_basis()
1264
+ (1, x*y*z + x - 2*y - 2*z, x*y + x*z - 2*y*z)
1265
+
1266
+ The most degenerate case (the exterior algebra)::
1267
+
1268
+ sage: Q = QuadraticForm(QQ, 3)
1269
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1270
+ sage: Cl.center_basis()
1271
+ (1, x*y, x*z, y*z, x*y*z)
1272
+ """
1273
+ R = self.base_ring()
1274
+ B = self.basis()
1275
+ K = list(B.keys())
1276
+ k = len(K)
1277
+ d = {}
1278
+ for a, i in enumerate(K):
1279
+ Bi = B[i]
1280
+ for b, j in enumerate(K):
1281
+ Bj = B[j]
1282
+ for m, c in (Bi*Bj - Bj*Bi):
1283
+ d[(a, K.index(m)+k*b)] = c
1284
+ m = Matrix(R, d, nrows=k, ncols=k*k, sparse=True)
1285
+ from_vector = lambda x: self.sum_of_terms(((K[i], c) for i, c in x.items()),
1286
+ distinct=True)
1287
+ return tuple(map(from_vector, m.kernel().basis()))
1288
+
1289
+ # Same as center except for superalgebras
1290
+ @cached_method
1291
+ def supercenter_basis(self):
1292
+ """
1293
+ Return a list of elements which correspond to a basis for the
1294
+ supercenter of ``self``.
1295
+
1296
+ This assumes that the ground ring can be used to compute the
1297
+ kernel of a matrix.
1298
+
1299
+ .. SEEALSO::
1300
+
1301
+ :meth:`center_basis`,
1302
+ http://math.stackexchange.com/questions/129183/center-of-clifford-algebra-depending-on-the-parity-of-dim-v
1303
+
1304
+ .. TODO::
1305
+
1306
+ Deprecate this in favor of a method called `supercenter()` once
1307
+ subalgebras are properly implemented in Sage.
1308
+
1309
+ EXAMPLES::
1310
+
1311
+ sage: Q = QuadraticForm(QQ, 3, [1,2,3,4,5,6])
1312
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1313
+ sage: SZ = Cl.supercenter_basis(); SZ
1314
+ (1,)
1315
+ sage: all(z.supercommutator(b) == 0 for z in SZ for b in Cl.basis())
1316
+ True
1317
+
1318
+ sage: Q = QuadraticForm(QQ, 3, [1,-2,-3, 4, 2, 1])
1319
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1320
+ sage: Cl.supercenter_basis()
1321
+ (1,)
1322
+
1323
+ sage: Q = QuadraticForm(QQ, 2, [1,-2,-3])
1324
+ sage: Cl.<x,y> = CliffordAlgebra(Q)
1325
+ sage: Cl.supercenter_basis()
1326
+ (1,)
1327
+
1328
+ sage: Q = QuadraticForm(QQ, 2, [-1,1,-3])
1329
+ sage: Cl.<x,y> = CliffordAlgebra(Q)
1330
+ sage: Cl.supercenter_basis()
1331
+ (1,)
1332
+
1333
+ Singular vectors of a quadratic form generate in the supercenter::
1334
+
1335
+ sage: Q = QuadraticForm(QQ, 3, [1/2,-2,4,256/249,3,-185/8])
1336
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1337
+ sage: Cl.supercenter_basis()
1338
+ (1, x + 249/322*y + 22/161*z)
1339
+
1340
+ sage: Q = QuadraticForm(QQ, 3, [4,4,-4,1,-2,1])
1341
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1342
+ sage: Cl.supercenter_basis()
1343
+ (1, x + 2*z, y + z, x*y + x*z - 2*y*z)
1344
+
1345
+ The most degenerate case::
1346
+
1347
+ sage: Q = QuadraticForm(QQ, 3)
1348
+ sage: Cl.<x,y,z> = CliffordAlgebra(Q)
1349
+ sage: Cl.supercenter_basis()
1350
+ (1, x, y, z, x*y, x*z, y*z, x*y*z)
1351
+ """
1352
+ R = self.base_ring()
1353
+ B = self.basis()
1354
+ K = list(B.keys())
1355
+ k = len(K)
1356
+ d = {}
1357
+ for a, i in enumerate(K):
1358
+ Bi = B[i]
1359
+ for b, j in enumerate(K):
1360
+ Bj = B[j]
1361
+ if len(i) % 2 and len(j) % 2:
1362
+ supercommutator = Bi * Bj + Bj * Bi
1363
+ else:
1364
+ supercommutator = Bi * Bj - Bj * Bi
1365
+ for m, c in supercommutator:
1366
+ d[(a, K.index(m) + k * b)] = c
1367
+ m = Matrix(R, d, nrows=k, ncols=k * k, sparse=True)
1368
+ from_vector = lambda x: self.sum_of_terms(((K[i], c) for i, c in x.items()),
1369
+ distinct=True)
1370
+ return tuple(map(from_vector, m.kernel().basis()))
1371
+
1372
+ Element = CliffordAlgebraElement
1373
+
1374
+
1375
+ class ExteriorAlgebra(CliffordAlgebra):
1376
+ r"""
1377
+ An exterior algebra of a free module over a commutative ring.
1378
+
1379
+ Let `V` be a module over a commutative ring `R`. The exterior algebra
1380
+ (or Grassmann algebra) `\Lambda(V)` of `V` is defined as the quotient
1381
+ of the tensor algebra `T(V)` of `V` modulo the two-sided ideal
1382
+ generated by all tensors of the form `x \otimes x` with `x \in V`. The
1383
+ multiplication on `\Lambda(V)` is denoted by `\wedge` (so
1384
+ `v_1 \wedge v_2 \wedge \cdots \wedge v_n` is the projection of
1385
+ `v_1 \otimes v_2 \otimes \cdots \otimes v_n` onto `\Lambda(V)`) and
1386
+ called the "exterior product" or "wedge product".
1387
+
1388
+ If `V` is a rank-`n` free `R`-module with a basis
1389
+ `\{e_1, \ldots, e_n\}`, then `\Lambda(V)` is the `R`-algebra
1390
+ noncommutatively generated by the `n` generators `e_1, \ldots, e_n`
1391
+ subject to the relations `e_i^2 = 0` for all `i`, and
1392
+ `e_i e_j = - e_j e_i` for all `i < j`. As an `R`-module,
1393
+ `\Lambda(V)` then has a basis `(\bigwedge_{i \in I} e_i)` with `I`
1394
+ ranging over the subsets of `\{1, 2, \ldots, n\}` (where
1395
+ `\bigwedge_{i \in I} e_i` is the wedge product of `e_i` for `i`
1396
+ running through all elements of `I` from smallest to largest), and
1397
+ hence is free of rank `2^n`.
1398
+
1399
+ The exterior algebra of an `R`-module `V` can also be realized
1400
+ as the Clifford algebra of `V` for the quadratic form `Q` given by
1401
+ `Q(v) = 0` for all vectors `v \in V`. See :class:`CliffordAlgebra`
1402
+ for the notion of a Clifford algebra.
1403
+
1404
+ The exterior algebra of an `R`-module `V` is a connected `\ZZ`-graded
1405
+ Hopf superalgebra. It is commutative in the super sense (i.e., the
1406
+ odd elements anticommute and square to `0`).
1407
+
1408
+ This class implements the exterior algebra `\Lambda(R^n)` for
1409
+ `n` a nonnegative integer.
1410
+
1411
+ INPUT:
1412
+
1413
+ - ``R`` -- the base ring, *or* the free module whose exterior algebra
1414
+ is to be computed
1415
+
1416
+ - ``names`` -- list of strings to name the generators of the
1417
+ exterior algebra; this list can either have one entry only (in which
1418
+ case the generators will be called ``e + '0'``, ``e + '1'``, ...,
1419
+ ``e + 'n-1'``, with ``e`` being said entry), or have ``n`` entries
1420
+ (in which case these entries will be used directly as names for the
1421
+ generators)
1422
+
1423
+ - ``n`` -- the number of generators, i.e., the rank of the free
1424
+ module whose exterior algebra is to be computed (this doesn't have
1425
+ to be provided if it can be inferred from the rest of the input)
1426
+
1427
+ REFERENCES:
1428
+
1429
+ - :wikipedia:`Exterior_algebra`
1430
+ """
1431
+ @staticmethod
1432
+ def __classcall_private__(cls, R, names=None, n=None):
1433
+ """
1434
+ Normalize arguments to ensure a unique representation.
1435
+
1436
+ EXAMPLES::
1437
+
1438
+ sage: E1.<e0,e1,e2> = ExteriorAlgebra(QQ)
1439
+ sage: E2 = ExteriorAlgebra(QQ, 3)
1440
+ sage: E3 = ExteriorAlgebra(QQ, ['e0','e1','e2'])
1441
+ sage: E1 is E2 and E2 is E3
1442
+ True
1443
+ """
1444
+ if names is None:
1445
+ names = 'e'
1446
+ elif names in ZZ:
1447
+ n = names
1448
+ names = 'e'
1449
+
1450
+ if isinstance(R, FreeModule_generic):
1451
+ if n is not None and n != R.dimension():
1452
+ raise ValueError("the number of variables does not match the dimension")
1453
+ n = R.dimension()
1454
+ R = R.base_ring()
1455
+
1456
+ names = tuple(names)
1457
+ if n is not None and len(names) != n:
1458
+ if len(names) == 1:
1459
+ names = tuple('{}{}'.format(names[0], i) for i in range(n))
1460
+ else:
1461
+ raise ValueError("the number of variables does not match the number of generators")
1462
+ return super().__classcall__(cls, R, names)
1463
+
1464
+ def __init__(self, R, names):
1465
+ """
1466
+ Initialize ``self``.
1467
+
1468
+ EXAMPLES::
1469
+
1470
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1471
+ sage: E.category()
1472
+ Category of finite dimensional supercommutative supercocommutative
1473
+ super Hopf algebras with basis over Rational Field
1474
+ sage: TestSuite(E).run()
1475
+
1476
+ sage: TestSuite(ExteriorAlgebra(GF(3), ['a', 'b'])).run()
1477
+ """
1478
+ cat = HopfAlgebrasWithBasis(R).FiniteDimensional().Supercommutative().Supercocommutative()
1479
+ CliffordAlgebra.__init__(self, QuadraticForm(R, len(names)), names, category=cat)
1480
+
1481
+ def _repr_(self):
1482
+ r"""
1483
+ Return a string representation of ``self``.
1484
+
1485
+ EXAMPLES::
1486
+
1487
+ sage: ExteriorAlgebra(QQ, 3)
1488
+ The exterior algebra of rank 3 over Rational Field
1489
+ """
1490
+ return "The exterior algebra of rank {} over {}".format(self.ngens(), self.base_ring())
1491
+
1492
+ def _repr_term(self, m):
1493
+ """
1494
+ Return a string representation of the basis element indexed by
1495
+ ``m``.
1496
+
1497
+ EXAMPLES::
1498
+
1499
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1500
+ sage: E._repr_term((0,1,2))
1501
+ 'x*y*z'
1502
+ sage: y*x + x*z
1503
+ -x*y + x*z
1504
+ """
1505
+ if len(m) == 0:
1506
+ return '1'
1507
+ term = ''
1508
+ for i in m:
1509
+ if len(term) != 0:
1510
+ term += '*'
1511
+ term += self.variable_names()[i]
1512
+ return term
1513
+
1514
+ def _ascii_art_term(self, m):
1515
+ r"""
1516
+ Return ascii art for the basis element indexed by ``m``.
1517
+
1518
+ EXAMPLES::
1519
+
1520
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1521
+ sage: E._ascii_art_term((0,1,2))
1522
+ x/\y/\z
1523
+ sage: ascii_art(y*x + 2*x*z)
1524
+ -x/\y + 2*x/\z
1525
+ """
1526
+ if len(m) == 0:
1527
+ return ascii_art('1')
1528
+ wedge = '/\\'
1529
+ return ascii_art(*[repr(self.basis()[FrozenBitset((i, ))]) for i in m], sep=wedge)
1530
+
1531
+ def _unicode_art_term(self, m):
1532
+ """
1533
+ Return unicode art for the basis element indexed by ``m``.
1534
+
1535
+ EXAMPLES::
1536
+
1537
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1538
+ sage: E._unicode_art_term((0,1,2))
1539
+ x∧y∧z
1540
+ sage: unicode_art(y*x + x*z)
1541
+ -x∧y + x∧z
1542
+ """
1543
+ if len(m) == 0:
1544
+ return unicode_art('1')
1545
+ wedge = unicodedata.lookup('LOGICAL AND')
1546
+ return unicode_art(*[self.variable_names()[i] for i in m], sep=wedge)
1547
+
1548
+ def _latex_term(self, m):
1549
+ r"""
1550
+ Return a `\LaTeX` representation of the basis element indexed
1551
+ by ``m``.
1552
+
1553
+ EXAMPLES::
1554
+
1555
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1556
+ sage: E._latex_term((0,1,2))
1557
+ ' x \\wedge y \\wedge z'
1558
+ sage: E.<x0,x1,x2> = ExteriorAlgebra(QQ)
1559
+ sage: E._latex_term((0,1,2))
1560
+ ' x_{0} \\wedge x_{1} \\wedge x_{2}'
1561
+ sage: E._latex_term(())
1562
+ '1'
1563
+ sage: E._latex_term((0,))
1564
+ ' x_{0}'
1565
+ """
1566
+ if len(m) == 0:
1567
+ return '1'
1568
+ term = ''
1569
+ for i in m:
1570
+ if len(term) != 0:
1571
+ term += ' \\wedge'
1572
+ term += ' ' + self.latex_variable_names()[i]
1573
+ return term
1574
+
1575
+ def lift_morphism(self, phi, names=None):
1576
+ r"""
1577
+ Lift the matrix ``m`` to an algebra morphism of exterior algebras.
1578
+
1579
+ Given a linear map `\phi : V \to W` (here represented by a matrix
1580
+ acting on column vectors over the base ring of `V`), this method
1581
+ returns the algebra morphism
1582
+ `\Lambda(\phi) : \Lambda(V) \to \Lambda(W)`. This morphism is defined
1583
+ on generators `v_i \in \Lambda(V)` by `v_i \mapsto \phi(v_i)`.
1584
+
1585
+ .. NOTE::
1586
+
1587
+ This is the map going out of ``self`` as opposed to
1588
+ :meth:`~sage.algebras.clifford_algebra.CliffordAlgebraElement.lift_module_morphism()`
1589
+ for general Clifford algebras.
1590
+
1591
+ INPUT:
1592
+
1593
+ - ``phi`` -- a linear map `\phi` from `V` to `W`, encoded as a
1594
+ matrix
1595
+ - ``names`` -- (default: ``'e'``) the names of the generators of
1596
+ the Clifford algebra of the domain of (the map represented by)
1597
+ ``phi``
1598
+
1599
+ OUTPUT: the algebra morphism `\Lambda(\phi)` from ``self`` to
1600
+ `\Lambda(W)`
1601
+
1602
+ EXAMPLES::
1603
+
1604
+ sage: E.<x,y> = ExteriorAlgebra(QQ)
1605
+ sage: phi = matrix([[0,1],[1,1],[1,2]]); phi
1606
+ [0 1]
1607
+ [1 1]
1608
+ [1 2]
1609
+ sage: L = E.lift_morphism(phi, ['a','b','c']); L
1610
+ Generic morphism:
1611
+ From: The exterior algebra of rank 2 over Rational Field
1612
+ To: The exterior algebra of rank 3 over Rational Field
1613
+ sage: L(x)
1614
+ b + c
1615
+ sage: L(y)
1616
+ a + b + 2*c
1617
+ sage: L.on_basis()((1,))
1618
+ a + b + 2*c
1619
+ sage: p = L(E.one()); p
1620
+ 1
1621
+ sage: p.parent()
1622
+ The exterior algebra of rank 3 over Rational Field
1623
+ sage: L(x*y)
1624
+ -a*b - a*c + b*c
1625
+ sage: L(x)*L(y)
1626
+ -a*b - a*c + b*c
1627
+ sage: L(x + y)
1628
+ a + 2*b + 3*c
1629
+ sage: L(x) + L(y)
1630
+ a + 2*b + 3*c
1631
+ sage: L(1/2*x + 2)
1632
+ 1/2*b + 1/2*c + 2
1633
+ sage: L(E(3))
1634
+ 3
1635
+
1636
+ sage: psi = matrix([[1, -3/2]]); psi
1637
+ [ 1 -3/2]
1638
+ sage: Lp = E.lift_morphism(psi, ['a']); Lp
1639
+ Generic morphism:
1640
+ From: The exterior algebra of rank 2 over Rational Field
1641
+ To: The exterior algebra of rank 1 over Rational Field
1642
+ sage: Lp(x)
1643
+ a
1644
+ sage: Lp(y)
1645
+ -3/2*a
1646
+ sage: Lp(x + 2*y + 3)
1647
+ -2*a + 3
1648
+
1649
+ TESTS:
1650
+
1651
+ Check that the resulting morphism knows it is for
1652
+ finite-dimensional algebras (:issue:`25339`)::
1653
+
1654
+ sage: E = ExteriorAlgebra(ZZ, 'e', 3)
1655
+ sage: T = jordan_block(0, 2).block_sum(jordan_block(0, 1))
1656
+ sage: phi = E.lift_morphism(T)
1657
+ sage: phi.category_for()
1658
+ Category of finite dimensional super algebras with basis over Integer Ring
1659
+ sage: phi.matrix()
1660
+ [1 0 0 0 0 0 0 0]
1661
+ [0 0 1 0 0 0 0 0]
1662
+ [0 0 0 0 0 0 0 0]
1663
+ [0 0 0 0 0 0 0 0]
1664
+ [0 0 0 0 0 0 0 0]
1665
+ [0 0 0 0 0 0 0 0]
1666
+ [0 0 0 0 0 0 0 0]
1667
+ [0 0 0 0 0 0 0 0]
1668
+ """
1669
+ n = phi.nrows()
1670
+ R = self.base_ring()
1671
+ E = ExteriorAlgebra(R, names, n)
1672
+ f = lambda x: E.prod(E._from_dict({FrozenBitset((j, )): phi[j, i] for j in range(n)},
1673
+ remove_zeros=True) for i in x)
1674
+ cat = AlgebrasWithBasis(R).Super().FiniteDimensional()
1675
+ return self.module_morphism(on_basis=f, codomain=E, category=cat)
1676
+
1677
+ def volume_form(self):
1678
+ r"""
1679
+ Return the volume form of ``self``.
1680
+
1681
+ Given the basis `e_1, e_2, \ldots, e_n` of the underlying
1682
+ `R`-module, the volume form is defined as `e_1 \wedge e_2
1683
+ \wedge \cdots \wedge e_n`.
1684
+
1685
+ This depends on the choice of basis.
1686
+
1687
+ EXAMPLES::
1688
+
1689
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1690
+ sage: E.volume_form()
1691
+ x*y*z
1692
+ """
1693
+ d = self._quadratic_form.dim()
1694
+ return self.element_class(self, {tuple(range(d)): self.base_ring().one()})
1695
+
1696
+ def boundary(self, s_coeff):
1697
+ r"""
1698
+ Return the boundary operator `\partial` defined by the structure
1699
+ coefficients ``s_coeff`` of a Lie algebra.
1700
+
1701
+ For more on the boundary operator, see
1702
+ :class:`ExteriorAlgebraBoundary`.
1703
+
1704
+ INPUT:
1705
+
1706
+ - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where
1707
+ `I` is the index set of the underlying vector space `V`, and whose
1708
+ values can be coerced into 1-forms (degree 1 elements) in ``E``
1709
+ (usually, these values will just be elements of `V`)
1710
+
1711
+ EXAMPLES::
1712
+
1713
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1714
+ sage: E.boundary({(0,1): z, (1,2): x, (2,0): y})
1715
+ Boundary endomorphism of The exterior algebra of rank 3 over Rational Field
1716
+ """
1717
+ return ExteriorAlgebraBoundary(self, s_coeff)
1718
+
1719
+ def coboundary(self, s_coeff):
1720
+ r"""
1721
+ Return the coboundary operator `d` defined by the structure
1722
+ coefficients ``s_coeff`` of a Lie algebra.
1723
+
1724
+ For more on the coboundary operator, see
1725
+ :class:`ExteriorAlgebraCoboundary`.
1726
+
1727
+ INPUT:
1728
+
1729
+ - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where
1730
+ `I` is the index set of the underlying vector space `V`, and whose
1731
+ values can be coerced into 1-forms (degree 1 elements) in ``E``
1732
+ (usually, these values will just be elements of `V`)
1733
+
1734
+ EXAMPLES::
1735
+
1736
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1737
+ sage: E.coboundary({(0,1): z, (1,2): x, (2,0): y})
1738
+ Coboundary endomorphism of The exterior algebra of rank 3 over Rational Field
1739
+ """
1740
+ return ExteriorAlgebraCoboundary(self, s_coeff)
1741
+
1742
+ def degree_on_basis(self, m):
1743
+ r"""
1744
+ Return the degree of the monomial indexed by ``m``.
1745
+
1746
+ The degree of ``m`` in the `\ZZ`-grading of ``self`` is defined
1747
+ to be the length of ``m``.
1748
+
1749
+ EXAMPLES::
1750
+
1751
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1752
+ sage: E.degree_on_basis(())
1753
+ 0
1754
+ sage: E.degree_on_basis((0,))
1755
+ 1
1756
+ sage: E.degree_on_basis((0,1))
1757
+ 2
1758
+ """
1759
+ return ZZ(len(m))
1760
+
1761
+ def coproduct_on_basis(self, a):
1762
+ r"""
1763
+ Return the coproduct on the basis element indexed by ``a``.
1764
+
1765
+ The coproduct is defined by
1766
+
1767
+ .. MATH::
1768
+
1769
+ \Delta(e_{i_1} \wedge \cdots \wedge e_{i_m}) = \sum_{k=0}^m
1770
+ \sum_{\sigma \in Ush_{k,m-k}} (-1)^{\sigma}
1771
+ (e_{i_{\sigma(1)}} \wedge \cdots \wedge e_{i_{\sigma(k)}}) \otimes
1772
+ (e_{i_{\sigma(k+1)}} \wedge \cdots \wedge e_{i_{\sigma(m)}}),
1773
+
1774
+ where `Ush_{k,m-k}` denotes the set of all `(k,m-k)`-unshuffles
1775
+ (i.e., permutations in `S_m` which are increasing on the interval
1776
+ `\{1, 2, \ldots, k\}` and on the interval
1777
+ `\{k+1, k+2, \ldots, k+m\}`).
1778
+
1779
+ .. WARNING::
1780
+
1781
+ This coproduct is a homomorphism of superalgebras, not a
1782
+ homomorphism of algebras!
1783
+
1784
+ EXAMPLES::
1785
+
1786
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1787
+ sage: E.coproduct_on_basis((0,))
1788
+ 1 # x + x # 1
1789
+ sage: E.coproduct_on_basis((0,1))
1790
+ 1 # x*y + x # y - y # x + x*y # 1
1791
+ sage: E.coproduct_on_basis((0,1,2))
1792
+ 1 # x*y*z + x # y*z - y # x*z + x*y # z
1793
+ + z # x*y - x*z # y + y*z # x + x*y*z # 1
1794
+ """
1795
+ from sage.combinat.combinat import unshuffle_iterator
1796
+ one = self.base_ring().one()
1797
+ L = unshuffle_iterator(tuple(a), one)
1798
+ return self.tensor_square()._from_dict(
1799
+ {tuple(FrozenBitset(e) if e else FrozenBitset() for e in t): c for t, c in L if c},
1800
+ coerce=False,
1801
+ remove_zeros=False)
1802
+
1803
+ def antipode_on_basis(self, m):
1804
+ r"""
1805
+ Return the antipode on the basis element indexed by ``m``.
1806
+
1807
+ Given a basis element `\omega`, the antipode is defined by
1808
+ `S(\omega) = (-1)^{\deg(\omega)} \omega`.
1809
+
1810
+ EXAMPLES::
1811
+
1812
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1813
+ sage: E.antipode_on_basis(())
1814
+ 1
1815
+ sage: E.antipode_on_basis((1,))
1816
+ -y
1817
+ sage: E.antipode_on_basis((1,2))
1818
+ y*z
1819
+ """
1820
+ return self.term(m, (-self.base_ring().one())**len(m))
1821
+
1822
+ def counit(self, x):
1823
+ r"""
1824
+ Return the counit of ``x``.
1825
+
1826
+ The counit of an element `\omega` of the exterior algebra
1827
+ is its constant coefficient.
1828
+
1829
+ EXAMPLES::
1830
+
1831
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1832
+ sage: elt = x*y - 2*x + 3
1833
+ sage: E.counit(elt)
1834
+ 3
1835
+ """
1836
+ return x.constant_coefficient()
1837
+
1838
+ def interior_product_on_basis(self, a, b):
1839
+ r"""
1840
+ Return the interior product `\iota_b a` of ``a`` with respect to
1841
+ ``b``.
1842
+
1843
+ See :meth:`~sage.algebras.clifford_algebra.CliffordAlgebra.Element.interior_product`
1844
+ for more information.
1845
+
1846
+ In this method, ``a`` and ``b`` are supposed to be
1847
+ basis elements (see
1848
+ :meth:`~sage.algebras.clifford_algebra.CliffordAlgebra.Element.interior_product`
1849
+ for a method that computes interior product of arbitrary
1850
+ elements), and to be input as their keys.
1851
+
1852
+ This depends on the choice of basis of the vector space
1853
+ whose exterior algebra is ``self``.
1854
+
1855
+ EXAMPLES::
1856
+
1857
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1858
+ sage: k = list(E.basis().keys())
1859
+ sage: E.interior_product_on_basis(k[1], k[1])
1860
+ 1
1861
+ sage: E.interior_product_on_basis(k[5], k[1])
1862
+ z
1863
+ sage: E.interior_product_on_basis(k[2], k[5])
1864
+ 0
1865
+ sage: E.interior_product_on_basis(k[5], k[2])
1866
+ 0
1867
+ sage: E.interior_product_on_basis(k[7], k[5])
1868
+ -y
1869
+
1870
+ Check :issue:`34694`::
1871
+
1872
+ sage: # needs sage.symbolic
1873
+ sage: E = ExteriorAlgebra(SR,'e',3)
1874
+ sage: E.inject_variables()
1875
+ Defining e0, e1, e2
1876
+ sage: a = (e0*e1).interior_product(e0)
1877
+ sage: a * e0
1878
+ -e0*e1
1879
+ """
1880
+ sgn = True
1881
+ t = list(a)
1882
+ for i in b:
1883
+ if i not in t:
1884
+ return self.zero()
1885
+ if t.index(i) % 2:
1886
+ sgn = not sgn
1887
+ t.remove(i)
1888
+ R = self.base_ring()
1889
+ if not t: # catch empty sets
1890
+ t = None
1891
+ return self.term(FrozenBitset(t), (R.one() if sgn else - R.one()))
1892
+
1893
+ def lifted_bilinear_form(self, M):
1894
+ r"""
1895
+ Return the bilinear form on the exterior algebra ``self``
1896
+ `= \Lambda(V)` which is obtained by lifting the bilinear
1897
+ form `f` on `V` given by the matrix ``M``.
1898
+
1899
+ Let `V` be a module over a commutative ring `R`, and let
1900
+ `f : V \times V \to R` be a bilinear form on `V`. Then,
1901
+ a bilinear form `\Lambda(f) : \Lambda(V) \times
1902
+ \Lambda(V) \to R` on `\Lambda(V)` can be canonically
1903
+ defined as follows: For every `n \in \NN`, `m \in \NN`,
1904
+ `v_1, v_2, \ldots, v_n, w_1, w_2, \ldots, w_m \in V`,
1905
+ we define
1906
+
1907
+ .. MATH::
1908
+
1909
+ \Lambda(f)
1910
+ ( v_1 \wedge v_2 \wedge \cdots \wedge v_n ,
1911
+ w_1 \wedge w_2 \wedge \cdots \wedge w_m )
1912
+ := \begin{cases}
1913
+ 0, &\mbox{if } n \neq m ; \\
1914
+ \det G, & \mbox{if } n = m \end{cases} ,
1915
+
1916
+ where `G` is the `n \times m`-matrix whose
1917
+ `(i, j)`-th entry is `f(v_i, w_j)`. This bilinear form
1918
+ `\Lambda(f)` is known as the bilinear form on
1919
+ `\Lambda(V)` obtained by lifting the bilinear form `f`.
1920
+ Its restriction to the `1`-st homogeneous component
1921
+ `V` of `\Lambda(V)` is `f`.
1922
+
1923
+ The bilinear form `\Lambda(f)` is symmetric if `f` is.
1924
+
1925
+ INPUT:
1926
+
1927
+ - ``M`` -- a matrix over the same base ring as ``self``,
1928
+ whose `(i, j)`-th entry is `f(e_i, e_j)`, where
1929
+ `(e_1, e_2, \ldots, e_N)` is the standard basis of the
1930
+ module `V` for which ``self`` `= \Lambda(V)` (so that
1931
+ `N = \dim(V)`), and where `f` is the bilinear form
1932
+ which is to be lifted.
1933
+
1934
+ OUTPUT:
1935
+
1936
+ A bivariate function which takes two elements `p` and
1937
+ `q` of ``self`` to `\Lambda(f)(p, q)`.
1938
+
1939
+ .. NOTE::
1940
+
1941
+ This takes a bilinear form on `V` as matrix, and
1942
+ returns a bilinear form on ``self`` as a function in
1943
+ two arguments. We do not return the bilinear form as
1944
+ a matrix since this matrix can be huge and one often
1945
+ needs just a particular value.
1946
+
1947
+ .. TODO::
1948
+
1949
+ Implement a class for bilinear forms and rewrite this
1950
+ method to use that class.
1951
+
1952
+ EXAMPLES::
1953
+
1954
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
1955
+ sage: M = Matrix(QQ, [[1, 2, 3], [2, 3, 4], [3, 4, 5]])
1956
+ sage: Eform = E.lifted_bilinear_form(M)
1957
+ sage: Eform
1958
+ Bilinear Form from The exterior algebra of rank 3 over Rational
1959
+ Field (+) The exterior algebra of rank 3 over Rational Field to
1960
+ Rational Field
1961
+ sage: Eform(x*y, y*z)
1962
+ -1
1963
+ sage: Eform(x*y, y)
1964
+ 0
1965
+ sage: Eform(x*(y+z), y*z)
1966
+ -3
1967
+ sage: Eform(x*(y+z), y*(z+x))
1968
+ 0
1969
+ sage: N = Matrix(QQ, [[3, 1, 7], [2, 0, 4], [-1, -3, -1]])
1970
+ sage: N.determinant()
1971
+ -8
1972
+ sage: Eform = E.lifted_bilinear_form(N)
1973
+ sage: Eform(x, E.one())
1974
+ 0
1975
+ sage: Eform(x, x*z*y)
1976
+ 0
1977
+ sage: Eform(E.one(), E.one())
1978
+ 1
1979
+ sage: Eform(E.zero(), E.one())
1980
+ 0
1981
+ sage: Eform(x, y)
1982
+ 1
1983
+ sage: Eform(z, y)
1984
+ -3
1985
+ sage: Eform(x*z, y*z)
1986
+ 20
1987
+ sage: Eform(x+x*y+x*y*z, z+z*y+z*y*x)
1988
+ 11
1989
+
1990
+ TESTS:
1991
+
1992
+ Exterior algebra over a zero space (a border case)::
1993
+
1994
+ sage: E = ExteriorAlgebra(QQ, 0)
1995
+ sage: M = Matrix(QQ, [])
1996
+ sage: Eform = E.lifted_bilinear_form(M)
1997
+ sage: Eform(E.one(), E.one())
1998
+ 1
1999
+ sage: Eform(E.zero(), E.one())
2000
+ 0
2001
+
2002
+ .. TODO::
2003
+
2004
+ Another way to compute this bilinear form seems to be to
2005
+ map `x` and `y` to the appropriate Clifford algebra and
2006
+ there compute `x^t y`, then send the result back to the
2007
+ exterior algebra and return its constant coefficient. Or
2008
+ something like this. Once the maps to the Clifford and
2009
+ back are implemented, check if this is faster.
2010
+ """
2011
+ R = self.base_ring()
2012
+
2013
+ def lifted_form(x, y):
2014
+ result = R.zero()
2015
+ for mx, cx in x:
2016
+ for my, cy in y:
2017
+ n = len(mx)
2018
+ m = len(my)
2019
+ if m != n:
2020
+ continue
2021
+ matrix_list = [M[i, j] for i in mx for j in my]
2022
+ MA = MatrixArgs(R, n, matrix_list)
2023
+ del matrix_list
2024
+ result += cx * cy * MA.matrix(False).determinant()
2025
+ return result
2026
+ from sage.categories.cartesian_product import cartesian_product
2027
+ return PoorManMap(lifted_form, domain=cartesian_product([self, self]),
2028
+ codomain=self.base_ring(),
2029
+ name="Bilinear Form")
2030
+
2031
+ def _ideal_class_(self, n=0):
2032
+ """
2033
+ Return the class that is used to implement ideals of ``self``.
2034
+
2035
+ EXAMPLES::
2036
+
2037
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2038
+ sage: type(E.ideal(x*y - z))
2039
+ <class 'sage.algebras.clifford_algebra.ExteriorAlgebraIdeal'>
2040
+
2041
+ TESTS::
2042
+
2043
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2044
+ sage: E._ideal_class_()
2045
+ <class 'sage.algebras.clifford_algebra.ExteriorAlgebraIdeal'>
2046
+ """
2047
+ return ExteriorAlgebraIdeal
2048
+
2049
+ Element = ExteriorAlgebraElement
2050
+
2051
+
2052
+ #####################################################################
2053
+ # Differentials
2054
+
2055
+
2056
+ class ExteriorAlgebraDifferential(ModuleMorphismByLinearity,
2057
+ UniqueRepresentation,
2058
+ metaclass=InheritComparisonClasscallMetaclass):
2059
+ r"""
2060
+ Internal class to store the data of a boundary or coboundary of
2061
+ an exterior algebra `\Lambda(L)` defined by the structure
2062
+ coefficients of a Lie algebra `L`.
2063
+
2064
+ See :class:`ExteriorAlgebraBoundary` and
2065
+ :class:`ExteriorAlgebraCoboundary` for the actual classes, which
2066
+ inherit from this.
2067
+
2068
+ .. WARNING::
2069
+
2070
+ This is not a general class for differentials on the exterior
2071
+ algebra.
2072
+ """
2073
+ @staticmethod
2074
+ def __classcall__(cls, E, s_coeff):
2075
+ """
2076
+ Standardize the structure coefficients to ensure a unique
2077
+ representation.
2078
+
2079
+ EXAMPLES::
2080
+
2081
+ sage: from sage.algebras.clifford_algebra import ExteriorAlgebraDifferential
2082
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2083
+ sage: par1 = ExteriorAlgebraDifferential(E, {(0,1): z, (1,2): x, (2,0): y})
2084
+ sage: par2 = ExteriorAlgebraDifferential(E, {(0,1): z, (1,2): x, (0,2): -y})
2085
+ sage: par3 = ExteriorAlgebraDifferential(E, {(1,0): {2:-1}, (1,2): {0:1}, (2,0):{1:1}})
2086
+ sage: par1 is par2
2087
+ True
2088
+ sage: par1 is par3
2089
+ True
2090
+ sage: par2 is par3
2091
+ True
2092
+
2093
+ sage: par4 = ExteriorAlgebraDifferential(E, {})
2094
+ sage: par5 = ExteriorAlgebraDifferential(E, {(1,0): 0, (1,2): {}, (0,2): E.zero()})
2095
+ sage: par6 = ExteriorAlgebraDifferential(E, {(1,0): 0, (1,2): 0, (0,2): 0})
2096
+ sage: par4 is par5 and par5 is par6
2097
+ True
2098
+ """
2099
+ d = {}
2100
+
2101
+ for k, v in dict(s_coeff).items():
2102
+ if not v: # Strip terms with 0
2103
+ continue
2104
+
2105
+ if isinstance(v, dict):
2106
+ R = E.base_ring()
2107
+ v = E._from_dict({FrozenBitset((i,)): R(c) for i, c in v.items()})
2108
+ else:
2109
+ # Make sure v is in ``E``
2110
+ v = E(v)
2111
+ # It's okay if v.degree results in an error
2112
+ # (we'd throw a similar error) unless v == 0 (which
2113
+ # is what v.list() is testing for)
2114
+ if v.list() and v.degree() != 1:
2115
+ raise ValueError("elements must be degree 1")
2116
+
2117
+ if k[0] < k[1]:
2118
+ d[tuple(k)] = v
2119
+ else:
2120
+ d[(k[1], k[0])] = -v
2121
+
2122
+ from sage.sets.family import Family
2123
+ return super().__classcall__(cls, E, Family(d))
2124
+
2125
+ def __init__(self, E, s_coeff):
2126
+ """
2127
+ Initialize ``self``.
2128
+
2129
+ EXAMPLES::
2130
+
2131
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2132
+ sage: par = E.boundary({(0,1): z, (1,2):x, (2,0):y})
2133
+
2134
+ We skip the pickling test as there is an infinite recursion when
2135
+ doing equality checks::
2136
+
2137
+ sage: TestSuite(par).run(skip='_test_pickling')
2138
+
2139
+ Check that it knows it is a finite-dimensional algebra
2140
+ morphism (:issue:`25339`):;
2141
+
2142
+ sage: par.category_for()
2143
+ Category of finite dimensional algebras with basis over Rational Field
2144
+ sage: par.matrix()
2145
+ [ 0 0 0 0 0 0 0 0]
2146
+ [ 0 0 0 0 0 0 1 0]
2147
+ [ 0 0 0 0 0 -1 0 0]
2148
+ [ 0 0 0 0 1 0 0 0]
2149
+ [ 0 0 0 0 0 0 0 0]
2150
+ [ 0 0 0 0 0 0 0 0]
2151
+ [ 0 0 0 0 0 0 0 0]
2152
+ [ 0 0 0 0 0 0 0 0]
2153
+ """
2154
+ self._s_coeff = s_coeff
2155
+
2156
+ # Technically this preserves the grading but with a shift of -1
2157
+ cat = AlgebrasWithBasis(E.base_ring()).FiniteDimensional()
2158
+ ModuleMorphismByLinearity.__init__(self, domain=E, codomain=E, category=cat)
2159
+
2160
+ def homology(self, deg=None, **kwds):
2161
+ """
2162
+ Return the homology determined by ``self``.
2163
+
2164
+ EXAMPLES::
2165
+
2166
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2167
+ sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y})
2168
+ sage: par.homology()
2169
+ {0: Vector space of dimension 1 over Rational Field,
2170
+ 1: Vector space of dimension 0 over Rational Field,
2171
+ 2: Vector space of dimension 0 over Rational Field,
2172
+ 3: Vector space of dimension 1 over Rational Field}
2173
+ sage: d = E.coboundary({(0,1): z, (1,2): x, (2,0): y})
2174
+ sage: d.homology()
2175
+ {0: Vector space of dimension 1 over Rational Field,
2176
+ 1: Vector space of dimension 0 over Rational Field,
2177
+ 2: Vector space of dimension 0 over Rational Field,
2178
+ 3: Vector space of dimension 1 over Rational Field}
2179
+ """
2180
+ return self.chain_complex().homology(deg, **kwds)
2181
+
2182
+
2183
+ class ExteriorAlgebraBoundary(ExteriorAlgebraDifferential):
2184
+ r"""
2185
+ The boundary `\partial` of an exterior algebra `\Lambda(L)` defined
2186
+ by the structure coefficients of `L`.
2187
+
2188
+ Let `L` be a Lie algebra. We give the exterior algebra
2189
+ `E = \Lambda(L)` a chain complex structure by considering a
2190
+ differential `\partial : \Lambda^{k+1}(L) \to \Lambda^k(L)` defined by
2191
+
2192
+ .. MATH::
2193
+
2194
+ \partial(x_1 \wedge x_2 \wedge \cdots \wedge x_{k+1})
2195
+ = \sum_{i < j} (-1)^{i+j+1}
2196
+ [x_i, x_j] \wedge x_1 \wedge \cdots \wedge \hat{x}_i \wedge \cdots
2197
+ \wedge \hat{x}_j \wedge \cdots \wedge x_{k+1}
2198
+
2199
+ where `\hat{x}_i` denotes a missing index. The corresponding homology is
2200
+ the Lie algebra homology.
2201
+
2202
+ INPUT:
2203
+
2204
+ - ``E`` -- an exterior algebra of a vector space `L`
2205
+ - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where
2206
+ `I` is the index set of the basis of the vector space `L`, and whose
2207
+ values can be coerced into 1-forms (degree 1 elements) in ``E``;
2208
+ this dictionary will be used to define the Lie algebra structure
2209
+ on `L` (indeed, the `i`-th coordinate of the Lie bracket of the
2210
+ `j`-th and `k`-th basis vectors of `L` for `j < k` is set to be
2211
+ the value at the key `(j, k)` if this key appears in ``s_coeff``,
2212
+ or otherwise the negated of the value at the key `(k, j)`)
2213
+
2214
+ .. WARNING::
2215
+
2216
+ The values of ``s_coeff`` are supposed to be coercible into
2217
+ 1-forms in ``E``; but they can also be dictionaries themselves
2218
+ (in which case they are interpreted as giving the coordinates of
2219
+ vectors in ``L``). In the interest of speed, these dictionaries
2220
+ are not sanitized or checked.
2221
+
2222
+ .. WARNING::
2223
+
2224
+ For any two distinct elements `i` and `j` of `I`, the dictionary
2225
+ ``s_coeff`` must have only one of the pairs `(i, j)` and
2226
+ `(j, i)` as a key. This is not checked.
2227
+
2228
+ EXAMPLES:
2229
+
2230
+ We consider the differential given by Lie algebra given by the cross
2231
+ product `\times` of `\RR^3`::
2232
+
2233
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2234
+ sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y})
2235
+ sage: par(x)
2236
+ 0
2237
+ sage: par(x*y)
2238
+ z
2239
+ sage: par(x*y*z)
2240
+ 0
2241
+ sage: par(x+y-y*z+x*y)
2242
+ -x + z
2243
+ sage: par(E.zero())
2244
+ 0
2245
+
2246
+ We check that `\partial \circ \partial = 0`::
2247
+
2248
+ sage: p2 = par * par
2249
+ sage: all(p2(b) == 0 for b in E.basis())
2250
+ True
2251
+
2252
+ Another example: the Lie algebra `\mathfrak{sl}_2`, which has a
2253
+ basis `e,f,h` satisfying `[h,e] = 2e`, `[h,f] = -2f`, and `[e,f] = h`::
2254
+
2255
+ sage: E.<e,f,h> = ExteriorAlgebra(QQ)
2256
+ sage: par = E.boundary({(0,1): h, (2,1): -2*f, (2,0): 2*e})
2257
+ sage: par(E.zero())
2258
+ 0
2259
+ sage: par(e)
2260
+ 0
2261
+ sage: par(e*f)
2262
+ h
2263
+ sage: par(f*h)
2264
+ 2*f
2265
+ sage: par(h*f)
2266
+ -2*f
2267
+ sage: C = par.chain_complex(); C
2268
+ Chain complex with at most 4 nonzero terms over Rational Field
2269
+ sage: ascii_art(C)
2270
+ [ 0 -2 0] [0]
2271
+ [ 0 0 2] [0]
2272
+ [0 0 0] [ 1 0 0] [0]
2273
+ 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0
2274
+ sage: C.homology()
2275
+ {0: Vector space of dimension 1 over Rational Field,
2276
+ 1: Vector space of dimension 0 over Rational Field,
2277
+ 2: Vector space of dimension 0 over Rational Field,
2278
+ 3: Vector space of dimension 1 over Rational Field}
2279
+
2280
+ Over the integers::
2281
+
2282
+ sage: C = par.chain_complex(R=ZZ); C
2283
+ Chain complex with at most 4 nonzero terms over Integer Ring
2284
+ sage: ascii_art(C)
2285
+ [ 0 -2 0] [0]
2286
+ [ 0 0 2] [0]
2287
+ [0 0 0] [ 1 0 0] [0]
2288
+ 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0
2289
+ sage: C.homology() # needs sage.libs.pari
2290
+ {0: Z, 1: C2 x C2, 2: 0, 3: Z}
2291
+
2292
+ REFERENCES:
2293
+
2294
+ - :wikipedia:`Exterior_algebra#Lie_algebra_homology`
2295
+ """
2296
+ def _repr_type(self):
2297
+ """
2298
+ TESTS::
2299
+
2300
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2301
+ sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y})
2302
+ sage: par._repr_type()
2303
+ 'Boundary'
2304
+ """
2305
+ return "Boundary"
2306
+
2307
+ def _on_basis(self, m):
2308
+ """
2309
+ Return the differential on the basis element indexed by ``m``.
2310
+
2311
+ EXAMPLES::
2312
+
2313
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2314
+ sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y})
2315
+ sage: par._on_basis(FrozenBitset())
2316
+ 0
2317
+ sage: par._on_basis((0,))
2318
+ 0
2319
+ sage: par._on_basis((0,1))
2320
+ z
2321
+ sage: par._on_basis((0,2))
2322
+ -y
2323
+ sage: par._on_basis((0,1,2))
2324
+ 0
2325
+ """
2326
+ from itertools import combinations
2327
+ E = self.domain()
2328
+ sc = self._s_coeff
2329
+ keys = sc.keys()
2330
+
2331
+ s = E.zero()
2332
+
2333
+ for b, (i, j) in enumerate(combinations(m, 2)):
2334
+ if (i, j) not in keys:
2335
+ continue
2336
+ t = Bitset(m)
2337
+ t.discard(i)
2338
+ t.discard(j)
2339
+ s += sc[i, j] * E.term(FrozenBitset(t), (-1)**b)
2340
+
2341
+ return s
2342
+
2343
+ @cached_method
2344
+ def chain_complex(self, R=None):
2345
+ """
2346
+ Return the chain complex over ``R`` determined by ``self``.
2347
+
2348
+ INPUT:
2349
+
2350
+ - ``R`` -- the base ring; the default is the base ring of
2351
+ the exterior algebra
2352
+
2353
+ EXAMPLES::
2354
+
2355
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2356
+ sage: par = E.boundary({(0,1): z, (1,2): x, (2,0): y})
2357
+ sage: C = par.chain_complex(); C
2358
+ Chain complex with at most 4 nonzero terms over Rational Field
2359
+ sage: ascii_art(C)
2360
+ [ 0 0 1] [0]
2361
+ [ 0 -1 0] [0]
2362
+ [0 0 0] [ 1 0 0] [0]
2363
+ 0 <-- C_0 <-------- C_1 <----------- C_2 <---- C_3 <-- 0
2364
+
2365
+ TESTS:
2366
+
2367
+ This still works in degree `1`::
2368
+
2369
+ sage: E.<x> = ExteriorAlgebra(QQ)
2370
+ sage: par = E.boundary({})
2371
+ sage: C = par.chain_complex(); C
2372
+ Chain complex with at most 2 nonzero terms over Rational Field
2373
+ sage: ascii_art(C)
2374
+ [0]
2375
+ 0 <-- C_0 <---- C_1 <-- 0
2376
+
2377
+ Also in degree `0`::
2378
+
2379
+ sage: E = ExteriorAlgebra(QQ, 0)
2380
+ sage: par = E.boundary({})
2381
+ sage: C = par.chain_complex(); C
2382
+ Chain complex with at most 1 nonzero terms over Rational Field
2383
+ sage: ascii_art(C)
2384
+ 0 <-- C_0 <-- 0
2385
+ """
2386
+ from sage.homology.chain_complex import ChainComplex
2387
+ from sage.matrix.constructor import Matrix
2388
+ E = self.domain()
2389
+ n = E.ngens()
2390
+ if R is None:
2391
+ R = E.base_ring()
2392
+
2393
+ if n == 0:
2394
+ # Special case because there are no matrices and thus the
2395
+ # ChainComplex constructor needs the dimension of the
2396
+ # 0th degree space explicitly given.
2397
+ return ChainComplex({1: Matrix(R, [[]])}, degree=-1)
2398
+ # If you are reading this because you changed something about
2399
+ # the ChainComplex constructor and the doctests are failing:
2400
+ # This should return a chain complex with degree -1 and
2401
+ # only one nontrivial module, namely a free module of rank 1,
2402
+ # situated in degree 0.
2403
+
2404
+ # Group the basis into degrees
2405
+ basis_by_deg = {deg: [] for deg in range(n+1)}
2406
+ for b in E.basis().keys():
2407
+ basis_by_deg[len(b)].append(b)
2408
+
2409
+ # Construct the transition matrices
2410
+ data = {}
2411
+ prev_basis = basis_by_deg[0]
2412
+ for deg in range(1, n+1):
2413
+ # Make sure within each basis we're sorted by lex
2414
+ basis = sorted(basis_by_deg[deg])
2415
+ mat = []
2416
+ for b in basis:
2417
+ ret = self._on_basis(b)
2418
+ mat.append([ret.coefficient(p) for p in prev_basis])
2419
+ data[deg] = Matrix(mat).transpose().change_ring(R)
2420
+ prev_basis = basis
2421
+
2422
+ return ChainComplex(data, degree=-1)
2423
+
2424
+
2425
+ class ExteriorAlgebraCoboundary(ExteriorAlgebraDifferential):
2426
+ r"""
2427
+ The coboundary `d` of an exterior algebra `\Lambda(L)` defined
2428
+ by the structure coefficients of a Lie algebra `L`.
2429
+
2430
+ Let `L` be a Lie algebra. We endow its exterior algebra
2431
+ `E = \Lambda(L)` with a cochain complex structure by considering a
2432
+ differential `d : \Lambda^k(L) \to \Lambda^{k+1}(L)` defined by
2433
+
2434
+ .. MATH::
2435
+
2436
+ d x_i = \sum_{j < k} s_{jk}^i x_j x_k,
2437
+
2438
+ where `(x_1, x_2, \ldots, x_n)` is a basis of `L`, and where
2439
+ `s_{jk}^i` is the `x_i`-coordinate of the Lie bracket `[x_j, x_k]`.
2440
+
2441
+ The corresponding cohomology is the Lie algebra cohomology of `L`.
2442
+
2443
+ This can also be thought of as the exterior derivative, in which case
2444
+ the resulting cohomology is the de Rham cohomology of a manifold whose
2445
+ exterior algebra of differential forms is ``E``.
2446
+
2447
+ INPUT:
2448
+
2449
+ - ``E`` -- an exterior algebra of a vector space `L`
2450
+ - ``s_coeff`` -- dictionary whose keys are in `I \times I`, where
2451
+ `I` is the index set of the basis of the vector space `L`, and whose
2452
+ values can be coerced into 1-forms (degree 1 elements) in ``E``;
2453
+ this dictionary will be used to define the Lie algebra structure
2454
+ on `L` (indeed, the `i`-th coordinate of the Lie bracket of the
2455
+ `j`-th and `k`-th basis vectors of `L` for `j < k` is set to be
2456
+ the value at the key `(j, k)` if this key appears in ``s_coeff``,
2457
+ or otherwise the negated of the value at the key `(k, j)`)
2458
+
2459
+ .. WARNING::
2460
+
2461
+ For any two distinct elements `i` and `j` of `I`, the dictionary
2462
+ ``s_coeff`` must have only one of the pairs `(i, j)` and
2463
+ `(j, i)` as a key. This is not checked.
2464
+
2465
+ EXAMPLES:
2466
+
2467
+ We consider the differential coming from the Lie algebra given by the
2468
+ cross product `\times` of `\RR^3`::
2469
+
2470
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2471
+ sage: d = E.coboundary({(0,1): z, (1,2): x, (0, 2): -y})
2472
+ sage: d(x)
2473
+ y*z
2474
+ sage: d(y)
2475
+ -x*z
2476
+ sage: d(x+y-y*z)
2477
+ -x*z + y*z
2478
+ sage: d(x*y)
2479
+ 0
2480
+ sage: d(E.one())
2481
+ 0
2482
+ sage: d(E.zero())
2483
+ 0
2484
+
2485
+ We check that `d \circ d = 0`::
2486
+
2487
+ sage: d2 = d * d
2488
+ sage: all(d2(b) == 0 for b in E.basis())
2489
+ True
2490
+
2491
+ Another example: the Lie algebra `\mathfrak{sl}_2`, which has a
2492
+ basis `e,f,h` satisfying `[h,e] = 2e`, `[h,f] = -2f`, and `[e,f] = h`::
2493
+
2494
+ sage: E.<e,f,h> = ExteriorAlgebra(QQ)
2495
+ sage: d = E.coboundary({(0,1): h, (2,1): -2*f, (2,0): 2*e})
2496
+ sage: d(E.zero())
2497
+ 0
2498
+ sage: d(e)
2499
+ -2*e*h
2500
+ sage: d(f)
2501
+ 2*f*h
2502
+ sage: d(h)
2503
+ e*f
2504
+ sage: d(e*f)
2505
+ 0
2506
+ sage: d(f*h)
2507
+ 0
2508
+ sage: d(e*h)
2509
+ 0
2510
+ sage: C = d.chain_complex(); C
2511
+ Chain complex with at most 4 nonzero terms over Rational Field
2512
+ sage: ascii_art(C)
2513
+ [ 0 0 1] [0]
2514
+ [-2 0 0] [0]
2515
+ [0 0 0] [ 0 2 0] [0]
2516
+ 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0
2517
+ sage: C.homology()
2518
+ {0: Vector space of dimension 1 over Rational Field,
2519
+ 1: Vector space of dimension 0 over Rational Field,
2520
+ 2: Vector space of dimension 0 over Rational Field,
2521
+ 3: Vector space of dimension 1 over Rational Field}
2522
+
2523
+ Over the integers::
2524
+
2525
+ sage: C = d.chain_complex(R=ZZ); C
2526
+ Chain complex with at most 4 nonzero terms over Integer Ring
2527
+ sage: ascii_art(C)
2528
+ [ 0 0 1] [0]
2529
+ [-2 0 0] [0]
2530
+ [0 0 0] [ 0 2 0] [0]
2531
+ 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0
2532
+ sage: C.homology() # needs sage.libs.pari
2533
+ {0: Z, 1: 0, 2: C2 x C2, 3: Z}
2534
+
2535
+ REFERENCES:
2536
+
2537
+ - :wikipedia:`Exterior_algebra#Differential_geometry`
2538
+ """
2539
+ def __init__(self, E, s_coeff):
2540
+ """
2541
+ Initialize ``self``.
2542
+
2543
+ EXAMPLES::
2544
+
2545
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2546
+ sage: d = E.coboundary({(0,1): z, (1,2):x, (2,0):y})
2547
+ sage: TestSuite(d).run() # known bug - morphisms are properly in a category
2548
+ """
2549
+ # Construct the dictionary of costructure coefficients, i.e. given
2550
+ # [x_j, x_k] = \sum_i s_{jk}^i x_i, we get x^i |-> \sum_{j<k} s_{jk}^i x^j x^k.
2551
+ # This dictionary might contain 0 values and might also be missing
2552
+ # some keys (both times meaning that the respective `s_{jk}^i` are
2553
+ # zero for all `j` and `k`).
2554
+ self._cos_coeff = {}
2555
+ zero = E.zero()
2556
+ B = E.basis()
2557
+ for k, v in dict(s_coeff).items():
2558
+ if k[0] > k[1]: # k will have length 2
2559
+ k = sorted(k)
2560
+ v = -v
2561
+
2562
+ k = B[FrozenBitset(k)]
2563
+ for m, c in v:
2564
+ self._cos_coeff[m] = self._cos_coeff.get(m, zero) + c * k
2565
+ ExteriorAlgebraDifferential.__init__(self, E, s_coeff)
2566
+
2567
+ def _repr_type(self):
2568
+ """
2569
+ TESTS::
2570
+
2571
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2572
+ sage: d = E.coboundary({(0,1): z, (1,2): x, (2,0): y})
2573
+ sage: d._repr_type()
2574
+ 'Coboundary'
2575
+ """
2576
+ return "Coboundary"
2577
+
2578
+ def _on_basis(self, m):
2579
+ r"""
2580
+ Return the differential on the basis element indexed by ``m``.
2581
+
2582
+ EXAMPLES:
2583
+
2584
+ The vector space `\RR^3` made into a Lie algebra using the
2585
+ cross product::
2586
+
2587
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2588
+ sage: d = E.coboundary({(0,1): z, (1,2): x, (0,2): -y})
2589
+ sage: d._on_basis(())
2590
+ 0
2591
+ sage: d._on_basis((0,))
2592
+ y*z
2593
+ sage: d._on_basis((1,))
2594
+ -x*z
2595
+ sage: d._on_basis((2,))
2596
+ x*y
2597
+ sage: d._on_basis((0,1))
2598
+ 0
2599
+ sage: d._on_basis((0,2))
2600
+ 0
2601
+ sage: d._on_basis((0,1,2))
2602
+ 0
2603
+ """
2604
+ E = self.domain()
2605
+ cc = self._cos_coeff
2606
+
2607
+ tot = E.zero()
2608
+
2609
+ for sgn, i in enumerate(m):
2610
+ k = FrozenBitset((i,))
2611
+ if k in cc:
2612
+ below = tuple([j for j in m if j < i])
2613
+ above = tuple([j for j in m if j > i])
2614
+
2615
+ # a hack to deal with empty bitsets
2616
+ if not below:
2617
+ below = E.one()
2618
+ else:
2619
+ below = E.monomial(FrozenBitset(below))
2620
+ if not above:
2621
+ above = E.one()
2622
+ else:
2623
+ above = E.monomial(FrozenBitset(above))
2624
+
2625
+ tot += (-1)**sgn * below * cc[k] * above
2626
+
2627
+ return tot
2628
+
2629
+ @cached_method
2630
+ def chain_complex(self, R=None):
2631
+ """
2632
+ Return the chain complex over ``R`` determined by ``self``.
2633
+
2634
+ INPUT:
2635
+
2636
+ - ``R`` -- the base ring; the default is the base ring of
2637
+ the exterior algebra
2638
+
2639
+ EXAMPLES::
2640
+
2641
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2642
+ sage: d = E.coboundary({(0,1): z, (1,2): x, (2,0): y})
2643
+ sage: C = d.chain_complex(); C
2644
+ Chain complex with at most 4 nonzero terms over Rational Field
2645
+ sage: ascii_art(C)
2646
+ [ 0 0 1] [0]
2647
+ [ 0 -1 0] [0]
2648
+ [0 0 0] [ 1 0 0] [0]
2649
+ 0 <-- C_3 <-------- C_2 <----------- C_1 <---- C_0 <-- 0
2650
+
2651
+ TESTS:
2652
+
2653
+ This still works in degree `1`::
2654
+
2655
+ sage: E.<x> = ExteriorAlgebra(QQ)
2656
+ sage: d = E.coboundary({})
2657
+ sage: C = d.chain_complex(); C
2658
+ Chain complex with at most 2 nonzero terms over Rational Field
2659
+ sage: ascii_art(C)
2660
+ [0]
2661
+ 0 <-- C_1 <---- C_0 <-- 0
2662
+
2663
+ Also in degree `0`::
2664
+
2665
+ sage: E = ExteriorAlgebra(QQ, 0)
2666
+ sage: d = E.coboundary({})
2667
+ sage: C = d.chain_complex(); C
2668
+ Chain complex with at most 1 nonzero terms over Rational Field
2669
+ sage: ascii_art(C)
2670
+ 0 <-- C_0 <-- 0
2671
+ """
2672
+ from sage.homology.chain_complex import ChainComplex
2673
+ from sage.matrix.constructor import Matrix
2674
+ E = self.domain()
2675
+ n = E.ngens()
2676
+ if R is None:
2677
+ R = E.base_ring()
2678
+
2679
+ if n == 0:
2680
+ # Special case because there are no matrices and thus the
2681
+ # ChainComplex constructor needs the dimension of the
2682
+ # 0th degree space explicitly given.
2683
+ return ChainComplex({-1: Matrix(R, [[]])}, degree=1)
2684
+ # If you are reading this because you changed something about
2685
+ # the ChainComplex constructor and the doctests are failing:
2686
+ # This should return a chain complex with degree 1 and
2687
+ # only one nontrivial module, namely a free module of rank 1,
2688
+ # situated in degree 0.
2689
+
2690
+ # Group the basis into degrees
2691
+ basis_by_deg = {deg: [] for deg in range(n+1)}
2692
+ for b in E.basis().keys():
2693
+ basis_by_deg[len(b)].append(b)
2694
+
2695
+ # Construct the transition matrices
2696
+ data = {}
2697
+ basis = basis_by_deg[0]
2698
+ for deg in range(n):
2699
+ # Make sure within each basis we're sorted by lex
2700
+ next_basis = sorted(basis_by_deg[deg+1])
2701
+ mat = []
2702
+ for b in basis:
2703
+ ret = self._on_basis(b)
2704
+ try:
2705
+ mat.append([ret.coefficient(p) for p in next_basis])
2706
+ except AttributeError: # if ret is in E.base_ring()
2707
+ mat.append([E.base_ring()(ret)]*len(next_basis))
2708
+ data[deg] = Matrix(mat).transpose().change_ring(R)
2709
+ basis = next_basis
2710
+
2711
+ return ChainComplex(data, degree=1)
2712
+
2713
+
2714
+ @richcmp_method
2715
+ class ExteriorAlgebraIdeal(Ideal_nc):
2716
+ """
2717
+ An ideal of the exterior algebra.
2718
+
2719
+ EXAMPLES::
2720
+
2721
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2722
+ sage: I = E.ideal(x*y); I
2723
+ Twosided Ideal (x*y) of The exterior algebra of rank 3 over Rational Field
2724
+
2725
+ We can also use it to build a quotient::
2726
+
2727
+ sage: Q = E.quotient(I); Q
2728
+ Quotient of The exterior algebra of rank 3 over Rational Field by the ideal (x*y)
2729
+ sage: Q.inject_variables()
2730
+ Defining xbar, ybar, zbar
2731
+ sage: xbar * ybar
2732
+ 0
2733
+ """
2734
+ def __init__(self, ring, gens, coerce=True, side='twosided'):
2735
+ """
2736
+ Initialize ``self``.
2737
+
2738
+ EXAMPLES:
2739
+
2740
+ We skip the category test because the ideals are not a proper
2741
+ element class of the monoid of all ideals::
2742
+
2743
+ sage: E.<y, x> = ExteriorAlgebra(QQ)
2744
+ sage: I = E.ideal([x*y - x, x*y - 1])
2745
+ sage: TestSuite(I).run(skip='_test_category')
2746
+
2747
+ sage: I = E.ideal([x*y - 3, 0, 2*3])
2748
+ sage: TestSuite(I).run(skip='_test_category')
2749
+
2750
+ sage: I = E.ideal([])
2751
+ sage: TestSuite(I).run(skip='_test_category')
2752
+ """
2753
+ self._groebner_strategy = None
2754
+ self._reduced = False
2755
+ self._homogeneous = all(x.is_super_homogeneous() for x in gens if x)
2756
+ if self._homogeneous:
2757
+ side = "twosided"
2758
+ Ideal_nc.__init__(self, ring, gens, coerce, side)
2759
+
2760
+ def reduce(self, f):
2761
+ """
2762
+ Reduce ``f`` modulo ``self``.
2763
+
2764
+ EXAMPLES::
2765
+
2766
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2767
+ sage: I = E.ideal(x*y);
2768
+ sage: I.reduce(x*y + x*y*z + z)
2769
+ z
2770
+ sage: I.reduce(x*y + x + y)
2771
+ x + y
2772
+ sage: I.reduce(x*y + x*y*z)
2773
+ 0
2774
+
2775
+ sage: E.<a,b,c,d> = ExteriorAlgebra(QQ)
2776
+ sage: I = E.ideal([a+b*c])
2777
+ sage: I.reduce(I.gen(0) * d)
2778
+ 0
2779
+ """
2780
+ if self._groebner_strategy is None:
2781
+ self.groebner_basis()
2782
+ R = self.ring()
2783
+ return self._groebner_strategy.reduce(R(f))
2784
+
2785
+ def _contains_(self, f):
2786
+ r"""
2787
+ Return ``True`` if ``f`` is in this ideal,
2788
+ ``False`` otherwise.
2789
+
2790
+ EXAMPLES::
2791
+
2792
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2793
+ sage: I = E.ideal([x, x*y*z + 2*x*z + 3*y*z], side='left')
2794
+ sage: I.groebner_basis()
2795
+ (x, y*z)
2796
+ sage: x in I
2797
+ True
2798
+ sage: y*z in I
2799
+ True
2800
+ sage: x + 3*y*z in I
2801
+ True
2802
+ sage: x + 3*y in I
2803
+ False
2804
+ sage: x*y in I
2805
+ True
2806
+ sage: x + x*y + y*z + x*z in I
2807
+ True
2808
+
2809
+ .. NOTE::
2810
+
2811
+ Requires computation of a Groebner basis, which can be a very
2812
+ expensive operation.
2813
+ """
2814
+ return not self.reduce(f)
2815
+
2816
+ def __richcmp__(self, other, op):
2817
+ """
2818
+ Compare ``self`` and ``other``.
2819
+
2820
+ EXAMPLES::
2821
+
2822
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
2823
+ sage: I = E.ideal([x, x*y*z + 2*x*z + 3*y*z])
2824
+ sage: I == I
2825
+ True
2826
+ sage: Ip = E.ideal([x, y*z])
2827
+ sage: Ip == I
2828
+ True
2829
+ sage: Ip <= I
2830
+ True
2831
+ sage: Ip < I
2832
+ False
2833
+ sage: Ip >= I
2834
+ True
2835
+ sage: Ip > I
2836
+ False
2837
+ sage: E.ideal([x]) < I
2838
+ True
2839
+ sage: E.ideal([x]) <= I
2840
+ True
2841
+ sage: I <= E.ideal([x])
2842
+ False
2843
+
2844
+ sage: E.<a,b,c,d> = ExteriorAlgebra(QQ)
2845
+ sage: p = a + b*c
2846
+ sage: IT = E.ideal([p], side='twosided')
2847
+ sage: IR = E.ideal([p], side='right')
2848
+ sage: IL = E.ideal([p], side='left')
2849
+ sage: IR == IL
2850
+ False
2851
+ sage: IR <= IL
2852
+ False
2853
+ sage: IR >= IL
2854
+ False
2855
+ sage: IL.reduce(p * d)
2856
+ 2*a*d
2857
+ sage: IR.reduce(d * p)
2858
+ -2*a*d
2859
+
2860
+ sage: IR <= IT
2861
+ True
2862
+ sage: IL <= IT
2863
+ True
2864
+ sage: IT <= IL
2865
+ False
2866
+ sage: IT <= IR
2867
+ False
2868
+ """
2869
+ if not isinstance(other, ExteriorAlgebraIdeal):
2870
+ if op == op_EQ:
2871
+ return False
2872
+ if op == op_NE:
2873
+ return True
2874
+ return NotImplemented
2875
+
2876
+ if self is other:
2877
+ return rich_to_bool(op, 0)
2878
+
2879
+ # comparison for >= and > : swap the arguments
2880
+ if op == op_GE:
2881
+ return other.__richcmp__(self, op_LE)
2882
+ elif op == op_GT:
2883
+ return other.__richcmp__(self, op_LT)
2884
+
2885
+ s_gens = {g for g in self.gens() if g}
2886
+ o_gens = {g for g in other.gens() if g}
2887
+
2888
+ if self.side() != other.side():
2889
+ if other.side() == "right":
2890
+ X = {t * f for t in self.ring().basis() for f in s_gens}
2891
+ s_gens.update(X)
2892
+ elif other.side() == "left":
2893
+ X = {f * t for t in self.ring().basis() for f in s_gens}
2894
+ s_gens.update(X)
2895
+
2896
+ if set(s_gens) == set(o_gens):
2897
+ return rich_to_bool(op, 0)
2898
+
2899
+ contained = all(f in other for f in s_gens)
2900
+ if op == op_LE:
2901
+ return contained
2902
+ if op == op_NE and not contained:
2903
+ return True
2904
+
2905
+ if self.side() != other.side():
2906
+ if self.side() == "right":
2907
+ X = {t * f for t in self.ring().basis() for f in o_gens}
2908
+ s_gens.update(X)
2909
+ elif self.side() == "left":
2910
+ X = {f * t for t in self.ring().basis() for f in o_gens}
2911
+ s_gens.update(X)
2912
+
2913
+ contains = all(f in self for f in o_gens)
2914
+ if op == op_EQ:
2915
+ return contained and contains
2916
+ if op == op_NE:
2917
+ return not (contained and contains)
2918
+ # remaining case <
2919
+ return contained and not contains
2920
+
2921
+ def __mul__(self, other):
2922
+ """
2923
+ Return the product of ``self`` with ``other``.
2924
+
2925
+ .. WARNING::
2926
+
2927
+ If ``self`` is a right ideal and ``other`` is a left ideal,
2928
+ this returns a submodule rather than an ideal.
2929
+
2930
+ EXAMPLES::
2931
+
2932
+ sage: E.<a,b,c,d> = ExteriorAlgebra(QQ)
2933
+
2934
+ sage: I = E.ideal([a + 1], side='left')
2935
+ sage: J = I * I; J
2936
+ Left Ideal (2*a + 1, a, b, c, d, a*b, a*c, a*d, 2*a*b*c + b*c, 2*a*b*d + b*d,
2937
+ 2*a*c*d + c*d, a*b*c, a*b*d, a*c*d, b*c*d, a*b*c*d)
2938
+ of The exterior algebra of rank 4 over Rational Field
2939
+ sage: J.groebner_basis()
2940
+ (1,)
2941
+ sage: I.gen(0)^2
2942
+ 2*a + 1
2943
+
2944
+ sage: J = E.ideal([b+c])
2945
+ sage: I * J
2946
+ Twosided Ideal (a*b + a*c + b + c) of The exterior algebra of rank 4 over Rational Field
2947
+ sage: J * I
2948
+ Left Ideal (-a*b - a*c + b + c) of The exterior algebra of rank 4 over Rational Field
2949
+
2950
+ sage: K = J * I
2951
+ sage: K
2952
+ Left Ideal (-a*b - a*c + b + c) of The exterior algebra of rank 4 over Rational Field
2953
+ sage: E.ideal([J.gen(0) * d * I.gen(0)], side='left') <= K
2954
+ True
2955
+
2956
+ sage: J = E.ideal([b + c*d], side='right')
2957
+ sage: I * J
2958
+ Twosided Ideal (a*c*d + a*b + c*d + b) of The exterior algebra of rank 4 over Rational Field
2959
+ sage: X = J * I; X
2960
+ Free module generated by {0, 1, 2, 3, 4, 5, 6, 7} over Rational Field
2961
+ sage: [X.lift(b) for b in X.basis()]
2962
+ [c*d + b, -a*c*d + a*b, b*c, b*d, a*b*c, a*b*d, b*c*d, a*b*c*d]
2963
+ sage: p = X.lift(X.basis()[0])
2964
+ sage: p
2965
+ c*d + b
2966
+ sage: a * p # not a left ideal
2967
+ a*c*d + a*b
2968
+
2969
+ sage: I = E.ideal([a + 1], side='right')
2970
+ sage: E.ideal([1]) * I
2971
+ Twosided Ideal (a + 1) of The exterior algebra of rank 4 over Rational Field
2972
+ sage: I * E.ideal([1])
2973
+ Right Ideal (a + 1) of The exterior algebra of rank 4 over Rational Field
2974
+ """
2975
+ if not isinstance(other, ExteriorAlgebraIdeal) or self.ring() != other.ring():
2976
+ return super().__mul__(other)
2977
+
2978
+ if self._homogeneous or other._homogeneous or (self.side() == "left" and other.side() == "right"):
2979
+ gens = (x * y for x in self.gens() for y in other.gens())
2980
+ else:
2981
+ gens = (x * t * y for t in self.ring().basis() for x in self.gens() for y in other.gens())
2982
+ gens = [z for z in gens if z]
2983
+
2984
+ if self.side() == "right" and other.side() == "left":
2985
+ return self.ring().submodule(gens)
2986
+
2987
+ if self.side() == "left" or self.side() == "twosided":
2988
+ if other.side() == "right" or other.side() == "twosided":
2989
+ return self.ring().ideal(gens, side='twosided')
2990
+ return self.ring().ideal(gens, side='left')
2991
+ return self.ring().ideal(gens, side='right')
2992
+
2993
+ def groebner_basis(self, term_order=None, reduced=True):
2994
+ r"""
2995
+ Return the (reduced) Gröbner basis of ``self``.
2996
+
2997
+ INPUT:
2998
+
2999
+ - ``term_order`` -- the term order used to compute the Gröbner basis;
3000
+ must be one of the following:
3001
+
3002
+ * ``'neglex'`` -- (default) negative (read right-to-left) lex order
3003
+ * ``'degrevlex'`` -- degree reverse lex order
3004
+ * ``'deglex'`` -- degree lex order
3005
+
3006
+ - ``reduced`` -- boolean (default: ``True``); whether or not to return
3007
+ the reduced Gröbner basis
3008
+
3009
+ EXAMPLES:
3010
+
3011
+ We compute an example::
3012
+
3013
+ sage: E.<a,b,c,d,e> = ExteriorAlgebra(QQ)
3014
+ sage: rels = [c*d*e - b*d*e + b*c*e - b*c*d,
3015
+ ....: c*d*e - a*d*e + a*c*e - a*c*d,
3016
+ ....: b*d*e - a*d*e + a*b*e - a*b*d,
3017
+ ....: b*c*e - a*c*e + a*b*e - a*b*c,
3018
+ ....: b*c*d - a*c*d + a*b*d - a*b*c]
3019
+ sage: I = E.ideal(rels)
3020
+ sage: I.groebner_basis()
3021
+ (-a*b*c + a*b*d - a*c*d + b*c*d,
3022
+ -a*b*c + a*b*e - a*c*e + b*c*e,
3023
+ -a*b*d + a*b*e - a*d*e + b*d*e,
3024
+ -a*c*d + a*c*e - a*d*e + c*d*e)
3025
+
3026
+ With different term orders::
3027
+
3028
+ sage: I.groebner_basis("degrevlex")
3029
+ (b*c*d - b*c*e + b*d*e - c*d*e,
3030
+ a*c*d - a*c*e + a*d*e - c*d*e,
3031
+ a*b*d - a*b*e + a*d*e - b*d*e,
3032
+ a*b*c - a*b*e + a*c*e - b*c*e)
3033
+
3034
+ sage: I.groebner_basis("deglex")
3035
+ (-a*b*c + a*b*d - a*c*d + b*c*d,
3036
+ -a*b*c + a*b*e - a*c*e + b*c*e,
3037
+ -a*b*d + a*b*e - a*d*e + b*d*e,
3038
+ -a*c*d + a*c*e - a*d*e + c*d*e)
3039
+
3040
+ The example above was computed first using M2, which agrees with
3041
+ the ``'degrevlex'`` ordering::
3042
+
3043
+ E = QQ[a..e, SkewCommutative => true]
3044
+ I = ideal( c*d*e - b*d*e + b*c*e - b*c*d,
3045
+ c*d*e - a*d*e + a*c*e - a*c*d,
3046
+ b*d*e - a*d*e + a*b*e - a*b*d,
3047
+ b*c*e - a*c*e + a*b*e - a*b*c,
3048
+ b*c*d - a*c*d + a*b*d - a*b*c)
3049
+ groebnerBasis(I)
3050
+
3051
+ returns:
3052
+ o3 = | bcd-bce+bde-cde acd-ace+ade-cde abd-abe+ade-bde abc-abe+ace-bce |
3053
+
3054
+ By default, the Gröbner basis is reduced, but we can get non-reduced
3055
+ Gröber bases (which are not unique)::
3056
+
3057
+ sage: E.<x,y,z> = ExteriorAlgebra(QQ)
3058
+ sage: I = E.ideal([x+y*z])
3059
+ sage: I.groebner_basis(reduced=False)
3060
+ (x*y, x*z, y*z + x, x*y*z)
3061
+ sage: I.groebner_basis(reduced=True)
3062
+ (x*y, x*z, y*z + x)
3063
+
3064
+ However, if we have already computed a reduced Gröbner basis (with
3065
+ a given term order), then we return that::
3066
+
3067
+ sage: I = E.ideal([x+y*z]) # A fresh ideal
3068
+ sage: I.groebner_basis()
3069
+ (x*y, x*z, y*z + x)
3070
+ sage: I.groebner_basis(reduced=False)
3071
+ (x*y, x*z, y*z + x)
3072
+
3073
+ TESTS::
3074
+
3075
+ sage: E.<a,b,c,d,e> = ExteriorAlgebra(ZZ)
3076
+ sage: I = E.ideal([a+1, b*c+d])
3077
+ sage: I.groebner_basis()
3078
+ Traceback (most recent call last):
3079
+ ...
3080
+ NotImplementedError: only implemented over fields
3081
+ """
3082
+ if self.ring().base_ring() not in Fields():
3083
+ raise NotImplementedError("only implemented over fields")
3084
+ if term_order is None:
3085
+ if self._groebner_strategy is not None:
3086
+ strategy = type(self._groebner_strategy)
3087
+ else:
3088
+ from sage.algebras.exterior_algebra_groebner import GroebnerStrategyNegLex as strategy
3089
+ else:
3090
+ if term_order == "neglex":
3091
+ from sage.algebras.exterior_algebra_groebner import GroebnerStrategyNegLex as strategy
3092
+ elif term_order == "degrevlex":
3093
+ from sage.algebras.exterior_algebra_groebner import GroebnerStrategyDegRevLex as strategy
3094
+ elif term_order == "deglex":
3095
+ from sage.algebras.exterior_algebra_groebner import GroebnerStrategyDegLex as strategy
3096
+ else:
3097
+ raise ValueError("invalid term order")
3098
+ if isinstance(self._groebner_strategy, strategy):
3099
+ if self._reduced or not reduced:
3100
+ return self._groebner_strategy.groebner_basis
3101
+ self._reduced = reduced
3102
+ self._groebner_strategy.reduce_computed_gb()
3103
+ return self._groebner_strategy.groebner_basis
3104
+ self._groebner_strategy = strategy(self)
3105
+ self._groebner_strategy.compute_groebner(reduced=reduced)
3106
+ self._reduced = reduced
3107
+ return self._groebner_strategy.groebner_basis