passagemath-singular 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-singular might be problematic. Click here for more details.

Files changed (490) hide show
  1. PySingular.cpython-314-aarch64-linux-gnu.so +0 -0
  2. passagemath_singular-10.6.31rc3.dist-info/METADATA +183 -0
  3. passagemath_singular-10.6.31rc3.dist-info/RECORD +490 -0
  4. passagemath_singular-10.6.31rc3.dist-info/WHEEL +6 -0
  5. passagemath_singular-10.6.31rc3.dist-info/top_level.txt +3 -0
  6. passagemath_singular.libs/libSingular-4-6a2a8666.4.1.so +0 -0
  7. passagemath_singular.libs/libcddgmp-ac579979.so.0.1.3 +0 -0
  8. passagemath_singular.libs/libfactory-4-66e33516.4.1.so +0 -0
  9. passagemath_singular.libs/libflint-81de1160.so.21.0.0 +0 -0
  10. passagemath_singular.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
  11. passagemath_singular.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  12. passagemath_singular.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
  13. passagemath_singular.libs/libgsl-e3525837.so.28.0.0 +0 -0
  14. passagemath_singular.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
  15. passagemath_singular.libs/libntl-0043a3a2.so.44.0.1 +0 -0
  16. passagemath_singular.libs/libomalloc-0-06512335.9.6.so +0 -0
  17. passagemath_singular.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  18. passagemath_singular.libs/libpolys-4-cb7246b5.4.1.so +0 -0
  19. passagemath_singular.libs/libreadline-28330744.so.8.2 +0 -0
  20. passagemath_singular.libs/libsingular_resources-4-8c425241.4.1.so +0 -0
  21. passagemath_singular.libs/libtinfo-f81c2d16.so.6.3 +0 -0
  22. sage/algebras/all__sagemath_singular.py +3 -0
  23. sage/algebras/fusion_rings/all.py +19 -0
  24. sage/algebras/fusion_rings/f_matrix.py +2448 -0
  25. sage/algebras/fusion_rings/fast_parallel_fmats_methods.cpython-314-aarch64-linux-gnu.so +0 -0
  26. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pxd +5 -0
  27. sage/algebras/fusion_rings/fast_parallel_fmats_methods.pyx +538 -0
  28. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.cpython-314-aarch64-linux-gnu.so +0 -0
  29. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pxd +3 -0
  30. sage/algebras/fusion_rings/fast_parallel_fusion_ring_braid_repn.pyx +331 -0
  31. sage/algebras/fusion_rings/fusion_double.py +899 -0
  32. sage/algebras/fusion_rings/fusion_ring.py +1580 -0
  33. sage/algebras/fusion_rings/poly_tup_engine.cpython-314-aarch64-linux-gnu.so +0 -0
  34. sage/algebras/fusion_rings/poly_tup_engine.pxd +24 -0
  35. sage/algebras/fusion_rings/poly_tup_engine.pyx +579 -0
  36. sage/algebras/fusion_rings/shm_managers.cpython-314-aarch64-linux-gnu.so +0 -0
  37. sage/algebras/fusion_rings/shm_managers.pxd +24 -0
  38. sage/algebras/fusion_rings/shm_managers.pyx +780 -0
  39. sage/algebras/letterplace/all.py +1 -0
  40. sage/algebras/letterplace/free_algebra_element_letterplace.cpython-314-aarch64-linux-gnu.so +0 -0
  41. sage/algebras/letterplace/free_algebra_element_letterplace.pxd +18 -0
  42. sage/algebras/letterplace/free_algebra_element_letterplace.pyx +755 -0
  43. sage/algebras/letterplace/free_algebra_letterplace.cpython-314-aarch64-linux-gnu.so +0 -0
  44. sage/algebras/letterplace/free_algebra_letterplace.pxd +35 -0
  45. sage/algebras/letterplace/free_algebra_letterplace.pyx +914 -0
  46. sage/algebras/letterplace/letterplace_ideal.cpython-314-aarch64-linux-gnu.so +0 -0
  47. sage/algebras/letterplace/letterplace_ideal.pyx +408 -0
  48. sage/algebras/quatalg/all.py +2 -0
  49. sage/algebras/quatalg/quaternion_algebra.py +4778 -0
  50. sage/algebras/quatalg/quaternion_algebra_cython.cpython-314-aarch64-linux-gnu.so +0 -0
  51. sage/algebras/quatalg/quaternion_algebra_cython.pyx +261 -0
  52. sage/algebras/quatalg/quaternion_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  53. sage/algebras/quatalg/quaternion_algebra_element.pxd +29 -0
  54. sage/algebras/quatalg/quaternion_algebra_element.pyx +2176 -0
  55. sage/all__sagemath_singular.py +11 -0
  56. sage/ext_data/all__sagemath_singular.py +1 -0
  57. sage/ext_data/singular/function_field/core.lib +98 -0
  58. sage/interfaces/all__sagemath_singular.py +1 -0
  59. sage/interfaces/singular.py +2835 -0
  60. sage/libs/all__sagemath_singular.py +1 -0
  61. sage/libs/singular/__init__.py +1 -0
  62. sage/libs/singular/decl.pxd +1168 -0
  63. sage/libs/singular/function.cpython-314-aarch64-linux-gnu.so +0 -0
  64. sage/libs/singular/function.pxd +87 -0
  65. sage/libs/singular/function.pyx +1901 -0
  66. sage/libs/singular/function_factory.py +61 -0
  67. sage/libs/singular/groebner_strategy.cpython-314-aarch64-linux-gnu.so +0 -0
  68. sage/libs/singular/groebner_strategy.pxd +22 -0
  69. sage/libs/singular/groebner_strategy.pyx +582 -0
  70. sage/libs/singular/option.cpython-314-aarch64-linux-gnu.so +0 -0
  71. sage/libs/singular/option.pyx +671 -0
  72. sage/libs/singular/polynomial.cpython-314-aarch64-linux-gnu.so +0 -0
  73. sage/libs/singular/polynomial.pxd +39 -0
  74. sage/libs/singular/polynomial.pyx +661 -0
  75. sage/libs/singular/ring.cpython-314-aarch64-linux-gnu.so +0 -0
  76. sage/libs/singular/ring.pxd +58 -0
  77. sage/libs/singular/ring.pyx +893 -0
  78. sage/libs/singular/singular.cpython-314-aarch64-linux-gnu.so +0 -0
  79. sage/libs/singular/singular.pxd +72 -0
  80. sage/libs/singular/singular.pyx +1944 -0
  81. sage/libs/singular/standard_options.py +145 -0
  82. sage/matrix/all__sagemath_singular.py +1 -0
  83. sage/matrix/matrix_mpolynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  84. sage/matrix/matrix_mpolynomial_dense.pxd +7 -0
  85. sage/matrix/matrix_mpolynomial_dense.pyx +615 -0
  86. sage/rings/all__sagemath_singular.py +1 -0
  87. sage/rings/function_field/all__sagemath_singular.py +1 -0
  88. sage/rings/function_field/derivations_polymod.py +911 -0
  89. sage/rings/function_field/element_polymod.cpython-314-aarch64-linux-gnu.so +0 -0
  90. sage/rings/function_field/element_polymod.pyx +406 -0
  91. sage/rings/function_field/function_field_polymod.py +2611 -0
  92. sage/rings/function_field/ideal_polymod.py +1775 -0
  93. sage/rings/function_field/order_polymod.py +1475 -0
  94. sage/rings/function_field/place_polymod.py +681 -0
  95. sage/rings/polynomial/all__sagemath_singular.py +1 -0
  96. sage/rings/polynomial/multi_polynomial_ideal_libsingular.cpython-314-aarch64-linux-gnu.so +0 -0
  97. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pxd +5 -0
  98. sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx +339 -0
  99. sage/rings/polynomial/multi_polynomial_libsingular.cpython-314-aarch64-linux-gnu.so +0 -0
  100. sage/rings/polynomial/multi_polynomial_libsingular.pxd +30 -0
  101. sage/rings/polynomial/multi_polynomial_libsingular.pyx +6277 -0
  102. sage/rings/polynomial/plural.cpython-314-aarch64-linux-gnu.so +0 -0
  103. sage/rings/polynomial/plural.pxd +48 -0
  104. sage/rings/polynomial/plural.pyx +3171 -0
  105. sage/symbolic/all__sagemath_singular.py +1 -0
  106. sage/symbolic/comparison_impl.pxi +428 -0
  107. sage/symbolic/constants_c_impl.pxi +178 -0
  108. sage/symbolic/expression.cpython-314-aarch64-linux-gnu.so +0 -0
  109. sage/symbolic/expression.pxd +7 -0
  110. sage/symbolic/expression.pyx +14200 -0
  111. sage/symbolic/getitem_impl.pxi +202 -0
  112. sage/symbolic/pynac.pxi +572 -0
  113. sage/symbolic/pynac_constant_impl.pxi +133 -0
  114. sage/symbolic/pynac_function_impl.pxi +206 -0
  115. sage/symbolic/pynac_impl.pxi +2576 -0
  116. sage/symbolic/pynac_wrap.h +124 -0
  117. sage/symbolic/series_impl.pxi +272 -0
  118. sage/symbolic/substitution_map_impl.pxi +94 -0
  119. sage_wheels/bin/ESingular +0 -0
  120. sage_wheels/bin/Singular +0 -0
  121. sage_wheels/bin/TSingular +0 -0
  122. sage_wheels/lib/singular/MOD/cohomo.la +41 -0
  123. sage_wheels/lib/singular/MOD/cohomo.so +0 -0
  124. sage_wheels/lib/singular/MOD/customstd.la +41 -0
  125. sage_wheels/lib/singular/MOD/customstd.so +0 -0
  126. sage_wheels/lib/singular/MOD/freealgebra.la +41 -0
  127. sage_wheels/lib/singular/MOD/freealgebra.so +0 -0
  128. sage_wheels/lib/singular/MOD/gfanlib.la +41 -0
  129. sage_wheels/lib/singular/MOD/gfanlib.so +0 -0
  130. sage_wheels/lib/singular/MOD/gitfan.la +41 -0
  131. sage_wheels/lib/singular/MOD/gitfan.so +0 -0
  132. sage_wheels/lib/singular/MOD/interval.la +41 -0
  133. sage_wheels/lib/singular/MOD/interval.so +0 -0
  134. sage_wheels/lib/singular/MOD/loctriv.la +41 -0
  135. sage_wheels/lib/singular/MOD/loctriv.so +0 -0
  136. sage_wheels/lib/singular/MOD/machinelearning.la +41 -0
  137. sage_wheels/lib/singular/MOD/machinelearning.so +0 -0
  138. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.la +41 -0
  139. sage_wheels/lib/singular/MOD/p_Procs_FieldGeneral.so +0 -0
  140. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.la +41 -0
  141. sage_wheels/lib/singular/MOD/p_Procs_FieldIndep.so +0 -0
  142. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.la +41 -0
  143. sage_wheels/lib/singular/MOD/p_Procs_FieldQ.so +0 -0
  144. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.la +41 -0
  145. sage_wheels/lib/singular/MOD/p_Procs_FieldZp.so +0 -0
  146. sage_wheels/lib/singular/MOD/partialgb.la +41 -0
  147. sage_wheels/lib/singular/MOD/partialgb.so +0 -0
  148. sage_wheels/lib/singular/MOD/pyobject.la +41 -0
  149. sage_wheels/lib/singular/MOD/pyobject.so +0 -0
  150. sage_wheels/lib/singular/MOD/singmathic.la +41 -0
  151. sage_wheels/lib/singular/MOD/singmathic.so +0 -0
  152. sage_wheels/lib/singular/MOD/sispasm.la +41 -0
  153. sage_wheels/lib/singular/MOD/sispasm.so +0 -0
  154. sage_wheels/lib/singular/MOD/subsets.la +41 -0
  155. sage_wheels/lib/singular/MOD/subsets.so +0 -0
  156. sage_wheels/lib/singular/MOD/systhreads.la +41 -0
  157. sage_wheels/lib/singular/MOD/systhreads.so +0 -0
  158. sage_wheels/lib/singular/MOD/syzextra.la +41 -0
  159. sage_wheels/lib/singular/MOD/syzextra.so +0 -0
  160. sage_wheels/libexec/singular/MOD/change_cost +0 -0
  161. sage_wheels/libexec/singular/MOD/singularsurf +11 -0
  162. sage_wheels/libexec/singular/MOD/singularsurf_jupyter +9 -0
  163. sage_wheels/libexec/singular/MOD/singularsurf_win +10 -0
  164. sage_wheels/libexec/singular/MOD/solve_IP +0 -0
  165. sage_wheels/libexec/singular/MOD/surfex +16 -0
  166. sage_wheels/libexec/singular/MOD/toric_ideal +0 -0
  167. sage_wheels/share/factory/gftables/10201 +342 -0
  168. sage_wheels/share/factory/gftables/1024 +37 -0
  169. sage_wheels/share/factory/gftables/10609 +356 -0
  170. sage_wheels/share/factory/gftables/11449 +384 -0
  171. sage_wheels/share/factory/gftables/11881 +398 -0
  172. sage_wheels/share/factory/gftables/121 +6 -0
  173. sage_wheels/share/factory/gftables/12167 +408 -0
  174. sage_wheels/share/factory/gftables/125 +7 -0
  175. sage_wheels/share/factory/gftables/12769 +428 -0
  176. sage_wheels/share/factory/gftables/128 +7 -0
  177. sage_wheels/share/factory/gftables/1331 +47 -0
  178. sage_wheels/share/factory/gftables/1369 +48 -0
  179. sage_wheels/share/factory/gftables/14641 +490 -0
  180. sage_wheels/share/factory/gftables/15625 +523 -0
  181. sage_wheels/share/factory/gftables/16 +3 -0
  182. sage_wheels/share/factory/gftables/16129 +540 -0
  183. sage_wheels/share/factory/gftables/16384 +549 -0
  184. sage_wheels/share/factory/gftables/16807 +563 -0
  185. sage_wheels/share/factory/gftables/1681 +58 -0
  186. sage_wheels/share/factory/gftables/169 +8 -0
  187. sage_wheels/share/factory/gftables/17161 +574 -0
  188. sage_wheels/share/factory/gftables/1849 +64 -0
  189. sage_wheels/share/factory/gftables/18769 +628 -0
  190. sage_wheels/share/factory/gftables/19321 +646 -0
  191. sage_wheels/share/factory/gftables/19683 +659 -0
  192. sage_wheels/share/factory/gftables/2048 +71 -0
  193. sage_wheels/share/factory/gftables/2187 +75 -0
  194. sage_wheels/share/factory/gftables/2197 +76 -0
  195. sage_wheels/share/factory/gftables/2209 +76 -0
  196. sage_wheels/share/factory/gftables/22201 +742 -0
  197. sage_wheels/share/factory/gftables/22801 +762 -0
  198. sage_wheels/share/factory/gftables/2401 +82 -0
  199. sage_wheels/share/factory/gftables/243 +11 -0
  200. sage_wheels/share/factory/gftables/24389 +815 -0
  201. sage_wheels/share/factory/gftables/24649 +824 -0
  202. sage_wheels/share/factory/gftables/25 +3 -0
  203. sage_wheels/share/factory/gftables/256 +11 -0
  204. sage_wheels/share/factory/gftables/26569 +888 -0
  205. sage_wheels/share/factory/gftables/27 +3 -0
  206. sage_wheels/share/factory/gftables/27889 +932 -0
  207. sage_wheels/share/factory/gftables/2809 +96 -0
  208. sage_wheels/share/factory/gftables/28561 +954 -0
  209. sage_wheels/share/factory/gftables/289 +12 -0
  210. sage_wheels/share/factory/gftables/29791 +995 -0
  211. sage_wheels/share/factory/gftables/29929 +1000 -0
  212. sage_wheels/share/factory/gftables/3125 +107 -0
  213. sage_wheels/share/factory/gftables/32 +4 -0
  214. sage_wheels/share/factory/gftables/32041 +1070 -0
  215. sage_wheels/share/factory/gftables/32761 +1094 -0
  216. sage_wheels/share/factory/gftables/32768 +1095 -0
  217. sage_wheels/share/factory/gftables/343 +14 -0
  218. sage_wheels/share/factory/gftables/3481 +118 -0
  219. sage_wheels/share/factory/gftables/361 +14 -0
  220. sage_wheels/share/factory/gftables/36481 +1218 -0
  221. sage_wheels/share/factory/gftables/3721 +126 -0
  222. sage_wheels/share/factory/gftables/37249 +1244 -0
  223. sage_wheels/share/factory/gftables/38809 +1296 -0
  224. sage_wheels/share/factory/gftables/39601 +1322 -0
  225. sage_wheels/share/factory/gftables/4 +3 -0
  226. sage_wheels/share/factory/gftables/4096 +139 -0
  227. sage_wheels/share/factory/gftables/44521 +1486 -0
  228. sage_wheels/share/factory/gftables/4489 +152 -0
  229. sage_wheels/share/factory/gftables/49 +4 -0
  230. sage_wheels/share/factory/gftables/4913 +166 -0
  231. sage_wheels/share/factory/gftables/49729 +1660 -0
  232. sage_wheels/share/factory/gftables/5041 +170 -0
  233. sage_wheels/share/factory/gftables/50653 +1691 -0
  234. sage_wheels/share/factory/gftables/512 +20 -0
  235. sage_wheels/share/factory/gftables/51529 +1720 -0
  236. sage_wheels/share/factory/gftables/52441 +1750 -0
  237. sage_wheels/share/factory/gftables/529 +20 -0
  238. sage_wheels/share/factory/gftables/5329 +180 -0
  239. sage_wheels/share/factory/gftables/54289 +1812 -0
  240. sage_wheels/share/factory/gftables/57121 +1906 -0
  241. sage_wheels/share/factory/gftables/58081 +1938 -0
  242. sage_wheels/share/factory/gftables/59049 +1971 -0
  243. sage_wheels/share/factory/gftables/6241 +210 -0
  244. sage_wheels/share/factory/gftables/625 +23 -0
  245. sage_wheels/share/factory/gftables/63001 +2102 -0
  246. sage_wheels/share/factory/gftables/64 +5 -0
  247. sage_wheels/share/factory/gftables/6561 +221 -0
  248. sage_wheels/share/factory/gftables/6859 +231 -0
  249. sage_wheels/share/factory/gftables/6889 +232 -0
  250. sage_wheels/share/factory/gftables/729 +27 -0
  251. sage_wheels/share/factory/gftables/7921 +266 -0
  252. sage_wheels/share/factory/gftables/8 +3 -0
  253. sage_wheels/share/factory/gftables/81 +5 -0
  254. sage_wheels/share/factory/gftables/8192 +276 -0
  255. sage_wheels/share/factory/gftables/841 +30 -0
  256. sage_wheels/share/factory/gftables/9 +3 -0
  257. sage_wheels/share/factory/gftables/9409 +316 -0
  258. sage_wheels/share/factory/gftables/961 +34 -0
  259. sage_wheels/share/info/singular.info +191898 -0
  260. sage_wheels/share/singular/LIB/GND.lib +1359 -0
  261. sage_wheels/share/singular/LIB/JMBTest.lib +976 -0
  262. sage_wheels/share/singular/LIB/JMSConst.lib +1363 -0
  263. sage_wheels/share/singular/LIB/KVequiv.lib +699 -0
  264. sage_wheels/share/singular/LIB/SingularityDBM.lib +491 -0
  265. sage_wheels/share/singular/LIB/VecField.lib +1542 -0
  266. sage_wheels/share/singular/LIB/absfact.lib +959 -0
  267. sage_wheels/share/singular/LIB/ainvar.lib +730 -0
  268. sage_wheels/share/singular/LIB/aksaka.lib +419 -0
  269. sage_wheels/share/singular/LIB/alexpoly.lib +2542 -0
  270. sage_wheels/share/singular/LIB/algebra.lib +1193 -0
  271. sage_wheels/share/singular/LIB/all.lib +136 -0
  272. sage_wheels/share/singular/LIB/arcpoint.lib +514 -0
  273. sage_wheels/share/singular/LIB/arnold.lib +4553 -0
  274. sage_wheels/share/singular/LIB/arnoldclassify.lib +2058 -0
  275. sage_wheels/share/singular/LIB/arr.lib +3486 -0
  276. sage_wheels/share/singular/LIB/assprimeszerodim.lib +755 -0
  277. sage_wheels/share/singular/LIB/autgradalg.lib +3361 -0
  278. sage_wheels/share/singular/LIB/bfun.lib +1964 -0
  279. sage_wheels/share/singular/LIB/bimodules.lib +774 -0
  280. sage_wheels/share/singular/LIB/brillnoether.lib +226 -0
  281. sage_wheels/share/singular/LIB/brnoeth.lib +5017 -0
  282. sage_wheels/share/singular/LIB/central.lib +2169 -0
  283. sage_wheels/share/singular/LIB/chern.lib +4162 -0
  284. sage_wheels/share/singular/LIB/cimonom.lib +571 -0
  285. sage_wheels/share/singular/LIB/cisimplicial.lib +1835 -0
  286. sage_wheels/share/singular/LIB/classify.lib +3239 -0
  287. sage_wheels/share/singular/LIB/classify2.lib +1462 -0
  288. sage_wheels/share/singular/LIB/classifyMapGerms.lib +1515 -0
  289. sage_wheels/share/singular/LIB/classify_aeq.lib +3253 -0
  290. sage_wheels/share/singular/LIB/classifyceq.lib +2092 -0
  291. sage_wheels/share/singular/LIB/classifyci.lib +1133 -0
  292. sage_wheels/share/singular/LIB/combinat.lib +91 -0
  293. sage_wheels/share/singular/LIB/compregb.lib +276 -0
  294. sage_wheels/share/singular/LIB/control.lib +1636 -0
  295. sage_wheels/share/singular/LIB/crypto.lib +3795 -0
  296. sage_wheels/share/singular/LIB/curveInv.lib +667 -0
  297. sage_wheels/share/singular/LIB/curvepar.lib +1817 -0
  298. sage_wheels/share/singular/LIB/customstd.lib +100 -0
  299. sage_wheels/share/singular/LIB/deRham.lib +5979 -0
  300. sage_wheels/share/singular/LIB/decodegb.lib +2134 -0
  301. sage_wheels/share/singular/LIB/decomp.lib +1655 -0
  302. sage_wheels/share/singular/LIB/deflation.lib +872 -0
  303. sage_wheels/share/singular/LIB/deform.lib +925 -0
  304. sage_wheels/share/singular/LIB/difform.lib +3055 -0
  305. sage_wheels/share/singular/LIB/divisors.lib +750 -0
  306. sage_wheels/share/singular/LIB/dmod.lib +5817 -0
  307. sage_wheels/share/singular/LIB/dmodapp.lib +3269 -0
  308. sage_wheels/share/singular/LIB/dmodideal.lib +1211 -0
  309. sage_wheels/share/singular/LIB/dmodloc.lib +2645 -0
  310. sage_wheels/share/singular/LIB/dmodvar.lib +818 -0
  311. sage_wheels/share/singular/LIB/dummy.lib +17 -0
  312. sage_wheels/share/singular/LIB/elim.lib +1009 -0
  313. sage_wheels/share/singular/LIB/ellipticcovers.lib +548 -0
  314. sage_wheels/share/singular/LIB/enumpoints.lib +146 -0
  315. sage_wheels/share/singular/LIB/equising.lib +2127 -0
  316. sage_wheels/share/singular/LIB/ffmodstd.lib +2384 -0
  317. sage_wheels/share/singular/LIB/ffsolve.lib +1289 -0
  318. sage_wheels/share/singular/LIB/findifs.lib +778 -0
  319. sage_wheels/share/singular/LIB/finitediff.lib +1768 -0
  320. sage_wheels/share/singular/LIB/finvar.lib +7989 -0
  321. sage_wheels/share/singular/LIB/fpadim.lib +2429 -0
  322. sage_wheels/share/singular/LIB/fpalgebras.lib +1666 -0
  323. sage_wheels/share/singular/LIB/fpaprops.lib +1462 -0
  324. sage_wheels/share/singular/LIB/freegb.lib +3853 -0
  325. sage_wheels/share/singular/LIB/general.lib +1350 -0
  326. sage_wheels/share/singular/LIB/gfan.lib +1768 -0
  327. sage_wheels/share/singular/LIB/gitfan.lib +3130 -0
  328. sage_wheels/share/singular/LIB/gkdim.lib +99 -0
  329. sage_wheels/share/singular/LIB/gmspoly.lib +589 -0
  330. sage_wheels/share/singular/LIB/gmssing.lib +1739 -0
  331. sage_wheels/share/singular/LIB/goettsche.lib +909 -0
  332. sage_wheels/share/singular/LIB/graal.lib +1366 -0
  333. sage_wheels/share/singular/LIB/gradedModules.lib +2541 -0
  334. sage_wheels/share/singular/LIB/graphics.lib +360 -0
  335. sage_wheels/share/singular/LIB/grobcov.lib +7706 -0
  336. sage_wheels/share/singular/LIB/groups.lib +1123 -0
  337. sage_wheels/share/singular/LIB/grwalk.lib +507 -0
  338. sage_wheels/share/singular/LIB/hdepth.lib +194 -0
  339. sage_wheels/share/singular/LIB/help.cnf +57 -0
  340. sage_wheels/share/singular/LIB/hess.lib +1946 -0
  341. sage_wheels/share/singular/LIB/hnoether.lib +4292 -0
  342. sage_wheels/share/singular/LIB/hodge.lib +400 -0
  343. sage_wheels/share/singular/LIB/homolog.lib +1965 -0
  344. sage_wheels/share/singular/LIB/hyperel.lib +975 -0
  345. sage_wheels/share/singular/LIB/inout.lib +679 -0
  346. sage_wheels/share/singular/LIB/integralbasis.lib +6224 -0
  347. sage_wheels/share/singular/LIB/interval.lib +1418 -0
  348. sage_wheels/share/singular/LIB/intprog.lib +778 -0
  349. sage_wheels/share/singular/LIB/invar.lib +443 -0
  350. sage_wheels/share/singular/LIB/involut.lib +980 -0
  351. sage_wheels/share/singular/LIB/jacobson.lib +1215 -0
  352. sage_wheels/share/singular/LIB/kskernel.lib +534 -0
  353. sage_wheels/share/singular/LIB/latex.lib +3146 -0
  354. sage_wheels/share/singular/LIB/lejeune.lib +651 -0
  355. sage_wheels/share/singular/LIB/linalg.lib +2040 -0
  356. sage_wheels/share/singular/LIB/locnormal.lib +212 -0
  357. sage_wheels/share/singular/LIB/lrcalc.lib +526 -0
  358. sage_wheels/share/singular/LIB/makedbm.lib +294 -0
  359. sage_wheels/share/singular/LIB/mathml.lib +813 -0
  360. sage_wheels/share/singular/LIB/matrix.lib +1372 -0
  361. sage_wheels/share/singular/LIB/maxlike.lib +1132 -0
  362. sage_wheels/share/singular/LIB/methods.lib +212 -0
  363. sage_wheels/share/singular/LIB/moddiq.lib +322 -0
  364. sage_wheels/share/singular/LIB/modfinduni.lib +181 -0
  365. sage_wheels/share/singular/LIB/modnormal.lib +218 -0
  366. sage_wheels/share/singular/LIB/modprimdec.lib +1278 -0
  367. sage_wheels/share/singular/LIB/modquotient.lib +269 -0
  368. sage_wheels/share/singular/LIB/modstd.lib +1024 -0
  369. sage_wheels/share/singular/LIB/modular.lib +545 -0
  370. sage_wheels/share/singular/LIB/modules.lib +2561 -0
  371. sage_wheels/share/singular/LIB/modwalk.lib +609 -0
  372. sage_wheels/share/singular/LIB/mondromy.lib +1016 -0
  373. sage_wheels/share/singular/LIB/monomialideal.lib +3851 -0
  374. sage_wheels/share/singular/LIB/mprimdec.lib +2353 -0
  375. sage_wheels/share/singular/LIB/mregular.lib +1863 -0
  376. sage_wheels/share/singular/LIB/multigrading.lib +5629 -0
  377. sage_wheels/share/singular/LIB/ncHilb.lib +777 -0
  378. sage_wheels/share/singular/LIB/ncModslimgb.lib +791 -0
  379. sage_wheels/share/singular/LIB/ncalg.lib +16311 -0
  380. sage_wheels/share/singular/LIB/ncall.lib +31 -0
  381. sage_wheels/share/singular/LIB/ncdecomp.lib +468 -0
  382. sage_wheels/share/singular/LIB/ncfactor.lib +13371 -0
  383. sage_wheels/share/singular/LIB/ncfrac.lib +1023 -0
  384. sage_wheels/share/singular/LIB/nchilbert.lib +448 -0
  385. sage_wheels/share/singular/LIB/nchomolog.lib +759 -0
  386. sage_wheels/share/singular/LIB/ncloc.lib +361 -0
  387. sage_wheels/share/singular/LIB/ncpreim.lib +795 -0
  388. sage_wheels/share/singular/LIB/ncrat.lib +2849 -0
  389. sage_wheels/share/singular/LIB/nctools.lib +1887 -0
  390. sage_wheels/share/singular/LIB/nets.lib +1456 -0
  391. sage_wheels/share/singular/LIB/nfmodstd.lib +1000 -0
  392. sage_wheels/share/singular/LIB/nfmodsyz.lib +732 -0
  393. sage_wheels/share/singular/LIB/noether.lib +1106 -0
  394. sage_wheels/share/singular/LIB/normal.lib +8700 -0
  395. sage_wheels/share/singular/LIB/normaliz.lib +2226 -0
  396. sage_wheels/share/singular/LIB/ntsolve.lib +362 -0
  397. sage_wheels/share/singular/LIB/numerAlg.lib +560 -0
  398. sage_wheels/share/singular/LIB/numerDecom.lib +2261 -0
  399. sage_wheels/share/singular/LIB/olga.lib +1933 -0
  400. sage_wheels/share/singular/LIB/orbitparam.lib +351 -0
  401. sage_wheels/share/singular/LIB/parallel.lib +319 -0
  402. sage_wheels/share/singular/LIB/paraplanecurves.lib +3110 -0
  403. sage_wheels/share/singular/LIB/perron.lib +202 -0
  404. sage_wheels/share/singular/LIB/pfd.lib +2223 -0
  405. sage_wheels/share/singular/LIB/phindex.lib +642 -0
  406. sage_wheels/share/singular/LIB/pointid.lib +673 -0
  407. sage_wheels/share/singular/LIB/polybori.lib +1430 -0
  408. sage_wheels/share/singular/LIB/polyclass.lib +525 -0
  409. sage_wheels/share/singular/LIB/polylib.lib +1174 -0
  410. sage_wheels/share/singular/LIB/polymake.lib +1902 -0
  411. sage_wheels/share/singular/LIB/presolve.lib +1533 -0
  412. sage_wheels/share/singular/LIB/primdec.lib +9576 -0
  413. sage_wheels/share/singular/LIB/primdecint.lib +1782 -0
  414. sage_wheels/share/singular/LIB/primitiv.lib +401 -0
  415. sage_wheels/share/singular/LIB/puiseuxexpansions.lib +1631 -0
  416. sage_wheels/share/singular/LIB/purityfiltration.lib +960 -0
  417. sage_wheels/share/singular/LIB/qhmoduli.lib +1561 -0
  418. sage_wheels/share/singular/LIB/qmatrix.lib +293 -0
  419. sage_wheels/share/singular/LIB/random.lib +455 -0
  420. sage_wheels/share/singular/LIB/ratgb.lib +489 -0
  421. sage_wheels/share/singular/LIB/realclassify.lib +5759 -0
  422. sage_wheels/share/singular/LIB/realizationMatroids.lib +772 -0
  423. sage_wheels/share/singular/LIB/realrad.lib +1197 -0
  424. sage_wheels/share/singular/LIB/recover.lib +2628 -0
  425. sage_wheels/share/singular/LIB/redcgs.lib +3984 -0
  426. sage_wheels/share/singular/LIB/reesclos.lib +465 -0
  427. sage_wheels/share/singular/LIB/resbinomial.lib +2802 -0
  428. sage_wheels/share/singular/LIB/resgraph.lib +789 -0
  429. sage_wheels/share/singular/LIB/resjung.lib +820 -0
  430. sage_wheels/share/singular/LIB/resolve.lib +5110 -0
  431. sage_wheels/share/singular/LIB/resources.lib +170 -0
  432. sage_wheels/share/singular/LIB/reszeta.lib +5473 -0
  433. sage_wheels/share/singular/LIB/ring.lib +1328 -0
  434. sage_wheels/share/singular/LIB/ringgb.lib +343 -0
  435. sage_wheels/share/singular/LIB/rinvar.lib +1153 -0
  436. sage_wheels/share/singular/LIB/rootisolation.lib +1481 -0
  437. sage_wheels/share/singular/LIB/rootsmr.lib +709 -0
  438. sage_wheels/share/singular/LIB/rootsur.lib +886 -0
  439. sage_wheels/share/singular/LIB/rstandard.lib +607 -0
  440. sage_wheels/share/singular/LIB/rwalk.lib +336 -0
  441. sage_wheels/share/singular/LIB/sagbi.lib +1353 -0
  442. sage_wheels/share/singular/LIB/sagbiNormaliz.lib +1622 -0
  443. sage_wheels/share/singular/LIB/sagbiNormaliz0.lib +1498 -0
  444. sage_wheels/share/singular/LIB/sagbigrob.lib +449 -0
  445. sage_wheels/share/singular/LIB/schreyer.lib +321 -0
  446. sage_wheels/share/singular/LIB/schubert.lib +2551 -0
  447. sage_wheels/share/singular/LIB/sets.lib +524 -0
  448. sage_wheels/share/singular/LIB/sheafcoh.lib +1663 -0
  449. sage_wheels/share/singular/LIB/signcond.lib +437 -0
  450. sage_wheels/share/singular/LIB/sing.lib +1094 -0
  451. sage_wheels/share/singular/LIB/sing4ti2.lib +419 -0
  452. sage_wheels/share/singular/LIB/solve.lib +2243 -0
  453. sage_wheels/share/singular/LIB/spcurve.lib +1077 -0
  454. sage_wheels/share/singular/LIB/spectrum.lib +62 -0
  455. sage_wheels/share/singular/LIB/sresext.lib +757 -0
  456. sage_wheels/share/singular/LIB/ssi.lib +143 -0
  457. sage_wheels/share/singular/LIB/standard.lib +2769 -0
  458. sage_wheels/share/singular/LIB/stanleyreisner.lib +473 -0
  459. sage_wheels/share/singular/LIB/stdmodule.lib +547 -0
  460. sage_wheels/share/singular/LIB/stratify.lib +1070 -0
  461. sage_wheels/share/singular/LIB/surf.lib +506 -0
  462. sage_wheels/share/singular/LIB/surf_jupyter.lib +223 -0
  463. sage_wheels/share/singular/LIB/surfacesignature.lib +522 -0
  464. sage_wheels/share/singular/LIB/surfex.lib +1462 -0
  465. sage_wheels/share/singular/LIB/swalk.lib +877 -0
  466. sage_wheels/share/singular/LIB/symodstd.lib +1570 -0
  467. sage_wheels/share/singular/LIB/systhreads.lib +74 -0
  468. sage_wheels/share/singular/LIB/tasks.lib +1324 -0
  469. sage_wheels/share/singular/LIB/tateProdCplxNegGrad.lib +2412 -0
  470. sage_wheels/share/singular/LIB/teachstd.lib +858 -0
  471. sage_wheels/share/singular/LIB/template.lib +116 -0
  472. sage_wheels/share/singular/LIB/toric.lib +1119 -0
  473. sage_wheels/share/singular/LIB/transformation.lib +116 -0
  474. sage_wheels/share/singular/LIB/triang.lib +1197 -0
  475. sage_wheels/share/singular/LIB/tropical.lib +8741 -0
  476. sage_wheels/share/singular/LIB/tropicalEllipticCovers.lib +2922 -0
  477. sage_wheels/share/singular/LIB/tropicalNewton.lib +1128 -0
  478. sage_wheels/share/singular/LIB/tst.lib +1108 -0
  479. sage_wheels/share/singular/LIB/weierstr.lib +241 -0
  480. sage_wheels/share/singular/LIB/zeroset.lib +1478 -0
  481. sage_wheels/share/singular/emacs/.emacs-general +184 -0
  482. sage_wheels/share/singular/emacs/.emacs-singular +234 -0
  483. sage_wheels/share/singular/emacs/COPYING +44 -0
  484. sage_wheels/share/singular/emacs/cmd-cmpl.el +241 -0
  485. sage_wheels/share/singular/emacs/ex-cmpl.el +1681 -0
  486. sage_wheels/share/singular/emacs/hlp-cmpl.el +4318 -0
  487. sage_wheels/share/singular/emacs/lib-cmpl.el +179 -0
  488. sage_wheels/share/singular/emacs/singular.el +4273 -0
  489. sage_wheels/share/singular/emacs/singular.xpm +39 -0
  490. sage_wheels/share/singular/singular.idx +5002 -0
@@ -0,0 +1,3171 @@
1
+ # sage_setup: distribution = sagemath-singular
2
+ # sage.doctest: needs sage.combinat
3
+ r"""
4
+ Noncommutative polynomials via libSINGULAR/Plural
5
+
6
+ This module provides specialized and optimized implementations for
7
+ noncommutative multivariate polynomials over many coefficient rings, via the
8
+ shared library interface to SINGULAR. In particular, the following coefficient
9
+ rings are supported by this implementation:
10
+
11
+ - the rational numbers `\QQ`, and
12
+
13
+ - finite fields `\GF{p}` for `p` prime
14
+
15
+ AUTHORS:
16
+
17
+ The PLURAL wrapper is due to
18
+
19
+ - Burcin Erocal (2008-11 and 2010-07): initial implementation and concept
20
+
21
+ - Michael Brickenstein (2008-11 and 2010-07): initial implementation and concept
22
+
23
+ - Oleksandr Motsak (2010-07): complete overall noncommutative functionality and first release
24
+
25
+ - Alexander Dreyer (2010-07): noncommutative ring functionality and documentation
26
+
27
+ - Simon King (2011-09): left and two-sided ideals; normal forms; pickling;
28
+ documentation
29
+
30
+ The underlying libSINGULAR interface was implemented by
31
+
32
+ - Martin Albrecht (2007-01): initial implementation
33
+
34
+ - Joel Mohler (2008-01): misc improvements, polishing
35
+
36
+ - Martin Albrecht (2008-08): added `\QQ(a)` and `\ZZ` support
37
+
38
+ - Simon King (2009-04): improved coercion
39
+
40
+ - Martin Albrecht (2009-05): added `\ZZ/n\ZZ` support, refactoring
41
+
42
+ - Martin Albrecht (2009-06): refactored the code to allow better re-use
43
+
44
+ .. TODO::
45
+
46
+ extend functionality towards those of libSINGULARs commutative part
47
+
48
+ EXAMPLES:
49
+
50
+ We show how to construct various noncommutative polynomial rings::
51
+
52
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
53
+ sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
54
+
55
+ sage: P
56
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
57
+
58
+ sage: y*x + 1/2
59
+ -x*y + 1/2
60
+
61
+ sage: A.<x,y,z> = FreeAlgebra(GF(17), 3)
62
+ sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
63
+ sage: P
64
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 17, nc-relations: {y*x: -x*y}
65
+
66
+ sage: y*x + 7
67
+ -x*y + 7
68
+
69
+
70
+ Raw use of this class; *this is not the intended use!*
71
+ ::
72
+
73
+ sage: from sage.matrix.constructor import Matrix
74
+ sage: c = Matrix(3)
75
+ sage: c[0,1] = -2
76
+ sage: c[0,2] = 1
77
+ sage: c[1,2] = 1
78
+
79
+ sage: d = Matrix(3)
80
+ sage: d[0, 1] = 17
81
+ sage: P = QQ['x','y','z']
82
+ sage: c = c.change_ring(P)
83
+ sage: d = d.change_ring(P)
84
+
85
+ sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
86
+ sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order=TermOrder('lex',3),category=Algebras(QQ))
87
+ sage: R
88
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -2*x*y + 17}
89
+
90
+ sage: R.term_order()
91
+ Lexicographic term order
92
+
93
+ sage: a,b,c = R.gens()
94
+ sage: f = 57 * a^2*b + 43 * c + 1; f
95
+ 57*x^2*y + 43*z + 1
96
+
97
+ TESTS::
98
+
99
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
100
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
101
+ sage: TestSuite(P).run()
102
+ sage: loads(dumps(P)) is P
103
+ True
104
+
105
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
106
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
107
+ sage: P.is_commutative()
108
+ False
109
+
110
+ sage: R.<x,y,z> = FreeAlgebra(QQ, 3)
111
+ sage: P = R.g_algebra(relations={}, order='lex')
112
+ sage: P.is_commutative()
113
+ True
114
+ """
115
+ from cysignals.memory cimport sig_malloc, sig_free
116
+
117
+ from sage.categories.algebras import Algebras
118
+ from sage.cpython.string cimport char_to_str
119
+
120
+ # singular rings
121
+
122
+ from sage.libs.singular.ring cimport singular_ring_delete, wrap_ring, singular_ring_reference
123
+
124
+ from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check
125
+
126
+
127
+ from sage.libs.singular.function cimport RingWrap
128
+
129
+ from sage.libs.singular.polynomial cimport (singular_polynomial_cmp, singular_polynomial_add, singular_polynomial_sub, singular_polynomial_neg, singular_polynomial_pow, singular_polynomial_mul, singular_polynomial_rmul, singular_polynomial_deg, singular_polynomial_str_with_changed_varnames, singular_polynomial_latex, singular_polynomial_str, singular_polynomial_div_coeff)
130
+
131
+ import sage.libs.singular.ring
132
+
133
+ from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn
134
+ from sage.rings.integer cimport Integer
135
+ from sage.rings.integer_ring import IntegerRing_class
136
+
137
+ from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular, new_MP
138
+ from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal
139
+
140
+ from sage.rings.polynomial.polydict import ETuple
141
+ from sage.rings.ring import CommutativeRing
142
+ from sage.structure.category_object cimport check_default_category
143
+ from sage.structure.element cimport CommutativeRingElement, Element, RingElement
144
+ from sage.structure.factory import UniqueFactory
145
+ from sage.structure.richcmp cimport rich_to_bool
146
+ from sage.structure.parent cimport Parent
147
+ from sage.rings.polynomial.term_order import TermOrder
148
+
149
+ from sage.misc.functional import coerce
150
+
151
+
152
+ class G_AlgFactory(UniqueFactory):
153
+ """
154
+ A factory for the creation of g-algebras as unique parents.
155
+
156
+ TESTS::
157
+
158
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
159
+ sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
160
+ sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) # indirect doctest
161
+ True
162
+ """
163
+ def create_object(self, version, key, **extra_args):
164
+ """
165
+ Create a g-algebra to a given unique key.
166
+
167
+ INPUT:
168
+
169
+ - ``key`` -- a 6-tuple, formed by a base ring, a tuple of names, two
170
+ matrices over a polynomial ring over the base ring with the given
171
+ variable names, a term order, and a category
172
+ - ``extra_args`` -- dictionary, whose only relevant key is 'check'
173
+
174
+ TESTS::
175
+
176
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
177
+ sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
178
+ sage: sorted(H.relations().items(), key=str)
179
+ [(y*x, x*y - z), (z*x, x*z + 2*x), (z*y, y*z - 2*y)]
180
+ """
181
+ # key = (base_ring,names, c,d, order, category)
182
+ # extra args: check
183
+ base_ring,names, c, d, order, category = key
184
+ check = extra_args.get('check')
185
+ return NCPolynomialRing_plural(base_ring, names, c, d, order,
186
+ category, check)
187
+
188
+ def create_key_and_extra_args(self, base_ring, c, d, names=None, order=None,
189
+ category=None, check=None, commutative=None):
190
+ """
191
+ Create a unique key for g-algebras.
192
+
193
+ INPUT:
194
+
195
+ - ``base_ring`` -- a ring
196
+ - ``c``, ``d`` -- two matrices
197
+ - ``names`` -- tuple or list of names
198
+ - ``order`` -- (optional) term order
199
+ - ``category`` -- (optional) category
200
+ - ``check`` -- (optional) boolean
201
+ - ``commutative`` -- (optional) boolean
202
+
203
+ TESTS::
204
+
205
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
206
+ sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
207
+ sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) # indirect doctest
208
+ True
209
+
210
+ sage: P = A.g_algebra(relations={}, order='lex')
211
+ sage: P.category()
212
+ Category of commutative algebras over Rational Field
213
+ """
214
+ if names is None:
215
+ raise ValueError("The generator names must be provided")
216
+
217
+ # Get the number of names:
218
+ names = tuple(names)
219
+ n = len(names)
220
+ if not isinstance(order, TermOrder):
221
+ order = TermOrder(order or 'degrevlex', n)
222
+
223
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
224
+ P = PolynomialRing(base_ring, n, names, order=order)
225
+ # The names may have been normalised in P:
226
+ names = P.variable_names()
227
+ c = c.change_ring(P)
228
+ c.set_immutable()
229
+ d = d.change_ring(P)
230
+ d.set_immutable()
231
+
232
+ # Get the correct category
233
+ if commutative:
234
+ usualcat = Algebras(base_ring).Commutative()
235
+ else:
236
+ usualcat = Algebras(base_ring)
237
+ category = check_default_category(usualcat, category)
238
+
239
+ # Extra arg
240
+ if check is None:
241
+ return (base_ring, names, c, d, order, category), {}
242
+ return (base_ring, names, c, d, order, category), {'check':check}
243
+
244
+
245
+ g_Algebra = G_AlgFactory('sage.rings.polynomial.plural.g_Algebra')
246
+
247
+
248
+ cdef class NCPolynomialRing_plural(Ring):
249
+ """
250
+ A non-commutative polynomial ring.
251
+
252
+ EXAMPLES::
253
+
254
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
255
+ sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
256
+ sage: H._is_category_initialized()
257
+ True
258
+ sage: H.category()
259
+ Category of algebras over Rational Field
260
+ sage: TestSuite(H).run()
261
+
262
+ Note that two variables commute if they are not part of the given
263
+ relations::
264
+
265
+ sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
266
+ sage: x*y == y*x
267
+ True
268
+ """
269
+ def __init__(self, base_ring, names, c, d, order, category, check=True):
270
+ r"""
271
+ Construct a noncommutative polynomial G-algebra subject to the following conditions:
272
+
273
+ INPUT:
274
+
275
+ - ``base_ring`` -- base ring (must be either `\GF{q}`, `\ZZ`, `\ZZ/n\ZZ`, `\QQ` or absolute number field)
276
+ - ``names`` -- tuple of names of ring variables
277
+ - ``c``, ``d`` -- upper triangular matrices of coefficients,
278
+ resp. commutative polynomials, satisfying the nondegeneracy
279
+ conditions, which are to be tested if ``check`` is ``True``. These
280
+ matrices describe the noncommutative relations:
281
+
282
+ ``self.gen(j)*self.gen(i) == c[i, j] * self.gen(i)*self.gen(j) + d[i, j],``
283
+
284
+ where ``0 <= i < j < self.ngens()``. Note that two variables
285
+ commute if they are not part of one of these relations.
286
+ - ``order`` -- term order
287
+ - ``check`` -- check the noncommutative conditions (default: ``True``)
288
+
289
+ TESTS:
290
+
291
+ It is strongly recommended to construct a g-algebra using
292
+ :class:`G_AlgFactory`. The following is just for documenting
293
+ the arguments of the ``__init__`` method::
294
+
295
+ sage: from sage.matrix.constructor import Matrix
296
+ sage: c0 = Matrix(3)
297
+ sage: c0[0,1] = -1
298
+ sage: c0[0,2] = 1
299
+ sage: c0[1,2] = 1
300
+
301
+ sage: d0 = Matrix(3)
302
+ sage: d0[0, 1] = 17
303
+ sage: P = QQ['x','y','z']
304
+ sage: c = c0.change_ring(P)
305
+ sage: d = d0.change_ring(P)
306
+
307
+ sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
308
+ sage: P.<x,y,z> = NCPolynomialRing_plural(QQ, c = c, d = d, order=TermOrder('lex',3), category=Algebras(QQ))
309
+
310
+ sage: P # indirect doctest
311
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y + 17}
312
+
313
+ sage: P(x*y)
314
+ x*y
315
+
316
+ sage: f = 27/113 * x^2 + y*z + 1/2; f
317
+ 27/113*x^2 + y*z + 1/2
318
+
319
+ sage: P.term_order()
320
+ Lexicographic term order
321
+
322
+ sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
323
+ sage: P = GF(7)['x','y','z']
324
+ sage: c = c0.change_ring(P)
325
+ sage: d = d0.change_ring(P)
326
+ sage: P.<x,y,z> = NCPolynomialRing_plural(GF(7), c = c, d = d, order=TermOrder('degrevlex',3), category=Algebras(GF(7)))
327
+
328
+ sage: P # indirect doctest
329
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 7, nc-relations: {y*x: -x*y + 3}
330
+
331
+ sage: P(x*y)
332
+ x*y
333
+
334
+ sage: f = 3 * x^2 + y*z + 5; f
335
+ 3*x^2 + y*z - 2
336
+
337
+ sage: P.term_order()
338
+ Degree reverse lexicographic term order
339
+ """
340
+ n = len(names)
341
+ self._relations = None
342
+
343
+ P = c.base_ring()
344
+ self._c = c
345
+ self._d = d
346
+
347
+ from sage.libs.singular.function import singular_function
348
+ ncalgebra = singular_function('nc_algebra')
349
+
350
+ cdef RingWrap rw = ncalgebra(self._c, self._d, ring=P)
351
+
352
+ # rw._output()
353
+ self._ring = singular_ring_reference(rw._ring)
354
+ self._ring.ShortOut = 0
355
+
356
+ self._ngens = n
357
+ self._term_order = order
358
+
359
+ Parent.__init__(self, base=base_ring, names=names, category=category)
360
+ self._populate_coercion_lists_()
361
+
362
+ assert n == len(self._names)
363
+
364
+ self._one_element = new_NCP(self, p_ISet(1, self._ring))
365
+ self._zero_element = new_NCP(self, NULL)
366
+
367
+ if check:
368
+ from sage.libs.singular.function_factory import ff
369
+ test = ff.nctools__lib.ndcond(ring = self)
370
+ if (len(test) != 1) or (test[0] != 0):
371
+ raise ValueError("NDC check failed!")
372
+
373
+ def __reduce__(self):
374
+ """
375
+ TESTS::
376
+
377
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
378
+ sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
379
+ sage: H is A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
380
+ True
381
+ sage: H is loads(dumps(H)) # indirect doctest
382
+ True
383
+ sage: A2.<x,y,z> = FreeAlgebra(GF(5), 3)
384
+ sage: R2 = A2.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2))
385
+
386
+ Check that :issue:`17224` is fixed::
387
+
388
+ sage: from sage.rings.polynomial.term_order import TermOrder
389
+ sage: F.<x,y> = FreeAlgebra(QQ)
390
+ sage: g = F.g_algebra({y*x:-x*y}, order=TermOrder('wdegrevlex', [1,2]))
391
+ sage: loads(dumps(g)) == g
392
+ True
393
+ """
394
+ return g_Algebra, (self.base_ring(), self._c, self._d,
395
+ self.variable_names(),
396
+ self.term_order(),
397
+ self.category())
398
+
399
+ def __dealloc__(self):
400
+ r"""
401
+ Carefully deallocate the ring, without changing "currRing"
402
+ (since this method can be at unpredictable times due to garbage
403
+ collection).
404
+
405
+ TESTS:
406
+
407
+ This example caused a segmentation fault with a previous version
408
+ of this method. This doctest still results in a segmentation fault
409
+ occasionally which is difficult to isolate, so this test is partially
410
+ disabled (:issue:`29528`)::
411
+
412
+ sage: import gc
413
+ sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
414
+ sage: from sage.algebras.free_algebra import FreeAlgebra
415
+ sage: A1.<x,y,z> = FreeAlgebra(QQ, 3)
416
+ sage: R1 = A1.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2))
417
+ sage: A2.<x,y,z> = FreeAlgebra(GF(5), 3) # not tested
418
+ sage: R2 = A2.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) # not tested
419
+ sage: A3.<x,y,z> = FreeAlgebra(GF(11), 3) # not tested
420
+ sage: R3 = A3.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) # not tested
421
+ sage: A4.<x,y,z> = FreeAlgebra(GF(13), 3) # not tested
422
+ sage: R4 = A4.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) # not tested
423
+ sage: _ = gc.collect()
424
+ sage: foo = R1.gen(0)
425
+ sage: del foo
426
+ sage: del R1
427
+ sage: _ = gc.collect()
428
+ sage: del R2 # not tested
429
+ sage: _ = gc.collect() # not tested
430
+ sage: del R3 # not tested
431
+ sage: _ = gc.collect() # not tested
432
+ """
433
+ singular_ring_delete(self._ring)
434
+
435
+ def _element_constructor_(self, element):
436
+ """
437
+ Make sure element is a valid member of ``self``, and return the constructed element.
438
+
439
+ EXAMPLES::
440
+
441
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
442
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
443
+
444
+ We can construct elements from the base ring::
445
+
446
+ sage: P(1/2)
447
+ 1/2
448
+
449
+ and all kinds of integers::
450
+
451
+ sage: P(17)
452
+ 17
453
+ sage: P(int(19))
454
+ 19
455
+
456
+ TESTS:
457
+
458
+ Check conversion from ``self``::
459
+
460
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
461
+ sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
462
+
463
+ sage: P._element_constructor_(1/2)
464
+ 1/2
465
+
466
+ sage: P._element_constructor_(x*y)
467
+ x*y
468
+
469
+ sage: P._element_constructor_(y*x)
470
+ -x*y
471
+
472
+ Testing special cases::
473
+
474
+ sage: P._element_constructor_(1)
475
+ 1
476
+
477
+ sage: P._element_constructor_(0)
478
+ 0
479
+
480
+ From the parent free algebra::
481
+
482
+ sage: F.<x,y,z> = FreeAlgebra(QQ,3)
483
+ sage: G = F.g_algebra({y*x: -x*y})
484
+ sage: G._element_constructor_(y*x)
485
+ -x*y
486
+
487
+ From another free algebra::
488
+
489
+ sage: A.<a,b> = FreeAlgebra(QQ, 2)
490
+ sage: G._element_constructor_(b)
491
+ Traceback (most recent call last):
492
+ ...
493
+ ValueError: unable to construct an element of this ring
494
+
495
+ From another g-algebra::
496
+
497
+ sage: B = A.g_algebra({b*a: -a*b})
498
+ sage: abar, bbar = B.gens()
499
+ sage: G._element_constructor_(bbar)
500
+ Traceback (most recent call last):
501
+ ...
502
+ ValueError: unable to construct an element of this ring
503
+
504
+ Check that it works for rings with parameters::
505
+
506
+ sage: F = PolynomialRing(QQ,'t1,t2').fraction_field()
507
+ sage: A = FreeAlgebra(F, 2, 'x,y')
508
+ sage: A.inject_variables()
509
+ Defining x, y
510
+ sage: B = A.g_algebra({y*x:-x*y})
511
+ sage: B(2)
512
+ 2
513
+ """
514
+ if element == 0:
515
+ return self._zero_element
516
+ if element == 1:
517
+ return self._one_element
518
+
519
+ cdef poly *_p
520
+ cdef ring *_ring,
521
+ cdef number *_n
522
+
523
+ _ring = self._ring
524
+
525
+ base_ring = self.base_ring()
526
+
527
+ try:
528
+ element = coerce(base_ring, element)
529
+ except Exception:
530
+ pass
531
+
532
+ if _ring != currRing:
533
+ rChangeCurrRing(_ring)
534
+
535
+ if isinstance(element, NCPolynomial_plural):
536
+
537
+ if element.parent() is <object>self:
538
+ return element
539
+ elif element.parent() == self:
540
+ # is this safe?
541
+ _p = p_Copy((<NCPolynomial_plural>element)._poly, _ring)
542
+ else:
543
+ raise ValueError("unable to construct an element of this ring")
544
+
545
+ elif isinstance(element, CommutativeRingElement):
546
+ # base ring elements
547
+ if <Parent>element.parent() is base_ring:
548
+ # shortcut for GF(p)
549
+ if isinstance(base_ring, FiniteField_prime_modn):
550
+ _p = p_ISet(int(element) % _ring.cf.ch, _ring)
551
+ else:
552
+ _n = sa2si(element,_ring)
553
+ _p = p_NSet(_n, _ring)
554
+
555
+ # also accepting ZZ
556
+ elif isinstance(element.parent(), IntegerRing_class):
557
+ if isinstance(base_ring, FiniteField_prime_modn):
558
+ _p = p_ISet(int(element),_ring)
559
+ else:
560
+ _n = sa2si(base_ring(element),_ring)
561
+ _p = p_NSet(_n, _ring)
562
+ else:
563
+ # fall back to base ring
564
+ element = base_ring.coerce(element)
565
+ _n = sa2si(element,_ring)
566
+ _p = p_NSet(_n, _ring)
567
+
568
+ elif isinstance(element, RingElement):
569
+ # the parent free algebra
570
+ if element.parent() == self.free_algebra():
571
+ return element(self.gens())
572
+ else:
573
+ raise ValueError("unable to construct an element of this ring")
574
+
575
+ # Accepting int
576
+ elif isinstance(element, int):
577
+ if isinstance(base_ring, FiniteField_prime_modn):
578
+ _p = p_ISet(int(element) % _ring.cf.ch, _ring)
579
+ else:
580
+ _n = sa2si(base_ring(element), _ring)
581
+ _p = p_NSet(_n, _ring)
582
+
583
+ else:
584
+ raise NotImplementedError(f"not able to interpret {element}"
585
+ f" of type {type(element)}"
586
+ " as noncommutative polynomial") # ???
587
+ return new_NCP(self, _p)
588
+
589
+ cpdef _coerce_map_from_(self, S):
590
+ """
591
+ The only things that coerce into this ring are:
592
+
593
+ - the integer ring
594
+ - other localizations away from fewer primes
595
+
596
+ EXAMPLES::
597
+
598
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
599
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
600
+ sage: P._coerce_map_from_(ZZ)
601
+ True
602
+ """
603
+ if self.base_ring().has_coerce_map_from(S):
604
+ return True
605
+
606
+ def free_algebra(self):
607
+ """
608
+ Return the free algebra of which this is the quotient.
609
+
610
+ EXAMPLES::
611
+
612
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
613
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
614
+ sage: B = P.free_algebra()
615
+ sage: A == B
616
+ True
617
+ """
618
+ from sage.algebras.free_algebra import FreeAlgebra
619
+ return FreeAlgebra(self.base_ring(), names=self.variable_names(), order=self.term_order())
620
+
621
+ def __hash__(self):
622
+ """
623
+ Return a hash for this noncommutative ring.
624
+
625
+ This is a hash of the string
626
+ representation of this polynomial ring.
627
+
628
+ NOTE:
629
+
630
+ G-algebras are unique parents, provided that the g-algebra constructor
631
+ is used. Thus, the hash simply is the memory address of the g-algebra
632
+ (so, it is a session hash, but no stable hash). It is possible to
633
+ destroy uniqueness of g-algebras on purpose, but that's your own
634
+ problem if you do those things.
635
+
636
+ EXAMPLES::
637
+
638
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
639
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
640
+ sage: {P:2}[P] # indirect doctest
641
+ 2
642
+ """
643
+ return <Py_hash_t> <void *> self
644
+
645
+ def __pow__(self, n, _):
646
+ """
647
+ Return the free module of rank `n` over this ring.
648
+
649
+ .. NOTE::
650
+
651
+ This is not properly implemented yet. Thus, there is
652
+ a warning.
653
+
654
+ EXAMPLES::
655
+
656
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
657
+ sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
658
+ sage: P^3
659
+ d...: UserWarning: You are constructing a free module
660
+ over a noncommutative ring. Sage does not have a concept
661
+ of left/right and both sided modules, so be careful.
662
+ It's also not guaranteed that all multiplications are
663
+ done from the right side.
664
+ d...: UserWarning: You are constructing a free module
665
+ over a noncommutative ring. Sage does not have a concept
666
+ of left/right and both sided modules, so be careful.
667
+ It's also not guaranteed that all multiplications are
668
+ done from the right side.
669
+ Ambient free module of rank 3 over Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
670
+ """
671
+ from sage.modules.free_module import FreeModule
672
+ return FreeModule(self, n)
673
+
674
+ def term_order(self):
675
+ """
676
+ Return the term ordering of the noncommutative ring.
677
+
678
+ EXAMPLES::
679
+
680
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
681
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
682
+ sage: P.term_order()
683
+ Lexicographic term order
684
+
685
+ sage: P = A.g_algebra(relations={y*x:-x*y})
686
+ sage: P.term_order()
687
+ Degree reverse lexicographic term order
688
+ """
689
+ return self._term_order
690
+
691
+ def is_field(self, *args, **kwargs) -> bool:
692
+ """
693
+ Return ``False``.
694
+
695
+ EXAMPLES::
696
+
697
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
698
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
699
+ sage: P.is_field()
700
+ False
701
+
702
+ TESTS:
703
+
704
+ Make the method accept additional parameters, such as the flag ``proof``.
705
+ See :issue:`22910`::
706
+
707
+ sage: P.is_field(proof=False)
708
+ False
709
+ """
710
+ return False
711
+
712
+ def _repr_(self):
713
+ """
714
+ EXAMPLES::
715
+
716
+ sage: A.<x,y> = FreeAlgebra(QQ, 2)
717
+ sage: H.<x,y> = A.g_algebra({y*x:-x*y})
718
+ sage: H # indirect doctest
719
+ Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: {y*x: -x*y}
720
+ sage: x*y
721
+ x*y
722
+ sage: y*x
723
+ -x*y
724
+ """
725
+ from sage.repl.rich_output.backend_base import BackendBase
726
+ from sage.repl.display.pretty_print import SagePrettyPrinter
727
+ varstr = ", ".join(char_to_str(rRingVar(i, self._ring))
728
+ for i in range(self._ngens))
729
+ backend = BackendBase()
730
+ relations = backend._apply_pretty_printer(SagePrettyPrinter,
731
+ self.relations())
732
+ return (f"Noncommutative Multivariate Polynomial Ring in {varstr} "
733
+ f"over {self.base_ring()}, nc-relations: {relations}")
734
+
735
+ def _ringlist(self):
736
+ """
737
+ Return an internal list representation of the noncommutative ring.
738
+
739
+ EXAMPLES::
740
+
741
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
742
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
743
+ sage: P._ringlist()
744
+ [
745
+ [ 0 -1 1]
746
+ [ 0 0 1]
747
+ 0, ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0,)]], [0], [ 0 0 0],
748
+ <BLANKLINE>
749
+ [0 0 0]
750
+ [0 0 0]
751
+ [0 0 0]
752
+ ]
753
+ """
754
+ cdef ring* _ring = self._ring
755
+ if _ring != currRing:
756
+ rChangeCurrRing(_ring)
757
+ from sage.libs.singular.function import singular_function
758
+ ringlist = singular_function('ringlist')
759
+ return ringlist(self, ring=self)
760
+
761
+ def relations(self, add_commutative=False):
762
+ """
763
+ Return the relations of this g-algebra.
764
+
765
+ INPUT:
766
+
767
+ - ``add_commutative`` -- boolean (default: ``False``)
768
+
769
+ OUTPUT:
770
+
771
+ The defining relations. There are some implicit relations:
772
+ Two generators commute if they are not part of any given
773
+ relation. The implicit relations are not provided, unless
774
+ ``add_commutative==True``.
775
+
776
+ EXAMPLES::
777
+
778
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
779
+ sage: H.<x,y,z> = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
780
+ sage: x*y == y*x
781
+ True
782
+ sage: H.relations()
783
+ {z*x: x*z + 2*x, z*y: y*z - 2*y}
784
+ sage: H.relations(add_commutative=True)
785
+ {y*x: x*y, z*x: x*z + 2*x, z*y: y*z - 2*y}
786
+ """
787
+ if add_commutative:
788
+ if self._relations_commutative is not None:
789
+ return self._relations_commutative
790
+
791
+ from sage.algebras.free_algebra import FreeAlgebra
792
+ A = FreeAlgebra(self.base_ring(), self.ngens(), self.variable_names())
793
+
794
+ res = {}
795
+ n = self.ngens()
796
+ for r in range(0, n-1, 1):
797
+ for c in range(r+1, n, 1):
798
+ res[A.gen(c) * A.gen(r)] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c]
799
+ self._relations_commutative = res
800
+ return res
801
+
802
+ if self._relations is not None:
803
+ return self._relations
804
+
805
+ from sage.algebras.free_algebra import FreeAlgebra
806
+ A = FreeAlgebra(self.base_ring(), self.ngens(), self.variable_names())
807
+
808
+ res = {}
809
+ n = self.ngens()
810
+ for r in range(0, n-1, 1):
811
+ for c in range(r+1, n, 1):
812
+ if (self.gen(c) * self.gen(r) != self.gen(r) * self.gen(c)):
813
+ res[A.gen(c) * A.gen(r)] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c]
814
+
815
+ self._relations = res
816
+ return self._relations
817
+
818
+ def ngens(self):
819
+ """
820
+ Return the number of variables in this noncommutative polynomial ring.
821
+
822
+ EXAMPLES::
823
+
824
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
825
+ sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
826
+ sage: P.ngens()
827
+ 3
828
+ """
829
+ return int(self._ngens)
830
+
831
+ def gen(self, int n=0):
832
+ """
833
+ Return the ``n``-th generator of this noncommutative polynomial
834
+ ring.
835
+
836
+ INPUT:
837
+
838
+ - ``n`` -- nonnegative integer
839
+
840
+ EXAMPLES::
841
+
842
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
843
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
844
+ sage: P.gen(),P.gen(1)
845
+ (x, y)
846
+
847
+ Note that the generators are not cached::
848
+
849
+ sage: P.gen(1) is P.gen(1)
850
+ False
851
+ """
852
+ cdef poly *_p
853
+ cdef ring *_ring = self._ring
854
+
855
+ if n < 0 or n >= self._ngens:
856
+ raise ValueError("Generator not defined.")
857
+
858
+ rChangeCurrRing(_ring)
859
+ _p = p_ISet(1,_ring)
860
+ p_SetExp(_p, n+1, 1, _ring)
861
+ p_Setm(_p, _ring)
862
+
863
+ return new_NCP(self,_p)
864
+
865
+ def algebra_generators(self):
866
+ r"""
867
+ Return the algebra generators of ``self``.
868
+
869
+ EXAMPLES::
870
+
871
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
872
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
873
+ sage: P.algebra_generators()
874
+ Finite family {'x': x, 'y': y, 'z': z}
875
+ """
876
+ from sage.sets.family import Family
877
+ return Family(self.gens_dict())
878
+
879
+ def ideal(self, *gens, **kwds):
880
+ """
881
+ Create an ideal in this polynomial ring.
882
+
883
+ INPUT:
884
+
885
+ - ``*gens`` -- list or tuple of generators (or several input arguments)
886
+ - ``coerce`` -- boolean (default: ``True``); this must be a
887
+ keyword argument. Only set it to ``False`` if you are certain
888
+ that each generator is already in the ring.
889
+ - ``side`` -- string (either "left", which is the default, or "twosided")
890
+ Must be a keyword argument. Defines whether the ideal is a left ideal
891
+ or a two-sided ideal. Right ideals are not implemented.
892
+
893
+ EXAMPLES::
894
+
895
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
896
+ sage: P.<x,y,z> = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
897
+
898
+ sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x])
899
+ Left Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
900
+ sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x], side='twosided')
901
+ Twosided Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
902
+ """
903
+ coerce = kwds.get('coerce', True)
904
+ if len(gens) == 1:
905
+ gens = gens[0]
906
+ # if is_SingularElement(gens):
907
+ # gens = list(gens)
908
+ # coerce = True
909
+ # elif is_Macaulay2Element(gens):
910
+ # gens = list(gens)
911
+ # coerce = True
912
+ if not isinstance(gens, (list, tuple)):
913
+ gens = [gens]
914
+ if coerce:
915
+ gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly!
916
+ return NCPolynomialIdeal(self, gens, coerce=False, side=kwds.get('side','left'))
917
+
918
+ def _list_to_ring(self, L):
919
+ """
920
+ Convert internal list representation to noncommutative ring.
921
+
922
+ EXAMPLES::
923
+
924
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
925
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
926
+ sage: rlist = P._ringlist()
927
+ sage: Q = P._list_to_ring(rlist)
928
+ sage: Q # indirect doctest
929
+ <noncommutative RingWrap>
930
+ """
931
+ cdef ring* _ring = self._ring
932
+ if _ring != currRing:
933
+ rChangeCurrRing(_ring)
934
+
935
+ from sage.libs.singular.function import singular_function
936
+ ring = singular_function('ring')
937
+ return ring(L, ring=self)
938
+
939
+ # TODO: Implement this properly!
940
+ # def quotient(self, I):
941
+ # """
942
+ # Construct quotient ring of ``self`` and the two-sided Groebner basis of `ideal`
943
+ #
944
+ # EXAMPLES::
945
+ #
946
+ # sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
947
+ # sage: H = A.g_algebra(relations={y*x:-x*y}, order='lex')
948
+ # sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd()
949
+ #
950
+ # sage: Q = H.quotient(I); Q
951
+ # Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
952
+ #
953
+ # TESTS:
954
+ #
955
+ # check coercion bug::
956
+ #
957
+ # sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
958
+ # sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
959
+ # sage: rlist = P._ringlist()
960
+ # sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
961
+ # sage: H = A.g_algebra(relations={y*x:-x*y}, order='lex')
962
+ # sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd()
963
+ # sage: Q = H.quotient(I); Q
964
+ # Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y}
965
+ # sage: Q.gen(0)^2
966
+ # 0
967
+ # sage: Q.gen(1) * Q.gen(0)
968
+ # -x*y
969
+ # """
970
+ # L = self._ringlist()
971
+ # L[3] = I.twostd()
972
+ # W = self._list_to_ring(L)
973
+ # return new_NRing(W, self.base_ring())
974
+
975
+ # The following methods are handy for implementing Groebner
976
+ # basis algorithms. They do only superficial type/sanity checks
977
+ # and should be called carefully.
978
+
979
+ def monomial_quotient(self, NCPolynomial_plural f, NCPolynomial_plural g, coeff=False):
980
+ r"""
981
+ Return ``f/g``, where both ``f`` and ``g`` are treated as
982
+ monomials.
983
+
984
+ Coefficients are ignored by default.
985
+
986
+ INPUT:
987
+
988
+ - ``f`` -- monomial
989
+ - ``g`` -- monomial
990
+ - ``coeff`` -- divide coefficients as well (default: ``False``)
991
+
992
+ EXAMPLES::
993
+
994
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
995
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
996
+ sage: P.inject_variables()
997
+ Defining x, y, z
998
+
999
+ sage: P.monomial_quotient(3/2*x*y,x,coeff=True)
1000
+ 3/2*y
1001
+
1002
+ Note that `\ZZ` behaves differently if ``coeff=True``::
1003
+
1004
+ sage: P.monomial_quotient(2*x,3*x)
1005
+ 1
1006
+ sage: P.monomial_quotient(2*x,3*x,coeff=True)
1007
+ 2/3
1008
+
1009
+ TESTS::
1010
+
1011
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1012
+ sage: R = A.g_algebra(relations={y*x:-x*y}, order='lex')
1013
+ sage: R.inject_variables()
1014
+ Defining x, y, z
1015
+
1016
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1017
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1018
+ sage: P.inject_variables()
1019
+ Defining x, y, z
1020
+
1021
+ sage: P.monomial_quotient(x*y,x)
1022
+ y
1023
+
1024
+ sage: P.monomial_quotient(x*y,R.gen()) # not tested
1025
+ y
1026
+
1027
+ sage: P.monomial_quotient(P(0),P(1))
1028
+ 0
1029
+
1030
+ sage: P.monomial_quotient(P(1),P(0))
1031
+ Traceback (most recent call last):
1032
+ ...
1033
+ ZeroDivisionError
1034
+
1035
+ sage: P.monomial_quotient(P(3/2),P(2/3), coeff=True)
1036
+ 9/4
1037
+
1038
+ sage: P.monomial_quotient(x,P(1))
1039
+ x
1040
+
1041
+ TESTS::
1042
+
1043
+ sage: P.monomial_quotient(x,y) # Note the wrong result
1044
+ x*y^...
1045
+
1046
+ .. WARNING::
1047
+
1048
+ Assumes that the head term of f is a multiple of the head
1049
+ term of g and return the multiplicant m. If this rule is
1050
+ violated, funny things may happen.
1051
+ """
1052
+ cdef poly *res
1053
+ cdef ring *r = self._ring
1054
+ cdef number *n
1055
+
1056
+ if self is not f._parent:
1057
+ f = self.coerce(f)
1058
+ if self is not g._parent:
1059
+ g = self.coerce(g)
1060
+
1061
+ if r != currRing:
1062
+ rChangeCurrRing(r)
1063
+
1064
+ if not f._poly:
1065
+ return self._zero_element
1066
+ if not g._poly:
1067
+ raise ZeroDivisionError
1068
+
1069
+ res = pMDivide(f._poly, g._poly)
1070
+ if coeff:
1071
+ if (r.cf.type == n_unknown) or r.cf.cfDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r), r.cf):
1072
+ n = r.cf.cfDiv(p_GetCoeff(f._poly, r),
1073
+ p_GetCoeff(g._poly, r), r.cf)
1074
+ p_SetCoeff0(res, n, r)
1075
+ else:
1076
+ raise ArithmeticError("Cannot divide these coefficients.")
1077
+ else:
1078
+ p_SetCoeff0(res, n_Init(1, r.cf), r)
1079
+ return new_NCP(self, res)
1080
+
1081
+ def monomial_divides(self, NCPolynomial_plural a, NCPolynomial_plural b):
1082
+ """
1083
+ Return ``False`` if ``a`` does not divide ``b`` and ``True``
1084
+ otherwise.
1085
+
1086
+ Coefficients are ignored.
1087
+
1088
+ INPUT:
1089
+
1090
+ - ``a`` -- monomial
1091
+
1092
+ - ``b`` -- monomial
1093
+
1094
+ EXAMPLES::
1095
+
1096
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1097
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1098
+ sage: P.inject_variables()
1099
+ Defining x, y, z
1100
+
1101
+ sage: P.monomial_divides(x*y*z, x^3*y^2*z^4)
1102
+ True
1103
+ sage: P.monomial_divides(x^3*y^2*z^4, x*y*z)
1104
+ False
1105
+
1106
+ TESTS::
1107
+
1108
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1109
+ sage: Q = A.g_algebra(relations={y*x:-x*y}, order='lex')
1110
+ sage: Q.inject_variables()
1111
+ Defining x, y, z
1112
+
1113
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1114
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1115
+ sage: P.inject_variables()
1116
+ Defining x, y, z
1117
+
1118
+ sage: P.monomial_divides(P(1), P(0))
1119
+ True
1120
+ sage: P.monomial_divides(P(1), x)
1121
+ True
1122
+ """
1123
+ cdef poly *_a
1124
+ cdef poly *_b
1125
+ cdef ring *_r
1126
+ if a._parent is not b._parent:
1127
+ b = (<NCPolynomialRing_plural>a._parent).coerce(b)
1128
+
1129
+ _a = a._poly
1130
+ _b = b._poly
1131
+ _r = (<NCPolynomialRing_plural>a._parent)._ring
1132
+
1133
+ if _a == NULL:
1134
+ raise ZeroDivisionError
1135
+ if _b == NULL:
1136
+ return True
1137
+
1138
+ if not p_DivisibleBy(_a, _b, _r):
1139
+ return False
1140
+ else:
1141
+ return True
1142
+
1143
+ def monomial_lcm(self, NCPolynomial_plural f, NCPolynomial_plural g):
1144
+ """
1145
+ LCM for monomials. Coefficients are ignored.
1146
+
1147
+ INPUT:
1148
+
1149
+ - ``f`` -- monomial
1150
+
1151
+ - ``g`` -- monomial
1152
+
1153
+ EXAMPLES::
1154
+
1155
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1156
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1157
+ sage: P.inject_variables()
1158
+ Defining x, y, z
1159
+
1160
+ sage: P.monomial_lcm(3/2*x*y,x)
1161
+ x*y
1162
+
1163
+ TESTS::
1164
+
1165
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1166
+ sage: R = A.g_algebra(relations={y*x:-x*y}, order='lex')
1167
+ sage: R.inject_variables()
1168
+ Defining x, y, z
1169
+
1170
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1171
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1172
+ sage: P.inject_variables()
1173
+ Defining x, y, z
1174
+
1175
+ sage: P.monomial_lcm(x*y,R.gen()) # not tested
1176
+ x*y
1177
+
1178
+ sage: P.monomial_lcm(P(3/2),P(2/3))
1179
+ 1
1180
+
1181
+ sage: P.monomial_lcm(x,P(1))
1182
+ x
1183
+ """
1184
+ cdef poly *m = p_ISet(1, self._ring)
1185
+
1186
+ if self is not f._parent:
1187
+ f = self.coerce(f)
1188
+ if self is not g._parent:
1189
+ g = self.coerce(g)
1190
+
1191
+ if f._poly == NULL:
1192
+ if g._poly == NULL:
1193
+ return self._zero_element
1194
+ else:
1195
+ raise ArithmeticError("Cannot compute LCM of zero and nonzero element.")
1196
+ if g._poly == NULL:
1197
+ raise ArithmeticError("Cannot compute LCM of zero and nonzero element.")
1198
+
1199
+ if self._ring != currRing:
1200
+ rChangeCurrRing(self._ring)
1201
+
1202
+ pLcm(f._poly, g._poly, m)
1203
+ p_Setm(m, self._ring)
1204
+ return new_NCP(self,m)
1205
+
1206
+ def monomial_reduce(self, NCPolynomial_plural f, G):
1207
+ """
1208
+ Try to find a ``g`` in ``G`` where ``g.lm()`` divides
1209
+ ``f``. If found ``(flt,g)`` is returned, ``(0,0)`` otherwise,
1210
+ where ``flt`` is ``f/g.lm()``.
1211
+
1212
+ It is assumed that ``G`` is iterable and contains *only*
1213
+ elements in this polynomial ring.
1214
+
1215
+ Coefficients are ignored.
1216
+
1217
+ INPUT:
1218
+
1219
+ - ``f`` -- monomial
1220
+ - ``G`` -- list/set of mpolynomials
1221
+
1222
+ EXAMPLES::
1223
+
1224
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1225
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1226
+ sage: P.inject_variables()
1227
+ Defining x, y, z
1228
+
1229
+ sage: f = x*y^2
1230
+ sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2 ]
1231
+ sage: P.monomial_reduce(f,G)
1232
+ (y, 1/4*x*y + 2/7)
1233
+
1234
+ TESTS::
1235
+
1236
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1237
+ sage: Q = A.g_algebra(relations={y*x:-x*y}, order='lex')
1238
+ sage: Q.inject_variables()
1239
+ Defining x, y, z
1240
+
1241
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1242
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1243
+ sage: P.inject_variables()
1244
+ Defining x, y, z
1245
+ sage: f = x*y^2
1246
+ sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2 ]
1247
+
1248
+ sage: P.monomial_reduce(P(0),G)
1249
+ (0, 0)
1250
+
1251
+ sage: P.monomial_reduce(f,[P(0)])
1252
+ (0, 0)
1253
+ """
1254
+ cdef poly *m = f._poly
1255
+ cdef ring *r = self._ring
1256
+ cdef poly *flt
1257
+
1258
+ if not m:
1259
+ return (f, f)
1260
+
1261
+ for g in G:
1262
+ if isinstance(g, NCPolynomial_plural) and g:
1263
+ h = <NCPolynomial_plural>g
1264
+ if p_LmDivisibleBy(h._poly, m, r):
1265
+ flt = pMDivide(f._poly, h._poly)
1266
+ p_SetCoeff(flt, n_Init(1, r.cf), r)
1267
+ return (new_NCP(self,flt), h)
1268
+ return (self._zero_element, self._zero_element)
1269
+
1270
+ def monomial_pairwise_prime(self, NCPolynomial_plural g, NCPolynomial_plural h):
1271
+ """
1272
+ Return ``True`` if ``h`` and ``g`` are pairwise prime.
1273
+
1274
+ Both ``h`` and ``g`` are treated as monomials.
1275
+
1276
+ Coefficients are ignored.
1277
+
1278
+ INPUT:
1279
+
1280
+ - ``h`` -- monomial
1281
+ - ``g`` -- monomial
1282
+
1283
+ EXAMPLES::
1284
+
1285
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1286
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1287
+ sage: P.inject_variables()
1288
+ Defining x, y, z
1289
+
1290
+ sage: P.monomial_pairwise_prime(x^2*z^3, y^4)
1291
+ True
1292
+
1293
+ sage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3)
1294
+ False
1295
+
1296
+ TESTS::
1297
+
1298
+ sage: A.<x1,y1,z1> = FreeAlgebra(QQ, 3)
1299
+ sage: Q = A.g_algebra(relations={y1*x1:-x1*y1}, order='lex')
1300
+ sage: Q.inject_variables()
1301
+ Defining x1, y1, z1
1302
+
1303
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1304
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1305
+ sage: P.inject_variables()
1306
+ Defining x, y, z
1307
+
1308
+ sage: P.monomial_pairwise_prime(x^2*z^3, x1^4) # not tested
1309
+ True
1310
+
1311
+ sage: P.monomial_pairwise_prime((2)*x^3*y^2, Q.zero()) # not tested
1312
+ True
1313
+
1314
+ sage: P.monomial_pairwise_prime(2*P.one(),x)
1315
+ False
1316
+ """
1317
+ cdef int i
1318
+ cdef ring *r
1319
+ cdef poly *p
1320
+ cdef poly *q
1321
+
1322
+ if h._parent is not g._parent:
1323
+ g = (<NCPolynomialRing_plural>h._parent).coerce(g)
1324
+
1325
+ r = (<NCPolynomialRing_plural>h._parent)._ring
1326
+ p = g._poly
1327
+ q = h._poly
1328
+
1329
+ if p == NULL:
1330
+ if q == NULL:
1331
+ return False # GCD(0,0) = 0
1332
+ else:
1333
+ return True # GCD(x,0) = 1
1334
+
1335
+ elif q == NULL:
1336
+ return True # GCD(0,x) = 1
1337
+
1338
+ elif p_IsConstant(p, r) or p_IsConstant(q, r): # assuming a base field
1339
+ return False
1340
+
1341
+ for i from 1 <= i <= r.N:
1342
+ if p_GetExp(p, i, r) and p_GetExp(q, i, r):
1343
+ return False
1344
+ return True
1345
+
1346
+ def monomial_all_divisors(self, NCPolynomial_plural t):
1347
+ """
1348
+ Return a list of all monomials that divide ``t``.
1349
+
1350
+ Coefficients are ignored.
1351
+
1352
+ INPUT:
1353
+
1354
+ - ``t`` -- a monomial
1355
+
1356
+ OUTPUT: list of monomials
1357
+
1358
+ EXAMPLES::
1359
+
1360
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1361
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1362
+ sage: P.inject_variables()
1363
+ Defining x, y, z
1364
+
1365
+ sage: P.monomial_all_divisors(x^2*z^3)
1366
+ [x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]
1367
+
1368
+ ALGORITHM: addwithcarry idea by Toon Segers
1369
+ """
1370
+
1371
+ M = list()
1372
+
1373
+ cdef ring *_ring = self._ring
1374
+ cdef poly *maxvector = t._poly
1375
+ cdef poly *tempvector = p_ISet(1, _ring)
1376
+
1377
+ pos = 1
1378
+
1379
+ while not p_ExpVectorEqual(tempvector, maxvector, _ring):
1380
+ tempvector = addwithcarry(tempvector, maxvector, pos, _ring)
1381
+ M.append(new_NCP(self, p_Copy(tempvector,_ring)))
1382
+ return M
1383
+
1384
+
1385
+ def unpickle_NCPolynomial_plural(NCPolynomialRing_plural R, d):
1386
+ """
1387
+ Auxiliary function to unpickle a non-commutative polynomial.
1388
+
1389
+ TESTS::
1390
+
1391
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1392
+ sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
1393
+ sage: p = x*y+2*z+4*x*y*z*x
1394
+ sage: loads(dumps(p)) == p # indirect doctest
1395
+ True
1396
+ """
1397
+ cdef ring *r = R._ring
1398
+ cdef poly *m
1399
+ cdef poly *p
1400
+ cdef int _i, _e
1401
+ p = p_ISet(0,r)
1402
+ rChangeCurrRing(r)
1403
+ for mon, c in d.items():
1404
+ m = p_Init(r)
1405
+ for i,e in mon.sparse_iter():
1406
+ _i = i
1407
+ if _i >= r.N:
1408
+ p_Delete(&p,r)
1409
+ p_Delete(&m,r)
1410
+ raise TypeError("variable index too big")
1411
+ _e = e
1412
+ if _e <= 0:
1413
+ p_Delete(&p,r)
1414
+ p_Delete(&m,r)
1415
+ raise TypeError("exponent too small")
1416
+ overflow_check(_e, r)
1417
+ p_SetExp(m, _i+1,_e, r)
1418
+ p_SetCoeff(m, sa2si(c, r), r)
1419
+ p_Setm(m,r)
1420
+ p = p_Add_q(p,m,r)
1421
+ return new_NCP(R,p)
1422
+
1423
+
1424
+ cdef class NCPolynomial_plural(RingElement):
1425
+ """
1426
+ A noncommutative multivariate polynomial implemented using libSINGULAR.
1427
+ """
1428
+ def __init__(self, NCPolynomialRing_plural parent):
1429
+ """
1430
+ Construct a zero element in parent.
1431
+
1432
+ EXAMPLES::
1433
+
1434
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1435
+ sage: H = A.g_algebra(relations={y*x:-x*y}, order='lex')
1436
+ sage: from sage.rings.polynomial.plural import NCPolynomial_plural
1437
+ sage: NCPolynomial_plural(H)
1438
+ 0
1439
+ """
1440
+ self._poly = NULL
1441
+ self._parent = parent
1442
+
1443
+ def __dealloc__(self):
1444
+ # TODO: Warn otherwise!
1445
+ # for some mysterious reason, various things may be NULL in some cases
1446
+ if self._parent is not None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL:
1447
+ p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring)
1448
+
1449
+ def __reduce__(self):
1450
+ """
1451
+ TESTS::
1452
+
1453
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1454
+ sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
1455
+ sage: loads(dumps(x*y+2*z+4*x*y*z*x))
1456
+ 4*x^2*y*z + 8*x^2*y - 4*x*z^2 + x*y - 8*x*z + 2*z
1457
+ """
1458
+ return unpickle_NCPolynomial_plural, (self._parent, self.dict())
1459
+
1460
+ def __hash__(self):
1461
+ """
1462
+ This hash incorporates the variable name in an effort to
1463
+ respect the obvious inclusions into multi-variable polynomial
1464
+ rings.
1465
+
1466
+ The tuple algorithm is borrowed from http://effbot.org/zone/python-hash.htm.
1467
+
1468
+ EXAMPLES::
1469
+
1470
+ sage: R.<x>=QQ[]
1471
+ sage: S.<x,y>=QQ[]
1472
+ sage: hash(S(1/2))==hash(1/2) # respect inclusions of the rationals
1473
+ True
1474
+ sage: hash(S.0)==hash(R.0) # respect inclusions into mpoly rings
1475
+ True
1476
+ sage: # the point is to make for more flexible dictionary look ups
1477
+ sage: d={S.0:12}
1478
+ sage: d[R.0]
1479
+ 12
1480
+ """
1481
+ return self._hash_c()
1482
+
1483
+ cpdef _richcmp_(left, right, int op):
1484
+ """
1485
+ Compare left and right.
1486
+
1487
+ EXAMPLES::
1488
+
1489
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1490
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1491
+ sage: P.inject_variables()
1492
+ Defining x, z, y
1493
+
1494
+ sage: x == x
1495
+ True
1496
+
1497
+ sage: x > y
1498
+ True
1499
+ sage: y^2 > x
1500
+ False
1501
+
1502
+ TESTS::
1503
+
1504
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1505
+ sage: P = A.g_algebra(relations={y*x:-x*y}, order='lex')
1506
+ sage: P.inject_variables()
1507
+ Defining x, z, y
1508
+
1509
+ sage: x > P(0)
1510
+ True
1511
+
1512
+ sage: P(0) == P(0)
1513
+ True
1514
+
1515
+ sage: P(0) < P(1)
1516
+ True
1517
+
1518
+ sage: x > P(1)
1519
+ True
1520
+
1521
+ sage: 1/2*x < 3/4*x
1522
+ True
1523
+
1524
+ sage: (x+1) > x
1525
+ True
1526
+ """
1527
+ if left is right:
1528
+ return rich_to_bool(op, 0)
1529
+ cdef poly *p = (<NCPolynomial_plural>left)._poly
1530
+ cdef poly *q = (<NCPolynomial_plural>right)._poly
1531
+ cdef ring *r = (<NCPolynomialRing_plural>left._parent)._ring
1532
+ return rich_to_bool(op, singular_polynomial_cmp(p, q, r))
1533
+
1534
+ cpdef _add_(left, right):
1535
+ """
1536
+ Add ``left`` and ``right``.
1537
+
1538
+ EXAMPLES::
1539
+
1540
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1541
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1542
+ sage: P.inject_variables()
1543
+ Defining x, z, y
1544
+ sage: 3/2*x + 1/2*y + 1 # indirect doctest
1545
+ 3/2*x + 1/2*y + 1
1546
+ """
1547
+ cdef poly *_p
1548
+ singular_polynomial_add(&_p, left._poly,
1549
+ (<NCPolynomial_plural>right)._poly,
1550
+ (<NCPolynomialRing_plural>left._parent)._ring)
1551
+ return new_NCP((<NCPolynomialRing_plural>left._parent), _p)
1552
+
1553
+ cpdef _sub_(left, right):
1554
+ """
1555
+ Subtract left and right.
1556
+
1557
+ EXAMPLES::
1558
+
1559
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1560
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1561
+ sage: P.inject_variables()
1562
+ Defining x, z, y
1563
+ sage: 3/2*x - 1/2*y - 1 # indirect doctest
1564
+ 3/2*x - 1/2*y - 1
1565
+ """
1566
+ cdef ring *_ring = (<NCPolynomialRing_plural>left._parent)._ring
1567
+
1568
+ cdef poly *_p
1569
+ singular_polynomial_sub(&_p, left._poly,
1570
+ (<NCPolynomial_plural>right)._poly,
1571
+ _ring)
1572
+ return new_NCP((<NCPolynomialRing_plural>left._parent), _p)
1573
+
1574
+ cpdef _lmul_(self, Element left):
1575
+ """
1576
+ Multiply ``self`` with a base ring element.
1577
+
1578
+ EXAMPLES::
1579
+
1580
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1581
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1582
+ sage: P.inject_variables()
1583
+ Defining x, z, y
1584
+ sage: 3/2*x # indirect doctest
1585
+ 3/2*x
1586
+
1587
+ ::
1588
+
1589
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1590
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1591
+ sage: P.inject_variables()
1592
+ Defining x, z, y
1593
+ sage: x* (2/3) # indirect doctest
1594
+ 2/3*x
1595
+ """
1596
+
1597
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
1598
+ if not left:
1599
+ return (<NCPolynomialRing_plural>self._parent)._zero_element
1600
+ cdef poly *_p
1601
+ singular_polynomial_rmul(&_p, self._poly, left, _ring)
1602
+ return new_NCP((<NCPolynomialRing_plural>self._parent),_p)
1603
+
1604
+ cpdef _mul_(left, right):
1605
+ """
1606
+ Multiply left and right.
1607
+
1608
+ EXAMPLES::
1609
+
1610
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1611
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1612
+ sage: P.inject_variables()
1613
+ Defining x, z, y
1614
+ sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest
1615
+ 9/4*x^2 + 3/2*x*y - 3/4*z - 1/4*y^2 - y - 1
1616
+
1617
+ TESTS::
1618
+
1619
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1620
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1621
+ sage: P.inject_variables()
1622
+ Defining x, z, y
1623
+ sage: (x^2^31) * x^2^31
1624
+ Traceback (most recent call last):
1625
+ ...
1626
+ OverflowError: exponent overflow (2147483648)
1627
+ """
1628
+ # all currently implemented rings are commutative
1629
+ cdef poly *_p
1630
+ singular_polynomial_mul(&_p, left._poly,
1631
+ (<NCPolynomial_plural>right)._poly,
1632
+ (<NCPolynomialRing_plural>left._parent)._ring)
1633
+ return new_NCP((<NCPolynomialRing_plural>left._parent),_p)
1634
+
1635
+ cpdef _div_(left, right):
1636
+ """
1637
+ Divide ``left`` by ``right``.
1638
+
1639
+ EXAMPLES::
1640
+
1641
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1642
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1643
+ sage: R.inject_variables()
1644
+ Defining x, z, y
1645
+ sage: f = (x + y)/3 # indirect doctest
1646
+ sage: f.parent()
1647
+ Noncommutative Multivariate Polynomial Ring in x, z, y over Rational Field, nc-relations: {y*x: -x*y + z}
1648
+
1649
+ TESTS::
1650
+
1651
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1652
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1653
+ sage: R.inject_variables()
1654
+ Defining x, z, y
1655
+ sage: x/0
1656
+ Traceback (most recent call last):
1657
+ ...
1658
+ ZeroDivisionError: rational division by zero
1659
+ """
1660
+ cdef poly *p
1661
+ cdef bint is_field = left._parent._base.is_field()
1662
+ if p_IsConstant((<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring):
1663
+ if is_field:
1664
+ singular_polynomial_div_coeff(&p, left._poly, (<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring)
1665
+ return new_NCP(left._parent, p)
1666
+ else:
1667
+ return left.change_ring(left.base_ring().fraction_field())/right
1668
+ else:
1669
+ return (<NCPolynomialRing_plural>left._parent).fraction_field()(left,right)
1670
+
1671
+ def __pow__(NCPolynomial_plural self, exp, mod):
1672
+ """
1673
+ Return ``self**(exp)``.
1674
+
1675
+ The exponent must be an integer.
1676
+
1677
+ EXAMPLES::
1678
+
1679
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1680
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1681
+ sage: R.inject_variables()
1682
+ Defining x, z, y
1683
+ sage: f = x^3 + y
1684
+ sage: f^2
1685
+ x^6 + x^2*z + y^2
1686
+
1687
+ TESTS::
1688
+
1689
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1690
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1691
+ sage: P.inject_variables()
1692
+ Defining x, z, y
1693
+ sage: (x+y^2^31)^10
1694
+ Traceback (most recent call last):
1695
+ ....
1696
+ OverflowError: exponent overflow (2147483648)
1697
+
1698
+ Check that using third argument raises an error::
1699
+
1700
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1701
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1702
+ sage: P.inject_variables()
1703
+ Defining x, z, y
1704
+ sage: pow(x + y + z, 2, x)
1705
+ Traceback (most recent call last):
1706
+ ...
1707
+ NotImplementedError: pow() with a modulus is not implemented for this ring
1708
+ """
1709
+ if mod is not None:
1710
+ raise NotImplementedError(
1711
+ "pow() with a modulus is not implemented for this ring"
1712
+ )
1713
+ if type(exp) is not Integer:
1714
+ try:
1715
+ exp = Integer(exp)
1716
+ except TypeError:
1717
+ raise TypeError("non-integral exponents not supported")
1718
+
1719
+ if exp < 0:
1720
+ return 1/(self**(-exp))
1721
+ elif exp == 0:
1722
+ return (<NCPolynomialRing_plural>self._parent)._one_element
1723
+
1724
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
1725
+ cdef poly *_p
1726
+ singular_polynomial_pow(&_p, self._poly, exp, _ring)
1727
+ return new_NCP((<NCPolynomialRing_plural>self._parent),_p)
1728
+
1729
+ def __neg__(self):
1730
+ """
1731
+ Return ``-self``.
1732
+
1733
+ EXAMPLES::
1734
+
1735
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1736
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1737
+ sage: R.inject_variables()
1738
+ Defining x, z, y
1739
+ sage: f = x^3 + y
1740
+ sage: -f
1741
+ -x^3 - y
1742
+ """
1743
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
1744
+
1745
+ cdef poly *p
1746
+ singular_polynomial_neg(&p, self._poly, _ring)
1747
+ return new_NCP((<NCPolynomialRing_plural>self._parent), p)
1748
+
1749
+ def reduce(self, I):
1750
+ """
1751
+
1752
+ EXAMPLES::
1753
+
1754
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
1755
+ sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
1756
+ sage: I = H.ideal([y^2, x^2, z^2-H.one()],coerce=False)
1757
+
1758
+ The result of reduction is not the normal form, if one reduces
1759
+ by a list of polynomials::
1760
+
1761
+ sage: (x*z).reduce(I.gens())
1762
+ x*z
1763
+
1764
+ However, if the argument is an ideal, then a normal form (reduction
1765
+ with respect to a two-sided Groebner basis) is returned::
1766
+
1767
+ sage: (x*z).reduce(I)
1768
+ -x
1769
+
1770
+ The Groebner basis shows that the result is correct::
1771
+
1772
+ sage: I.std() #random
1773
+ Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
1774
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Rational
1775
+ Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
1776
+ sage: sorted(I.std().gens(),key=str)
1777
+ [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]
1778
+ """
1779
+ cdef ideal *_I
1780
+ cdef NCPolynomialRing_plural parent = <NCPolynomialRing_plural>self._parent
1781
+ cdef int i = 0
1782
+ cdef ring *r = parent._ring
1783
+ cdef poly *res
1784
+
1785
+ if r != currRing:
1786
+ rChangeCurrRing(r)
1787
+
1788
+ if isinstance(I, NCPolynomialIdeal):
1789
+ try:
1790
+ strat = I._groebner_strategy()
1791
+ return strat.normal_form(self)
1792
+ except (TypeError, NotImplementedError) as msg:
1793
+ pass
1794
+ I = I.gens()
1795
+
1796
+ _I = idInit(len(I),1)
1797
+ for f in I:
1798
+ if not (isinstance(f, NCPolynomial_plural)
1799
+ and <NCPolynomialRing_plural>(<NCPolynomial_plural>f)._parent is parent):
1800
+ try:
1801
+ f = parent.coerce(f)
1802
+ except TypeError as msg:
1803
+ id_Delete(&_I,r)
1804
+ raise TypeError(msg)
1805
+
1806
+ _I.m[i] = p_Copy((<NCPolynomial_plural>f)._poly, r)
1807
+ i+=1
1808
+
1809
+ # the second parameter would be qring!
1810
+ res = kNF(_I, NULL, self._poly)
1811
+ id_Delete(&_I, r)
1812
+ return new_NCP(parent,res)
1813
+
1814
+ def _repr_(self):
1815
+ """
1816
+ EXAMPLES::
1817
+
1818
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1819
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1820
+ sage: R.inject_variables()
1821
+ Defining x, z, y
1822
+ sage: f = x^3 + y*x*z + z
1823
+ sage: f # indirect doctest
1824
+ x^3 - x*z*y + z^2 + z
1825
+ """
1826
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
1827
+ s = singular_polynomial_str(self._poly, _ring)
1828
+ return s
1829
+
1830
+ cpdef _repr_short_(self):
1831
+ """
1832
+ This is a faster but less pretty way to print polynomials. If
1833
+ available it uses the short SINGULAR notation.
1834
+
1835
+ EXAMPLES::
1836
+
1837
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1838
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1839
+ sage: R.inject_variables()
1840
+ Defining x, z, y
1841
+ sage: f = x^3 + y
1842
+ sage: f._repr_short_()
1843
+ 'x3+y'
1844
+ """
1845
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
1846
+ rChangeCurrRing(_ring)
1847
+ if _ring.CanShortOut:
1848
+ _ring.ShortOut = 1
1849
+ s = char_to_str(p_String(self._poly, _ring, _ring))
1850
+ _ring.ShortOut = 0
1851
+ else:
1852
+ s = char_to_str(p_String(self._poly, _ring, _ring))
1853
+ return s
1854
+
1855
+ def _latex_(self):
1856
+ r"""
1857
+ Return a polynomial LaTeX representation of this polynomial.
1858
+
1859
+ EXAMPLES::
1860
+
1861
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1862
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1863
+ sage: R.inject_variables()
1864
+ Defining x, z, y
1865
+ sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
1866
+ sage: latex(f) # indirect doctest
1867
+ -x^{2} y - z^{2} - \frac{25}{27} y^{3}
1868
+ """
1869
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
1870
+ gens = self.parent().latex_variable_names()
1871
+ base = self.parent().base()
1872
+ return singular_polynomial_latex(self._poly, _ring, base, gens)
1873
+
1874
+ def _repr_with_changed_varnames(self, varnames):
1875
+ """
1876
+ Return string representing this polynomial but change the
1877
+ variable names to ``varnames``.
1878
+
1879
+ EXAMPLES::
1880
+
1881
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1882
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1883
+ sage: R.inject_variables()
1884
+ Defining x, z, y
1885
+ sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
1886
+ sage: print(f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR']))
1887
+ -FOO^2*FOOBAR - BAR^2 - 25/27*FOOBAR^3
1888
+ """
1889
+ return singular_polynomial_str_with_changed_varnames(self._poly, (<NCPolynomialRing_plural>self._parent)._ring, varnames)
1890
+
1891
+ def degree(self, NCPolynomial_plural x=None):
1892
+ """
1893
+ Return the maximal degree of this polynomial in ``x``, where
1894
+ ``x`` must be one of the generators for the parent of this
1895
+ polynomial.
1896
+
1897
+ INPUT:
1898
+
1899
+ - ``x`` -- multivariate polynomial (a generator of the parent of
1900
+ self) If x is not specified (or is ``None``), return the total
1901
+ degree, which is the maximum degree of any monomial.
1902
+
1903
+ OUTPUT: integer
1904
+
1905
+ EXAMPLES::
1906
+
1907
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1908
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1909
+ sage: R.inject_variables()
1910
+ Defining x, z, y
1911
+ sage: f = y^2 - x^9 - x
1912
+ sage: f.degree(x)
1913
+ 9
1914
+ sage: f.degree(y)
1915
+ 2
1916
+ sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x)
1917
+ 3
1918
+ sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y)
1919
+ 10
1920
+
1921
+ TESTS::
1922
+
1923
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1924
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1925
+ sage: P.inject_variables()
1926
+ Defining x, z, y
1927
+ sage: P(0).degree(x)
1928
+ -1
1929
+ sage: P(1).degree(x)
1930
+ 0
1931
+ """
1932
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
1933
+ cdef poly *p = self._poly
1934
+ if not x:
1935
+ return singular_polynomial_deg(p,NULL,r)
1936
+
1937
+ # TODO: we can do this faster
1938
+ if x not in self._parent.gens():
1939
+ raise TypeError("x must be one of the generators of the parent.")
1940
+
1941
+ return singular_polynomial_deg(p, (<NCPolynomial_plural>x)._poly, r)
1942
+
1943
+ def total_degree(self):
1944
+ """
1945
+ Return the total degree of ``self``, which is the maximum degree
1946
+ of all monomials in ``self``.
1947
+
1948
+ EXAMPLES::
1949
+
1950
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1951
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1952
+ sage: R.inject_variables()
1953
+ Defining x, z, y
1954
+ sage: f=2*x*y^3*z^2
1955
+ sage: f.total_degree()
1956
+ 6
1957
+ sage: f=4*x^2*y^2*z^3
1958
+ sage: f.total_degree()
1959
+ 7
1960
+ sage: f=99*x^6*y^3*z^9
1961
+ sage: f.total_degree()
1962
+ 18
1963
+ sage: f=x*y^3*z^6+3*x^2
1964
+ sage: f.total_degree()
1965
+ 10
1966
+ sage: f=z^3+8*x^4*y^5*z
1967
+ sage: f.total_degree()
1968
+ 10
1969
+ sage: f=z^9+10*x^4+y^8*x^2
1970
+ sage: f.total_degree()
1971
+ 10
1972
+
1973
+ TESTS::
1974
+
1975
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
1976
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
1977
+ sage: R.inject_variables()
1978
+ Defining x, z, y
1979
+ sage: R(0).total_degree()
1980
+ -1
1981
+ sage: R(1).total_degree()
1982
+ 0
1983
+ """
1984
+ cdef poly *p = self._poly
1985
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
1986
+ return singular_polynomial_deg(p,NULL,r)
1987
+
1988
+ def degrees(self):
1989
+ """
1990
+ Return a tuple with the maximal degree of each variable in
1991
+ this polynomial.
1992
+
1993
+ The list of degrees is ordered by the order
1994
+ of the generators.
1995
+
1996
+ EXAMPLES::
1997
+
1998
+ sage: A.<y0,y1,y2> = FreeAlgebra(QQ, 3)
1999
+ sage: R = A.g_algebra(relations={y1*y0:-y0*y1 + y2}, order='lex')
2000
+ sage: R.inject_variables()
2001
+ Defining y0, y1, y2
2002
+ sage: q = 3*y0*y1*y1*y2; q
2003
+ 3*y0*y1^2*y2
2004
+ sage: q.degrees()
2005
+ (1, 2, 1)
2006
+ sage: (q + y0^5).degrees()
2007
+ (5, 2, 1)
2008
+ """
2009
+ cdef poly *p = self._poly
2010
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
2011
+ cdef int i
2012
+ cdef list d = [0 for _ in range(r.N)]
2013
+ while p:
2014
+ for i from 0 <= i < r.N:
2015
+ d[i] = max(d[i],p_GetExp(p, i+1, r))
2016
+ p = pNext(p)
2017
+ return tuple(d)
2018
+
2019
+ def coefficient(self, degrees):
2020
+ """
2021
+ Return the coefficient of the variables with the degrees
2022
+ specified in the python dictionary ``degrees``.
2023
+
2024
+ Mathematically, this is the coefficient in the base ring
2025
+ adjoined by the variables of this ring not listed in
2026
+ ``degrees``. However, the result has the same parent as this
2027
+ polynomial.
2028
+
2029
+ This function contrasts with the function
2030
+ :meth:`monomial_coefficient` which returns the coefficient in the
2031
+ base ring of a monomial.
2032
+
2033
+ INPUT:
2034
+
2035
+ - ``degrees`` -- can be any of:
2036
+ - a dictionary of degree restrictions
2037
+ - a list of degree restrictions (with ``None`` in the unrestricted variables)
2038
+ - a monomial (very fast, but not as flexible)
2039
+
2040
+ OUTPUT: element of the parent of this element
2041
+
2042
+ .. NOTE::
2043
+
2044
+ For coefficients of specific monomials, look at :meth:`monomial_coefficient`.
2045
+
2046
+ EXAMPLES::
2047
+
2048
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
2049
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2050
+ sage: R.inject_variables()
2051
+ Defining x, z, y
2052
+ sage: f=x*y+y+5
2053
+ sage: f.coefficient({x:0,y:1})
2054
+ 1
2055
+ sage: f.coefficient({x:0})
2056
+ y + 5
2057
+ sage: f=(1+y+y^2)*(1+x+x^2)
2058
+ sage: f.coefficient({x:0})
2059
+ z + y^2 + y + 1
2060
+
2061
+ sage: f.coefficient(x)
2062
+ y^2 - y + 1
2063
+
2064
+ sage: f.coefficient([0,None]) # not tested
2065
+ y^2 + y + 1
2066
+
2067
+ Be aware that this may not be what you think! The physical
2068
+ appearance of the variable x is deceiving -- particularly if
2069
+ the exponent would be a variable. ::
2070
+
2071
+ sage: f.coefficient(x^0) # outputs the full polynomial
2072
+ x^2*y^2 + x^2*y + x^2 + x*y^2 - x*y + x + z + y^2 + y + 1
2073
+
2074
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2075
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2076
+ sage: R.inject_variables()
2077
+ Defining x, z, y
2078
+ sage: f=x*y+5
2079
+ sage: c=f.coefficient({x:0,y:0}); c
2080
+ 5
2081
+ sage: parent(c)
2082
+ Noncommutative Multivariate Polynomial Ring in x, z, y over Finite Field of size 389, nc-relations: {y*x: -x*y + z}
2083
+
2084
+ AUTHOR:
2085
+
2086
+ - Joel B. Mohler (2007-10-31)
2087
+ """
2088
+ cdef poly *_degrees = <poly*>0
2089
+ cdef poly *p = self._poly
2090
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
2091
+ cdef poly *newp = p_ISet(0, r)
2092
+ cdef poly *newptemp
2093
+ cdef int i
2094
+ cdef int flag
2095
+ cdef int gens = self._parent.ngens()
2096
+ cdef int *exps = <int*>sig_malloc(sizeof(int)*gens)
2097
+ for i from 0<=i<gens:
2098
+ exps[i] = -1
2099
+
2100
+ if isinstance(degrees, NCPolynomial_plural) and self._parent is (<NCPolynomial_plural>degrees)._parent:
2101
+ _degrees = (<NCPolynomial_plural>degrees)._poly
2102
+ if pLength(_degrees) != 1:
2103
+ raise TypeError("degrees must be a monomial")
2104
+ for i from 0<=i<gens:
2105
+ if p_GetExp(_degrees,i+1,r)!=0:
2106
+ exps[i] = p_GetExp(_degrees,i+1,r)
2107
+ elif type(degrees) is list:
2108
+ for i from 0<=i<gens:
2109
+ if degrees[i] is None:
2110
+ exps[i] = -1
2111
+ else:
2112
+ exps[i] = int(degrees[i])
2113
+ elif type(degrees) is dict:
2114
+ # Extract the ordered list of degree specifications from the dictionary
2115
+ poly_vars = self.parent().gens()
2116
+ for i from 0<=i<gens:
2117
+ try:
2118
+ exps[i] = degrees[poly_vars[i]]
2119
+ except KeyError:
2120
+ pass
2121
+ else:
2122
+ raise TypeError("The input degrees must be a dictionary of variables to exponents.")
2123
+
2124
+ # Extract the monomials that match the specifications
2125
+ while p:
2126
+ flag = 0
2127
+ for i from 0<=i<gens:
2128
+ if exps[i] != -1 and p_GetExp(p,i+1,r)!=exps[i]:
2129
+ flag = 1
2130
+ if flag == 0:
2131
+ newptemp = p_LmInit(p,r)
2132
+ p_SetCoeff(newptemp,n_Copy(p_GetCoeff(p,r),r.cf),r)
2133
+ for i from 0<=i<gens:
2134
+ if exps[i] != -1:
2135
+ p_SetExp(newptemp,i+1,0,r)
2136
+ p_Setm(newptemp,r)
2137
+ newp = p_Add_q(newp,newptemp,r)
2138
+ p = pNext(p)
2139
+
2140
+ sig_free(exps)
2141
+
2142
+ return new_NCP(self.parent(),newp)
2143
+
2144
+ def monomial_coefficient(self, NCPolynomial_plural mon):
2145
+ """
2146
+ Return the coefficient in the base ring of the monomial ``mon`` in
2147
+ ``self``, where ``mon`` must have the same parent as ``self``.
2148
+
2149
+ This function contrasts with the function :meth:`coefficient`
2150
+ which returns the coefficient of a monomial viewing this
2151
+ polynomial in a polynomial ring over a base ring having fewer
2152
+ variables.
2153
+
2154
+ INPUT:
2155
+
2156
+ - ``mon`` -- a monomial
2157
+
2158
+ OUTPUT: coefficient in base ring
2159
+
2160
+ .. SEEALSO::
2161
+
2162
+ For coefficients in a base ring of fewer variables, look at :meth:`coefficient`
2163
+
2164
+ EXAMPLES::
2165
+
2166
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2167
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2168
+ sage: P.inject_variables()
2169
+ Defining x, z, y
2170
+
2171
+ The parent of the return is a member of the base ring.
2172
+ sage: f = 2 * x * y
2173
+ sage: c = f.monomial_coefficient(x*y); c
2174
+ 2
2175
+ sage: c.parent()
2176
+ Finite Field of size 389
2177
+
2178
+ sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y
2179
+ sage: f.monomial_coefficient(y^2)
2180
+ 1
2181
+ sage: f.monomial_coefficient(x*y)
2182
+ 5
2183
+ sage: f.monomial_coefficient(x^9)
2184
+ 388
2185
+ sage: f.monomial_coefficient(x^10)
2186
+ 0
2187
+ """
2188
+ cdef poly *p = self._poly
2189
+ cdef poly *m = mon._poly
2190
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
2191
+
2192
+ if mon._parent is not self._parent:
2193
+ raise TypeError("mon must have same parent as self")
2194
+
2195
+ while p:
2196
+ if p_ExpVectorEqual(p, m, r) == 1:
2197
+ return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base)
2198
+ p = pNext(p)
2199
+
2200
+ return (<NCPolynomialRing_plural>self._parent)._base._zero_element
2201
+
2202
+ cpdef dict dict(self):
2203
+ """
2204
+ Return a dictionary representing ``self``. This dictionary is in
2205
+ the same format as the generic MPolynomial: The dictionary
2206
+ consists of ``ETuple:coefficient`` pairs.
2207
+
2208
+ EXAMPLES::
2209
+
2210
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2211
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2212
+ sage: R.inject_variables()
2213
+ Defining x, z, y
2214
+
2215
+ sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3))
2216
+ sage: f.dict()
2217
+ {(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
2218
+
2219
+ sage: f.monomial_coefficients()
2220
+ {(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
2221
+ """
2222
+ cdef poly *p
2223
+ cdef ring *r
2224
+ cdef int n
2225
+ cdef int v
2226
+ r = (<NCPolynomialRing_plural>self._parent)._ring
2227
+ if r != currRing:
2228
+ rChangeCurrRing(r)
2229
+ base = (<NCPolynomialRing_plural>self._parent)._base
2230
+ p = self._poly
2231
+ cdef dict d
2232
+ cdef dict pd = dict()
2233
+ while p:
2234
+ d = dict()
2235
+ for v from 1 <= v <= r.N:
2236
+ n = p_GetExp(p, v, r)
2237
+ if n != 0:
2238
+ d[v-1] = n
2239
+
2240
+ pd[ETuple(d, r.N)] = si2sa(p_GetCoeff(p, r), r, base)
2241
+
2242
+ p = pNext(p)
2243
+ return pd
2244
+
2245
+ cpdef dict monomial_coefficients(self, bint copy=True):
2246
+ """
2247
+ Return a dictionary representation of ``self`` with the keys
2248
+ the exponent vectors and the values the corresponding coefficients.
2249
+
2250
+ INPUT:
2251
+
2252
+ - ``copy`` -- ignored
2253
+
2254
+ EXAMPLES::
2255
+
2256
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2257
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2258
+ sage: R.inject_variables()
2259
+ Defining x, z, y
2260
+ sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3))
2261
+ sage: d = f.monomial_coefficients(False); d
2262
+ {(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
2263
+ sage: d.clear()
2264
+ sage: f.monomial_coefficients()
2265
+ {(0, 0, 0): 3, (1, 2, 3): 2, (2, 0, 0): 7}
2266
+ """
2267
+ return self.dict()
2268
+
2269
+ def _im_gens_(self, codomain, im_gens, base_map=None):
2270
+ """
2271
+ Return the image of ``self`` in codomain under the map that sends
2272
+ the images of the generators of the parent of ``self`` to the
2273
+ tuple of elements of im_gens.
2274
+
2275
+ INPUT:
2276
+
2277
+ - ``codomain`` -- the parent where the images live
2278
+
2279
+ - ``im_gens`` -- list or tuple with the images of the generators of this ring
2280
+
2281
+ EXAMPLES::
2282
+
2283
+ sage: A.<x,z,y> = FreeAlgebra(GF(9), 3)
2284
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2285
+ sage: R.inject_variables()
2286
+ Defining x, z, y
2287
+ sage: B.<a,b,c> = FreeAlgebra(GF(9), 3)
2288
+ sage: S = B.g_algebra({b*a:2*a*b, c*a:-2*a*c})
2289
+ sage: S.inject_variables()
2290
+ Defining a, b, c
2291
+ sage: (x*y - x^2*z)._im_gens_(S, [a*b, b, a*b*c])
2292
+ a^2*b^3 - a^2*b^2*c
2293
+ sage: -(a*b)*(a*b)*b+(a*b)*(a*b*c)
2294
+ a^2*b^3 - a^2*b^2*c
2295
+
2296
+ sage: z2 = GF(9).gen()
2297
+ sage: phi = R.hom([a*b, b, a*b*c], check=False)
2298
+ sage: phi(x*y - x^2*z)
2299
+ a^2*b^3 - a^2*b^2*c
2300
+ sage: phi(x*y - z2*x^2*z)
2301
+ z2*a^2*b^3 - a^2*b^2*c
2302
+ sage: phi = R.hom([a*b, b, a*b*c], base_map=GF(9).frobenius_endomorphism(), check=False)
2303
+ sage: phi(x*y - x^2*z)
2304
+ a^2*b^3 - a^2*b^2*c
2305
+ sage: phi(x*y - z2*x^2*z)
2306
+ (-z2 + 1)*a^2*b^3 - a^2*b^2*c
2307
+ sage: z2^3
2308
+ 2*z2 + 1
2309
+ """
2310
+ if self.is_zero():
2311
+ return codomain.zero()
2312
+ from sage.misc.misc_c import prod
2313
+ d = self.dict()
2314
+ if base_map is None:
2315
+ base_map = codomain
2316
+ return sum(prod(im_gens[i]**val for i, val in enumerate(t))*base_map(d[t]) for t in d)
2317
+
2318
+ cdef long _hash_c(self) noexcept:
2319
+ """
2320
+ See :meth:`__hash__`
2321
+ """
2322
+ cdef poly *p
2323
+ cdef ring *r
2324
+ cdef int n
2325
+ cdef int v
2326
+ r = (<NCPolynomialRing_plural>self._parent)._ring
2327
+ if r != currRing:
2328
+ rChangeCurrRing(r)
2329
+ base = (<NCPolynomialRing_plural>self._parent)._base
2330
+ p = self._poly
2331
+ cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap
2332
+ cdef long result_mon
2333
+ var_name_hash = [hash(vn) for vn in self._parent.variable_names()]
2334
+ cdef long c_hash
2335
+ while p:
2336
+ c_hash = hash(si2sa(p_GetCoeff(p, r), r, base))
2337
+ if c_hash != 0: # this is always going to be true, because we are sparse (correct?)
2338
+ # Hash (self[i], gen_a, exp_a, gen_b, exp_b, gen_c, exp_c, ...) as a tuple according to the algorithm.
2339
+ # I omit gen,exp pairs where the exponent is zero.
2340
+ result_mon = c_hash
2341
+ for v from 1 <= v <= r.N:
2342
+ n = p_GetExp(p,v,r)
2343
+ if n!=0:
2344
+ result_mon = (1000003 * result_mon) ^ var_name_hash[v-1]
2345
+ result_mon = (1000003 * result_mon) ^ n
2346
+ result += result_mon
2347
+
2348
+ p = pNext(p)
2349
+ if result == -1:
2350
+ return -2
2351
+ return result
2352
+
2353
+ def __getitem__(self, x):
2354
+ """
2355
+ Same as :meth:`monomial_coefficient` but for exponent vectors.
2356
+
2357
+ INPUT:
2358
+
2359
+ - ``x`` -- tuple or, in case of a single-variable MPolynomial
2360
+ ring ``x`` can also be an integer
2361
+
2362
+ EXAMPLES::
2363
+
2364
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2365
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2366
+ sage: R.inject_variables()
2367
+ Defining x, z, y
2368
+ sage: f = (-10*x^3*y + 17*x*y)* ( 15*z^3 + 2*x*y*z - 1); f
2369
+ 20*x^4*z*y^2 - 150*x^3*z^3*y - 20*x^3*z^2*y + 10*x^3*y - 34*x^2*z*y^2 - 134*x*z^3*y + 34*x*z^2*y - 17*x*y
2370
+ sage: f[4,1,2]
2371
+ 20
2372
+ sage: f[1,0,1]
2373
+ 372
2374
+ sage: f[0,0,0]
2375
+ 0
2376
+
2377
+ sage: R.<x> = PolynomialRing(GF(7), implementation='singular'); R
2378
+ Multivariate Polynomial Ring in x over Finite Field of size 7
2379
+ sage: f = 5*x^2 + 3; f
2380
+ -2*x^2 + 3
2381
+ sage: f[2]
2382
+ 5
2383
+ """
2384
+ cdef poly *m
2385
+ cdef poly *p = self._poly
2386
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
2387
+ cdef int i
2388
+
2389
+ if isinstance(x, NCPolynomial_plural):
2390
+ return self.monomial_coefficient(x)
2391
+ if not isinstance(x, tuple):
2392
+ try:
2393
+ x = tuple(x)
2394
+ except TypeError:
2395
+ x = (x,)
2396
+
2397
+ if len(x) != (<NCPolynomialRing_plural>self._parent)._ngens:
2398
+ raise TypeError("x must have length self.ngens()")
2399
+
2400
+ m = p_ISet(1,r)
2401
+ i = 1
2402
+ for e in x:
2403
+ overflow_check(e, r)
2404
+ p_SetExp(m, i, int(e), r)
2405
+ i += 1
2406
+ p_Setm(m, r)
2407
+
2408
+ while p:
2409
+ if p_ExpVectorEqual(p, m, r) == 1:
2410
+ p_Delete(&m,r)
2411
+ return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base)
2412
+ p = pNext(p)
2413
+
2414
+ p_Delete(&m,r)
2415
+ return (<NCPolynomialRing_plural>self._parent)._base._zero_element
2416
+
2417
+ def exponents(self, as_ETuples=True):
2418
+ """
2419
+ Return the exponents of the monomials appearing in this polynomial.
2420
+
2421
+ INPUT:
2422
+
2423
+ - ``as_ETuples`` -- boolean (default: ``True``); if ``True`` returns
2424
+ the result as an list of ETuples, otherwise returns a list of tuples
2425
+
2426
+ EXAMPLES::
2427
+
2428
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2429
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2430
+ sage: R.inject_variables()
2431
+ Defining x, z, y
2432
+ sage: f = x^3 + y + 2*z^2
2433
+ sage: f.exponents()
2434
+ [(3, 0, 0), (0, 2, 0), (0, 0, 1)]
2435
+ sage: f.exponents(as_ETuples=False)
2436
+ [(3, 0, 0), (0, 2, 0), (0, 0, 1)]
2437
+ """
2438
+ cdef poly *p
2439
+ cdef ring *r
2440
+ cdef int v
2441
+ cdef list pl, ml
2442
+
2443
+ r = (< NCPolynomialRing_plural>self._parent)._ring
2444
+ p = self._poly
2445
+
2446
+ pl = list()
2447
+ ml = list(range(r.N))
2448
+ while p:
2449
+ for v from 1 <= v <= r.N:
2450
+ ml[v - 1] = p_GetExp(p, v, r)
2451
+
2452
+ if as_ETuples:
2453
+ pl.append(ETuple(ml))
2454
+ else:
2455
+ pl.append(tuple(ml))
2456
+
2457
+ p = pNext(p)
2458
+ return pl
2459
+
2460
+ def is_homogeneous(self):
2461
+ """
2462
+ Return ``True`` if this polynomial is homogeneous.
2463
+
2464
+ EXAMPLES::
2465
+
2466
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2467
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2468
+ sage: P.inject_variables()
2469
+ Defining x, z, y
2470
+ sage: (x+y+z).is_homogeneous()
2471
+ True
2472
+ sage: (x.parent()(0)).is_homogeneous()
2473
+ True
2474
+ sage: (x+y^2+z^3).is_homogeneous()
2475
+ False
2476
+ sage: (x^2 + y^2).is_homogeneous()
2477
+ True
2478
+ sage: (x^2 + y^2*x).is_homogeneous()
2479
+ False
2480
+ sage: (x^2*y + y^2*x).is_homogeneous()
2481
+ True
2482
+ """
2483
+ cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring
2484
+ if _ring != currRing:
2485
+ rChangeCurrRing(_ring)
2486
+ return bool(p_IsHomogeneous(self._poly,_ring))
2487
+
2488
+ def is_monomial(self):
2489
+ """
2490
+ Return ``True`` if this polynomial is a monomial.
2491
+
2492
+ A monomial is defined to be a product of generators with
2493
+ coefficient 1.
2494
+
2495
+ EXAMPLES::
2496
+
2497
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2498
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2499
+ sage: P.inject_variables()
2500
+ Defining x, z, y
2501
+ sage: x.is_monomial()
2502
+ True
2503
+ sage: (2*x).is_monomial()
2504
+ False
2505
+ sage: (x*y).is_monomial()
2506
+ True
2507
+ sage: (x*y + x).is_monomial()
2508
+ False
2509
+ """
2510
+ cdef poly *_p
2511
+ cdef ring *_ring
2512
+ cdef number *_n
2513
+ _ring = (<NCPolynomialRing_plural>self._parent)._ring
2514
+
2515
+ if self._poly == NULL:
2516
+ return True
2517
+
2518
+ if _ring != currRing:
2519
+ rChangeCurrRing(_ring)
2520
+
2521
+ _p = p_Head(self._poly, _ring)
2522
+ _n = p_GetCoeff(_p, _ring)
2523
+
2524
+ ret = bool((not self._poly.next) and _ring.cf.cfIsOne(_n,_ring.cf))
2525
+
2526
+ p_Delete(&_p, _ring)
2527
+ return ret
2528
+
2529
+ def monomials(self):
2530
+ """
2531
+ Return the list of monomials in ``self``.
2532
+
2533
+ The returned list is decreasingly ordered by the term ordering
2534
+ of ``self.parent()``.
2535
+
2536
+ EXAMPLES::
2537
+
2538
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2539
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2540
+ sage: P.inject_variables()
2541
+ Defining x, z, y
2542
+ sage: f = x + (3*2)*y*z^2 + (2+3)
2543
+ sage: f.monomials()
2544
+ [x, z^2*y, 1]
2545
+ sage: f = P(3^2)
2546
+ sage: f.monomials()
2547
+ [1]
2548
+
2549
+ TESTS::
2550
+
2551
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2552
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2553
+ sage: P.inject_variables()
2554
+ Defining x, z, y
2555
+ sage: f = x
2556
+ sage: f.monomials()
2557
+ [x]
2558
+
2559
+ Check if :issue:`12706` is fixed::
2560
+
2561
+ sage: f = P(0)
2562
+ sage: f.monomials()
2563
+ []
2564
+
2565
+ Check if :issue:`7152` is fixed::
2566
+
2567
+ sage: # needs sage.symbolic
2568
+ sage: x = var('x')
2569
+ sage: K.<rho> = NumberField(x**2 + 1)
2570
+ sage: R.<x,y> = QQ[]
2571
+ sage: p = rho*x
2572
+ sage: q = x
2573
+ sage: p.monomials()
2574
+ [x]
2575
+ sage: q.monomials()
2576
+ [x]
2577
+ sage: p.monomials()
2578
+ [x]
2579
+ """
2580
+ l = list()
2581
+ cdef NCPolynomialRing_plural parent = <NCPolynomialRing_plural>self._parent
2582
+ cdef ring *_ring = parent._ring
2583
+ if _ring != currRing:
2584
+ rChangeCurrRing(_ring)
2585
+ cdef poly *p = p_Copy(self._poly, _ring)
2586
+ cdef poly *t
2587
+
2588
+ if p == NULL:
2589
+ return []
2590
+
2591
+ while p:
2592
+ t = pNext(p)
2593
+ p.next = NULL
2594
+ p_SetCoeff(p, n_Init(1,_ring.cf), _ring)
2595
+ p_Setm(p, _ring)
2596
+ l.append(new_NCP(parent, p))
2597
+ p = t
2598
+
2599
+ return l
2600
+
2601
+ def constant_coefficient(self):
2602
+ """
2603
+ Return the constant coefficient of this multivariate
2604
+ polynomial.
2605
+
2606
+ EXAMPLES::
2607
+
2608
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2609
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2610
+ sage: P.inject_variables()
2611
+ Defining x, z, y
2612
+ sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
2613
+ sage: f.constant_coefficient()
2614
+ 5
2615
+ sage: f = 3*x^2
2616
+ sage: f.constant_coefficient()
2617
+ 0
2618
+ """
2619
+ cdef poly *p = self._poly
2620
+ cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring
2621
+ if p == NULL:
2622
+ return (<NCPolynomialRing_plural>self._parent)._base._zero_element
2623
+
2624
+ while p.next:
2625
+ p = pNext(p)
2626
+
2627
+ if p_LmIsConstant(p, r):
2628
+ return si2sa(p_GetCoeff(p, r), r,
2629
+ (<NCPolynomialRing_plural>self._parent)._base)
2630
+ return (<NCPolynomialRing_plural>self._parent)._base._zero_element
2631
+
2632
+ cpdef is_constant(self):
2633
+ """
2634
+ Return ``True`` if this polynomial is constant.
2635
+
2636
+ EXAMPLES::
2637
+
2638
+ sage: A.<x,z,y> = FreeAlgebra(GF(389), 3)
2639
+ sage: P = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2640
+ sage: P.inject_variables()
2641
+ Defining x, z, y
2642
+ sage: x.is_constant()
2643
+ False
2644
+ sage: P(1).is_constant()
2645
+ True
2646
+ """
2647
+ return bool(p_IsConstant(self._poly, (<NCPolynomialRing_plural>self._parent)._ring))
2648
+
2649
+ def lm(NCPolynomial_plural self):
2650
+ """
2651
+ Return the lead monomial of ``self`` with respect to the term
2652
+ order of ``self.parent()``.
2653
+
2654
+ In Sage, a monomial is a product of variables in some power
2655
+ without a coefficient.
2656
+
2657
+ EXAMPLES::
2658
+
2659
+ sage: A.<x,y,z> = FreeAlgebra(GF(7), 3)
2660
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2661
+ sage: R.inject_variables()
2662
+ Defining x, y, z
2663
+ sage: f = x^1*y^2 + y^3*z^4
2664
+ sage: f.lm()
2665
+ x*y^2
2666
+ sage: f = x^3*y^2*z^4 + x^3*y^2*z^1
2667
+ sage: f.lm()
2668
+ x^3*y^2*z^4
2669
+
2670
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
2671
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='deglex')
2672
+ sage: R.inject_variables()
2673
+ Defining x, y, z
2674
+ sage: f = x^1*y^2*z^3 + x^3*y^2*z^0
2675
+ sage: f.lm()
2676
+ x*y^2*z^3
2677
+ sage: f = x^1*y^2*z^4 + x^1*y^1*z^5
2678
+ sage: f.lm()
2679
+ x*y^2*z^4
2680
+
2681
+ sage: A.<x,y,z> = FreeAlgebra(GF(127), 3)
2682
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='degrevlex')
2683
+ sage: R.inject_variables()
2684
+ Defining x, y, z
2685
+ sage: f = x^1*y^5*z^2 + x^4*y^1*z^3
2686
+ sage: f.lm()
2687
+ x*y^5*z^2
2688
+ sage: f = x^4*y^7*z^1 + x^4*y^2*z^3
2689
+ sage: f.lm()
2690
+ x^4*y^7*z
2691
+ """
2692
+ cdef poly *_p
2693
+ cdef ring *_ring
2694
+ _ring = (<NCPolynomialRing_plural>self._parent)._ring
2695
+ if self._poly == NULL:
2696
+ return (<NCPolynomialRing_plural>self._parent)._zero_element
2697
+ _p = p_Head(self._poly, _ring)
2698
+ p_SetCoeff(_p, n_Init(1,_ring.cf), _ring)
2699
+ p_Setm(_p,_ring)
2700
+ return new_NCP((<NCPolynomialRing_plural>self._parent), _p)
2701
+
2702
+ def lc(NCPolynomial_plural self):
2703
+ """
2704
+ Leading coefficient of this polynomial with respect to the
2705
+ term order of ``self.parent()``.
2706
+
2707
+ EXAMPLES::
2708
+
2709
+ sage: A.<x,y,z> = FreeAlgebra(GF(7), 3)
2710
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2711
+ sage: R.inject_variables()
2712
+ Defining x, y, z
2713
+
2714
+ sage: f = 3*x^1*y^2 + 2*y^3*z^4
2715
+ sage: f.lc()
2716
+ 3
2717
+
2718
+ sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1
2719
+ sage: f.lc()
2720
+ 5
2721
+ """
2722
+ cdef poly *_p
2723
+ cdef ring *_ring
2724
+ cdef number *_n
2725
+ _ring = (<NCPolynomialRing_plural>self._parent)._ring
2726
+
2727
+ if self._poly == NULL:
2728
+ return (<NCPolynomialRing_plural>self._parent)._base._zero_element
2729
+
2730
+ if _ring != currRing:
2731
+ rChangeCurrRing(_ring)
2732
+
2733
+ _p = p_Head(self._poly, _ring)
2734
+ _n = p_GetCoeff(_p, _ring)
2735
+
2736
+ ret = si2sa(_n, _ring, (<NCPolynomialRing_plural>self._parent)._base)
2737
+ p_Delete(&_p, _ring)
2738
+ return ret
2739
+
2740
+ def lt(NCPolynomial_plural self):
2741
+ """
2742
+ Return the leading term of this polynomial.
2743
+
2744
+ In Sage, a term is a product of variables in some power and a
2745
+ coefficient.
2746
+
2747
+ EXAMPLES::
2748
+
2749
+ sage: A.<x,y,z> = FreeAlgebra(GF(7), 3)
2750
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2751
+ sage: R.inject_variables()
2752
+ Defining x, y, z
2753
+
2754
+ sage: f = 3*x^1*y^2 + 2*y^3*z^4
2755
+ sage: f.lt()
2756
+ 3*x*y^2
2757
+
2758
+ sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1
2759
+ sage: f.lt()
2760
+ -2*x^3*y^2*z^4
2761
+ """
2762
+ if self._poly == NULL:
2763
+ return (<NCPolynomialRing_plural>self._parent)._zero_element
2764
+
2765
+ return new_NCP((<NCPolynomialRing_plural>self._parent),
2766
+ p_Head(self._poly, (<NCPolynomialRing_plural>self._parent)._ring))
2767
+
2768
+ def is_zero(self):
2769
+ """
2770
+ Return ``True`` if this polynomial is zero.
2771
+
2772
+ EXAMPLES::
2773
+
2774
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
2775
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2776
+ sage: R.inject_variables()
2777
+ Defining x, z, y
2778
+
2779
+ sage: x.is_zero()
2780
+ False
2781
+ sage: (x-x).is_zero()
2782
+ True
2783
+ """
2784
+ return self._poly is NULL
2785
+
2786
+ def __bool__(self):
2787
+ """
2788
+ EXAMPLES::
2789
+
2790
+ sage: A.<x,z,y> = FreeAlgebra(QQ, 3)
2791
+ sage: R = A.g_algebra(relations={y*x:-x*y + z}, order='lex')
2792
+ sage: R.inject_variables()
2793
+ Defining x, z, y
2794
+
2795
+ sage: bool(x) # indirect doctest
2796
+ True
2797
+ sage: bool(x-x)
2798
+ False
2799
+ """
2800
+ return True if self._poly else False
2801
+
2802
+ def __call__(self, *x, **kwds):
2803
+ """
2804
+ EXAMPLES::
2805
+
2806
+ sage: F.<x,y,z>=FreeAlgebra(QQ,3)
2807
+ sage: G = F.g_algebra({y*x: -x*y})
2808
+ sage: G.inject_variables()
2809
+ Defining x, y, z
2810
+ sage: a = x+y+x*y
2811
+ sage: a.subs(x=0, y=1)
2812
+ 1
2813
+ sage: a.subs(x=y,y=x) == x + y - x*y
2814
+ True
2815
+ """
2816
+ # Modified version of method from algebras/free_algebra_element.py.
2817
+ if isinstance(x[0], tuple):
2818
+ x = x[0]
2819
+
2820
+ if len(x) != self.parent().ngens():
2821
+ raise ValueError("must specify as many values as generators in parent")
2822
+
2823
+ # I don't start with 0, because I don't want to preclude evaluation with
2824
+ # arbitrary objects (e.g. matrices) because of funny coercion.
2825
+
2826
+ result = None
2827
+ for m in self.monomials():
2828
+ c = self.monomial_coefficient(m)
2829
+ summand = None
2830
+ for (elt, pow) in zip(x, m.exponents()[0]):
2831
+ if summand is None:
2832
+ summand = elt**pow
2833
+ else:
2834
+ summand *= elt**pow
2835
+
2836
+ if result is None:
2837
+ result = c*summand
2838
+ else:
2839
+ result += c*summand
2840
+
2841
+ if result is None:
2842
+ return self.parent().zero()
2843
+ return result
2844
+
2845
+
2846
+ #####################################################################
2847
+
2848
+ cdef inline NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent,
2849
+ poly *juice):
2850
+ """
2851
+ Construct NCPolynomial_plural from parent and SINGULAR poly.
2852
+
2853
+ EXAMPLES::
2854
+
2855
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
2856
+ sage: H = A.g_algebra({z*x:x*z+2*x, z*y:y*z-2*y})
2857
+ sage: H.gen(2) # indirect doctest
2858
+ z
2859
+ """
2860
+ cdef NCPolynomial_plural p = NCPolynomial_plural.__new__(NCPolynomial_plural)
2861
+ p._parent = parent
2862
+ p._poly = juice
2863
+ p_Normalize(p._poly, parent._ring)
2864
+ return p
2865
+
2866
+
2867
+ cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring):
2868
+ """
2869
+ Construct ``MPolynomialRing_libsingular`` from ``RingWrap``, assuming the
2870
+ ground field to be ``base_ring``.
2871
+
2872
+ EXAMPLES::
2873
+
2874
+ sage: H.<x,y,z> = PolynomialRing(QQ, 3)
2875
+ sage: from sage.libs.singular.function import singular_function
2876
+
2877
+ sage: ringlist = singular_function('ringlist')
2878
+ sage: ring = singular_function("ring")
2879
+
2880
+ sage: L = ringlist(H, ring=H); L
2881
+ [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0]]
2882
+
2883
+ sage: len(L)
2884
+ 4
2885
+
2886
+ sage: W = ring(L, ring=H); W
2887
+ <RingWrap>
2888
+
2889
+ sage: from sage.rings.polynomial.plural import new_CRing
2890
+ sage: R = new_CRing(W, H.base_ring())
2891
+ sage: R # indirect doctest
2892
+ Multivariate Polynomial Ring in x, y, z over Rational Field
2893
+
2894
+ Check that :issue:`13145` has been resolved::
2895
+
2896
+ sage: h = hash(R.gen() + 1) # sets currRing
2897
+ sage: from sage.libs.singular.ring import ring_refcount_dict, currRing_wrapper
2898
+ sage: curcnt = ring_refcount_dict[currRing_wrapper()]
2899
+ sage: newR = new_CRing(W, H.base_ring())
2900
+ sage: ring_refcount_dict[currRing_wrapper()] - curcnt
2901
+ 2
2902
+
2903
+ Check that :issue:`29311` is fixed::
2904
+
2905
+ sage: R.<x,y,z> = QQ[]
2906
+ sage: from sage.libs.singular.function_factory import ff
2907
+ sage: W = ff.ring(ff.ringlist(R), ring=R)
2908
+ sage: C = sage.rings.polynomial.plural.new_CRing(W, R.base_ring())
2909
+ sage: C.one()
2910
+ 1
2911
+ """
2912
+ assert rw.is_commutative()
2913
+
2914
+ cdef MPolynomialRing_libsingular self = <MPolynomialRing_libsingular>MPolynomialRing_libsingular.__new__(MPolynomialRing_libsingular)
2915
+
2916
+ self._ring = rw._ring
2917
+ cdef MPolynomial_libsingular one = new_MP(self, p_ISet(1, self._ring))
2918
+ self._one_element = one
2919
+ self._one_element_poly = one._poly
2920
+
2921
+ wrapped_ring = wrap_ring(self._ring)
2922
+ sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] += 1
2923
+
2924
+ self._ring.ShortOut = 0
2925
+
2926
+ self._ngens = rw.ngens()
2927
+ self._term_order = TermOrder(rw.ordering_string(), force=True)
2928
+
2929
+ names = tuple(rw.var_names())
2930
+ CommutativeRing.__init__(self, base_ring, names, category=Algebras(base_ring),
2931
+ normalize=False)
2932
+
2933
+ self._has_singular = True
2934
+
2935
+ return self
2936
+
2937
+
2938
+ cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring):
2939
+ """
2940
+ Construct ``NCPolynomialRing_plural`` from ``RingWrap``, assuming the
2941
+ ground field to be ``base_ring``.
2942
+
2943
+ EXAMPLES::
2944
+
2945
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
2946
+ sage: H = A.g_algebra({y*x:x*y-1})
2947
+ sage: H.inject_variables()
2948
+ Defining x, y, z
2949
+ sage: z*x
2950
+ x*z
2951
+ sage: z*y
2952
+ y*z
2953
+ sage: y*x
2954
+ x*y - 1
2955
+ sage: I = H.ideal([y^2, x^2, z^2-1])
2956
+ sage: I._groebner_basis_libsingular()
2957
+ [1]
2958
+
2959
+ sage: from sage.libs.singular.function import singular_function
2960
+
2961
+ sage: ringlist = singular_function('ringlist')
2962
+ sage: ring = singular_function("ring")
2963
+
2964
+ sage: L = ringlist(H, ring=H); L
2965
+ [
2966
+ [0 1 1]
2967
+ [0 0 1]
2968
+ 0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 0 0],
2969
+ <BLANKLINE>
2970
+ [ 0 -1 0]
2971
+ [ 0 0 0]
2972
+ [ 0 0 0]
2973
+ ]
2974
+ sage: len(L)
2975
+ 6
2976
+
2977
+ sage: W = ring(L, ring=H); W
2978
+ <noncommutative RingWrap>
2979
+
2980
+ sage: from sage.rings.polynomial.plural import new_NRing
2981
+ sage: R = new_NRing(W, H.base_ring())
2982
+ sage: R # indirect doctest
2983
+ Noncommutative Multivariate Polynomial Ring in x, y, z over
2984
+ Rational Field, nc-relations: {y*x: x*y - 1}
2985
+ """
2986
+ assert not rw.is_commutative()
2987
+
2988
+ cdef NCPolynomialRing_plural self = <NCPolynomialRing_plural>NCPolynomialRing_plural.__new__(NCPolynomialRing_plural)
2989
+ self._ring = rw._ring
2990
+
2991
+ wrapped_ring = wrap_ring(self._ring)
2992
+ sage.libs.singular.ring.ring_refcount_dict[wrapped_ring] += 1
2993
+
2994
+ self._ring.ShortOut = 0
2995
+
2996
+ self._ngens = rw.ngens()
2997
+ self._term_order = TermOrder(rw.ordering_string(), force=True)
2998
+
2999
+ Parent.__init__(self, base=base_ring, names=rw.var_names(), category=Algebras(base_ring))
3000
+
3001
+ self._has_singular = True
3002
+ self._relations = self.relations()
3003
+
3004
+ return self
3005
+
3006
+
3007
+ def new_Ring(RingWrap rw, base_ring):
3008
+ """
3009
+ Construct a Sage ring out of low level ``RingWrap``, which wraps a pointer
3010
+ to a Singular ring.
3011
+
3012
+ The constructed ring is either commutative or noncommutative depending on
3013
+ the Singular ring.
3014
+
3015
+ EXAMPLES::
3016
+
3017
+ sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
3018
+ sage: H = A.g_algebra({y*x:x*y-1})
3019
+ sage: H.inject_variables()
3020
+ Defining x, y, z
3021
+ sage: z*x
3022
+ x*z
3023
+ sage: z*y
3024
+ y*z
3025
+ sage: y*x
3026
+ x*y - 1
3027
+ sage: I = H.ideal([y^2, x^2, z^2-1])
3028
+ sage: I._groebner_basis_libsingular()
3029
+ [1]
3030
+
3031
+ sage: from sage.libs.singular.function import singular_function
3032
+
3033
+ sage: ringlist = singular_function('ringlist')
3034
+ sage: ring = singular_function("ring")
3035
+
3036
+ sage: L = ringlist(H, ring=H); L
3037
+ [
3038
+ [0 1 1]
3039
+ [0 0 1]
3040
+ 0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 0 0],
3041
+ <BLANKLINE>
3042
+ [ 0 -1 0]
3043
+ [ 0 0 0]
3044
+ [ 0 0 0]
3045
+ ]
3046
+ sage: len(L)
3047
+ 6
3048
+
3049
+ sage: W = ring(L, ring=H); W
3050
+ <noncommutative RingWrap>
3051
+
3052
+ sage: from sage.rings.polynomial.plural import new_Ring
3053
+ sage: R = new_Ring(W, H.base_ring()); R
3054
+ Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1}
3055
+ """
3056
+ # import warnings
3057
+ # warnings.warn("This is a hack. Please, use it on your own risk...")
3058
+ if rw.is_commutative():
3059
+ return new_CRing(rw, base_ring)
3060
+ return new_NRing(rw, base_ring)
3061
+
3062
+
3063
+ def SCA(base_ring, names, alt_vars, order='degrevlex'):
3064
+ """
3065
+ Return a free graded-commutative algebra.
3066
+
3067
+ This is also known as a free super-commutative algebra.
3068
+
3069
+ INPUT:
3070
+
3071
+ - ``base_ring`` -- the ground field
3072
+ - ``names`` -- list of variable names
3073
+ - ``alt_vars`` -- list of indices of to be anti-commutative variables (odd variables)
3074
+ - ``order`` -- ordering to be used for the constructed algebra
3075
+
3076
+ EXAMPLES::
3077
+
3078
+ sage: from sage.rings.polynomial.plural import SCA
3079
+ sage: E = SCA(QQ, ['x', 'y', 'z'], [0, 1], order = 'degrevlex')
3080
+ sage: E
3081
+ Quotient of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} by the ideal (y^2, x^2)
3082
+ sage: E.inject_variables()
3083
+ Defining xbar, ybar, zbar
3084
+ sage: x,y,z = (xbar,ybar,zbar)
3085
+ sage: y*x
3086
+ -x*y
3087
+ sage: z*x
3088
+ x*z
3089
+ sage: x^2
3090
+ 0
3091
+ sage: y^2
3092
+ 0
3093
+ sage: z^2
3094
+ z^2
3095
+ sage: E.one()
3096
+ 1
3097
+ """
3098
+ n = len(names)
3099
+ alt_start = min(alt_vars)
3100
+ alt_end = max(alt_vars)
3101
+ assert 0 <= alt_start <= alt_end < n
3102
+
3103
+ relations = {} # {y*x:-x*y}
3104
+ from sage.algebras.free_algebra import FreeAlgebra
3105
+ A = FreeAlgebra(base_ring, n, names)
3106
+ for r in range(0, n-1, 1):
3107
+ for c in range(r+1, n, 1):
3108
+ if r in alt_vars and c in alt_vars:
3109
+ relations[A.gen(c) * A.gen(r)] = - A.gen(r) * A.gen(c)
3110
+
3111
+ cdef NCPolynomialRing_plural H = A.g_algebra(relations=relations,
3112
+ order=order)
3113
+ I = H.ideal([H.gen(i) * H.gen(i) for i in alt_vars]).twostd()
3114
+ return H.quotient(I)
3115
+
3116
+
3117
+ def ExteriorAlgebra(base_ring, names, order='degrevlex'):
3118
+ """
3119
+ Return the exterior algebra on some generators.
3120
+
3121
+ This is also known as a Grassmann algebra. This is a finite
3122
+ dimensional algebra, where all generators anti-commute.
3123
+
3124
+ See :wikipedia:`Exterior algebra`
3125
+
3126
+ INPUT:
3127
+
3128
+ - ``base_ring`` -- the ground ring
3129
+ - ``names`` -- list of variable names
3130
+
3131
+ EXAMPLES::
3132
+
3133
+ sage: from sage.rings.polynomial.plural import ExteriorAlgebra
3134
+ sage: E = ExteriorAlgebra(QQ, ['x', 'y', 'z']) ; E #random
3135
+ Quotient of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: -x*z, z*y: -y*z, y*x: -x*y} by the ideal (z^2, y^2, x^2)
3136
+ sage: sorted(E.cover().domain().relations().items(), key=str)
3137
+ [(y*x, -x*y), (z*x, -x*z), (z*y, -y*z)]
3138
+ sage: sorted(E.cover().kernel().gens(),key=str)
3139
+ [x^2, y^2, z^2]
3140
+ sage: E.inject_variables()
3141
+ Defining xbar, ybar, zbar
3142
+ sage: x,y,z = (xbar,ybar,zbar)
3143
+ sage: y*x
3144
+ -x*y
3145
+ sage: all(v^2==0 for v in E.gens())
3146
+ True
3147
+ sage: E.one()
3148
+ 1
3149
+ """
3150
+ n = len(names)
3151
+ relations = {} # {y*x:-x*y}
3152
+ from sage.algebras.free_algebra import FreeAlgebra
3153
+ A = FreeAlgebra(base_ring, n, names)
3154
+ for r in range(n-1):
3155
+ for c in range(r+1, n):
3156
+ relations[A.gen(c) * A.gen(r)] = - A.gen(r) * A.gen(c)
3157
+
3158
+ cdef NCPolynomialRing_plural H = A.g_algebra(relations=relations,
3159
+ order=order)
3160
+ I = H.ideal([H.gen(i) * H.gen(i) for i in range(n)]).twostd()
3161
+ return H.quotient(I)
3162
+
3163
+
3164
+ cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring) noexcept:
3165
+ if p_GetExp(tempvector, pos, _ring) < p_GetExp(maxvector, pos, _ring):
3166
+ p_SetExp(tempvector, pos, p_GetExp(tempvector, pos, _ring)+1, _ring)
3167
+ else:
3168
+ p_SetExp(tempvector, pos, 0, _ring)
3169
+ tempvector = addwithcarry(tempvector, maxvector, pos + 1, _ring)
3170
+ p_Setm(tempvector, _ring)
3171
+ return tempvector