passagemath-pari 10.6.32__cp314-cp314-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (331) hide show
  1. PARIKernel/__init__.py +2 -0
  2. PARIKernel/__main__.py +5 -0
  3. PARIKernel/io.cpython-314-x86_64-linux-musl.so +0 -0
  4. PARIKernel/io.pxd +7 -0
  5. PARIKernel/io.pyx +84 -0
  6. PARIKernel/kernel.cpython-314-x86_64-linux-musl.so +0 -0
  7. PARIKernel/kernel.pyx +260 -0
  8. PARIKernel/paridecl.pxd +95 -0
  9. PARIKernel/svg.cpython-314-x86_64-linux-musl.so +0 -0
  10. PARIKernel/svg.pyx +52 -0
  11. cypari2/__init__.py +8 -0
  12. cypari2/auto_paridecl.pxd +1070 -0
  13. cypari2/closure.cpython-314-x86_64-linux-musl.so +0 -0
  14. cypari2/closure.pxd +5 -0
  15. cypari2/closure.pyx +246 -0
  16. cypari2/convert.cpython-314-x86_64-linux-musl.so +0 -0
  17. cypari2/convert.pxd +80 -0
  18. cypari2/convert.pyx +613 -0
  19. cypari2/custom_block.cpython-314-x86_64-linux-musl.so +0 -0
  20. cypari2/custom_block.pyx +30 -0
  21. cypari2/cypari.h +13 -0
  22. cypari2/gen.cpython-314-x86_64-linux-musl.so +0 -0
  23. cypari2/gen.pxd +69 -0
  24. cypari2/gen.pyx +4819 -0
  25. cypari2/handle_error.cpython-314-x86_64-linux-musl.so +0 -0
  26. cypari2/handle_error.pxd +7 -0
  27. cypari2/handle_error.pyx +232 -0
  28. cypari2/pari_instance.cpython-314-x86_64-linux-musl.so +0 -0
  29. cypari2/pari_instance.pxd +27 -0
  30. cypari2/pari_instance.pyx +1438 -0
  31. cypari2/paridecl.pxd +5353 -0
  32. cypari2/paripriv.pxd +34 -0
  33. cypari2/pycore_long.h +98 -0
  34. cypari2/pycore_long.pxd +9 -0
  35. cypari2/stack.cpython-314-x86_64-linux-musl.so +0 -0
  36. cypari2/stack.pxd +27 -0
  37. cypari2/stack.pyx +278 -0
  38. cypari2/string_utils.cpython-314-x86_64-linux-musl.so +0 -0
  39. cypari2/string_utils.pxd +29 -0
  40. cypari2/string_utils.pyx +65 -0
  41. cypari2/types.pxd +147 -0
  42. passagemath_pari-10.6.32.data/data/etc/jupyter/nbconfig/notebook.d/gp-mode.json +5 -0
  43. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.js +28 -0
  44. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/kernel.json +6 -0
  45. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/pari_jupyter/logo-64x64.png +0 -0
  46. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/kernel.json +13 -0
  47. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-32x32.png +0 -0
  48. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-64x64.png +0 -0
  49. passagemath_pari-10.6.32.data/data/share/jupyter/kernels/xeus-gp/logo-svg.svg +75 -0
  50. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/gp.js +284 -0
  51. passagemath_pari-10.6.32.data/data/share/jupyter/nbextensions/gp-mode/main.js +15 -0
  52. passagemath_pari-10.6.32.dist-info/METADATA +209 -0
  53. passagemath_pari-10.6.32.dist-info/RECORD +331 -0
  54. passagemath_pari-10.6.32.dist-info/WHEEL +5 -0
  55. passagemath_pari-10.6.32.dist-info/top_level.txt +4 -0
  56. passagemath_pari.libs/libcrypto-f04afe95.so.3 +0 -0
  57. passagemath_pari.libs/libflint-fd6f12fc.so.21.0.0 +0 -0
  58. passagemath_pari.libs/libgcc_s-0cd532bd.so.1 +0 -0
  59. passagemath_pari.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  60. passagemath_pari.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
  61. passagemath_pari.libs/libgivaro-9a94c711.so.9.2.1 +0 -0
  62. passagemath_pari.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  63. passagemath_pari.libs/libgmpxx-9e08595c.so.4.7.0 +0 -0
  64. passagemath_pari.libs/libgsl-42cda06f.so.28.0.0 +0 -0
  65. passagemath_pari.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  66. passagemath_pari.libs/libncursesw-9c9e32c3.so.6.5 +0 -0
  67. passagemath_pari.libs/libntl-26885ca2.so.44.0.1 +0 -0
  68. passagemath_pari.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
  69. passagemath_pari.libs/libpari-gmp-tls-f31f908f.so.2.17.2 +0 -0
  70. passagemath_pari.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
  71. passagemath_pari.libs/libreadline-06542304.so.8.2 +0 -0
  72. passagemath_pari.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  73. passagemath_pari.libs/libuuid-f3770415.so.1.3.0 +0 -0
  74. passagemath_pari.libs/libxeus-735780ff.so.13.1.0 +0 -0
  75. passagemath_pari.libs/libxeus-zmq-c68577b4.so.6.0.1 +0 -0
  76. passagemath_pari.libs/libzmq-1ba9a3da.so.5.2.5 +0 -0
  77. sage/all__sagemath_pari.py +26 -0
  78. sage/databases/all__sagemath_pari.py +7 -0
  79. sage/databases/conway.py +274 -0
  80. sage/ext/all__sagemath_pari.py +1 -0
  81. sage/ext/memory.cpython-314-x86_64-linux-musl.so +0 -0
  82. sage/ext/memory.pyx +98 -0
  83. sage/ext_data/pari/buzzard/DimensionSk.g +286 -0
  84. sage/ext_data/pari/buzzard/Tpprog.g +179 -0
  85. sage/ext_data/pari/buzzard/genusn.g +129 -0
  86. sage/ext_data/pari/dokchitser/computel.gp +740 -0
  87. sage/ext_data/pari/dokchitser/computel.gp.template +740 -0
  88. sage/ext_data/pari/dokchitser/ex-bsw +43 -0
  89. sage/ext_data/pari/dokchitser/ex-chgen +48 -0
  90. sage/ext_data/pari/dokchitser/ex-chqua +37 -0
  91. sage/ext_data/pari/dokchitser/ex-delta +35 -0
  92. sage/ext_data/pari/dokchitser/ex-eisen +30 -0
  93. sage/ext_data/pari/dokchitser/ex-gen2 +38 -0
  94. sage/ext_data/pari/dokchitser/ex-gen3 +49 -0
  95. sage/ext_data/pari/dokchitser/ex-gen4 +54 -0
  96. sage/ext_data/pari/dokchitser/ex-nf +48 -0
  97. sage/ext_data/pari/dokchitser/ex-shin +50 -0
  98. sage/ext_data/pari/dokchitser/ex-tau2 +30 -0
  99. sage/ext_data/pari/dokchitser/ex-zeta +27 -0
  100. sage/ext_data/pari/dokchitser/ex-zeta2 +47 -0
  101. sage/ext_data/pari/dokchitser/testall +13 -0
  102. sage/ext_data/pari/simon/ell.gp +2129 -0
  103. sage/ext_data/pari/simon/ellQ.gp +2151 -0
  104. sage/ext_data/pari/simon/ellcommon.gp +126 -0
  105. sage/ext_data/pari/simon/qfsolve.gp +722 -0
  106. sage/ext_data/pari/simon/resultant3.gp +306 -0
  107. sage/groups/all__sagemath_pari.py +3 -0
  108. sage/groups/pari_group.py +175 -0
  109. sage/interfaces/all__sagemath_pari.py +1 -0
  110. sage/interfaces/genus2reduction.py +464 -0
  111. sage/interfaces/gp.py +1114 -0
  112. sage/libs/all__sagemath_pari.py +2 -0
  113. sage/libs/linkages/__init__.py +1 -0
  114. sage/libs/linkages/padics/API.pxi +617 -0
  115. sage/libs/linkages/padics/Polynomial_ram.pxi +388 -0
  116. sage/libs/linkages/padics/Polynomial_shared.pxi +554 -0
  117. sage/libs/linkages/padics/__init__.py +1 -0
  118. sage/libs/linkages/padics/fmpz_poly_unram.pxi +869 -0
  119. sage/libs/linkages/padics/mpz.pxi +691 -0
  120. sage/libs/linkages/padics/relaxed/API.pxi +518 -0
  121. sage/libs/linkages/padics/relaxed/__init__.py +1 -0
  122. sage/libs/linkages/padics/relaxed/flint.pxi +543 -0
  123. sage/libs/linkages/padics/unram_shared.pxi +247 -0
  124. sage/libs/pari/__init__.py +210 -0
  125. sage/libs/pari/all.py +5 -0
  126. sage/libs/pari/convert_flint.cpython-314-x86_64-linux-musl.so +0 -0
  127. sage/libs/pari/convert_flint.pxd +14 -0
  128. sage/libs/pari/convert_flint.pyx +159 -0
  129. sage/libs/pari/convert_gmp.cpython-314-x86_64-linux-musl.so +0 -0
  130. sage/libs/pari/convert_gmp.pxd +14 -0
  131. sage/libs/pari/convert_gmp.pyx +210 -0
  132. sage/libs/pari/convert_sage.cpython-314-x86_64-linux-musl.so +0 -0
  133. sage/libs/pari/convert_sage.pxd +16 -0
  134. sage/libs/pari/convert_sage.pyx +588 -0
  135. sage/libs/pari/convert_sage_complex_double.cpython-314-x86_64-linux-musl.so +0 -0
  136. sage/libs/pari/convert_sage_complex_double.pxd +14 -0
  137. sage/libs/pari/convert_sage_complex_double.pyx +132 -0
  138. sage/libs/pari/convert_sage_matrix.cpython-314-x86_64-linux-musl.so +0 -0
  139. sage/libs/pari/convert_sage_matrix.pyx +106 -0
  140. sage/libs/pari/convert_sage_real_double.cpython-314-x86_64-linux-musl.so +0 -0
  141. sage/libs/pari/convert_sage_real_double.pxd +5 -0
  142. sage/libs/pari/convert_sage_real_double.pyx +14 -0
  143. sage/libs/pari/convert_sage_real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
  144. sage/libs/pari/convert_sage_real_mpfr.pxd +7 -0
  145. sage/libs/pari/convert_sage_real_mpfr.pyx +108 -0
  146. sage/libs/pari/misc.cpython-314-x86_64-linux-musl.so +0 -0
  147. sage/libs/pari/misc.pxd +4 -0
  148. sage/libs/pari/misc.pyx +26 -0
  149. sage/libs/pari/tests.py +1848 -0
  150. sage/matrix/all__sagemath_pari.py +1 -0
  151. sage/matrix/matrix_integer_pari.cpython-314-x86_64-linux-musl.so +0 -0
  152. sage/matrix/matrix_integer_pari.pyx +187 -0
  153. sage/matrix/matrix_rational_pari.cpython-314-x86_64-linux-musl.so +0 -0
  154. sage/matrix/matrix_rational_pari.pyx +160 -0
  155. sage/quadratic_forms/all__sagemath_pari.py +10 -0
  156. sage/quadratic_forms/genera/all.py +9 -0
  157. sage/quadratic_forms/genera/genus.py +3506 -0
  158. sage/quadratic_forms/genera/normal_form.py +1519 -0
  159. sage/quadratic_forms/genera/spinor_genus.py +243 -0
  160. sage/quadratic_forms/qfsolve.py +255 -0
  161. sage/quadratic_forms/quadratic_form__automorphisms.py +427 -0
  162. sage/quadratic_forms/quadratic_form__genus.py +141 -0
  163. sage/quadratic_forms/quadratic_form__local_density_interfaces.py +140 -0
  164. sage/quadratic_forms/quadratic_form__local_normal_form.py +421 -0
  165. sage/quadratic_forms/quadratic_form__local_representation_conditions.py +889 -0
  166. sage/quadratic_forms/quadratic_form__mass.py +69 -0
  167. sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +663 -0
  168. sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +373 -0
  169. sage/quadratic_forms/quadratic_form__siegel_product.py +198 -0
  170. sage/quadratic_forms/special_values.py +323 -0
  171. sage/rings/all__sagemath_pari.py +15 -0
  172. sage/rings/factorint_pari.cpython-314-x86_64-linux-musl.so +0 -0
  173. sage/rings/factorint_pari.pyx +80 -0
  174. sage/rings/finite_rings/all__sagemath_pari.py +1 -0
  175. sage/rings/finite_rings/element_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  176. sage/rings/finite_rings/element_givaro.pxd +91 -0
  177. sage/rings/finite_rings/element_givaro.pyx +1769 -0
  178. sage/rings/finite_rings/element_ntl_gf2e.cpython-314-x86_64-linux-musl.so +0 -0
  179. sage/rings/finite_rings/element_ntl_gf2e.pxd +22 -0
  180. sage/rings/finite_rings/element_ntl_gf2e.pyx +1333 -0
  181. sage/rings/finite_rings/element_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  182. sage/rings/finite_rings/element_pari_ffelt.pxd +13 -0
  183. sage/rings/finite_rings/element_pari_ffelt.pyx +1441 -0
  184. sage/rings/finite_rings/finite_field_givaro.py +612 -0
  185. sage/rings/finite_rings/finite_field_pari_ffelt.py +238 -0
  186. sage/rings/finite_rings/hom_finite_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  187. sage/rings/finite_rings/hom_finite_field_givaro.pxd +28 -0
  188. sage/rings/finite_rings/hom_finite_field_givaro.pyx +280 -0
  189. sage/rings/finite_rings/residue_field_givaro.cpython-314-x86_64-linux-musl.so +0 -0
  190. sage/rings/finite_rings/residue_field_givaro.pyx +133 -0
  191. sage/rings/finite_rings/residue_field_pari_ffelt.cpython-314-x86_64-linux-musl.so +0 -0
  192. sage/rings/finite_rings/residue_field_pari_ffelt.pyx +128 -0
  193. sage/rings/function_field/all__sagemath_pari.py +1 -0
  194. sage/rings/function_field/valuation.py +1450 -0
  195. sage/rings/function_field/valuation_ring.py +212 -0
  196. sage/rings/number_field/all__sagemath_pari.py +14 -0
  197. sage/rings/number_field/totallyreal.cpython-314-x86_64-linux-musl.so +0 -0
  198. sage/rings/number_field/totallyreal.pyx +509 -0
  199. sage/rings/number_field/totallyreal_data.cpython-314-x86_64-linux-musl.so +0 -0
  200. sage/rings/number_field/totallyreal_data.pxd +26 -0
  201. sage/rings/number_field/totallyreal_data.pyx +928 -0
  202. sage/rings/number_field/totallyreal_phc.py +144 -0
  203. sage/rings/number_field/totallyreal_rel.py +1018 -0
  204. sage/rings/padics/CA_template.pxi +1847 -0
  205. sage/rings/padics/CA_template_header.pxi +50 -0
  206. sage/rings/padics/CR_template.pxi +2563 -0
  207. sage/rings/padics/CR_template_header.pxi +57 -0
  208. sage/rings/padics/FM_template.pxi +1575 -0
  209. sage/rings/padics/FM_template_header.pxi +50 -0
  210. sage/rings/padics/FP_template.pxi +2176 -0
  211. sage/rings/padics/FP_template_header.pxi +57 -0
  212. sage/rings/padics/all.py +3 -0
  213. sage/rings/padics/all__sagemath_pari.py +11 -0
  214. sage/rings/padics/common_conversion.cpython-314-x86_64-linux-musl.so +0 -0
  215. sage/rings/padics/common_conversion.pxd +15 -0
  216. sage/rings/padics/common_conversion.pyx +508 -0
  217. sage/rings/padics/eisenstein_extension_generic.py +232 -0
  218. sage/rings/padics/factory.py +3623 -0
  219. sage/rings/padics/generic_nodes.py +1615 -0
  220. sage/rings/padics/lattice_precision.py +2889 -0
  221. sage/rings/padics/morphism.cpython-314-x86_64-linux-musl.so +0 -0
  222. sage/rings/padics/morphism.pxd +11 -0
  223. sage/rings/padics/morphism.pyx +366 -0
  224. sage/rings/padics/padic_base_generic.py +467 -0
  225. sage/rings/padics/padic_base_leaves.py +1235 -0
  226. sage/rings/padics/padic_capped_absolute_element.cpython-314-x86_64-linux-musl.so +0 -0
  227. sage/rings/padics/padic_capped_absolute_element.pxd +15 -0
  228. sage/rings/padics/padic_capped_absolute_element.pyx +520 -0
  229. sage/rings/padics/padic_capped_relative_element.cpython-314-x86_64-linux-musl.so +0 -0
  230. sage/rings/padics/padic_capped_relative_element.pxd +14 -0
  231. sage/rings/padics/padic_capped_relative_element.pyx +614 -0
  232. sage/rings/padics/padic_extension_generic.py +990 -0
  233. sage/rings/padics/padic_extension_leaves.py +738 -0
  234. sage/rings/padics/padic_fixed_mod_element.cpython-314-x86_64-linux-musl.so +0 -0
  235. sage/rings/padics/padic_fixed_mod_element.pxd +15 -0
  236. sage/rings/padics/padic_fixed_mod_element.pyx +584 -0
  237. sage/rings/padics/padic_floating_point_element.cpython-314-x86_64-linux-musl.so +0 -0
  238. sage/rings/padics/padic_floating_point_element.pxd +14 -0
  239. sage/rings/padics/padic_floating_point_element.pyx +447 -0
  240. sage/rings/padics/padic_generic_element.cpython-314-x86_64-linux-musl.so +0 -0
  241. sage/rings/padics/padic_generic_element.pxd +48 -0
  242. sage/rings/padics/padic_generic_element.pyx +4642 -0
  243. sage/rings/padics/padic_lattice_element.py +1342 -0
  244. sage/rings/padics/padic_printing.cpython-314-x86_64-linux-musl.so +0 -0
  245. sage/rings/padics/padic_printing.pxd +38 -0
  246. sage/rings/padics/padic_printing.pyx +1505 -0
  247. sage/rings/padics/padic_relaxed_element.cpython-314-x86_64-linux-musl.so +0 -0
  248. sage/rings/padics/padic_relaxed_element.pxd +56 -0
  249. sage/rings/padics/padic_relaxed_element.pyx +18 -0
  250. sage/rings/padics/padic_relaxed_errors.cpython-314-x86_64-linux-musl.so +0 -0
  251. sage/rings/padics/padic_relaxed_errors.pxd +11 -0
  252. sage/rings/padics/padic_relaxed_errors.pyx +71 -0
  253. sage/rings/padics/padic_template_element.pxi +1212 -0
  254. sage/rings/padics/padic_template_element_header.pxi +50 -0
  255. sage/rings/padics/padic_valuation.py +1423 -0
  256. sage/rings/padics/pow_computer_flint.cpython-314-x86_64-linux-musl.so +0 -0
  257. sage/rings/padics/pow_computer_flint.pxd +38 -0
  258. sage/rings/padics/pow_computer_flint.pyx +641 -0
  259. sage/rings/padics/pow_computer_relative.cpython-314-x86_64-linux-musl.so +0 -0
  260. sage/rings/padics/pow_computer_relative.pxd +29 -0
  261. sage/rings/padics/pow_computer_relative.pyx +415 -0
  262. sage/rings/padics/qadic_flint_CA.cpython-314-x86_64-linux-musl.so +0 -0
  263. sage/rings/padics/qadic_flint_CA.pxd +21 -0
  264. sage/rings/padics/qadic_flint_CA.pyx +130 -0
  265. sage/rings/padics/qadic_flint_CR.cpython-314-x86_64-linux-musl.so +0 -0
  266. sage/rings/padics/qadic_flint_CR.pxd +13 -0
  267. sage/rings/padics/qadic_flint_CR.pyx +172 -0
  268. sage/rings/padics/qadic_flint_FM.cpython-314-x86_64-linux-musl.so +0 -0
  269. sage/rings/padics/qadic_flint_FM.pxd +14 -0
  270. sage/rings/padics/qadic_flint_FM.pyx +111 -0
  271. sage/rings/padics/qadic_flint_FP.cpython-314-x86_64-linux-musl.so +0 -0
  272. sage/rings/padics/qadic_flint_FP.pxd +12 -0
  273. sage/rings/padics/qadic_flint_FP.pyx +165 -0
  274. sage/rings/padics/relative_extension_leaves.py +429 -0
  275. sage/rings/padics/relative_ramified_CA.cpython-314-x86_64-linux-musl.so +0 -0
  276. sage/rings/padics/relative_ramified_CA.pxd +9 -0
  277. sage/rings/padics/relative_ramified_CA.pyx +33 -0
  278. sage/rings/padics/relative_ramified_CR.cpython-314-x86_64-linux-musl.so +0 -0
  279. sage/rings/padics/relative_ramified_CR.pxd +8 -0
  280. sage/rings/padics/relative_ramified_CR.pyx +33 -0
  281. sage/rings/padics/relative_ramified_FM.cpython-314-x86_64-linux-musl.so +0 -0
  282. sage/rings/padics/relative_ramified_FM.pxd +9 -0
  283. sage/rings/padics/relative_ramified_FM.pyx +33 -0
  284. sage/rings/padics/relative_ramified_FP.cpython-314-x86_64-linux-musl.so +0 -0
  285. sage/rings/padics/relative_ramified_FP.pxd +8 -0
  286. sage/rings/padics/relative_ramified_FP.pyx +33 -0
  287. sage/rings/padics/relaxed_template.pxi +4229 -0
  288. sage/rings/padics/relaxed_template_header.pxi +160 -0
  289. sage/rings/padics/tests.py +35 -0
  290. sage/rings/padics/tutorial.py +341 -0
  291. sage/rings/padics/unramified_extension_generic.py +335 -0
  292. sage/rings/padics/witt_vector.py +917 -0
  293. sage/rings/padics/witt_vector_ring.py +934 -0
  294. sage/rings/pari_ring.py +235 -0
  295. sage/rings/polynomial/all__sagemath_pari.py +1 -0
  296. sage/rings/polynomial/padics/all.py +1 -0
  297. sage/rings/polynomial/padics/polynomial_padic.py +360 -0
  298. sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +1324 -0
  299. sage/rings/polynomial/padics/polynomial_padic_flat.py +72 -0
  300. sage/rings/power_series_pari.cpython-314-x86_64-linux-musl.so +0 -0
  301. sage/rings/power_series_pari.pxd +6 -0
  302. sage/rings/power_series_pari.pyx +934 -0
  303. sage/rings/tate_algebra.py +1282 -0
  304. sage/rings/tate_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
  305. sage/rings/tate_algebra_element.pxd +49 -0
  306. sage/rings/tate_algebra_element.pyx +3464 -0
  307. sage/rings/tate_algebra_ideal.cpython-314-x86_64-linux-musl.so +0 -0
  308. sage/rings/tate_algebra_ideal.pxd +7 -0
  309. sage/rings/tate_algebra_ideal.pyx +1307 -0
  310. sage/rings/valuation/all.py +7 -0
  311. sage/rings/valuation/augmented_valuation.py +2118 -0
  312. sage/rings/valuation/developing_valuation.py +362 -0
  313. sage/rings/valuation/gauss_valuation.py +812 -0
  314. sage/rings/valuation/inductive_valuation.py +1686 -0
  315. sage/rings/valuation/limit_valuation.py +946 -0
  316. sage/rings/valuation/mapped_valuation.py +656 -0
  317. sage/rings/valuation/scaled_valuation.py +322 -0
  318. sage/rings/valuation/trivial_valuation.py +382 -0
  319. sage/rings/valuation/valuation.py +1119 -0
  320. sage/rings/valuation/valuation_space.py +1615 -0
  321. sage/rings/valuation/valuations_catalog.py +10 -0
  322. sage/rings/valuation/value_group.py +697 -0
  323. sage/schemes/all__sagemath_pari.py +1 -0
  324. sage/schemes/elliptic_curves/all__sagemath_pari.py +1 -0
  325. sage/schemes/elliptic_curves/descent_two_isogeny_pari.cpython-314-x86_64-linux-musl.so +0 -0
  326. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pyx +46 -0
  327. sage_wheels/bin/gp +0 -0
  328. sage_wheels/bin/gp2c +0 -0
  329. sage_wheels/bin/gp2c-run +57 -0
  330. sage_wheels/bin/xeus-gp +0 -0
  331. sage_wheels/share/gp2c/func.dsc +18414 -0
@@ -0,0 +1,1307 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ """
3
+ Ideals in Tate algebra
4
+
5
+ The module gives tools for manipulating ideals in Tate algebras
6
+ and, in particular, provides an implementation of the Buchberger
7
+ algorithm in this context.
8
+
9
+ AUTHORS:
10
+
11
+ - Xavier Caruso, Thibaut Verron (2018-09): Buchberger algorithm
12
+
13
+ - Xavier Caruso, Thibaut Verron (2019-04): F5-type algorithms (PoTe and VaPoTe)
14
+ """
15
+
16
+ # ***************************************************************************
17
+ # Copyright (C) 2018 Xavier Caruso <xavier.caruso@normalesup.org>
18
+ # Thibaut Verron <thibaut.verron@gmail.com>
19
+ #
20
+ # This program is free software: you can redistribute it and/or modify
21
+ # it under the terms of the GNU General Public License as published by
22
+ # the Free Software Foundation, either version 2 of the License, or
23
+ # (at your option) any later version.
24
+ # https://www.gnu.org/licenses/
25
+ # ***************************************************************************
26
+
27
+ from sage.rings.ideal import Ideal_generic
28
+
29
+ from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_GT, op_LE, op_GE
30
+
31
+ from sage.rings.polynomial.polydict cimport PolyDict
32
+
33
+ from sage.rings.tate_algebra_element cimport TateAlgebraTerm
34
+ from sage.rings.tate_algebra_element cimport TateAlgebraElement
35
+ from heapq import heappush, heappop
36
+
37
+ from cysignals.signals cimport sig_check
38
+
39
+
40
+ class TateAlgebraIdeal(Ideal_generic):
41
+ r"""
42
+ Initialize a class for ideals in a Tate series algebra.
43
+
44
+ EXAMPLES::
45
+
46
+ sage: R = Zp(3, prec=10, print_mode='digits')
47
+ sage: A.<x,y> = TateAlgebra(R)
48
+ sage: f = 3*x^2 + 5*x*y^2
49
+ sage: g = 5*x^2*y + 3
50
+ sage: I = A.ideal([f,g]); I
51
+ Ideal (...0000000012*x*y^2 + ...00000000010*x^2, ...0000000012*x^2*y + ...00000000010) of Tate Algebra in x (val >= 0), y (val >= 0) over 3-adic Field with capped relative precision 10
52
+ """
53
+
54
+ #@cached_method
55
+ def groebner_basis(self, prec=None, algorithm='VaPoTe', **options):
56
+ r"""
57
+ Compute a Groebner basis of the ideal.
58
+
59
+ INPUT:
60
+
61
+ - ``prec`` -- integer or ``None`` (default: ``None``); the precision
62
+ at which the computations are carried. If ``None``, defaults to the
63
+ algebra precision cap.
64
+
65
+ - ``algorithm`` -- string (default: ``'VaPoTe'``), the algorithm to
66
+ use in the calculations; available algorithms are:
67
+
68
+ - ``'buchberger'``: classical Buchberger algorithm
69
+
70
+ - ``'buchberger-integral'``: first computes a Groebner basis of the
71
+ ideal generated by the same generators over the ring of integers
72
+ (provides better numerical stability)
73
+
74
+ - ``'PoTe'``: a F5-type algorithm where signatures are ordered by
75
+ position over term
76
+
77
+ - ``'VaPoTe'``: a F5-type algorithm where signatures are ordered
78
+ by valuation over position over term
79
+
80
+ We refer to [CVV2019]_ and [CVV2020]_ for a detailed description
81
+ of these algorithms.
82
+
83
+ - ``options`` -- extra arguments that are passed in to the
84
+ algorithm; this notably include the keyword ``verbose`` (only
85
+ available for ``PoTe`` and ``VaPoTe``) which is an integer
86
+ defining the verbosity level:
87
+
88
+ - ``0``: no verbosity (quiet)
89
+
90
+ - ``1``: print each new generator and a notification each time a
91
+ J-pair is popped
92
+
93
+ - ``2``: in addition, print the outcome of the treatment of a J-pair
94
+
95
+ - ``3``: in addition, print all added J-pairs
96
+
97
+ - ``4``: print entire series instead of only their leading terms
98
+
99
+ OUTPUT:
100
+
101
+ The Groebner basis `(g_1,\dots,g_n)` of this ideal, uniquely determined
102
+ by the following conditions::
103
+
104
+ - it is minimal, in the sense that the leading coefficient of `g_i`
105
+ does not divide the leading coefficient of `g_j` if `i \neq j`,
106
+
107
+ - it is reduced, in the sense that each term of `g_i` is not divisible
108
+ by leading term of `g_j` for `j \neq i` or the leading term of
109
+ `\pi g_i` where `\pi` is the uniformizer,
110
+
111
+ - it is normalized so that the leading coefficient of each `g_i` is
112
+ a power of the uniformizer and moreover, if we are working over a Tate
113
+ algebra (and not its ring of integers), each `g_i` has valuation `0`,
114
+
115
+ - it is sorted, in the sense that the leading term of `g_i` is greater
116
+ than the leading of `g_{i+1}` for all `i`.
117
+
118
+ .. NOTE::
119
+
120
+ The result of this method is cached.
121
+
122
+ EXAMPLES::
123
+
124
+ sage: R = Zp(3, prec=10, print_mode='digits')
125
+ sage: A.<x,y> = TateAlgebra(R)
126
+ sage: f = 3*x^2 + 5*x*y^2
127
+ sage: g = 5*x^2*y + 3
128
+ sage: I = A.ideal([f,g])
129
+ sage: I.groebner_basis()
130
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
131
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
132
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
133
+
134
+ The algorithm ``buchberger`` is faster than ``buchberger-integral``
135
+ but may lose more precision::
136
+
137
+ sage: R = Zp(2, 5, print_mode='digits')
138
+ sage: A.<x,y> = TateAlgebra(R)
139
+ sage: f = x^2*y^6 + x^4 + 25*y^2 + 2*x^3*y^3 + 10*x*y^4 + 10*x^2*y
140
+ sage: g = x^4*y^5 + x^5*y^2 + x^4 + 5*x^2*y + 2*x^5*y^4 + 2*x^6*y + 6*x^3*y^3
141
+ sage: h = 2*x^6*y^4 + 2*x^4 + 4*x^5*y^2 + 8*x^8*y^2 + 8*x^7*y^3 + 8*x^6*y
142
+ sage: I = A.ideal([f,g,h])
143
+ sage: I.groebner_basis(algorithm='buchberger-integral')
144
+ [...0001*x^4 + O(2^4 * <x, y>),
145
+ ...0001*x^2*y + O(2^4 * <x, y>),
146
+ ...0001*y^2 + O(2^4 * <x, y>)]
147
+ sage: I.groebner_basis(algorithm='buchberger')
148
+ [...001*x^4 + O(2^3 * <x, y>),
149
+ ...001*x^2*y + O(2^3 * <x, y>),
150
+ ...001*y^2 + O(2^3 * <x, y>)]
151
+
152
+ TESTS::
153
+
154
+ sage: I.groebner_basis(algorithm='F4')
155
+ Traceback (most recent call last):
156
+ ...
157
+ NotImplementedError: available algorithms are 'buchberger', 'buchberger-integral', 'PoTe' and 'VaPoTe'
158
+ """
159
+ if prec is None:
160
+ prec = self.ring().precision_cap()
161
+ if algorithm == "buchberger":
162
+ return groebner_basis_buchberger(self, prec, False, **options)
163
+ elif algorithm == "buchberger-integral":
164
+ return groebner_basis_buchberger(self, prec, True, **options)
165
+ elif algorithm == "pote" or algorithm == "PoTe":
166
+ return groebner_basis_pote(self, prec, **options)
167
+ elif algorithm == "vapote" or algorithm == "VaPoTe":
168
+ return groebner_basis_vapote(self, prec, **options)
169
+ else:
170
+ raise NotImplementedError("available algorithms are 'buchberger', 'buchberger-integral', 'PoTe' and 'VaPoTe'")
171
+
172
+ def _contains_(self, x):
173
+ r"""
174
+ Return ``True`` if ``x`` lies in this ideal.
175
+
176
+ INPUT:
177
+
178
+ - ``x`` -- a Tate series
179
+
180
+ EXAMPLES::
181
+
182
+ sage: R = Zp(3, 10)
183
+ sage: A.<x,y> = TateAlgebra(R)
184
+ sage: f = 3*x^2 + 5*x*y^2
185
+ sage: g = 5*x^2*y + 3
186
+ sage: I = A.ideal([f,g])
187
+ sage: f in I # indirect doctest
188
+ True
189
+ sage: (f+g) in I # indirect doctest
190
+ True
191
+ sage: (f+1) in I # indirect doctest
192
+ False
193
+
194
+ TESTS::
195
+
196
+ sage: I.random_element() in I
197
+ True
198
+ """
199
+ rgb = self.groebner_basis()
200
+ return (x % rgb).is_zero()
201
+
202
+ def _contains_ideal(self, I):
203
+ r"""
204
+ Return ``True`` if ``I`` is contained in this ideal.
205
+
206
+ INPUT:
207
+
208
+ - ``I`` -- an ideal in a Tate series algebra
209
+
210
+ EXAMPLES::
211
+
212
+ sage: R = Zp(3,prec=10,print_mode='digits')
213
+ sage: A.<x,y> = TateAlgebra(R)
214
+ sage: f = 3*x^2 + 5*x*y^2
215
+ sage: g = 5*x^2*y + 3
216
+ sage: I = A.ideal([f,g])
217
+ sage: A.ideal([f]) < I # indirect doctest
218
+ True
219
+ sage: I < A.ideal([f]) # indirect doctest
220
+ False
221
+ sage: A.ideal([1]) < I # indirect doctest
222
+ False
223
+ sage: I < A.ideal([1]) # indirect doctest
224
+ True
225
+ """
226
+ self.groebner_basis()
227
+ return all(f in self for f in I.gens())
228
+
229
+ def _richcmp_(self, other, op):
230
+ r"""
231
+ Compare this ideal with ``other`` for the rich comparison
232
+ operator ``op``
233
+
234
+ INPUT:
235
+
236
+ - ``other`` -- an ideal in a Tate series algebra
237
+
238
+ - ``op`` -- a comparison operator
239
+
240
+ EXAMPLES::
241
+
242
+ sage: R = Zp(3, 10)
243
+ sage: A.<x,y> = TateAlgebra(R)
244
+ sage: f = 3*x^2 + 5*x*y^2
245
+ sage: g = 5*x^2*y + 3
246
+ sage: I = A.ideal([f,g])
247
+ sage: A.ideal([f]) < I
248
+ True
249
+ sage: I < A.ideal([f])
250
+ False
251
+ sage: A.ideal([1]) < I
252
+ False
253
+ sage: I < A.ideal([1])
254
+ True
255
+ sage: I <= A.ideal([f,g])
256
+ True
257
+ sage: I == A.ideal([f,g])
258
+ True
259
+ sage: I <= A.ideal([f])
260
+ False
261
+ sage: A.ideal([f]) <= I
262
+ True
263
+ sage: A.ideal([f]) == I
264
+ False
265
+ """
266
+ if op == op_GT:
267
+ return self._contains_ideal(other) and not other._contains_ideal(self)
268
+ elif op == op_GE:
269
+ return self._contains_ideal(other)
270
+ elif op == op_EQ:
271
+ return self._contains_ideal(other) and other._contains_ideal(self)
272
+ elif op == op_NE:
273
+ return not(self._contains_ideal(other) and other._contains_ideal(self))
274
+ elif op == op_LE:
275
+ return other._contains_ideal(self)
276
+ elif op == op_LT:
277
+ return other._contains_ideal(self) and not self._contains_ideal(other)
278
+
279
+ def is_saturated(self):
280
+ r"""
281
+ Return ``True`` if this ideal is saturated.
282
+
283
+ The ideal `I` is saturated if `\pi f \in I` implies `f \in I`
284
+ for any `f` in the underlying ring. Here `\pi` denotes a
285
+ uniformizer of the field of coefficients.
286
+
287
+ .. NOTE::
288
+
289
+ All ideals are saturated when `\pi` is invertible.
290
+
291
+ EXAMPLES:
292
+
293
+ Over classical Tate algebras (where `\pi` is invertible), this
294
+ method always returns ``True``::
295
+
296
+ sage: R = Zp(3, prec=10, print_mode='digits')
297
+ sage: A.<x,y> = TateAlgebra(R)
298
+ sage: f = 3*x^2 + 5*x*y^2
299
+ sage: g = 5*x^2*y + 3
300
+ sage: A.ideal([f,g]).is_saturated()
301
+ True
302
+ sage: A.ideal([f,3*g]).is_saturated()
303
+ True
304
+
305
+ The test is only relevant over the rings of integers of Tate
306
+ algebras::
307
+
308
+ sage: Ao = A.integer_ring()
309
+ sage: Io = Ao.ideal([f,g])
310
+ sage: Io.is_saturated()
311
+ False
312
+ sage: Io.groebner_basis()
313
+ [...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
314
+ ...0000000001*x*y^2 + ...1210121020*x^2 + O(3^10 * <x, y>),
315
+ ...0000000010*x^3 + ...2222222220*y + O(3^10 * <x, y>),
316
+ ...0000000010*y^2 + ...2101210200*x + O(3^10 * <x, y>)]
317
+
318
+ Principal ideals are not always saturated::
319
+
320
+ sage: Ao.ideal([3*f]).is_saturated()
321
+ False
322
+ """
323
+ if self.ring().base_ring().is_field():
324
+ return True
325
+ gb = self.groebner_basis()
326
+ for g in gb:
327
+ if g.valuation() > 0:
328
+ return False
329
+ return True
330
+
331
+ def saturate(self):
332
+ r"""
333
+ Return the ideal obtained by saturating this ideal.
334
+
335
+ In other words, the result is the ideal
336
+
337
+ .. MATH::
338
+
339
+ (I:\pi^\infty) = \{f \in A : \exists n \in \mathbb{N}, \pi^n f \in I\}`
340
+
341
+ where `A` is the underlying ring and `\pi` is the uniformizer of the
342
+ field of coefficients.
343
+
344
+ .. NOTE::
345
+
346
+ When `\pi` is invertible in `A`, all ideals are saturated.
347
+
348
+ EXAMPLES:
349
+
350
+ Over classical Tate algebras (where `\pi` is invertible), this
351
+ method always returns the same ideal::
352
+
353
+ sage: R = Zp(3, prec=10, print_mode='digits')
354
+ sage: A.<x,y> = TateAlgebra(R)
355
+ sage: f = 3*x^2 + 5*x*y^2
356
+ sage: g = 5*x^2*y + 3
357
+ sage: I = A.ideal([f,g]); I
358
+ Ideal (...0000000012*x*y^2 + ...00000000010*x^2, ...0000000012*x^2*y + ...00000000010)
359
+ of Tate Algebra in x (val >= 0), y (val >= 0) over 3-adic Field with capped relative precision 10
360
+ sage: I.saturate()
361
+ Ideal (...0000000012*x*y^2 + ...00000000010*x^2, ...0000000012*x^2*y + ...00000000010)
362
+ of Tate Algebra in x (val >= 0), y (val >= 0) over 3-adic Field with capped relative precision 10
363
+
364
+ sage: I.saturate() == I
365
+ True
366
+
367
+ However, the result might be different over the ring of integers
368
+ of a Tate algebra::
369
+
370
+ sage: Ao = A.integer_ring()
371
+ sage: Io = Ao.ideal([f,g])
372
+ sage: Ios = Io.saturate(); Ios
373
+ Ideal (...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
374
+ ...0000000001*x*y^2 + ...1210121020*x^2 + O(3^10 * <x, y>),
375
+ ...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
376
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>))
377
+ of Integer ring of the Tate Algebra in x (val >= 0), y (val >= 0) over 3-adic Field with capped relative precision 10
378
+
379
+ sage: Io == Ios
380
+ False
381
+ sage: Ios.is_saturated()
382
+ True
383
+
384
+ TESTS::
385
+
386
+ sage: Io < Ios
387
+ True
388
+ sage: 3*Ios < Io
389
+ True
390
+ """
391
+ if self.ring().base_ring().is_field():
392
+ return self
393
+ gb = self.groebner_basis()
394
+ gens = [ g.monic() for g in gb ]
395
+ return self.ring().ideal(gens)
396
+
397
+
398
+ # Grobner bases computations
399
+ ############################
400
+
401
+ # Buchberger algorithm
402
+
403
+ def groebner_basis_buchberger(I, prec, py_integral):
404
+ r"""
405
+ Compute a Groebner basis of the Tate algebra ideal I using Buchberger's algorithm.
406
+
407
+ INPUT:
408
+
409
+ - ``I`` -- an ideal in a Tate series algebra
410
+
411
+ - ``prec`` -- the related precision at which the initial generators
412
+ are truncated
413
+
414
+ - ``integral`` -- boolean; if ``True``, first compute a
415
+ Grobner basis of the ideal generated by the same generators over
416
+ the ring over the ring of integers
417
+
418
+ .. NOTE::
419
+
420
+ This function is not meant to be called directly, but through the
421
+ ``groebner_basis`` method of Tate algebra ideals.
422
+
423
+ EXAMPLES::
424
+
425
+ sage: R = Zp(3, prec=10, print_mode='digits');
426
+ sage: A.<x,y> = TateAlgebra(R)
427
+ sage: f = 3*x^2 + 5*x*y^2
428
+ sage: g = 5*x^2*y + 3
429
+ sage: I = A.ideal([f,g]); I
430
+ Ideal (...0000000012*x*y^2 + ...00000000010*x^2, ...0000000012*x^2*y + ...00000000010) of Tate Algebra in x (val >= 0), y (val >= 0) over 3-adic Field with capped relative precision 10
431
+ sage: I.groebner_basis() # indirect doctest
432
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
433
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
434
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
435
+ """
436
+ cdef list gb, rgb, indices, ts, S = [ ]
437
+ cdef int i, j, l
438
+ cdef TateAlgebraTerm ti, tj, t
439
+ cdef TateAlgebraElement f, g, r, s
440
+ cdef bint do_reduce = True
441
+ cdef bint integral = py_integral
442
+
443
+ gb = [ ]
444
+ l = 0
445
+ for f in I.gens():
446
+ if not f:
447
+ continue
448
+ g = f.add_bigoh(f.valuation() + prec)
449
+ if not g:
450
+ continue
451
+ gb.append(g)
452
+ l += 1
453
+ indices = list(range(l))
454
+
455
+ # We minimize the family of generators
456
+ rgb = gb[:]
457
+ i = 0
458
+ while i < len(rgb):
459
+ ti = (<TateAlgebraElement>rgb[i])._terms_c()[0]
460
+ for j in range(len(rgb)):
461
+ tj = (<TateAlgebraElement>rgb[j])._terms_c()[0]
462
+ if j != i and tj._divides_c(ti, integral):
463
+ del rgb[i]
464
+ del indices[i]
465
+ break
466
+ else:
467
+ i += 1
468
+
469
+ # We compute the initial S-polynomials
470
+ for i in range(l):
471
+ ti = (<TateAlgebraElement>gb[i])._terms_c()[0]
472
+ for j in range(i+1, l):
473
+ tj = (<TateAlgebraElement>gb[j])._terms_c()[0]
474
+ if not ti.is_coprime_with(tj):
475
+ s = (<TateAlgebraElement>gb[i])._Spoly_c(<TateAlgebraElement>gb[j])
476
+ if not s.is_zero():
477
+ t = s._terms_c()[0]
478
+ heappush(S, (t._valuation_c(), t._exponent, i, j, s))
479
+
480
+ # Main loop of Buchberger algorithm
481
+ # Loop invariant:
482
+ # the S-polynomials of pairs of elements in rgb
483
+ # all reduce to zero modulo (rgb,S)
484
+ while S:
485
+ sig_check()
486
+ # We reduce the Grobner basis if needed
487
+ if do_reduce:
488
+ do_reduce = False
489
+ for i in range(len(rgb)-1, -1, -1):
490
+ g = rgb[i]
491
+ rgb[i] = g._positive_lshift_c(1)
492
+ _, rgb[i] = g._quo_rem_c(rgb, False, True, True)
493
+ gb[indices[i]] = rgb[i]
494
+
495
+ # We pop a new S-polynomial
496
+ _, _, i, j, f = heappop(S)
497
+ if i >= 0 and (gb[i] is None or gb[j] is None):
498
+ continue
499
+ _, r = f._quo_rem_c(rgb, False, True, integral)
500
+ if r.is_zero():
501
+ continue
502
+
503
+ # We add it to our Grobner basis
504
+ tj = r._terms_c()[0]
505
+ j = len(gb)
506
+ for i in range(j):
507
+ g = gb[i]
508
+ if g is None: continue
509
+ ti = g._terms_c()[0]
510
+ if not ti.is_coprime_with(tj): # first Buchberger criterium
511
+ s = g._Spoly_c(r)
512
+ if not s.is_zero():
513
+ t = s._terms_c()[0]
514
+ heappush(S, (t._valuation_c(), t._exponent, i, j, s))
515
+ gb.append(r)
516
+
517
+ # We minimize the Grobner basis
518
+ i = 0
519
+ while i < len(rgb):
520
+ ti = (<TateAlgebraElement>rgb[i])._terms_c()[0]
521
+ if tj._divides_c(ti, integral):
522
+ if indices[i] >= l:
523
+ heappush(S, (ti._valuation_c(), ti._exponent, -1, -1, rgb[i]))
524
+ gb[indices[i]] = None
525
+ del rgb[i]
526
+ del indices[i]
527
+ else:
528
+ i += 1
529
+ rgb.append(r)
530
+ indices.append(j)
531
+ # and reduce it
532
+ do_reduce = True
533
+
534
+ base = I.ring().base_ring()
535
+ if base.is_field():
536
+ if integral:
537
+ # We need to minimize and reduce the Groebner basis again
538
+ i = 0
539
+ while i < len(rgb):
540
+ ti = (<TateAlgebraElement>rgb[i])._terms_c()[0]
541
+ for j in range(len(rgb)):
542
+ tj = (<TateAlgebraElement>rgb[j])._terms_c()[0]
543
+ if j != i and tj._divides_c(ti, False):
544
+ del rgb[i]
545
+ break
546
+ else:
547
+ rgb[i] = rgb[i].monic()
548
+ i += 1
549
+ for i in range(len(rgb)):
550
+ g = rgb[i]
551
+ rgb[i] = g._positive_lshift_c(1)
552
+ _, rgb[i] = g._quo_rem_c(rgb, False, True, True)
553
+ else:
554
+ rgb = [ g.monic() for g in rgb ]
555
+ else:
556
+ rgb = [ g * base(g.leading_coefficient().unit_part()).inverse_of_unit() for g in rgb ]
557
+
558
+ rgb.sort(reverse=True)
559
+ return rgb
560
+
561
+
562
+ # F5 algorithms
563
+
564
+ cdef Jpair(p1, p2):
565
+ r"""
566
+ Return the J-pair of ``p1`` and ``p2``.
567
+
568
+ INPUT:
569
+
570
+ - ``p1`` -- a pair (signature, series)
571
+
572
+ - ``p2`` -- a pair (signature, series)
573
+ """
574
+ cdef TateAlgebraTerm s1, s2
575
+ cdef TateAlgebraElement v1, v2
576
+ cdef TateAlgebraTerm t, t1, t2, su1, su2, sv1, sv2
577
+ s1, v1 = p1 # we assume that s1 is not None
578
+ s2, v2 = p2
579
+ if v1 == 0 or v2 == 0:
580
+ return
581
+ sv1 = v1.leading_term()
582
+ sv2 = v2.leading_term()
583
+ # TODO: Maybe can be made more efficient when we know the elements are "monic"
584
+ t = sv1.lcm(sv2)
585
+ t1 = t // sv1
586
+ t2 = t // sv2
587
+ su1 = t1*s1
588
+ if s2 is None:
589
+ return su1, t1*v1
590
+ su2 = t2*s2
591
+ if su1 > su2:
592
+ return su1, t1*v1
593
+ elif su2 > su1:
594
+ return su2, t2*v2
595
+
596
+
597
+ cdef TateAlgebraElement regular_reduce(sgb, TateAlgebraTerm s, TateAlgebraElement v, stopval):
598
+ r"""
599
+ Return the result of the regular reduction of the pair ``(s,v)`` by ``sgb``.
600
+
601
+ INPUT:
602
+
603
+ - ``sgb`` -- list of pairs (signature, series), candidate to be a strong
604
+ Groebner basis; all leading coefficients are assumed to be a power of the
605
+ uniformizer
606
+
607
+ - ``s`` -- a term (the signature)
608
+
609
+ - ``v`` -- a series
610
+
611
+ - ``stopval`` -- the valuation until which reductions are performed
612
+
613
+ TESTS::
614
+
615
+ sage: cython( # needs sage.misc.cython
616
+ ....: '''
617
+ ....: from sage.rings.tate_algebra_ideal cimport regular_reduce
618
+ ....: def python_regular_reduce(gb, s, v, stopval):
619
+ ....: return regular_reduce(gb, s, v, stopval)
620
+ ....: ''')
621
+
622
+ sage: R = Zp(3, prec=8)
623
+ sage: A.<x,y> = TateAlgebra(R)
624
+ sage: tx = x.leading_term() # the term x
625
+ sage: ty = y.leading_term() # the term y
626
+ sage: v = (x + y + 2*x^2*y - x^3).add_bigoh(8)
627
+ sage: p1 = (tx, x^3 + 9*x*y)
628
+ sage: p2 = (ty, x*y + 3*x^2*y)
629
+
630
+ sage: python_regular_reduce([p1,p2], tx*ty, v, 8) # indirect doctest # needs sage.misc.cython
631
+ (2 + O(3^8))*x^2*y + (1 + O(3^8))*x + (1 + O(3^8))*y + O(3^8 * <x, y>)
632
+
633
+ sage: python_regular_reduce([p1,p2], tx, v, 8) # indirect doctest # needs sage.misc.cython
634
+ (2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + O(3^8))*x^3
635
+ + (2 + O(3^8))*x^2*y + (1 + O(3^8))*x + (1 + O(3^8))*y + O(3^8 * <x, y>)
636
+ """
637
+ # We assume that the elements of the sgb are such that lt(g) = p^v lm(g) to
638
+ # avoid performing divisions
639
+ cdef dict coeffs = { }
640
+ cdef TateAlgebraElement f
641
+ cdef TateAlgebraTerm lt, factor
642
+ cdef list ltds = [ (<TateAlgebraElement>(d[1]))._terms_c()[0] for d in sgb ]
643
+ cdef list terms = v._terms_c()
644
+ cdef int index = 0
645
+ cdef int i
646
+ cdef bint in_rem
647
+
648
+ f = v._new_c()
649
+ f._poly = PolyDict(v._poly.__repn, None)
650
+ f._prec = v._prec
651
+ factor = (<TateAlgebraTerm>terms[0])._new_c()
652
+ while len(terms) > index:
653
+ sig_check()
654
+ lt = terms[index]
655
+ if (not lt) or (lt._valuation_c() >= stopval):
656
+ break
657
+ for i in range(len(sgb)):
658
+ sig_check()
659
+ # The comparison below does not perform a division, it only compares valuation and exponents
660
+ if (<TateAlgebraTerm>ltds[i])._divides_c(lt, integral=True):
661
+ # Here we need the elements of sgb to be "monic"
662
+ factor._exponent = lt._exponent.esub((<TateAlgebraTerm>ltds[i])._exponent)
663
+ factor._coeff = lt._coeff >> (<TateAlgebraTerm>ltds[i])._valuation_c()
664
+ if sgb[i][0] is None or factor * sgb[i][0] < s:
665
+ f = f - (<TateAlgebraElement>sgb[i][1])._term_mul_c(factor)
666
+ terms = f._terms_c()
667
+ index = 0
668
+ break
669
+ else:
670
+ if lt._exponent in coeffs:
671
+ coeffs[lt._exponent] += lt._coeff
672
+ else:
673
+ coeffs[lt._exponent] = lt._coeff
674
+ del f._poly.__repn[lt._exponent]
675
+ index += 1
676
+ f._poly += PolyDict(coeffs, None)
677
+ f._terms = None
678
+ return f
679
+
680
+
681
+ cdef TateAlgebraElement reduce(gb, TateAlgebraElement v, stopval):
682
+ r"""
683
+ Return the result of the reduction of ``v`` by ``gb``.
684
+
685
+ INPUT:
686
+
687
+ - ``gb`` -- list of reductors
688
+
689
+ - ``v`` -- a series
690
+
691
+ - ``stopval`` -- the valuation until which reductions are performed
692
+
693
+ TESTS::
694
+
695
+ sage: cython(''' # optional - sage.misc.cython
696
+ ....: from sage.rings.tate_algebra_ideal cimport reduce
697
+ ....: def python_reduce(gb, v, stopval):
698
+ ....: return reduce(gb, v, stopval)
699
+ ....: ''')
700
+
701
+ sage: R = Zp(3, prec=8)
702
+ sage: A.<x,y> = TateAlgebra(R)
703
+ sage: v = (x + y + 2*x^2*y - x^3*y^2).add_bigoh(8)
704
+ sage: g1 = x*y + 3*x^2*y
705
+ sage: g2 = x^3 + 9*y
706
+ sage: python_reduce([g1,g2], v, 8) # indirect doctest # needs sage.misc.cython
707
+ (1 + O(3^8))*x + (1 + O(3^8))*y + O(3^8 * <x, y>)
708
+
709
+ sage: python_reduce([g1,g2], v, 5) # indirect doctest # needs sage.misc.cython
710
+ (1 + O(3^8))*x + (1 + O(3^8))*y + (3^5 + O(3^8))*x^8*y^2
711
+ + (3^5 + 2*3^6 + 2*3^7 + O(3^8))*x^7*y + O(3^8 * <x, y>)
712
+ """
713
+ cdef dict coeffs = { }
714
+ cdef TateAlgebraElement f
715
+ cdef TateAlgebraTerm lt, factor
716
+ cdef list ltds = [ (<TateAlgebraElement>d)._terms_c()[0] for d in gb ]
717
+ cdef list terms = v._terms_c()
718
+ cdef int index = 0
719
+ cdef int i
720
+
721
+ f = v._new_c()
722
+ f._poly = PolyDict(v._poly.__repn, None)
723
+ f._prec = v._prec
724
+ while len(terms) > index:
725
+ lt = terms[index]
726
+ if (not lt) or (lt._valuation_c() >= stopval):
727
+ break
728
+ for i in range(len(gb)):
729
+ if (<TateAlgebraTerm>ltds[i])._divides_c(lt, integral=True):
730
+ factor = lt._floordiv_c(<TateAlgebraTerm>ltds[i])
731
+ f = f - (<TateAlgebraElement>gb[i])._term_mul_c(factor)
732
+ terms = f._terms_c()
733
+ index = 0
734
+ break
735
+ else:
736
+ if lt._exponent in coeffs:
737
+ coeffs[lt._exponent] += lt._coeff
738
+ else:
739
+ coeffs[lt._exponent] = lt._coeff
740
+ del f._poly.__repn[lt._exponent]
741
+ index += 1
742
+ f._poly += PolyDict(coeffs, None)
743
+ f._terms = None
744
+ return f
745
+
746
+
747
+ def print_pair(p, verbose):
748
+ r"""
749
+ Return a string representation of the pair ``p``.
750
+
751
+ INPUT:
752
+
753
+ - ``p`` -- a pair (signature, series)
754
+
755
+ - ``verbose`` -- integer
756
+
757
+ TESTS::
758
+
759
+ sage: from sage.rings.tate_algebra_ideal import print_pair
760
+ sage: R = Zp(3, prec=10, print_mode='digits')
761
+ sage: A.<x,y> = TateAlgebra(R)
762
+ sage: v = 3*x^2 + 5*x*y^2
763
+ sage: s = v.leading_term()
764
+ sage: p = (s,v)
765
+
766
+ When ``verbose`` is less than 4, only the leading term of
767
+ the series is printed::
768
+
769
+ sage: print_pair(p, 0)
770
+ '(sign = ...0000000012*x*y^2, series = ...0000000012*x*y^2 + ...)'
771
+
772
+ When ``verbose`` is at least 4, the entire series is printed::
773
+
774
+ sage: print_pair(p, 4)
775
+ '(sign = ...0000000012*x*y^2, series = ...0000000012*x*y^2 + ...00000000010*x^2)'
776
+ """
777
+ if verbose > 3:
778
+ return "(sign = %s, series = %s)" % p
779
+ else:
780
+ s, v = p
781
+ return "(sign = %s, series = %s + ...)" % (s, v.leading_term())
782
+
783
+
784
+ def groebner_basis_pote(I, prec, verbose=0):
785
+ r"""
786
+ Run the PoTe algorithm to compute the Groebner basis of ``I``
787
+ and return it
788
+
789
+ INPUT:
790
+
791
+ - ``I`` -- an ideal
792
+
793
+ - ``prec`` -- the precision at which the Groebner basis is computed
794
+
795
+ - ``verbose`` -- integer (default: 0)
796
+
797
+ TESTS::
798
+
799
+ sage: R = Zp(3, prec=10, print_mode='digits')
800
+ sage: A.<x,y> = TateAlgebra(R)
801
+ sage: f = 3*x^2 + 5*x*y^2
802
+ sage: g = 5*x^2*y + 3
803
+ sage: I = A.ideal([f,g])
804
+ sage: I.groebner_basis(algorithm='PoTe') # indirect doctest
805
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
806
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
807
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
808
+
809
+ sage: I.groebner_basis(algorithm='PoTe', verbose=2) # indirect doctest
810
+ ---
811
+ new generator: ...0000000001*x*y^2 + ...
812
+ 0 initial J-pairs
813
+ 1 elements in GB before minimization
814
+ 1 elements in GB after minimization
815
+ grobner basis reduced
816
+ ---
817
+ new generator: ...0000000001*x^2*y + ...
818
+ 1 initial J-pairs
819
+ current J-pair: (sign = ...0000000001*y, series = ...0000000001*x^2*y^2 + ...)
820
+ 0 remaining J-pairs
821
+ | new element in SGB: (sign = ...0000000001*y, series = ...0000000010*x^3 + ...)
822
+ | add 2 J-pairs
823
+ current J-pair: (sign = ...000000001*y^2, series = ...0000000010*x^3*y + ...)
824
+ 1 remaining J-pairs
825
+ | new element in SGB: (sign = ...000000001*y^2, series = ...0000000010*y^2 + ...)
826
+ | add 3 J-pairs
827
+ current J-pair: (sign = ...000000001*y^3, series = ...0000000010*x^3*y^2 + ...)
828
+ 3 remaining J-pairs
829
+ | skip: cover by (sign = ...000000001*y^2, series = ...0000000010*y^2 + ...)
830
+ current J-pair: (sign = ...000000001*x*y^2, series = ...0000000010*x*y^2 + ...)
831
+ 2 remaining J-pairs
832
+ | skip: sygyzy criterium; signature = ...0000000001*x*y^2
833
+ current J-pair: (sign = ...000000001*x^2*y^2, series = ...0000000010*x^2*y^2 + ...)
834
+ 1 remaining J-pairs
835
+ | skip: sygyzy criterium; signature = ...0000000001*x*y^2
836
+ current J-pair: (sign = ...000000001*x^3*y^2, series = ...0000000010*x^3*y^2 + ...)
837
+ 0 remaining J-pairs
838
+ | skip: sygyzy criterium; signature = ...0000000001*x*y^2
839
+ 4 elements in GB before minimization
840
+ 3 elements in GB after minimization
841
+ grobner basis reduced
842
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
843
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
844
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
845
+
846
+ We check that :issue:`30101` is fixed::
847
+
848
+ sage: I.groebner_basis(algorithm='PoTe', prec=100) # indirect doctest
849
+ [...0000000001*x^3 + ...2222222222*y + ...000000000*x^2*y^2 + O(3^99 * <x, y>),
850
+ ...0000000001*x^2*y + ...01210121020 + O(3^100 * <x, y>),
851
+ ...0000000001*y^2 + ...01210121020*x + ...0000000000*x^3*y + O(3^99 * <x, y>)]
852
+ """
853
+ cdef TateAlgebraElement g, v
854
+ cdef TateAlgebraTerm s, sv, S, ti, tj
855
+ cdef list terms
856
+ cdef TateAlgebraTerm term_one = I.ring().monoid_of_terms().one()
857
+ cdef bint integral = not I.ring().base_ring().is_field()
858
+
859
+ gb = [ ]
860
+
861
+ for f in sorted(I.gens()):
862
+ sig_check()
863
+ if not f: # Maybe reduce first?
864
+ continue
865
+
866
+ # TODO: this should probably be a single function call
867
+ f = f.monic() << f.valuation()
868
+
869
+ if verbose > 0:
870
+ print("---")
871
+ print("new generator: %s + ..." % f.leading_term())
872
+ # Initial strong Grobner basis:
873
+ # we add signatures
874
+ sgb = [ (None, g) for g in gb if g ]
875
+ # We compute initial J-pairs
876
+ l = len(sgb)
877
+ p = (term_one, f.add_bigoh(prec))
878
+ Jpairs = [ ]
879
+ for P in sgb:
880
+ sig_check()
881
+ J = Jpair(p, P)
882
+ if J is not None:
883
+ heappush(Jpairs, J)
884
+ sgb.append(p)
885
+
886
+ # For the syzygy criterium
887
+ gb0 = [ g.leading_term() for g in gb ]
888
+
889
+ if verbose > 1:
890
+ print("%s initial J-pairs" % len(Jpairs))
891
+ if verbose > 2:
892
+ for s,v in Jpairs:
893
+ print("| " + print_pair((s,v),verbose))
894
+
895
+ while Jpairs:
896
+ sig_check()
897
+ s, v = heappop(Jpairs)
898
+ sv = v.leading_term()
899
+
900
+ if verbose == 1:
901
+ print("pop one J-pair; %s remaining J-pairs" % len(Jpairs))
902
+ if verbose > 1:
903
+ print("current J-pair: " + print_pair((s,v), verbose))
904
+ print("%s remaining J-pairs" % len(Jpairs))
905
+
906
+ # The syzygy criterium
907
+ syzygy = None
908
+ for S in gb0:
909
+ sig_check()
910
+ if S.divides(s):
911
+ syzygy = S
912
+ break
913
+ if syzygy is not None:
914
+ if verbose > 1:
915
+ print("| skip: sygyzy criterium; signature = %s" % syzygy)
916
+ continue
917
+
918
+ # We check if (s,v) is covered by
919
+ # the current strong Grobner basis
920
+ cover = None
921
+ for S, V in sgb:
922
+ sig_check()
923
+ if S is not None and S.divides(s):
924
+ sV = V.leading_term()
925
+ if (s // S)*sV < sv:
926
+ cover = (S,V)
927
+ break
928
+ if cover is not None:
929
+ if verbose > 1:
930
+ print("| skip: cover by " + print_pair(cover, verbose))
931
+ continue
932
+
933
+ # We perform regular top-reduction
934
+ sgb.append((None, v._positive_lshift_c(1)))
935
+ v = regular_reduce(sgb, s, v, prec)
936
+ terms = v._terms_c()
937
+ if terms:
938
+ sv = terms[0]
939
+ if not sv:
940
+ v = v.add_bigoh(sv._coeff.precision_absolute())
941
+ del sgb[-1]
942
+
943
+ if not v or v.valuation() >= prec:
944
+ # We have a new element in (I0:f) whose signature
945
+ # could be useful to strengthen the syzygy criterium
946
+ gb0.append(s)
947
+ else:
948
+ # We update the current strong Grobner basis
949
+ # and the J-pairs accordingly
950
+ vv = v.monic() << v.valuation()
951
+ p = (s,vv)
952
+ if verbose > 1:
953
+ print("| new element in SGB: " + print_pair(p, verbose))
954
+ count = 0
955
+ for P in sgb:
956
+ sig_check()
957
+ J = Jpair(p, P)
958
+ if J is not None:
959
+ count += 1
960
+ if verbose > 2:
961
+ print("| add J-pair: " + print_pair(J, verbose))
962
+ heappush(Jpairs, J)
963
+ if verbose > 1:
964
+ print("| add %s J-pairs" % count)
965
+ sgb.append(p)
966
+
967
+ # We forget signatures
968
+ gb = [g for (s,g) in sgb]
969
+ if verbose > 1:
970
+ print("%s elements in GB before minimization" % len(gb))
971
+ if verbose > 3:
972
+ for g in gb:
973
+ print("| %s" % g)
974
+
975
+ # We minimize the Grobner basis
976
+ i = 0
977
+ while i < len(gb):
978
+ ti = (<TateAlgebraElement>gb[i])._terms_c()[0]
979
+ for j in range(len(gb)):
980
+ sig_check()
981
+ tj = (<TateAlgebraElement>gb[j])._terms_c()[0]
982
+ if j != i and tj._divides_c(ti, integral):
983
+ del gb[i]
984
+ break
985
+ else:
986
+ i += 1
987
+ if verbose > 0:
988
+ if verbose > 1:
989
+ aft = " after minimization"
990
+ else:
991
+ aft = ""
992
+ print("%s elements in GB%s" % (len(gb), aft))
993
+ if verbose > 3:
994
+ for g in gb:
995
+ print("| %s" % g)
996
+ # and reduce it
997
+ for i in range(len(gb)-1, -1, -1):
998
+ sig_check()
999
+ g = gb[i]
1000
+ gb[i] = g._positive_lshift_c(1)
1001
+ _, gb[i] = g._quo_rem_c(gb, False, True, True)
1002
+ if verbose > 1:
1003
+ print("grobner basis reduced")
1004
+ if verbose > 3:
1005
+ for g in gb:
1006
+ print("| %s" % g)
1007
+
1008
+ if not integral:
1009
+ gb = [ f.monic() for f in gb ]
1010
+ gb.sort(reverse=True)
1011
+ return gb
1012
+
1013
+
1014
+ def groebner_basis_vapote(I, prec, verbose=0, interrupt_red_with_val=False, interrupt_interred_with_val=False):
1015
+ r"""
1016
+ Run the VaPoTe algorithm to compute the Groebner basis of ``I``
1017
+ and return it
1018
+
1019
+ INPUT:
1020
+
1021
+ - ``I`` -- an ideal
1022
+
1023
+ - ``prec`` -- the precision at which the Groebner basis is computed
1024
+
1025
+ - ``verbose`` -- integer (default: 0)
1026
+
1027
+ - ``interrupt_red_with_val`` -- boolean (default: ``False``); if
1028
+ regular reductions have to be interrupted as soon as the valuation
1029
+ raises
1030
+
1031
+ - ``interrupt_interred_with_val`` -- boolean (default: ``False'');
1032
+ if intermediate interreductions of the Groebner basis have to be
1033
+ interrupted as soon as the valuation raises
1034
+
1035
+ TESTS::
1036
+
1037
+ sage: R = Zp(3, prec=10, print_mode='digits')
1038
+ sage: A.<x,y> = TateAlgebra(R)
1039
+ sage: f = 3*x^2 + 5*x*y^2
1040
+ sage: g = 5*x^2*y + 3
1041
+ sage: I = A.ideal([f,g])
1042
+ sage: I.groebner_basis(algorithm='VaPoTe') # indirect doctest
1043
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
1044
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
1045
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
1046
+
1047
+ sage: I.groebner_basis(algorithm='VaPoTe', interrupt_red_with_val=True) # indirect doctest
1048
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
1049
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
1050
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
1051
+
1052
+ sage: I.groebner_basis(algorithm='VaPoTe', verbose=2) # indirect doctest
1053
+ grobner basis reduced
1054
+ ---
1055
+ new generator: ...0000000012*x*y^2 + ...
1056
+ generator reduced
1057
+ 0 initial J-pairs
1058
+ 1 elements in GB before minimization
1059
+ 1 elements in GB after minimization
1060
+ grobner basis reduced
1061
+ ---
1062
+ new generator: ...0000000012*x^2*y + ...
1063
+ generator reduced
1064
+ 1 initial J-pairs
1065
+ pop one J-pair; 0 remaining J-pairs
1066
+ | add signature for syzygy criterium: ...0000000001*y
1067
+ 2 elements in GB before minimization
1068
+ 2 elements in GB after minimization
1069
+ grobner basis reduced
1070
+ ---
1071
+ new generator: ...0000000010*x^3 + ...
1072
+ generator reduced
1073
+ 2 initial J-pairs
1074
+ pop one J-pair; 1 remaining J-pairs
1075
+ | new element is SGB: (sign = ...000000001*y, series = ...0000000010*y^2 + ...)
1076
+ | add 3 J-pairs
1077
+ pop one J-pair; 3 remaining J-pairs
1078
+ | skip: cover by (sign = ...000000001*y, series = ...0000000010*y^2 + ...)
1079
+ pop one J-pair; 2 remaining J-pairs
1080
+ | add signature for syzygy criterium: ...000000001*x*y
1081
+ pop one J-pair; 1 remaining J-pairs
1082
+ | skip: sygyzy criterium; signature = ...0000000001*x^2*y
1083
+ pop one J-pair; 0 remaining J-pairs
1084
+ | skip: sygyzy criterium; signature = ...0000000001*x^2*y
1085
+ 4 elements in GB before minimization
1086
+ 3 elements in GB after minimization
1087
+ grobner basis reduced
1088
+ [...000000001*x^3 + ...222222222*y + O(3^9 * <x, y>),
1089
+ ...0000000001*x^2*y + ...1210121020 + O(3^10 * <x, y>),
1090
+ ...000000001*y^2 + ...210121020*x + O(3^9 * <x, y>)]
1091
+
1092
+ We check that :issue:`30101` is fixed::
1093
+
1094
+ sage: I.groebner_basis(algorithm='VaPoTe', prec=100) # indirect doctest
1095
+ [...0000000001*x^3 + ...2222222222*y + ...000000000*x^2*y^2 + O(3^99 * <x, y>),
1096
+ ...0000000001*x^2*y + ...01210121020 + O(3^100 * <x, y>),
1097
+ ...0000000001*y^2 + ...01210121020*x + ...0000000000*x^3*y + O(3^99 * <x, y>)]
1098
+ """
1099
+ cdef TateAlgebraElement g, v
1100
+ cdef TateAlgebraTerm s, S, sv, ti, tj
1101
+ cdef list terms
1102
+ cdef bint do_reduce, integral
1103
+ term_one = I.ring().monoid_of_terms().one()
1104
+ gb = [ ]
1105
+
1106
+ gens = [ ]
1107
+ for f in I.gens():
1108
+ if f:
1109
+ val = f.valuation()
1110
+ if val < prec:
1111
+ heappush(gens, (val, f.add_bigoh(prec)))
1112
+
1113
+ do_reduce = False
1114
+ integral = not I.ring().base_ring().is_field()
1115
+
1116
+ while gens:
1117
+ sig_check()
1118
+ val, f = heappop(gens)
1119
+ if val > prec:
1120
+ break
1121
+
1122
+ # We reduce the current Gröbner basis
1123
+ if val == 0 or do_reduce:
1124
+ for i in range(len(gb)-1, -1, -1):
1125
+ sig_check()
1126
+ g = gb[i]
1127
+ gb[i] = g._positive_lshift_c(1)
1128
+ tgtval = val + 1 if interrupt_interred_with_val else prec
1129
+ gb[i] = reduce(gb, g, tgtval)
1130
+ if verbose > 1:
1131
+ print("grobner basis reduced")
1132
+ if verbose > 3:
1133
+ for g in gb:
1134
+ print("| %s" % g)
1135
+ do_reduce = False
1136
+
1137
+ if verbose > 0:
1138
+ print("---")
1139
+ print("new generator: %s + ..." % f.leading_term())
1140
+
1141
+ tgtval = val + 1 if interrupt_red_with_val else prec
1142
+ f = reduce(gb, f, tgtval)
1143
+ if verbose > 1:
1144
+ print("generator reduced")
1145
+
1146
+ if not f:
1147
+ if verbose > 0:
1148
+ print("reduction to zero")
1149
+ continue
1150
+
1151
+ f = f.monic() << f.valuation()
1152
+
1153
+ if f and f.valuation() > val:
1154
+ if verbose > 0:
1155
+ print("reduction increases the valuation")
1156
+ heappush(gens, (f.valuation(), f))
1157
+ continue
1158
+
1159
+ # Initial strong Grobner basis:
1160
+ # we add signatures
1161
+ sgb = [ (None, g) for g in gb if g ]
1162
+ # We compute initial J-pairs
1163
+ l = len(sgb)
1164
+ p = (term_one, f.add_bigoh(prec))
1165
+ Jpairs = [ ]
1166
+ for P in sgb:
1167
+ J = Jpair(p, P)
1168
+ if J is not None:
1169
+ heappush(Jpairs, J)
1170
+ sgb.append(p)
1171
+
1172
+ # For the syzygy criterium
1173
+ gb0 = [ g.leading_term() for g in gb ]
1174
+
1175
+ if verbose > 1:
1176
+ print("%s initial J-pairs" % len(Jpairs))
1177
+ if verbose > 2:
1178
+ for s,v in Jpairs:
1179
+ print("| " + print_pair((s,v),verbose))
1180
+
1181
+ while Jpairs:
1182
+ sig_check()
1183
+ s, v = heappop(Jpairs)
1184
+ sv = v.leading_term()
1185
+
1186
+ if verbose == 2:
1187
+ print("pop one J-pair; %s remaining J-pairs" % len(Jpairs))
1188
+ if verbose > 2:
1189
+ print("current J-pair: " + print_pair((s,v), verbose))
1190
+ print("%s remaining J-pairs" % len(Jpairs))
1191
+
1192
+ # The syzygy criterium
1193
+ syzygy = None
1194
+ for S in gb0:
1195
+ sig_check()
1196
+ if S.divides(s):
1197
+ syzygy = S
1198
+ break
1199
+ if syzygy is not None:
1200
+ if verbose > 1:
1201
+ print("| skip: sygyzy criterium; signature = %s" % syzygy)
1202
+ continue
1203
+
1204
+ # We check if (s,v) is covered by
1205
+ # the current strong Grobner basis
1206
+ cover = None
1207
+ for S, V in sgb:
1208
+ sig_check()
1209
+ if S is not None and S.divides(s):
1210
+ sV = V.leading_term()
1211
+ # FIXME: should be a monic division
1212
+ if (s // S)*sV < sv:
1213
+ cover = (S,V)
1214
+ break
1215
+ if cover is not None:
1216
+ if verbose > 1:
1217
+ print("| skip: cover by " + print_pair(cover, verbose))
1218
+ continue
1219
+
1220
+ # We perform regular top-reduction
1221
+ sgb.append((None, v._positive_lshift_c(1)))
1222
+ tgtval = val + 1 if interrupt_red_with_val else prec
1223
+ v = regular_reduce(sgb, s, v, tgtval)
1224
+ terms = v._terms_c()
1225
+ if terms:
1226
+ sv = terms[0]
1227
+ if not sv:
1228
+ v = v.add_bigoh(sv._coeff.precision_absolute())
1229
+ del sgb[-1]
1230
+
1231
+ if v:
1232
+ v = v.monic() << v.valuation()
1233
+ if v.valuation() > val:
1234
+ # We have a new element in (I0:f) whose signature
1235
+ # could be useful to strengthen the syzygy criterium
1236
+ if verbose > 1:
1237
+ print ("| add signature for syzygy criterium: %s" % s)
1238
+ gb0.append(s)
1239
+ if v:
1240
+ heappush(gens, (v.valuation(), v))
1241
+ else:
1242
+ # We update the current strong Grobner basis
1243
+ # and the J-pairs accordingly
1244
+ p = (s,v)
1245
+ if verbose > 1:
1246
+ print("| new element is SGB: " + print_pair(p, verbose))
1247
+ count = 0
1248
+ for P in sgb:
1249
+ sig_check()
1250
+ J = Jpair(p, P)
1251
+ if J is not None:
1252
+ count += 1
1253
+ if verbose > 2:
1254
+ print("| add J-pair: " + print_pair(J, verbose))
1255
+ heappush(Jpairs, J)
1256
+ if verbose > 1:
1257
+ print("| add %s J-pairs" % count)
1258
+ sgb.append(p)
1259
+
1260
+ # We forget signatures
1261
+ # gb = [ v.monic() for (s,v) in sgb ]
1262
+ gb = [ v for (s,v) in sgb ]
1263
+ if verbose > 1:
1264
+ print("%s elements in GB before minimization" % len(gb))
1265
+ if verbose > 3:
1266
+ for g in gb:
1267
+ print("| %s" % g)
1268
+ # we minimize the Grobner basis
1269
+ i = 0
1270
+ while i < len(gb):
1271
+ ti = (<TateAlgebraElement>gb[i])._terms_c()[0]
1272
+ for j in range(len(gb)):
1273
+ sig_check()
1274
+ tj = (<TateAlgebraElement>gb[j])._terms_c()[0]
1275
+ if j != i and tj._divides_c(ti, integral):
1276
+ del gb[i]
1277
+ break
1278
+ else:
1279
+ i += 1
1280
+ if verbose > 0:
1281
+ if verbose > 1:
1282
+ aft = " after minimization"
1283
+ else:
1284
+ aft = ""
1285
+ print("%s elements in GB%s" % (len(gb), aft))
1286
+ if verbose > 3:
1287
+ for g in gb:
1288
+ print("| %s" % g)
1289
+ # and reduce it
1290
+ do_reduce = True
1291
+
1292
+ # We normalize the final Gröbner basis
1293
+ for i in range(len(gb)-1, -1, -1):
1294
+ sig_check()
1295
+ g = gb[i]
1296
+ gb[i] = g._positive_lshift_c(1)
1297
+ gb[i] = reduce(gb, g, prec)
1298
+ if verbose > 1:
1299
+ print("grobner basis reduced")
1300
+ if verbose > 3:
1301
+ for g in gb:
1302
+ print("| %s" % g)
1303
+ if not integral:
1304
+ gb = [ f.monic() for f in gb ]
1305
+ gb.sort(reverse=True)
1306
+
1307
+ return gb