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,2576 @@
1
+ # sage_setup: distribution = sagemath-singular
2
+ # sage.doctest: needs sage.symbolic
3
+ """
4
+ Pynac interface
5
+ """
6
+
7
+ # ****************************************************************************
8
+ # Copyright (C) 2008 William Stein <wstein@gmail.com>
9
+ # Copyright (C) 2008-2014 Burcin Erocal <burcin@erocal.org>
10
+ # Copyright (C) 2009 Carl Witty
11
+ # Copyright (C) 2009 Minh Van Nguyen
12
+ # Copyright (C) 2009-2011 Mike Hansen
13
+ # Copyright (C) 2010 Flavia Stan
14
+ # Copyright (C) 2010 Tom Coates
15
+ # Copyright (C) 2014 Eviatar Bach
16
+ # Copyright (C) 2014 Jean-Pierre Flori
17
+ # Copyright (C) 2014 R. Andrew Ohana
18
+ # Copyright (C) 2015-2017 Ralf Stephan
19
+ # Copyright (C) 2015-2018 Jeroen Demeyer <jdemeyer@cage.ugent.be>
20
+ # Copyright (C) 2015-2020 Marc Mezzarobba
21
+ # Copyright (C) 2016 Frédéric Chapoton
22
+ # Copyright (C) 2016 Jori Mäntysalo
23
+ # Copyright (C) 2016 Nils Bruin
24
+ # Copyright (C) 2016-2018 Frédéric Chapoton
25
+ # Copyright (C) 2017-2018 Erik M. Bray
26
+ # Copyright (C) 2019 Volker Braun
27
+ # Copyright (C) 2021 Jonathan Kliem
28
+ # Copyright (C) 2021 Matthias Koeppe
29
+ #
30
+ # This program is free software: you can redistribute it and/or modify
31
+ # it under the terms of the GNU General Public License as published by
32
+ # the Free Software Foundation, either version 2 of the License, or
33
+ # (at your option) any later version.
34
+ # https://www.gnu.org/licenses/
35
+ # ****************************************************************************
36
+
37
+ from cpython cimport *
38
+ from libc cimport math
39
+
40
+ from sage.arith.misc import bernoulli, factorial, GCD as gcd, is_prime
41
+ from sage.arith.functions import lcm
42
+ from sage.cpython.string cimport str_to_bytes, char_to_str
43
+ from sage.ext.stdsage cimport PY_NEW
44
+ from sage.libs.gmp.all cimport *
45
+ from sage.libs.gsl.complex cimport *
46
+ from sage.libs.gsl.gamma cimport gsl_sf_lngamma_complex_e
47
+ from sage.libs.mpmath import utils as mpmath_utils
48
+ from sage.misc.persist import loads, dumps
49
+ from sage.rings.integer_ring import ZZ
50
+ from sage.rings.integer cimport Integer, smallInteger
51
+ from sage.rings.rational cimport Rational
52
+ from sage.rings.real_mpfr import RR, RealField
53
+ from sage.rings.rational cimport rational_power_parts
54
+ from sage.rings.real_double cimport RealDoubleElement
55
+ from sage.rings.cc import CC
56
+ from sage.structure.coerce cimport coercion_model
57
+ from sage.structure.element cimport Element, parent
58
+ from sage.symbolic.function cimport Function
59
+
60
+ #################################################################
61
+ # Symbolic function helpers
62
+ #################################################################
63
+
64
+ cdef ex_to_pyExpression(GEx juice):
65
+ """
66
+ Convert given GiNaC::ex object to a python Expression instance.
67
+
68
+ Used to pass parameters to custom power and series functions.
69
+ """
70
+ cdef Expression nex
71
+ nex = <Expression>Expression.__new__(Expression)
72
+ nex._gobj = GEx(juice)
73
+ from sage.symbolic.ring import SR
74
+ nex._parent = SR
75
+ return nex
76
+
77
+ cdef exprseq_to_PyTuple(GEx seq):
78
+ """
79
+ Convert an exprseq to a Python tuple.
80
+
81
+ Used while converting arguments of symbolic functions to Python objects.
82
+
83
+ EXAMPLES::
84
+
85
+ sage: from sage.symbolic.function import BuiltinFunction
86
+ sage: class TFunc(BuiltinFunction):
87
+ ....: def __init__(self):
88
+ ....: BuiltinFunction.__init__(self, 'tfunc', nargs=0)
89
+ ....:
90
+ ....: def _eval_(self, *args):
91
+ ....: print("len(args): %s, types: %s"%(len(args), str(list(map(type, args)))))
92
+ ....: for i, a in enumerate(args):
93
+ ....: if isinstance(a, tuple):
94
+ ....: print("argument %s is a tuple, with types %s"%(str(i), str(list(map(type, a)))))
95
+ ....:
96
+ sage: tfunc = TFunc()
97
+ sage: u = SR._force_pyobject((1, x+1, 2))
98
+ sage: tfunc(u, x, SR._force_pyobject((3.0, 2^x)))
99
+ len(args): 3, types: [<... 'tuple'>, <class 'sage.symbolic.expression.Expression'>, <... 'tuple'>]
100
+ argument 0 is a tuple, with types [<class 'sage.rings.integer.Integer'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.rings.integer.Integer'>]
101
+ argument 2 is a tuple, with types [<class 'sage.rings.real_mpfr.RealLiteral'>, <class 'sage.symbolic.expression.Expression'>]
102
+ tfunc((1, x + 1, 2), x, (3.00000000000000, 2^x))
103
+ """
104
+ from sage.symbolic.ring import SR
105
+ res = []
106
+ for i in range(seq.nops()):
107
+ if is_a_numeric(seq.op(i)):
108
+ res.append(py_object_from_numeric(seq.op(i)))
109
+ elif is_exactly_a_exprseq(seq.op(i)):
110
+ res.append(exprseq_to_PyTuple(seq.op(i)))
111
+ else:
112
+ res.append(new_Expression_from_GEx(SR, seq.op(i)))
113
+ return tuple(res)
114
+
115
+
116
+ def unpack_operands(Expression ex):
117
+ """
118
+ EXAMPLES::
119
+
120
+ sage: from sage.symbolic.expression import unpack_operands
121
+ sage: t = SR._force_pyobject((1, 2, x, x+1, x+2))
122
+ sage: unpack_operands(t)
123
+ (1, 2, x, x + 1, x + 2)
124
+ sage: type(unpack_operands(t))
125
+ <... 'tuple'>
126
+ sage: list(map(type, unpack_operands(t)))
127
+ [<class 'sage.rings.integer.Integer'>, <class 'sage.rings.integer.Integer'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>]
128
+ sage: u = SR._force_pyobject((t, x^2))
129
+ sage: unpack_operands(u)
130
+ ((1, 2, x, x + 1, x + 2), x^2)
131
+ sage: type(unpack_operands(u)[0])
132
+ <... 'tuple'>
133
+ """
134
+ return exprseq_to_PyTuple(ex._gobj)
135
+
136
+
137
+ cdef exvector_to_PyTuple(GExVector seq):
138
+ """
139
+ Convert arguments list given to a function to a PyTuple.
140
+
141
+ Used to pass arguments to python methods assigned to custom
142
+ evaluation, derivative, etc. functions of symbolic functions.
143
+
144
+ We convert Python objects wrapped in symbolic expressions back to regular
145
+ Python objects.
146
+
147
+ EXAMPLES::
148
+
149
+ sage: from sage.symbolic.function import BuiltinFunction
150
+ sage: class TFunc(BuiltinFunction):
151
+ ....: def __init__(self):
152
+ ....: BuiltinFunction.__init__(self, 'tfunc', nargs=0)
153
+ ....:
154
+ ....: def _eval_(self, *args):
155
+ ....: print("len(args): %s, types: %s"%(len(args), str(list(map(type, args)))))
156
+ sage: tfunc = TFunc()
157
+ sage: u = SR._force_pyobject((1, x+1, 2))
158
+ sage: tfunc(u, x, 3.0, 5.0r)
159
+ len(args): 4, types: [<... 'tuple'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.rings.real_mpfr.RealLiteral'>, <... 'float'>]
160
+ tfunc((1, x + 1, 2), x, 3.00000000000000, 5.0)
161
+
162
+ TESTS:
163
+
164
+ Check if symbolic functions in the arguments are preserved::
165
+
166
+ sage: tfunc(sin(x), tfunc(1, x^2))
167
+ len(args): 2, types: [<class 'sage.rings.integer.Integer'>, <class 'sage.symbolic.expression.Expression'>]
168
+ len(args): 2, types: [<class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>]
169
+ tfunc(sin(x), tfunc(1, x^2))
170
+ """
171
+ from sage.symbolic.ring import SR
172
+ res = []
173
+ for i in range(seq.size()):
174
+ if is_a_numeric(seq.at(i)):
175
+ res.append(py_object_from_numeric(seq.at(i)))
176
+ elif is_exactly_a_exprseq(seq.at(i)):
177
+ res.append(exprseq_to_PyTuple(seq.at(i)))
178
+ else:
179
+ res.append(new_Expression_from_GEx(SR, seq.at(i)))
180
+ return tuple(res)
181
+
182
+ cdef GEx pyExpression_to_ex(res) except *:
183
+ """
184
+ Convert an Expression object to a GiNaC::ex.
185
+
186
+ Used to pass return values of custom python evaluation, derivation
187
+ functions back to C++ level.
188
+ """
189
+ if res is None:
190
+ raise TypeError("function returned None, expected return value of type sage.symbolic.expression.Expression")
191
+ from sage.symbolic.ring import SR
192
+ try:
193
+ t = SR.coerce(res)
194
+ except TypeError as err:
195
+ raise TypeError("function did not return a symbolic expression or an element that can be coerced into a symbolic expression")
196
+ return (<Expression>t)._gobj
197
+
198
+ cdef paramset_to_PyTuple(const_paramset_ref s):
199
+ """
200
+ Convert a std::multiset<unsigned> to a PyTuple.
201
+
202
+ Used to pass a list of parameter numbers with respect to which a function
203
+ is differentiated to the printing functions py_print_fderivative and
204
+ py_latex_fderivative.
205
+ """
206
+ cdef GParamSetIter itr = s.begin()
207
+ res = []
208
+ while itr != s.end():
209
+ res.append(itr.obj())
210
+ itr.inc()
211
+ return res
212
+
213
+
214
+ def paramset_from_Expression(Expression e):
215
+ """
216
+ EXAMPLES::
217
+
218
+ sage: from sage.symbolic.expression import paramset_from_Expression
219
+ sage: f = function('f')
220
+ sage: paramset_from_Expression(f(x).diff(x))
221
+ [0]
222
+ """
223
+ return paramset_to_PyTuple(ex_to_fderivative(e._gobj).get_parameter_set())
224
+
225
+
226
+ cdef int GINAC_FN_SERIAL = 0
227
+
228
+ cdef set_ginac_fn_serial():
229
+ """
230
+ Initialize the GINAC_FN_SERIAL variable to the number of functions
231
+ defined by GiNaC. This allows us to prevent collisions with C++ level
232
+ special functions when a user asks to construct a symbolic function
233
+ with the same name.
234
+ """
235
+ global GINAC_FN_SERIAL
236
+ GINAC_FN_SERIAL = g_registered_functions().size()
237
+
238
+ cdef int py_get_ginac_serial() noexcept:
239
+ """
240
+ Return the number of C++ level functions defined by GiNaC.
241
+
242
+ EXAMPLES::
243
+
244
+ sage: from sage.symbolic.expression import get_ginac_serial
245
+ sage: get_ginac_serial() >= 35
246
+ True
247
+ """
248
+ global GINAC_FN_SERIAL
249
+ return GINAC_FN_SERIAL
250
+
251
+
252
+ def get_ginac_serial():
253
+ """
254
+ Number of C++ level functions defined by GiNaC. (Defined mainly for testing.)
255
+
256
+ EXAMPLES::
257
+
258
+ sage: sage.symbolic.expression.get_ginac_serial() >= 35
259
+ True
260
+ """
261
+ return py_get_ginac_serial()
262
+
263
+
264
+ cdef get_fn_serial_c():
265
+ """
266
+ Return overall size of Pynac function registry.
267
+ """
268
+ return g_registered_functions().size()
269
+
270
+
271
+ def get_fn_serial():
272
+ """
273
+ Return the overall size of the Pynac function registry which
274
+ corresponds to the last serial value plus one.
275
+
276
+ EXAMPLES::
277
+
278
+ sage: from sage.symbolic.expression import get_fn_serial
279
+ sage: from sage.symbolic.function import get_sfunction_from_serial
280
+ sage: get_fn_serial() > 125
281
+ True
282
+ sage: print(get_sfunction_from_serial(get_fn_serial()))
283
+ None
284
+ sage: get_sfunction_from_serial(get_fn_serial() - 1) is not None
285
+ True
286
+ """
287
+ return get_fn_serial_c()
288
+
289
+
290
+ cdef subs_args_to_PyTuple(const GExMap& map, unsigned options, const GExVector& seq):
291
+ """
292
+ Convert arguments from ``GiNaC::subs()`` to a PyTuple.
293
+
294
+ EXAMPLES::
295
+
296
+ sage: from sage.symbolic.function import BuiltinFunction
297
+ sage: class TFunc(BuiltinFunction):
298
+ ....: def __init__(self):
299
+ ....: BuiltinFunction.__init__(self, 'tfunc', nargs=0)
300
+ ....:
301
+ ....: def _subs_(self, *args):
302
+ ....: print("len(args): %s, types: %s"%(len(args), str(list(map(type, args)))))
303
+ ....: return args[-1]
304
+ sage: tfunc = TFunc()
305
+ sage: tfunc(x).subs(x=1)
306
+ len(args): 3, types: [<class 'sage.symbolic.expression.SubstitutionMap'>,
307
+ <class 'int'>,
308
+ <class 'sage.symbolic.expression.Expression'>]
309
+ x
310
+ """
311
+ res = []
312
+ res.append(new_SubstitutionMap_from_GExMap(map))
313
+ res.append(options)
314
+ return tuple(res) + exvector_to_PyTuple(seq)
315
+
316
+ #################################################################
317
+ # Printing helpers
318
+ #################################################################
319
+
320
+ ##########################################################################
321
+ # Pynac's precedence levels, as extracted from the raw source code on
322
+ # 2009-05-15. If this changes in Pynac it could cause a bug in
323
+ # printing. But it's hardcoded in Pynac now, so there's not much to
324
+ # be done (at present).
325
+ # Container: 10
326
+ # Expairseq: 10
327
+ # Relational: 20
328
+ # Numeric: 30
329
+ # Pseries: 38
330
+ # Addition: 40
331
+ # Integral: 45
332
+ # Multiplication: 50
333
+ # Noncummative mult: 50
334
+ # Index: 55
335
+ # Power: 60
336
+ # Clifford: 65
337
+ # Function: 70
338
+ # Structure: 70
339
+ ##########################################################################
340
+
341
+ cdef stdstring* py_repr(o, int level) noexcept:
342
+ """
343
+ Return string representation of o. If level > 0, possibly put
344
+ parentheses around the string.
345
+ """
346
+ s = repr(o)
347
+ if level >= 20:
348
+ # s may need parens (e.g., is in an exponent), so decide if we
349
+ # have to put parentheses around s:
350
+ # A regexp might seem better, but I don't think it's really faster.
351
+ # It would be more readable. Python does the below (with in) very quickly.
352
+ if level <= 50:
353
+ t = s[1:] # ignore leading minus
354
+ else:
355
+ t = s
356
+ # Python complexes are always printed with parentheses
357
+ # we try to avoid double parentheses
358
+ if not isinstance(o, complex) and \
359
+ (' ' in t or '/' in t or '+' in t or '-' in t or '*' in t
360
+ or '^' in t):
361
+ s = '(%s)' % s
362
+ return string_from_pystr(s)
363
+
364
+
365
+ cdef stdstring* py_latex(o, int level) noexcept:
366
+ """
367
+ Return latex string representation of o. If level > 0, possibly
368
+ put parentheses around the string.
369
+ """
370
+ from sage.misc.latex import latex
371
+ s = latex(o)
372
+ if level >= 20:
373
+ if ' ' in s or '/' in s or '+' in s or '-' in s or '*' in s or '^' in s or '\\frac' in s:
374
+ s = '\\left(%s\\right)' % s
375
+ return string_from_pystr(s)
376
+
377
+
378
+ cdef stdstring* string_from_pystr(py_str) except NULL:
379
+ """
380
+ Create a C++ string with the same contents as the given python string.
381
+
382
+ Used when passing string output to Pynac for printing, since we don't want
383
+ to mess with reference counts of the python objects and we cannot guarantee
384
+ they won't be garbage collected before the output is printed.
385
+ """
386
+ cdef bytes s
387
+ if isinstance(py_str, bytes):
388
+ s = <bytes>py_str
389
+ elif isinstance(py_str, str):
390
+ # Note: This should only by the case on Python 3 since on Python 2
391
+ # bytes is str
392
+ s = str_to_bytes(py_str)
393
+ else:
394
+ s = b"(INVALID)" # Avoid segfaults for invalid input
395
+ return new stdstring(s)
396
+
397
+ cdef stdstring* py_latex_variable(var_name) noexcept:
398
+ r"""
399
+ Return a c++ string containing the latex representation of the given
400
+ variable name.
401
+
402
+ Real work is done by the function sage.misc.latex.latex_variable_name.
403
+
404
+ EXAMPLES::
405
+
406
+ sage: from sage.symbolic.expression import py_latex_variable_for_doctests
407
+ sage: py_latex_variable = py_latex_variable_for_doctests
408
+
409
+ sage: py_latex_variable('a')
410
+ a
411
+ sage: py_latex_variable('abc')
412
+ \mathit{abc}
413
+ sage: py_latex_variable('a_00')
414
+ a_{00}
415
+ sage: py_latex_variable('sigma_k')
416
+ \sigma_{k}
417
+ sage: py_latex_variable('sigma389')
418
+ \sigma_{389}
419
+ sage: py_latex_variable('beta_00')
420
+ \beta_{00}
421
+ """
422
+ from sage.misc.latex import latex_variable_name
423
+ py_vlatex = latex_variable_name(var_name)
424
+ return string_from_pystr(py_vlatex)
425
+
426
+
427
+ def py_latex_variable_for_doctests(x):
428
+ r"""
429
+ Internal function used so we can doctest a certain cdef'd method.
430
+
431
+ EXAMPLES::
432
+
433
+ sage: sage.symbolic.expression.py_latex_variable_for_doctests('x')
434
+ x
435
+ sage: sage.symbolic.expression.py_latex_variable_for_doctests('sigma')
436
+ \sigma
437
+ """
438
+ cdef stdstring* ostr = py_latex_variable(x)
439
+ print(char_to_str(ostr.c_str()))
440
+ del ostr
441
+
442
+
443
+ def py_print_function_pystring(id, args, fname_paren=False):
444
+ """
445
+ Return a string with the representation of the symbolic function specified
446
+ by the given id applied to args.
447
+
448
+ INPUT:
449
+
450
+ - ``id`` -- serial number of the corresponding symbolic function
451
+ - ``params`` -- set of parameter numbers with respect to which to take the
452
+ derivative
453
+ - ``args`` -- arguments of the function
454
+
455
+ EXAMPLES::
456
+
457
+ sage: from sage.symbolic.expression import py_print_function_pystring, get_ginac_serial, get_fn_serial
458
+ sage: from sage.symbolic.function import get_sfunction_from_serial
459
+ sage: var('x,y,z')
460
+ (x, y, z)
461
+ sage: foo = function('foo', nargs=2)
462
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
463
+ ....: if get_sfunction_from_serial(i) == foo: break
464
+
465
+ sage: get_sfunction_from_serial(i) == foo
466
+ True
467
+ sage: py_print_function_pystring(i, (x,y))
468
+ 'foo(x, y)'
469
+ sage: py_print_function_pystring(i, (x,y), True)
470
+ '(foo)(x, y)'
471
+ sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args))
472
+ sage: foo = function('foo', nargs=2, print_func=my_print)
473
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
474
+ ....: if get_sfunction_from_serial(i) == foo: break
475
+
476
+ sage: get_sfunction_from_serial(i) == foo
477
+ True
478
+ sage: py_print_function_pystring(i, (x,y))
479
+ 'my args are: x, y'
480
+ """
481
+ cdef Function func = get_sfunction_from_serial(id)
482
+ # This function is called from two places, from function::print in Pynac
483
+ # and from py_print_fderivative. function::print checks if the serial
484
+ # belongs to a function defined at the C++ level. There are no C++ level
485
+ # functions that return an instance of fderivative when derivated. Hence,
486
+ # func will never be None.
487
+ assert(func is not None)
488
+
489
+ # if function has a custom print function call it
490
+ if hasattr(func,'_print_'):
491
+ res = func._print_(*args)
492
+ # make sure the output is a string
493
+ if res is None:
494
+ return ""
495
+ if not isinstance(res, str):
496
+ return str(res)
497
+ return res
498
+
499
+ # otherwise use default output
500
+ if fname_paren:
501
+ olist = ['(', func._name, ')']
502
+ else:
503
+ olist = [func._name]
504
+ olist.extend(['(', ', '.join(map(repr, args)), ')'])
505
+ return ''.join(olist)
506
+
507
+
508
+ cdef stdstring* py_print_function(unsigned id, args) noexcept:
509
+ return string_from_pystr(py_print_function_pystring(id, args))
510
+
511
+
512
+ def py_latex_function_pystring(id, args, fname_paren=False):
513
+ r"""
514
+ Return a string with the latex representation of the symbolic function
515
+ specified by the given id applied to args.
516
+
517
+ See documentation of py_print_function_pystring for more information.
518
+
519
+ EXAMPLES::
520
+
521
+ sage: from sage.symbolic.expression import py_latex_function_pystring, get_ginac_serial, get_fn_serial
522
+ sage: from sage.symbolic.function import get_sfunction_from_serial
523
+ sage: var('x,y,z')
524
+ (x, y, z)
525
+ sage: foo = function('foo', nargs=2)
526
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
527
+ ....: if get_sfunction_from_serial(i) == foo: break
528
+
529
+ sage: get_sfunction_from_serial(i) == foo
530
+ True
531
+ sage: py_latex_function_pystring(i, (x,y^z))
532
+ '{\\rm foo}\\left(x, y^{z}\\right)'
533
+ sage: py_latex_function_pystring(i, (x,y^z), True)
534
+ '\\left({\\rm foo}\\right)\\left(x, y^{z}\\right)'
535
+ sage: py_latex_function_pystring(i, (int(0),x))
536
+ '{\\rm foo}\\left(0, x\\right)'
537
+
538
+ Test latex_name::
539
+
540
+ sage: foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}')
541
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
542
+ ....: if get_sfunction_from_serial(i) == foo: break
543
+
544
+ sage: get_sfunction_from_serial(i) == foo
545
+ True
546
+ sage: py_latex_function_pystring(i, (x,y^z))
547
+ '\\mathrm{bar}\\left(x, y^{z}\\right)'
548
+
549
+ Test custom func::
550
+
551
+ sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args))
552
+ sage: foo = function('foo', nargs=2, print_latex_func=my_print)
553
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
554
+ ....: if get_sfunction_from_serial(i) == foo: break
555
+
556
+ sage: get_sfunction_from_serial(i) == foo
557
+ True
558
+ sage: py_latex_function_pystring(i, (x,y^z))
559
+ 'my args are: x, y^z'
560
+ """
561
+ cdef Function func = get_sfunction_from_serial(id)
562
+ # This function is called from two places, from function::print in Pynac
563
+ # and from py_latex_fderivative. function::print checks if the serial
564
+ # belongs to a function defined at the C++ level. There are no C++ level
565
+ # functions that return an instance of fderivative when derivated. Hence,
566
+ # func will never be None.
567
+ assert(func is not None)
568
+
569
+ # if function has a custom print method call it
570
+ if hasattr(func, '_print_latex_'):
571
+ res = func._print_latex_(*args)
572
+ # make sure the output is a string
573
+ if res is None:
574
+ return ""
575
+ if not isinstance(res, str):
576
+ return str(res)
577
+ return res
578
+
579
+ # otherwise, use the latex name if defined
580
+ if func._latex_name:
581
+ name = func._latex_name
582
+ else:
583
+ # if latex_name is not defined, then call
584
+ # latex_variable_name with "is_fname=True" flag
585
+ from sage.misc.latex import latex_variable_name
586
+ name = latex_variable_name(func._name, is_fname=True)
587
+ if fname_paren:
588
+ olist = [r'\left(', name, r'\right)']
589
+ else:
590
+ olist = [name]
591
+ # print the arguments
592
+ from sage.misc.latex import latex
593
+ olist.extend([r'\left(', ', '.join(latex(x) for x in args),
594
+ r'\right)'])
595
+ return ''.join(olist)
596
+
597
+
598
+ cdef stdstring* py_latex_function(unsigned id, args) noexcept:
599
+ return string_from_pystr(py_latex_function_pystring(id, args))
600
+
601
+
602
+ def tolerant_is_symbol(a):
603
+ """
604
+ Utility function to test if something is a symbol.
605
+
606
+ Returns False for arguments that do not have an is_symbol attribute.
607
+ Returns the result of calling the is_symbol method otherwise.
608
+
609
+ EXAMPLES::
610
+
611
+ sage: from sage.symbolic.expression import tolerant_is_symbol
612
+ sage: tolerant_is_symbol(var("x"))
613
+ True
614
+ sage: tolerant_is_symbol(None)
615
+ False
616
+ sage: None.is_symbol()
617
+ Traceback (most recent call last):
618
+ ...
619
+ AttributeError: 'NoneType' object has no attribute 'is_symbol'...
620
+ """
621
+ try:
622
+ return a.is_symbol()
623
+ except AttributeError:
624
+ return False
625
+
626
+
627
+ cdef stdstring* py_print_fderivative(unsigned id, params,
628
+ args) noexcept:
629
+ """
630
+ Return a string with the representation of the derivative of the symbolic
631
+ function specified by the given id, lists of params and args.
632
+
633
+ INPUT:
634
+
635
+ - ``id`` -- serial number of the corresponding symbolic function
636
+ - ``params`` -- set of parameter numbers with respect to which to take the
637
+ derivative
638
+ - ``args`` -- arguments of the function
639
+ """
640
+ if all(tolerant_is_symbol(a) for a in args) and len(set(args)) == len(args):
641
+ diffvarstr = ', '.join(repr(args[i]) for i in params)
642
+ py_res = ''.join(['diff(', py_print_function_pystring(id, args, False),
643
+ ', ', diffvarstr, ')'])
644
+ else:
645
+ ostr = ''.join(['D[', ', '.join(repr(int(x)) for x in params), ']'])
646
+ fstr = py_print_function_pystring(id, args, True)
647
+ py_res = ostr + fstr
648
+ return string_from_pystr(py_res)
649
+
650
+
651
+ def py_print_fderivative_for_doctests(id, params, args):
652
+ """
653
+ Used for testing a cdef'd function.
654
+
655
+ EXAMPLES::
656
+
657
+ sage: from sage.symbolic.expression import py_print_fderivative_for_doctests as py_print_fderivative, get_ginac_serial, get_fn_serial
658
+ sage: var('x,y,z')
659
+ (x, y, z)
660
+ sage: from sage.symbolic.function import get_sfunction_from_serial
661
+ sage: foo = function('foo', nargs=2)
662
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
663
+ ....: if get_sfunction_from_serial(i) == foo: break
664
+
665
+ sage: get_sfunction_from_serial(i) == foo
666
+ True
667
+ sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
668
+ D[0, 1, 0, 1](foo)(x, y^z)
669
+
670
+ Test custom print function::
671
+
672
+ sage: def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')'
673
+ sage: foo = function('foo', nargs=2, print_func=my_print)
674
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
675
+ ....: if get_sfunction_from_serial(i) == foo: break
676
+
677
+ sage: get_sfunction_from_serial(i) == foo
678
+ True
679
+ sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
680
+ D[0, 1, 0, 1]func_with_args(x, y^z)
681
+ """
682
+ cdef stdstring* ostr = py_print_fderivative(id, params, args)
683
+ print(char_to_str(ostr.c_str()))
684
+ del ostr
685
+
686
+
687
+ cdef stdstring* py_latex_fderivative(unsigned id, params,
688
+ args) noexcept:
689
+ """
690
+ Return a string with the latex representation of the derivative of the
691
+ symbolic function specified by the given id, lists of params and args.
692
+
693
+ See documentation of py_print_fderivative for more information.
694
+ """
695
+ if all(tolerant_is_symbol(a) for a in args) and len(set(args)) == len(args):
696
+ param_iter = iter(params)
697
+ v = next(param_iter)
698
+ nv = 1
699
+ diff_args = []
700
+ for next_v in param_iter:
701
+ if next_v == v:
702
+ nv += 1
703
+ else:
704
+ if nv == 1:
705
+ diff_args.append(r"\partial %s" % (args[v]._latex_(),))
706
+ else:
707
+ diff_args.append(r"(\partial %s)^{%s}" % (args[v]._latex_(),nv))
708
+ v=next_v
709
+ nv=1
710
+ if nv == 1:
711
+ diff_args.append(r"\partial %s" % (args[v]._latex_(),))
712
+ else:
713
+ diff_args.append(r"(\partial %s)^{%s}" % (args[v]._latex_(),nv))
714
+ if len(params) == 1:
715
+ operator_string=r"\frac{\partial}{%s}" % (''.join(diff_args),)
716
+ else:
717
+ operator_string=r"\frac{\partial^{%s}}{%s}" % (len(params),''.join(diff_args))
718
+ py_res = operator_string+py_latex_function_pystring(id, args, False)
719
+ else:
720
+ ostr = ''.join([r'\mathrm{D}_{',
721
+ ', '.join(repr(int(x)) for x in params), '}'])
722
+ fstr = py_latex_function_pystring(id, args, True)
723
+ py_res = ostr + fstr
724
+ return string_from_pystr(py_res)
725
+
726
+
727
+ def py_latex_fderivative_for_doctests(id, params, args):
728
+ r"""
729
+ Used internally for writing doctests for certain cdef'd functions.
730
+
731
+ EXAMPLES::
732
+
733
+ sage: from sage.symbolic.expression import py_latex_fderivative_for_doctests as py_latex_fderivative, get_ginac_serial, get_fn_serial
734
+
735
+ sage: var('x,y,z')
736
+ (x, y, z)
737
+ sage: from sage.symbolic.function import get_sfunction_from_serial
738
+ sage: foo = function('foo', nargs=2)
739
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
740
+ ....: if get_sfunction_from_serial(i) == foo: break
741
+
742
+ sage: get_sfunction_from_serial(i) == foo
743
+ True
744
+ sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
745
+ \mathrm{D}_{0, 1, 0, 1}\left({\rm foo}\right)\left(x, y^{z}\right)
746
+
747
+ Test latex_name::
748
+
749
+ sage: foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}')
750
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
751
+ ....: if get_sfunction_from_serial(i) == foo: break
752
+
753
+ sage: get_sfunction_from_serial(i) == foo
754
+ True
755
+ sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
756
+ \mathrm{D}_{0, 1, 0, 1}\left(\mathrm{bar}\right)\left(x, y^{z}\right)
757
+
758
+ Test custom func::
759
+
760
+ sage: def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')'
761
+ sage: foo = function('foo', nargs=2, print_latex_func=my_print)
762
+ sage: for i in range(get_ginac_serial(), get_fn_serial()):
763
+ ....: if get_sfunction_from_serial(i) == foo: break
764
+
765
+ sage: get_sfunction_from_serial(i) == foo
766
+ True
767
+ sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
768
+ \mathrm{D}_{0, 1, 0, 1}func_with_args(x, y^z)
769
+ """
770
+ cdef stdstring* ostr = py_latex_fderivative(id, params, args)
771
+ print(char_to_str(ostr.c_str()))
772
+ del ostr
773
+
774
+ #################################################################
775
+ # Archive helpers
776
+ #################################################################
777
+
778
+ cdef stdstring* py_dumps(o) noexcept:
779
+ s = dumps(o, compress=False)
780
+ # pynac archive format terminates atoms with zeroes.
781
+ # since pickle output can break the archive format
782
+ # we use the base64 data encoding
783
+ import base64
784
+ s = base64.b64encode(s)
785
+ return string_from_pystr(s)
786
+
787
+ cdef py_loads(s):
788
+ import base64
789
+ s = base64.b64decode(s)
790
+ return loads(s)
791
+
792
+ cdef py_get_sfunction_from_serial(unsigned s):
793
+ """
794
+ Return the Python object associated with a serial.
795
+ """
796
+ return get_sfunction_from_serial(s)
797
+
798
+ cdef unsigned py_get_serial_from_sfunction(f) noexcept:
799
+ """
800
+ Given a Function object return its serial.
801
+
802
+ Python's unpickling mechanism is used to unarchive a symbolic function with
803
+ custom methods (evaluation, differentiation, etc.). Pynac extracts a string
804
+ representation from the archive, calls loads() to recreate the stored
805
+ function. This allows us to extract the serial from the Python object to
806
+ set the corresponding member variable of the C++ object representing this
807
+ function.
808
+ """
809
+ return (<Function>f)._serial
810
+
811
+ cdef unsigned py_get_serial_for_new_sfunction(stdstring &s,
812
+ unsigned nargs) noexcept:
813
+ """
814
+ Return a symbolic function with the given name and number of arguments.
815
+
816
+ When unarchiving a user defined symbolic function, Pynac goes through
817
+ the registry of existing functions. If there is no function already defined
818
+ with the archived name and number of arguments, this method is called to
819
+ create one and set up the function tables properly.
820
+ """
821
+ from sage.symbolic.function_factory import function_factory
822
+ cdef Function fn = function_factory(s.c_str(), nargs)
823
+ return fn._serial
824
+
825
+
826
+ #################################################################
827
+ # Modular helpers
828
+ #################################################################
829
+
830
+ cdef int py_get_parent_char(o) except -1:
831
+ """
832
+ TESTS:
833
+
834
+ :issue:`24072` fixes the workaround provided in :issue:`21187`::
835
+
836
+ sage: # needs sage.rings.finite_rings
837
+ sage: p = next_prime(2^100)
838
+ sage: R.<y> = FiniteField(p)[]
839
+ sage: y = SR(y)
840
+ Traceback (most recent call last):
841
+ ...
842
+ TypeError: positive characteristic not allowed in symbolic computations
843
+ """
844
+ if not isinstance(o, Element):
845
+ return 0
846
+
847
+ c = (<Element>o)._parent.characteristic()
848
+
849
+ # Pynac only differentiates between
850
+ # - characteristic 0
851
+ # - characteristic 2
852
+ # - characteristic > 0 but not 2
853
+ #
854
+ # To avoid integer overflow in the last case, we just return 3
855
+ # instead of the actual characteristic.
856
+ if not c:
857
+ return 0
858
+ elif c == 2:
859
+ return 2
860
+ else:
861
+ return 3
862
+
863
+
864
+ #################################################################
865
+ # power helpers
866
+ #################################################################
867
+
868
+ cdef py_rational_power_parts(base, exp):
869
+ if type(base) is not Rational:
870
+ base = Rational(base)
871
+ if type(exp) is not Rational:
872
+ exp = Rational(exp)
873
+ res= rational_power_parts(base, exp)
874
+ return res + (bool(res[0] == 1),)
875
+
876
+ #################################################################
877
+ # Binomial Coefficients
878
+ #################################################################
879
+
880
+
881
+ cdef py_binomial_int(int n, unsigned int k):
882
+ cdef bint sign
883
+ if n < 0:
884
+ n = -n + (k-1)
885
+ sign = k % 2
886
+ else:
887
+ sign = 0
888
+ cdef Integer ans = PY_NEW(Integer)
889
+ # Compute the binomial coefficient using GMP.
890
+ mpz_bin_uiui(ans.value, n, k)
891
+ # Return the answer or the negative of it (only if k is odd and n is negative).
892
+ if sign:
893
+ return -ans
894
+ else:
895
+ return ans
896
+
897
+ cdef py_binomial(n, k):
898
+ # Keep track of the sign we should use.
899
+ cdef bint sign
900
+ if n < 0:
901
+ n = k-n-1
902
+ sign = k % 2
903
+ else:
904
+ sign = 0
905
+ # Convert n and k to unsigned ints.
906
+ cdef unsigned int n_ = n, k_ = k
907
+ cdef Integer ans = PY_NEW(Integer)
908
+ # Compute the binomial coefficient using GMP.
909
+ mpz_bin_uiui(ans.value, n_, k_)
910
+ # Return the answer or the negative of it (only if k is odd and n is negative).
911
+ if sign:
912
+ return -ans
913
+ else:
914
+ return ans
915
+
916
+
917
+ def test_binomial(n, k):
918
+ """
919
+ The Binomial coefficients. It computes the binomial coefficients. For
920
+ integer n and k and positive n this is the number of ways of choosing k
921
+ objects from n distinct objects. If n is negative, the formula
922
+ binomial(n,k) == (-1)^k*binomial(k-n-1,k) is used to compute the result.
923
+
924
+ INPUT:
925
+
926
+ - ``n``, ``k`` -- integers, with ``k >= 0``
927
+
928
+ OUTPUT: integer
929
+
930
+ EXAMPLES::
931
+
932
+ sage: import sage.symbolic.expression
933
+ sage: sage.symbolic.expression.test_binomial(5,2)
934
+ 10
935
+ sage: sage.symbolic.expression.test_binomial(-5,3)
936
+ -35
937
+ sage: -sage.symbolic.expression.test_binomial(3-(-5)-1, 3)
938
+ -35
939
+ """
940
+ return py_binomial(n, k)
941
+
942
+
943
+ #################################################################
944
+ # GCD
945
+ #################################################################
946
+ cdef py_gcd(n, k):
947
+ if isinstance(n, Integer) and isinstance(k, Integer):
948
+ if mpz_cmp_si((<Integer>n).value, 1) == 0:
949
+ return n
950
+ elif mpz_cmp_si((<Integer>k).value, 1) == 0:
951
+ return k
952
+ return n.gcd(k)
953
+
954
+ if type(n) is Rational and type(k) is Rational:
955
+ return n.content(k)
956
+ try:
957
+ return gcd(n, k)
958
+ except (TypeError, ValueError, AttributeError):
959
+ # some strange meaning in case of weird things with no usual lcm.
960
+ return 1
961
+
962
+
963
+ #################################################################
964
+ # LCM
965
+ #################################################################
966
+ cdef py_lcm(n, k):
967
+ if isinstance(n, Integer) and isinstance(k, Integer):
968
+ if mpz_cmp_si((<Integer>n).value, 1) == 0:
969
+ return k
970
+ elif mpz_cmp_si((<Integer>k).value, 1) == 0:
971
+ return n
972
+ return n.lcm(k)
973
+ try:
974
+ return lcm(n, k)
975
+ except (TypeError, ValueError, AttributeError):
976
+ # some strange meaning in case of weird things with no usual lcm, e.g.,
977
+ # elements of finite fields.
978
+ return 1
979
+
980
+
981
+ #################################################################
982
+ # Real Part
983
+ #################################################################
984
+ cdef py_real(x):
985
+ """
986
+ Return the real part of x.
987
+
988
+ TESTS::
989
+
990
+ sage: from sage.symbolic.expression import py_real_for_doctests as py_real
991
+ sage: py_real(I)
992
+ 0
993
+ sage: py_real(CC(1,5))
994
+ 1.00000000000000
995
+ sage: py_real(CC(1))
996
+ 1.00000000000000
997
+ sage: py_real(RR(1))
998
+ 1.00000000000000
999
+
1000
+ sage: py_real(Mod(2,7))
1001
+ 2
1002
+
1003
+ sage: py_real(QQ['x'].gen())
1004
+ x
1005
+ sage: py_real(float(2))
1006
+ 2.0
1007
+ sage: py_real(complex(2,2))
1008
+ 2.0
1009
+ """
1010
+ if isinstance(x, (float, int)):
1011
+ return x
1012
+ elif isinstance(x, complex):
1013
+ return x.real
1014
+
1015
+ try:
1016
+ return x.real()
1017
+ except AttributeError:
1018
+ pass
1019
+ try:
1020
+ return x.real_part()
1021
+ except AttributeError:
1022
+ pass
1023
+
1024
+ return x # assume x is real
1025
+
1026
+
1027
+ def py_real_for_doctests(x):
1028
+ """
1029
+ Used for doctesting py_real.
1030
+
1031
+ TESTS::
1032
+
1033
+ sage: from sage.symbolic.expression import py_real_for_doctests
1034
+ sage: py_real_for_doctests(I)
1035
+ 0
1036
+ """
1037
+ return py_real(x)
1038
+
1039
+
1040
+ #################################################################
1041
+ # Imaginary Part
1042
+ #################################################################
1043
+ cdef py_imag(x):
1044
+ """
1045
+ Return the imaginary part of x.
1046
+
1047
+ TESTS::
1048
+
1049
+ sage: from sage.symbolic.expression import py_imag_for_doctests as py_imag
1050
+ sage: py_imag(I)
1051
+ 1
1052
+ sage: py_imag(CC(1,5))
1053
+ 5.00000000000000
1054
+ sage: py_imag(CC(1))
1055
+ 0.000000000000000
1056
+ sage: py_imag(RR(1))
1057
+ 0
1058
+ sage: py_imag(Mod(2,7))
1059
+ 0
1060
+
1061
+ sage: py_imag(QQ['x'].gen())
1062
+ 0
1063
+ sage: py_imag(float(2))
1064
+ 0.0
1065
+ sage: py_imag(complex(2,2))
1066
+ 2.0
1067
+ """
1068
+ if isinstance(x, float):
1069
+ return 0.0
1070
+ if isinstance(x, complex):
1071
+ return x.imag
1072
+ try:
1073
+ return x.imag()
1074
+ except AttributeError:
1075
+ pass
1076
+ try:
1077
+ return x.imag_part()
1078
+ except AttributeError:
1079
+ pass
1080
+
1081
+ return 0 # assume x is real
1082
+
1083
+
1084
+ def py_imag_for_doctests(x):
1085
+ """
1086
+ Used for doctesting py_imag.
1087
+
1088
+ TESTS::
1089
+
1090
+ sage: from sage.symbolic.expression import py_imag_for_doctests
1091
+ sage: py_imag_for_doctests(I)
1092
+ 1
1093
+ """
1094
+ return py_imag(x)
1095
+
1096
+
1097
+ #################################################################
1098
+ # Conjugate
1099
+ #################################################################
1100
+ cdef py_conjugate(x):
1101
+ try:
1102
+ return x.conjugate()
1103
+ except AttributeError:
1104
+ return x # assume is real since it doesn't have an imag attribute.
1105
+
1106
+
1107
+ cdef bint py_is_rational(x) noexcept:
1108
+ return (type(x) is Rational or
1109
+ type(x) is Integer or
1110
+ isinstance(x, int))
1111
+
1112
+
1113
+ cdef bint py_is_equal(x, y) noexcept:
1114
+ """
1115
+ Return ``True`` precisely if x and y are equal.
1116
+ """
1117
+ return bool(x == y)
1118
+
1119
+
1120
+ cdef bint py_is_integer(x) noexcept:
1121
+ r"""
1122
+ Return ``True`` if pynac should treat this object as an integer.
1123
+
1124
+ EXAMPLES::
1125
+
1126
+ sage: from sage.symbolic.expression import py_is_integer_for_doctests
1127
+ sage: py_is_integer = py_is_integer_for_doctests
1128
+
1129
+ sage: py_is_integer(1r)
1130
+ True
1131
+ sage: py_is_integer(3^57)
1132
+ True
1133
+ sage: py_is_integer(SR(5))
1134
+ True
1135
+ sage: SCR = SR.subring(no_variables=True); SCR
1136
+ Symbolic Constants Subring
1137
+ sage: py_is_integer(SCR(5))
1138
+ True
1139
+ sage: py_is_integer(4/2)
1140
+ True
1141
+ sage: py_is_integer(QQbar(sqrt(2))^2) # needs sage.rings.number_field
1142
+ True
1143
+ sage: py_is_integer(3.0)
1144
+ False
1145
+ sage: py_is_integer(3.0r)
1146
+ False
1147
+ """
1148
+ if isinstance(x, (int, Integer)):
1149
+ return True
1150
+ if not isinstance(x, Element):
1151
+ return False
1152
+ P = (<Element>x)._parent
1153
+ from sage.symbolic.ring import SymbolicRing
1154
+ return (isinstance(P, SymbolicRing) or P.is_exact()) and x in ZZ
1155
+
1156
+
1157
+ def py_is_integer_for_doctests(x):
1158
+ """
1159
+ Used internally for doctesting purposes.
1160
+
1161
+ TESTS::
1162
+
1163
+ sage: sage.symbolic.expression.py_is_integer_for_doctests(1r)
1164
+ True
1165
+ sage: sage.symbolic.expression.py_is_integer_for_doctests(1/3)
1166
+ False
1167
+ sage: sage.symbolic.expression.py_is_integer_for_doctests(2)
1168
+ True
1169
+ """
1170
+ return py_is_integer(x)
1171
+
1172
+
1173
+ cdef bint py_is_even(x) noexcept:
1174
+ try:
1175
+ return not(x % 2)
1176
+ except Exception:
1177
+ try:
1178
+ return not(ZZ(x) % 2)
1179
+ except Exception:
1180
+ pass
1181
+ return 0
1182
+
1183
+
1184
+ cdef bint py_is_crational(x) noexcept:
1185
+ if py_is_rational(x):
1186
+ return True
1187
+ return isinstance(x, Element) and (<Element>x)._parent is pynac_I._parent
1188
+
1189
+
1190
+ def py_is_crational_for_doctest(x):
1191
+ r"""
1192
+ Return ``True`` if pynac should treat this object as an element of `\QQ(i)`.
1193
+
1194
+ TESTS::
1195
+
1196
+ sage: from sage.symbolic.expression import py_is_crational_for_doctest
1197
+ sage: py_is_crational_for_doctest(1)
1198
+ True
1199
+ sage: py_is_crational_for_doctest(-2r)
1200
+ True
1201
+ sage: py_is_crational_for_doctest(1.5)
1202
+ False
1203
+ sage: py_is_crational_for_doctest(I)
1204
+ True
1205
+ sage: py_is_crational_for_doctest(I+1/2)
1206
+ True
1207
+ """
1208
+ return py_is_crational(x)
1209
+
1210
+
1211
+ cdef bint py_is_real(a) noexcept:
1212
+ if isinstance(a, (int, Integer, float)):
1213
+ return True
1214
+ try:
1215
+ P = parent(a)
1216
+ if P.is_field() and P.is_finite():
1217
+ return False
1218
+ except NotImplementedError:
1219
+ return False
1220
+ except (TypeError, AttributeError):
1221
+ pass
1222
+ return py_imag(a) == 0
1223
+
1224
+
1225
+ cdef bint py_is_prime(n) noexcept:
1226
+ try:
1227
+ return n.is_prime()
1228
+ except Exception: # yes, I'm doing this on purpose.
1229
+ pass
1230
+ try:
1231
+ return is_prime(n)
1232
+ except Exception:
1233
+ pass
1234
+ return False
1235
+
1236
+
1237
+ cdef bint py_is_exact(x) noexcept:
1238
+ if isinstance(x, (int, Integer)):
1239
+ return True
1240
+ if not isinstance(x, Element):
1241
+ return False
1242
+ P = (<Element>x)._parent
1243
+ from sage.symbolic.ring import SymbolicRing
1244
+ return isinstance(P, SymbolicRing) or P.is_exact()
1245
+
1246
+
1247
+ cdef py_numer(n):
1248
+ """
1249
+ Return the numerator of the given object. This is called for
1250
+ typesetting coefficients.
1251
+
1252
+ TESTS::
1253
+
1254
+ sage: from sage.symbolic.expression import py_numer_for_doctests as py_numer
1255
+ sage: py_numer(2r)
1256
+ 2
1257
+ sage: py_numer(3)
1258
+ 3
1259
+ sage: py_numer(2/3)
1260
+ 2
1261
+ sage: C.<i> = NumberField(x^2 + 1) # needs sage.rings.number_field
1262
+ sage: py_numer(2/3*i) # needs sage.rings.number_field
1263
+ 2*i
1264
+ sage: class no_numer:
1265
+ ....: def denominator(self):
1266
+ ....: return 5
1267
+ ....: def __mul__(left, right):
1268
+ ....: return 42
1269
+ ...
1270
+ sage: py_numer(no_numer())
1271
+ 42
1272
+ """
1273
+ if isinstance(n, (int, Integer)):
1274
+ return n
1275
+ try:
1276
+ return n.numerator()
1277
+ except AttributeError:
1278
+ try:
1279
+ return n*n.denominator()
1280
+ except AttributeError:
1281
+ return n
1282
+
1283
+
1284
+ def py_numer_for_doctests(n):
1285
+ """
1286
+ This function is used to test py_numer().
1287
+
1288
+ EXAMPLES::
1289
+
1290
+ sage: from sage.symbolic.expression import py_numer_for_doctests
1291
+ sage: py_numer_for_doctests(2/3)
1292
+ 2
1293
+ """
1294
+ return py_numer(n)
1295
+
1296
+ cdef py_denom(n):
1297
+ """
1298
+ Return the denominator of the given object. This is called for
1299
+ typesetting coefficients.
1300
+
1301
+ TESTS::
1302
+
1303
+ sage: from sage.symbolic.expression import py_denom_for_doctests as py_denom
1304
+ sage: py_denom(5)
1305
+ 1
1306
+ sage: py_denom(2/3)
1307
+ 3
1308
+ sage: C.<i> = NumberField(x^2 + 1) # needs sage.rings.number_field
1309
+ sage: py_denom(2/3*i) # needs sage.rings.number_field
1310
+ 3
1311
+ """
1312
+ if isinstance(n, (int, Integer)):
1313
+ return 1
1314
+ try:
1315
+ return n.denominator()
1316
+ except AttributeError:
1317
+ return 1
1318
+
1319
+
1320
+ def py_denom_for_doctests(n):
1321
+ """
1322
+ This function is used to test py_denom().
1323
+
1324
+ EXAMPLES::
1325
+
1326
+ sage: from sage.symbolic.expression import py_denom_for_doctests
1327
+ sage: py_denom_for_doctests(2/3)
1328
+ 3
1329
+ """
1330
+ return py_denom(n)
1331
+
1332
+
1333
+ cdef bint py_is_cinteger(x) noexcept:
1334
+ return py_is_integer(x) or (py_is_crational(x) and py_denom(x) == 1)
1335
+
1336
+
1337
+ def py_is_cinteger_for_doctest(x):
1338
+ r"""
1339
+ Return ``True`` if pynac should treat this object as an element of `\ZZ(i)`.
1340
+
1341
+ TESTS::
1342
+
1343
+ sage: from sage.symbolic.expression import py_is_cinteger_for_doctest
1344
+ sage: py_is_cinteger_for_doctest(1)
1345
+ True
1346
+ sage: py_is_cinteger_for_doctest(I)
1347
+ True
1348
+ sage: py_is_cinteger_for_doctest(I - 3)
1349
+ True
1350
+ sage: py_is_cinteger_for_doctest(I + 1/2)
1351
+ False
1352
+ """
1353
+ return py_is_cinteger(x)
1354
+
1355
+ cdef py_float(n, PyObject* kwds):
1356
+ """
1357
+ Evaluate pynac numeric objects numerically.
1358
+
1359
+ TESTS::
1360
+
1361
+ sage: from sage.symbolic.expression import py_float_for_doctests as py_float
1362
+ sage: py_float(I, {'parent':ComplexField(10)})
1363
+ 1.0*I
1364
+ sage: py_float(pi, {'parent':RealField(100)})
1365
+ 3.1415926535897932384626433833
1366
+ sage: py_float(10, {'parent':CDF})
1367
+ 10.0
1368
+ sage: type(py_float(10, {'parent':CDF}))
1369
+ <class 'sage.rings.complex_double.ComplexDoubleElement'>
1370
+ sage: py_float(1/2, {'parent':CC})
1371
+ 0.500000000000000
1372
+ sage: type(py_float(1/2, {'parent':CC}))
1373
+ <class 'sage.rings.complex_mpfr.ComplexNumber'>
1374
+ """
1375
+ if kwds is not NULL:
1376
+ p = (<object>kwds)['parent']
1377
+ if p is float:
1378
+ try:
1379
+ return float(n)
1380
+ except TypeError:
1381
+ return complex(n)
1382
+ elif p is complex:
1383
+ return p(n)
1384
+ else:
1385
+ try:
1386
+ return p(n)
1387
+ except (TypeError,ValueError):
1388
+ return p.complex_field()(n)
1389
+ else:
1390
+ try:
1391
+ return RR(n)
1392
+ except TypeError:
1393
+ return CC(n)
1394
+
1395
+
1396
+ def py_float_for_doctests(n, kwds):
1397
+ """
1398
+ This function is for testing py_float.
1399
+
1400
+ EXAMPLES::
1401
+
1402
+ sage: from sage.symbolic.expression import py_float_for_doctests
1403
+ sage: py_float_for_doctests(pi, {'parent':RealField(80)})
1404
+ 3.1415926535897932384626
1405
+ sage: py_float_for_doctests(I, {'parent':RealField(80)})
1406
+ 1.0000000000000000000000*I
1407
+ sage: py_float_for_doctests(I, {'parent':float})
1408
+ 1j
1409
+ sage: py_float_for_doctests(pi, {'parent':complex})
1410
+ (3.141592653589793+0j)
1411
+ """
1412
+ return py_float(n, <PyObject*>kwds)
1413
+
1414
+
1415
+ cdef py_RDF_from_double(double x):
1416
+ cdef RealDoubleElement r = RealDoubleElement.__new__(RealDoubleElement)
1417
+ r._value = x
1418
+ return r
1419
+
1420
+ #################################################################
1421
+ # SPECIAL FUNCTIONS
1422
+ #################################################################
1423
+ cdef py_tgamma(x):
1424
+ """
1425
+ The gamma function exported to pynac.
1426
+
1427
+ TESTS::
1428
+
1429
+ sage: from sage.symbolic.expression import py_tgamma_for_doctests as py_tgamma
1430
+ sage: py_tgamma(4)
1431
+ 6
1432
+ sage: py_tgamma(1/2)
1433
+ 1.77245385090552
1434
+ """
1435
+ if isinstance(x, int):
1436
+ x = float(x)
1437
+ if type(x) is float:
1438
+ return math.tgamma(PyFloat_AS_DOUBLE(x))
1439
+
1440
+ # try / except blocks are faster than
1441
+ # if hasattr(x, 'gamma')
1442
+ try:
1443
+ res = x.gamma()
1444
+ except AttributeError:
1445
+ return CC(x).gamma()
1446
+
1447
+ # the result should be numeric, however the gamma method of rationals may
1448
+ # return symbolic expressions. for example (1/2).gamma() -> sqrt(pi).
1449
+ if isinstance(res, Expression):
1450
+ try:
1451
+ return RR(res)
1452
+ except ValueError:
1453
+ return CC(res)
1454
+ return res
1455
+
1456
+
1457
+ def py_tgamma_for_doctests(x):
1458
+ """
1459
+ This function is for testing py_tgamma().
1460
+
1461
+ TESTS::
1462
+
1463
+ sage: from sage.symbolic.expression import py_tgamma_for_doctests
1464
+ sage: py_tgamma_for_doctests(3)
1465
+ 2
1466
+ """
1467
+ return py_tgamma(x)
1468
+
1469
+ cdef py_factorial(x):
1470
+ """
1471
+ The factorial function exported to pynac.
1472
+
1473
+ TESTS::
1474
+
1475
+ sage: from sage.symbolic.expression import py_factorial_py as py_factorial
1476
+ sage: py_factorial(4)
1477
+ 24
1478
+ sage: py_factorial(-2/3)
1479
+ 2.67893853470775
1480
+ """
1481
+ # factorial(x) is only defined for nonnegative integers x
1482
+ # so we first test if x can be coerced into ZZ and is nonnegative.
1483
+ # If this is not the case then we return the symbolic expression gamma(x+1)
1484
+ # This fixes Issue 9240
1485
+ try:
1486
+ x_in_ZZ = ZZ(x)
1487
+ coercion_success = True
1488
+ except (TypeError, ValueError):
1489
+ coercion_success = False
1490
+
1491
+ if coercion_success and x_in_ZZ >= 0:
1492
+ return factorial(x)
1493
+ else:
1494
+ return py_tgamma(x+1)
1495
+
1496
+
1497
+ def py_factorial_py(x):
1498
+ """
1499
+ This function is a python wrapper around py_factorial(). This wrapper
1500
+ is needed when we override the eval() method for GiNaC's factorial
1501
+ function in sage.functions.other.Function_factorial.
1502
+
1503
+ TESTS::
1504
+
1505
+ sage: from sage.symbolic.expression import py_factorial_py
1506
+ sage: py_factorial_py(3)
1507
+ 6
1508
+ """
1509
+ return py_factorial(x)
1510
+
1511
+ cdef py_doublefactorial(x):
1512
+ n = Integer(x)
1513
+ if n < -1:
1514
+ raise ValueError("argument must be >= -1")
1515
+ from sage.misc.misc_c import prod # fast balanced product
1516
+ return prod([n - 2*i for i in range(n//2)])
1517
+
1518
+
1519
+ def doublefactorial(n):
1520
+ """
1521
+ The double factorial combinatorial function:
1522
+
1523
+ n!! == n * (n-2) * (n-4) * ... * ({1|2}) with 0!! == (-1)!! == 1.
1524
+
1525
+ INPUT:
1526
+
1527
+ - ``n`` -- integer ``>= 1``
1528
+
1529
+ EXAMPLES::
1530
+
1531
+ sage: from sage.symbolic.expression import doublefactorial
1532
+ sage: doublefactorial(-1)
1533
+ 1
1534
+ sage: doublefactorial(0)
1535
+ 1
1536
+ sage: doublefactorial(1)
1537
+ 1
1538
+ sage: doublefactorial(5)
1539
+ 15
1540
+ sage: doublefactorial(20)
1541
+ 3715891200
1542
+ sage: prod( [20,18,..,2] )
1543
+ 3715891200
1544
+ """
1545
+ return py_doublefactorial(n)
1546
+
1547
+
1548
+ cdef py_fibonacci(n):
1549
+ from sage.libs.pari import pari
1550
+ return Integer(pari(n).fibonacci())
1551
+
1552
+ cdef py_step(n):
1553
+ """
1554
+ Return step function of n.
1555
+ """
1556
+ from sage.symbolic.ring import SR
1557
+ if n < 0:
1558
+ return SR(0)
1559
+ elif n > 0:
1560
+ return SR(1)
1561
+ return SR(Rational((1,2)))
1562
+
1563
+ cdef py_bernoulli(x):
1564
+ return bernoulli(x)
1565
+
1566
+ cdef py_sin(x):
1567
+ """
1568
+ TESTS::
1569
+
1570
+ sage: sin(float(2)) #indirect doctest
1571
+ 0.9092974268256817
1572
+ sage: sin(2.)
1573
+ 0.909297426825682
1574
+ sage: sin(2.*I)
1575
+ 3.62686040784702*I
1576
+ sage: sin(QQbar(I)) # known bug
1577
+ I*sinh(1)
1578
+ """
1579
+ try:
1580
+ return x.sin()
1581
+ except AttributeError:
1582
+ pass
1583
+ try:
1584
+ return RR(x).sin()
1585
+ except (TypeError, ValueError):
1586
+ return CC(x).sin()
1587
+
1588
+ cdef py_cos(x):
1589
+ """
1590
+ TESTS::
1591
+
1592
+ sage: cos(float(2)) #indirect doctest
1593
+ -0.4161468365471424
1594
+ sage: cos(2.)
1595
+ -0.416146836547142
1596
+ sage: cos(2.*I)
1597
+ 3.76219569108363
1598
+ sage: cos(QQbar(I)) # known bug
1599
+ cosh(1)
1600
+ """
1601
+ try:
1602
+ return x.cos()
1603
+ except AttributeError:
1604
+ pass
1605
+ try:
1606
+ return RR(x).cos()
1607
+ except (TypeError, ValueError):
1608
+ return CC(x).cos()
1609
+
1610
+ cdef py_stieltjes(x):
1611
+ """
1612
+ Return the Stieltjes constant of the given index.
1613
+
1614
+ The value is expected to be a nonnegative integer.
1615
+
1616
+ TESTS::
1617
+
1618
+ sage: from sage.symbolic.expression import py_stieltjes_for_doctests as py_stieltjes
1619
+ sage: py_stieltjes(0)
1620
+ 0.577215664901533
1621
+ sage: py_stieltjes(1.0)
1622
+ -0.0728158454836767
1623
+ sage: py_stieltjes(RealField(100)(5))
1624
+ 0.00079332381730106270175333487744
1625
+ sage: py_stieltjes(-1)
1626
+ Traceback (most recent call last):
1627
+ ...
1628
+ ValueError: Stieltjes constant of negative index
1629
+ """
1630
+ n = ZZ(x)
1631
+ if n < 0:
1632
+ raise ValueError("Stieltjes constant of negative index")
1633
+ import mpmath
1634
+ if isinstance(x, Element) and hasattr((<Element>x)._parent, 'prec'):
1635
+ prec = (<Element>x)._parent.prec()
1636
+ else:
1637
+ prec = 53
1638
+ return mpmath_utils.call(mpmath.stieltjes, n, prec=prec)
1639
+
1640
+
1641
+ def py_stieltjes_for_doctests(x):
1642
+ """
1643
+ This function is for testing py_stieltjes().
1644
+
1645
+ EXAMPLES::
1646
+
1647
+ sage: from sage.symbolic.expression import py_stieltjes_for_doctests
1648
+ sage: py_stieltjes_for_doctests(0.0)
1649
+ 0.577215664901533
1650
+ """
1651
+ return py_stieltjes(x)
1652
+
1653
+ cdef py_zeta(x):
1654
+ """
1655
+ Return the value of the zeta function at the given value.
1656
+
1657
+ The value is expected to be a numerical object, in RR, CC, RDF or CDF,
1658
+ different from 1.
1659
+
1660
+ TESTS::
1661
+
1662
+ sage: # needs sage.libs.pari
1663
+ sage: from sage.symbolic.expression import py_zeta_for_doctests as py_zeta
1664
+ sage: py_zeta(CC.0)
1665
+ 0.00330022368532410 - 0.418155449141322*I
1666
+ sage: py_zeta(CDF(5))
1667
+ 1.03692775514337
1668
+ sage: py_zeta(RealField(100)(5))
1669
+ 1.0369277551433699263313654865
1670
+ """
1671
+ try:
1672
+ return x.zeta()
1673
+ except AttributeError:
1674
+ return CC(x).zeta()
1675
+
1676
+
1677
+ def py_zeta_for_doctests(x):
1678
+ """
1679
+ This function is for testing py_zeta().
1680
+
1681
+ EXAMPLES::
1682
+
1683
+ sage: # needs sage.libs.pari
1684
+ sage: from sage.symbolic.expression import py_zeta_for_doctests
1685
+ sage: py_zeta_for_doctests(CC.0)
1686
+ 0.00330022368532410 - 0.418155449141322*I
1687
+ """
1688
+ return py_zeta(x)
1689
+
1690
+ cdef py_exp(x):
1691
+ """
1692
+ Return the value of the exp function at the given value.
1693
+
1694
+ The value is expected to be a numerical object, in RR, CC, RDF or CDF.
1695
+
1696
+ TESTS::
1697
+
1698
+ sage: from sage.symbolic.expression import py_exp_for_doctests as py_exp
1699
+ sage: py_exp(CC(1))
1700
+ 2.71828182845905
1701
+ sage: py_exp(CC(.5*I))
1702
+ 0.877582561890373 + 0.479425538604203*I
1703
+ sage: py_exp(float(1))
1704
+ 2.718281828459045...
1705
+ sage: py_exp(QQbar(I))
1706
+ 0.540302305868140 + 0.841470984807897*I
1707
+ """
1708
+ if type(x) is float:
1709
+ return math.exp(PyFloat_AS_DOUBLE(x))
1710
+ try:
1711
+ return x.exp()
1712
+ except AttributeError:
1713
+ pass
1714
+ try:
1715
+ return RR(x).exp()
1716
+ except (TypeError, ValueError):
1717
+ return CC(x).exp()
1718
+
1719
+
1720
+ def py_exp_for_doctests(x):
1721
+ """
1722
+ This function tests py_exp.
1723
+
1724
+ EXAMPLES::
1725
+
1726
+ sage: from sage.symbolic.expression import py_exp_for_doctests
1727
+ sage: py_exp_for_doctests(CC(2))
1728
+ 7.38905609893065
1729
+ """
1730
+ return py_exp(x)
1731
+
1732
+ cdef py_log(x):
1733
+ """
1734
+ Return the value of the log function at the given value.
1735
+
1736
+ The value is expected to be a numerical object, in RR, CC, RDF or CDF.
1737
+
1738
+ TESTS::
1739
+
1740
+ sage: from sage.symbolic.expression import py_log_for_doctests as py_log
1741
+ sage: py_log(CC(e))
1742
+ 1.00000000000000
1743
+ sage: py_log(CC.0)
1744
+ 1.57079632679490*I
1745
+ sage: py_log(float(e))
1746
+ 1.0
1747
+ sage: py_log(float(0))
1748
+ -inf
1749
+ sage: py_log(float(-1))
1750
+ 3.141592653589793j
1751
+ sage: py_log(int(1))
1752
+ 0.0
1753
+ sage: py_log(int(0))
1754
+ -inf
1755
+ sage: py_log(complex(0))
1756
+ -inf
1757
+ sage: py_log(2)
1758
+ 0.693147180559945
1759
+ """
1760
+ cdef gsl_complex res
1761
+ cdef double real, imag
1762
+ if isinstance(x, int):
1763
+ x = float(x)
1764
+ if type(x) is float:
1765
+ real = PyFloat_AS_DOUBLE(x)
1766
+ if real > 0:
1767
+ return math.log(real)
1768
+ elif real < 0:
1769
+ res = gsl_complex_log(gsl_complex_rect(real, 0))
1770
+ return PyComplex_FromDoubles(GSL_REAL(res), GSL_IMAG(res))
1771
+ else:
1772
+ return float('-inf')
1773
+ elif type(x) is complex:
1774
+ real = PyComplex_RealAsDouble(x)
1775
+ imag = PyComplex_ImagAsDouble(x)
1776
+ if real == 0 and imag == 0:
1777
+ return float('-inf')
1778
+ res = gsl_complex_log(gsl_complex_rect(real, imag))
1779
+ return PyComplex_FromDoubles(GSL_REAL(res), GSL_IMAG(res))
1780
+ elif isinstance(x, Integer):
1781
+ return x.log().n()
1782
+ elif hasattr(x, 'log'):
1783
+ return x.log()
1784
+ try:
1785
+ return RR(x).log()
1786
+ except (TypeError, ValueError):
1787
+ return CC(x).log()
1788
+
1789
+
1790
+ def py_log_for_doctests(x):
1791
+ """
1792
+ This function tests py_log.
1793
+
1794
+ EXAMPLES::
1795
+
1796
+ sage: from sage.symbolic.expression import py_log_for_doctests
1797
+ sage: py_log_for_doctests(CC(e))
1798
+ 1.00000000000000
1799
+ """
1800
+ return py_log(x)
1801
+
1802
+ cdef py_tan(x):
1803
+ try:
1804
+ return x.tan()
1805
+ except AttributeError:
1806
+ pass
1807
+ try:
1808
+ return RR(x).tan()
1809
+ except TypeError:
1810
+ return CC(x).tan()
1811
+
1812
+ cdef py_asin(x):
1813
+ try:
1814
+ return x.arcsin()
1815
+ except AttributeError:
1816
+ return RR(x).arcsin()
1817
+
1818
+
1819
+ cdef py_acos(x):
1820
+ try:
1821
+ return x.arccos()
1822
+ except AttributeError:
1823
+ return RR(x).arccos()
1824
+
1825
+
1826
+ cdef py_atan(x):
1827
+ try:
1828
+ return x.arctan()
1829
+ except AttributeError:
1830
+ return RR(x).arctan()
1831
+
1832
+
1833
+ cdef py_atan2(x, y):
1834
+ """
1835
+ Return the value of the two argument arctan function at the given values.
1836
+
1837
+ The values are expected to be numerical objects, for example in RR, CC,
1838
+ RDF or CDF.
1839
+
1840
+ Note that the usual call signature of this function has the arguments
1841
+ reversed.
1842
+
1843
+ TESTS::
1844
+
1845
+ sage: from sage.symbolic.expression import py_atan2_for_doctests as py_atan2
1846
+ sage: py_atan2(0, 1)
1847
+ 1.57079632679490
1848
+ sage: py_atan2(0.r, 1.r)
1849
+ 1.5707963267948966
1850
+ sage: CC100 = ComplexField(100)
1851
+ sage: py_atan2(CC100(0), CC100(1))
1852
+ 1.5707963267948966192313216916
1853
+ sage: RR100 = RealField(100)
1854
+ sage: py_atan2(RR100(0), RR100(1))
1855
+ 1.5707963267948966192313216916
1856
+
1857
+ Check that :issue:`21428` is fixed::
1858
+
1859
+ sage: plot(real(sqrt(x - 1.*I)), (x,0,1)) # needs sage.plot
1860
+ Graphics object consisting of 1 graphics primitive
1861
+
1862
+ Check that :issue:`22553` is fixed::
1863
+
1864
+ sage: arctan2(1.5, -1.300000000000001)
1865
+ 2.284887025407...
1866
+ sage: atan2(2.1000000000000000000000000000000000000, -1.20000000000000000000000000000000)
1867
+ 2.089942441041419571002776071...
1868
+
1869
+ Check that :issue:`22877` is fixed::
1870
+
1871
+ sage: atan2(CC(I), CC(I+1))
1872
+ 0.553574358897045 + 0.402359478108525*I
1873
+ sage: atan2(CBF(I), CBF(I+1))
1874
+ [0.55357435889705 +/- ...] + [0.402359478108525 +/- ...]*I
1875
+
1876
+ Check that :issue:`23776` is fixed and RDF input gives real output::
1877
+
1878
+ sage: atan2(RDF(-3), RDF(-1))
1879
+ -1.8925468811915387
1880
+ """
1881
+ from sage.symbolic.constants import I, pi, NaN
1882
+ P = coercion_model.common_parent(x, y)
1883
+ if P is ZZ:
1884
+ P = RR
1885
+ if y != 0:
1886
+ if RR.has_coerce_map_from(P):
1887
+ if x > 0:
1888
+ res = py_atan(abs(y/x))
1889
+ elif x < 0:
1890
+ res = P(pi) - py_atan(abs(y/x))
1891
+ else:
1892
+ res = P(pi)/2
1893
+ return res if y > 0 else -res
1894
+ else:
1895
+ return -I*py_log((x + I*y)/py_sqrt(x**2 + y**2))
1896
+ else:
1897
+ if x > 0:
1898
+ return P(0)
1899
+ elif x < 0:
1900
+ return P(pi)
1901
+ else:
1902
+ return P(NaN)
1903
+
1904
+
1905
+ def py_atan2_for_doctests(x, y):
1906
+ """
1907
+ Wrapper function to test py_atan2.
1908
+
1909
+ TESTS::
1910
+
1911
+ sage: from sage.symbolic.expression import py_atan2_for_doctests
1912
+ sage: py_atan2_for_doctests(0., 1.)
1913
+ 1.57079632679490
1914
+ """
1915
+ return py_atan2(x, y)
1916
+
1917
+
1918
+ cdef py_sinh(x):
1919
+ try:
1920
+ return x.sinh()
1921
+ except AttributeError:
1922
+ return RR(x).sinh()
1923
+
1924
+
1925
+ cdef py_cosh(x):
1926
+ if type(x) is float:
1927
+ return math.cosh(PyFloat_AS_DOUBLE(x))
1928
+ try:
1929
+ return x.cosh()
1930
+ except AttributeError:
1931
+ return RR(x).cosh()
1932
+
1933
+
1934
+ cdef py_tanh(x):
1935
+ try:
1936
+ return x.tanh()
1937
+ except AttributeError:
1938
+ return RR(x).tanh()
1939
+
1940
+
1941
+ cdef py_asinh(x):
1942
+ try:
1943
+ return x.arcsinh()
1944
+ except AttributeError:
1945
+ pass
1946
+ try:
1947
+ return RR(x).arcsinh()
1948
+ except TypeError:
1949
+ return CC(x).arcsinh()
1950
+
1951
+
1952
+ cdef py_acosh(x):
1953
+ try:
1954
+ return x.arccosh()
1955
+ except AttributeError:
1956
+ pass
1957
+ try:
1958
+ return RR(x).arccosh()
1959
+ except TypeError:
1960
+ return CC(x).arccosh()
1961
+
1962
+
1963
+ cdef py_atanh(x):
1964
+ try:
1965
+ return x.arctanh()
1966
+ except AttributeError:
1967
+ pass
1968
+ try:
1969
+ return RR(x).arctanh()
1970
+ except TypeError:
1971
+ return CC(x).arctanh()
1972
+
1973
+
1974
+ cdef py_lgamma(x):
1975
+ """
1976
+ Return the value of the principal branch of the log gamma function at the
1977
+ given value.
1978
+
1979
+ The value is expected to be a numerical object, in RR, CC, RDF or CDF, or
1980
+ of the Python ``float`` or ``complex`` type.
1981
+
1982
+ EXAMPLES::
1983
+
1984
+ sage: from sage.symbolic.expression import py_lgamma_for_doctests as py_lgamma
1985
+ sage: py_lgamma(4)
1986
+ 1.79175946922805
1987
+ sage: py_lgamma(4.r) # abs tol 2e-14
1988
+ 1.79175946922805
1989
+ sage: py_lgamma(4r) # abs tol 2e-14
1990
+ 1.79175946922805
1991
+ sage: py_lgamma(CC.0)
1992
+ -0.650923199301856 - 1.87243664726243*I
1993
+ sage: py_lgamma(ComplexField(100).0)
1994
+ -0.65092319930185633888521683150 - 1.8724366472624298171188533494*I
1995
+ """
1996
+ from mpmath import loggamma
1997
+
1998
+ try:
1999
+ return x.log_gamma()
2000
+ except AttributeError:
2001
+ pass
2002
+ try:
2003
+ return RR(x).log_gamma()
2004
+ except TypeError:
2005
+ return mpmath_utils.call(loggamma, x, parent=parent(x))
2006
+
2007
+
2008
+ def py_lgamma_for_doctests(x):
2009
+ """
2010
+ This function tests py_lgamma.
2011
+
2012
+ EXAMPLES::
2013
+
2014
+ sage: from sage.symbolic.expression import py_lgamma_for_doctests
2015
+ sage: py_lgamma_for_doctests(CC(I))
2016
+ -0.650923199301856 - 1.87243664726243*I
2017
+ """
2018
+ return py_lgamma(x)
2019
+
2020
+
2021
+ cdef py_isqrt(x):
2022
+ return Integer(x).isqrt()
2023
+
2024
+
2025
+ cdef py_sqrt(x):
2026
+ try:
2027
+ # WORRY: What if Integer's sqrt calls symbolic one and we go in circle?
2028
+ return x.sqrt()
2029
+ except AttributeError as msg:
2030
+ return math.sqrt(float(x))
2031
+
2032
+
2033
+ cdef py_abs(x):
2034
+ return abs(x)
2035
+
2036
+
2037
+ cdef py_mod(x, n):
2038
+ """
2039
+ Return x mod n. Both x and n are assumed to be integers.
2040
+
2041
+ EXAMPLES::
2042
+
2043
+ sage: from sage.symbolic.expression import py_mod_for_doctests as py_mod
2044
+ sage: py_mod(I.parent(5), 4)
2045
+ 1
2046
+ sage: py_mod(3, -2)
2047
+ -1
2048
+ sage: py_mod(3/2, 2)
2049
+ Traceback (most recent call last):
2050
+ ...
2051
+ TypeError: no conversion of this rational to integer
2052
+
2053
+
2054
+ Note: The original code for this function in GiNaC checks if the arguments
2055
+ are integers, and returns 0 otherwise. We omit this check, since all the
2056
+ calls to py_mod are preceded by an integer check. We also raise an error
2057
+ if converting the arguments to integers fails, since silently returning 0
2058
+ would hide possible misuses of this function.
2059
+
2060
+ Regarding the sign of the return value, the CLN reference manual says:
2061
+
2062
+ If x and y are both >= 0, mod(x,y) = rem(x,y) >= 0. In general,
2063
+ mod(x,y) has the sign of y or is zero, and rem(x,y) has the sign of
2064
+ x or is zero.
2065
+
2066
+ This matches the behavior of the % operator for integers in Sage.
2067
+ """
2068
+ return Integer(x) % Integer(n)
2069
+
2070
+
2071
+ def py_mod_for_doctests(x, n):
2072
+ """
2073
+ This function is a python wrapper so py_mod can be tested. The real tests
2074
+ are in the docstring for py_mod.
2075
+
2076
+ EXAMPLES::
2077
+
2078
+ sage: from sage.symbolic.expression import py_mod_for_doctests
2079
+ sage: py_mod_for_doctests(5, 2)
2080
+ 1
2081
+ """
2082
+ return py_mod(x, n)
2083
+
2084
+
2085
+ cdef py_smod(a, b):
2086
+ # Modulus (in symmetric representation).
2087
+ # Equivalent to Maple's mods.
2088
+ # returns a mod b in the range [-iquo(abs(b)-1,2), iquo(abs(b),2)]
2089
+ a = Integer(a)
2090
+ b = Integer(b)
2091
+ b = abs(b)
2092
+ c = a % b
2093
+ if c > b // 2:
2094
+ c -= b
2095
+ return c
2096
+
2097
+
2098
+ cdef py_irem(x, n):
2099
+ return Integer(x) % Integer(n)
2100
+
2101
+
2102
+ cdef py_iquo(x, n):
2103
+ return Integer(x)//Integer(n)
2104
+
2105
+
2106
+ cdef py_iquo2(x, n):
2107
+ x = Integer(x)
2108
+ n = Integer(n)
2109
+ try:
2110
+ q = x//n
2111
+ r = x - q*n
2112
+ return q, r
2113
+ except (TypeError, ValueError):
2114
+ return 0, 0
2115
+
2116
+
2117
+ cdef int py_int_length(x) except -1:
2118
+ # Size in binary notation. For integers, this is the smallest n >= 0 such
2119
+ # that -2^n <= x < 2^n. If x > 0, this is the unique n > 0 such that
2120
+ # 2^(n-1) <= x < 2^n. This returns 0 if x is not an integer.
2121
+ return Integer(x).nbits()
2122
+
2123
+
2124
+ cdef py_li(x, n, parent):
2125
+ """
2126
+ Return a numerical approximation of polylog(n, x) with precision given
2127
+ by the ``parent`` argument.
2128
+
2129
+ EXAMPLES::
2130
+
2131
+ sage: from sage.symbolic.expression import py_li_for_doctests as py_li
2132
+ sage: py_li(0,2,RR)
2133
+ 0.000000000000000
2134
+ sage: py_li(-1,2,RR)
2135
+ -0.822467033424113
2136
+ sage: py_li(0, 1, float)
2137
+ 0.000000000000000
2138
+ """
2139
+ import mpmath
2140
+ try:
2141
+ prec = parent.prec()
2142
+ except AttributeError:
2143
+ prec = 53
2144
+ return mpmath_utils.call(mpmath.polylog, n, x, prec=prec)
2145
+
2146
+
2147
+ def py_li_for_doctests(x, n, parent):
2148
+ """
2149
+ This function is a python wrapper so py_li can be tested. The real tests
2150
+ are in the docstring for py_li.
2151
+
2152
+ EXAMPLES::
2153
+
2154
+ sage: from sage.symbolic.expression import py_li_for_doctests
2155
+ sage: py_li_for_doctests(0,2,float)
2156
+ 0.000000000000000
2157
+ """
2158
+ return py_li(x, n, parent)
2159
+
2160
+
2161
+ cdef py_psi(x):
2162
+ """
2163
+ EXAMPLES::
2164
+
2165
+ sage: from sage.symbolic.expression import py_psi_for_doctests as py_psi
2166
+ sage: py_psi(0)
2167
+ Traceback (most recent call last):
2168
+ ...
2169
+ ValueError: polygamma pole
2170
+ sage: py_psi(1)
2171
+ -0.577215664901533
2172
+ sage: euler_gamma.n()
2173
+ 0.577215664901533
2174
+ """
2175
+ import mpmath
2176
+ if isinstance(x, Element) and hasattr((<Element>x)._parent, 'prec'):
2177
+ prec = (<Element>x)._parent.prec()
2178
+ else:
2179
+ prec = 53
2180
+ return mpmath_utils.call(mpmath.psi, 0, x, prec=prec)
2181
+
2182
+
2183
+ def py_psi_for_doctests(x):
2184
+ """
2185
+ This function is a python wrapper so py_psi can be tested. The real tests
2186
+ are in the docstring for py_psi.
2187
+
2188
+ EXAMPLES::
2189
+
2190
+ sage: from sage.symbolic.expression import py_psi_for_doctests
2191
+ sage: py_psi_for_doctests(2)
2192
+ 0.422784335098467
2193
+ """
2194
+ return py_psi(x)
2195
+
2196
+ cdef py_psi2(n, x):
2197
+ """
2198
+ EXAMPLES::
2199
+
2200
+ sage: from sage.symbolic.expression import py_psi2_for_doctests as py_psi2
2201
+ sage: py_psi2(2, 1)
2202
+ -2.40411380631919
2203
+ """
2204
+ import mpmath
2205
+ if isinstance(x, Element) and hasattr((<Element>x)._parent, 'prec'):
2206
+ prec = (<Element>x)._parent.prec()
2207
+ else:
2208
+ prec = 53
2209
+ return mpmath_utils.call(mpmath.psi, n, x, prec=prec)
2210
+
2211
+
2212
+ def py_psi2_for_doctests(n, x):
2213
+ """
2214
+ This function is a python wrapper so py_psi2 can be tested. The real tests
2215
+ are in the docstring for py_psi2.
2216
+
2217
+ EXAMPLES::
2218
+
2219
+ sage: from sage.symbolic.expression import py_psi2_for_doctests
2220
+ sage: py_psi2_for_doctests(1, 2)
2221
+ 0.644934066848226
2222
+ """
2223
+ return py_psi2(n, x)
2224
+
2225
+ cdef py_li2(x):
2226
+ """
2227
+ EXAMPLES::
2228
+
2229
+ sage: from sage.symbolic.expression import py_li2_for_doctests as py_li2
2230
+ sage: py_li2(-1.1)
2231
+ -0.890838090262283
2232
+ """
2233
+ import mpmath
2234
+ if isinstance(x, Element) and hasattr((<Element>x)._parent, 'prec'):
2235
+ prec = (<Element>x)._parent.prec()
2236
+ else:
2237
+ prec = 53
2238
+ return mpmath_utils.call(mpmath.polylog, 2, x, prec=prec)
2239
+
2240
+
2241
+ def py_li2_for_doctests(x):
2242
+ """
2243
+ This function is a python wrapper so py_psi2 can be tested. The real tests
2244
+ are in the docstring for py_psi2.
2245
+
2246
+ EXAMPLES::
2247
+
2248
+ sage: from sage.symbolic.expression import py_li2_for_doctests
2249
+ sage: py_li2_for_doctests(-1.1)
2250
+ -0.890838090262283
2251
+ """
2252
+ return py_li2(x)
2253
+
2254
+
2255
+ ##################################################################
2256
+ # Constants
2257
+ ##################################################################
2258
+
2259
+ cdef GConstant py_get_constant(const char* name) noexcept:
2260
+ """
2261
+ Return a constant given its name. This is called by constant::unarchive in
2262
+ constant.cpp in Pynac and is used for pickling.
2263
+ """
2264
+ from sage.symbolic.constants import constants_name_table
2265
+ cdef PynacConstant pc
2266
+ c = constants_name_table.get(char_to_str(name), None)
2267
+ if c is None:
2268
+ raise RuntimeError
2269
+ else:
2270
+ pc = c._pynac
2271
+ return pc.pointer[0]
2272
+
2273
+ cdef py_eval_constant(unsigned serial, kwds):
2274
+ from sage.symbolic.constants import constants_table
2275
+ constant = constants_table[serial]
2276
+ return kwds['parent'](constant)
2277
+
2278
+ cdef py_eval_unsigned_infinity():
2279
+ """
2280
+ Return ``unsigned_infinity``.
2281
+ """
2282
+ from sage.rings.infinity import unsigned_infinity
2283
+ return unsigned_infinity
2284
+
2285
+
2286
+ def py_eval_unsigned_infinity_for_doctests():
2287
+ """
2288
+ This function tests py_eval_unsigned_infinity.
2289
+
2290
+ TESTS::
2291
+
2292
+ sage: from sage.symbolic.expression import py_eval_unsigned_infinity_for_doctests as py_eval_unsigned_infinity
2293
+ sage: py_eval_unsigned_infinity()
2294
+ Infinity
2295
+ """
2296
+ return py_eval_unsigned_infinity()
2297
+
2298
+ cdef py_eval_infinity():
2299
+ """
2300
+ Return positive infinity, i.e., oo.
2301
+ """
2302
+ from sage.rings.infinity import infinity
2303
+ return infinity
2304
+
2305
+
2306
+ def py_eval_infinity_for_doctests():
2307
+ """
2308
+ This function tests py_eval_infinity.
2309
+
2310
+ TESTS::
2311
+
2312
+ sage: from sage.symbolic.expression import py_eval_infinity_for_doctests as py_eval_infinity
2313
+ sage: py_eval_infinity()
2314
+ +Infinity
2315
+ """
2316
+ return py_eval_infinity()
2317
+
2318
+ cdef py_eval_neg_infinity():
2319
+ """
2320
+ Return ``minus_infinity``.
2321
+ """
2322
+ from sage.rings.infinity import minus_infinity
2323
+ return minus_infinity
2324
+
2325
+
2326
+ def py_eval_neg_infinity_for_doctests():
2327
+ """
2328
+ This function tests py_eval_neg_infinity.
2329
+
2330
+ TESTS::
2331
+
2332
+ sage: from sage.symbolic.expression import py_eval_neg_infinity_for_doctests as py_eval_neg_infinity
2333
+ sage: py_eval_neg_infinity()
2334
+ -Infinity
2335
+ """
2336
+ return py_eval_neg_infinity()
2337
+
2338
+ ##################################################################
2339
+ # Constructors
2340
+ ##################################################################
2341
+
2342
+ cdef py_integer_from_long(long x):
2343
+ return smallInteger(x)
2344
+
2345
+ cdef py_integer_from_python_obj(x):
2346
+ return Integer(x)
2347
+
2348
+ cdef py_integer_from_mpz(mpz_t bigint):
2349
+ cdef Integer z = PY_NEW(Integer)
2350
+ mpz_set(z.value, bigint)
2351
+ return z
2352
+
2353
+ cdef py_rational_from_mpq(mpq_t bigrat):
2354
+ cdef Rational rat = Rational.__new__(Rational)
2355
+ mpq_set(rat.value, bigrat)
2356
+ mpq_canonicalize(rat.value)
2357
+ return rat
2358
+
2359
+
2360
+ cdef bint py_is_Integer(x) noexcept:
2361
+ return isinstance(x, Integer)
2362
+
2363
+
2364
+ cdef bint py_is_Rational(x) noexcept:
2365
+ return isinstance(x, Rational)
2366
+
2367
+
2368
+ cdef mpz_ptr py_mpz_from_integer(x) noexcept:
2369
+ return <mpz_ptr>((<Integer>x).value)
2370
+
2371
+
2372
+ cdef mpq_ptr py_mpq_from_rational(x) noexcept:
2373
+ return <mpq_ptr>((<Rational>x).value)
2374
+
2375
+
2376
+ import sage.rings.integer
2377
+ ginac_pyinit_Integer(sage.rings.integer.Integer)
2378
+
2379
+ import sage.rings.real_double
2380
+ ginac_pyinit_Float(sage.rings.real_double.RDF)
2381
+
2382
+ cdef Element pynac_I
2383
+
2384
+
2385
+ def init_pynac_I():
2386
+ """
2387
+ Initialize the numeric ``I`` object in pynac. We use the generator of ``QQ(i)``.
2388
+
2389
+ EXAMPLES::
2390
+
2391
+ sage: from sage.symbolic.constants import I as symbolic_I
2392
+ sage: symbolic_I
2393
+ I
2394
+ sage: symbolic_I^2
2395
+ -1
2396
+
2397
+ Note that conversions to real fields will give :exc:`TypeError`::
2398
+
2399
+ sage: float(symbolic_I)
2400
+ Traceback (most recent call last):
2401
+ ...
2402
+ TypeError: unable to simplify to float approximation
2403
+ sage: gp(symbolic_I) # needs sage.libs.pari
2404
+ I
2405
+ sage: RR(symbolic_I)
2406
+ Traceback (most recent call last):
2407
+ ...
2408
+ TypeError: unable to convert '1.00000000000000*I' to a real number
2409
+
2410
+ We can convert to complex fields::
2411
+
2412
+ sage: C = ComplexField(200); C
2413
+ Complex Field with 200 bits of precision
2414
+ sage: C(symbolic_I)
2415
+ 1.0000000000000000000000000000000000000000000000000000000000*I
2416
+ sage: symbolic_I._complex_mpfr_field_(ComplexField(53))
2417
+ 1.00000000000000*I
2418
+
2419
+ sage: symbolic_I._complex_double_(CDF)
2420
+ 1.0*I
2421
+ sage: CDF(symbolic_I)
2422
+ 1.0*I
2423
+
2424
+ sage: z = symbolic_I + symbolic_I; z
2425
+ 2*I
2426
+ sage: C(z)
2427
+ 2.0000000000000000000000000000000000000000000000000000000000*I
2428
+ sage: 1e8*symbolic_I
2429
+ 1.00000000000000e8*I
2430
+
2431
+ sage: complex(symbolic_I)
2432
+ 1j
2433
+
2434
+ sage: QQbar(symbolic_I)
2435
+ I
2436
+
2437
+ sage: abs(symbolic_I)
2438
+ 1
2439
+
2440
+ sage: symbolic_I.minpoly()
2441
+ x^2 + 1
2442
+ sage: maxima(2*symbolic_I)
2443
+ 2*%i
2444
+
2445
+ TESTS::
2446
+
2447
+ sage: repr(symbolic_I)
2448
+ 'I'
2449
+ sage: latex(symbolic_I)
2450
+ i
2451
+
2452
+ sage: I = sage.symbolic.expression.init_pynac_I()
2453
+ sage: type(I)
2454
+ <class 'sage.symbolic.expression.Expression'>
2455
+ sage: type(I.pyobject())
2456
+ <class 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_gaussian'>
2457
+
2458
+ Check that :issue:`10064` is fixed::
2459
+
2460
+ sage: y = symbolic_I*symbolic_I*x / x # so y is the expression -1
2461
+ sage: y.is_positive()
2462
+ False
2463
+ sage: z = -x / x
2464
+ sage: z.is_positive()
2465
+ False
2466
+ sage: bool(z == y)
2467
+ True
2468
+
2469
+ Check that :issue:`31869` is fixed::
2470
+
2471
+ sage: x * ((3*I + 4)*x - 5)
2472
+ ((3*I + 4)*x - 5)*x
2473
+ """
2474
+ global pynac_I
2475
+ from sage.rings.number_field.number_field import GaussianField
2476
+ pynac_I = GaussianField().gen()
2477
+ ginac_pyinit_I(pynac_I)
2478
+ from sage.symbolic.ring import SR
2479
+ return new_Expression_from_GEx(SR, g_I)
2480
+
2481
+
2482
+ def init_function_table():
2483
+ """
2484
+ Initialize the function pointer table in Pynac. This must be
2485
+ called before Pynac is used; otherwise, there will be segfaults.
2486
+ """
2487
+
2488
+ py_funcs.py_gcd = &py_gcd
2489
+ py_funcs.py_lcm = &py_lcm
2490
+ py_funcs.py_real = &py_real
2491
+ py_funcs.py_imag = &py_imag
2492
+ py_funcs.py_numer = &py_numer
2493
+ py_funcs.py_denom = &py_denom
2494
+
2495
+ py_funcs.py_is_rational = &py_is_rational
2496
+ py_funcs.py_is_real = &py_is_real
2497
+ py_funcs.py_is_integer = &py_is_integer
2498
+ py_funcs.py_is_equal = &py_is_equal
2499
+ py_funcs.py_is_even = &py_is_even
2500
+ py_funcs.py_is_prime = &py_is_prime
2501
+ py_funcs.py_is_exact = &py_is_exact
2502
+
2503
+ py_funcs.py_integer_from_mpz = &py_integer_from_mpz
2504
+ py_funcs.py_rational_from_mpq = &py_rational_from_mpq
2505
+ py_funcs.py_integer_from_long = &py_integer_from_long
2506
+ py_funcs.py_integer_from_python_obj = &py_integer_from_python_obj
2507
+ py_funcs.py_is_Integer = &py_is_Integer
2508
+ py_funcs.py_is_Rational = &py_is_Rational
2509
+ py_funcs.py_mpz_from_integer = &py_mpz_from_integer
2510
+ py_funcs.py_mpq_from_rational = &py_mpq_from_rational
2511
+
2512
+ py_funcs.py_float = &py_float
2513
+
2514
+ py_funcs.py_factorial = &py_factorial
2515
+ py_funcs.py_doublefactorial = &py_doublefactorial
2516
+ py_funcs.py_fibonacci = &py_fibonacci
2517
+ py_funcs.py_step = &py_step
2518
+ py_funcs.py_bernoulli = &py_bernoulli
2519
+ py_funcs.py_sin = &py_sin
2520
+ py_funcs.py_cos = &py_cos
2521
+ py_funcs.py_stieltjes = &py_stieltjes
2522
+ py_funcs.py_zeta = &py_zeta
2523
+ py_funcs.py_exp = &py_exp
2524
+ py_funcs.py_log = &py_log
2525
+ py_funcs.py_tan = &py_tan
2526
+ py_funcs.py_asin = &py_asin
2527
+ py_funcs.py_acos = &py_acos
2528
+ py_funcs.py_atan = &py_atan
2529
+ py_funcs.py_atan2 = &py_atan2
2530
+ py_funcs.py_sinh = &py_sinh
2531
+ py_funcs.py_cosh = &py_cosh
2532
+ py_funcs.py_tanh = &py_tanh
2533
+ py_funcs.py_asinh = &py_asinh
2534
+ py_funcs.py_acosh = &py_acosh
2535
+ py_funcs.py_atanh = &py_atanh
2536
+ py_funcs.py_isqrt = &py_isqrt
2537
+ py_funcs.py_sqrt = &py_sqrt
2538
+ py_funcs.py_mod = &py_mod
2539
+ py_funcs.py_smod = &py_smod
2540
+ py_funcs.py_irem = &py_irem
2541
+ py_funcs.py_psi = &py_psi
2542
+ py_funcs.py_psi2 = &py_psi2
2543
+
2544
+ py_funcs.py_eval_constant = &py_eval_constant
2545
+ py_funcs.py_eval_unsigned_infinity = &py_eval_unsigned_infinity
2546
+ py_funcs.py_eval_infinity = &py_eval_infinity
2547
+ py_funcs.py_eval_neg_infinity = &py_eval_neg_infinity
2548
+
2549
+ py_funcs.py_get_parent_char = &py_get_parent_char
2550
+
2551
+ py_funcs.py_latex = &py_latex
2552
+ py_funcs.py_repr = &py_repr
2553
+
2554
+ py_funcs.py_dumps = &py_dumps
2555
+ py_funcs.py_loads = &py_loads
2556
+
2557
+ py_funcs.exvector_to_PyTuple = &exvector_to_PyTuple
2558
+ py_funcs.pyExpression_to_ex = &pyExpression_to_ex
2559
+ py_funcs.ex_to_pyExpression = &ex_to_pyExpression
2560
+ py_funcs.subs_args_to_PyTuple = &subs_args_to_PyTuple
2561
+ py_funcs.py_print_function = &py_print_function
2562
+ py_funcs.py_latex_function = &py_latex_function
2563
+ py_funcs.py_get_ginac_serial = &py_get_ginac_serial
2564
+ py_funcs.py_get_sfunction_from_serial = &py_get_sfunction_from_serial
2565
+ py_funcs.py_get_serial_from_sfunction = &py_get_serial_from_sfunction
2566
+ py_funcs.py_get_serial_for_new_sfunction = &py_get_serial_for_new_sfunction
2567
+
2568
+ py_funcs.py_get_constant = &py_get_constant
2569
+ py_funcs.py_print_fderivative = &py_print_fderivative
2570
+ py_funcs.py_latex_fderivative = &py_latex_fderivative
2571
+ py_funcs.paramset_to_PyTuple = &paramset_to_PyTuple
2572
+
2573
+
2574
+ init_function_table()
2575
+
2576
+ set_ginac_fn_serial()