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,1119 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ r"""
3
+ Discrete valuations
4
+
5
+ This file defines abstract base classes for discrete (pseudo-)valuations.
6
+
7
+ AUTHORS:
8
+
9
+ - Julian Rüth (2013-03-16): initial version
10
+
11
+ EXAMPLES:
12
+
13
+ Discrete valuations can be created on a variety of rings::
14
+
15
+ sage: ZZ.valuation(2)
16
+ 2-adic valuation
17
+ sage: GaussianIntegers().valuation(3) # needs sage.rings.number_field
18
+ 3-adic valuation
19
+ sage: QQ.valuation(5)
20
+ 5-adic valuation
21
+ sage: Zp(7).valuation()
22
+ 7-adic valuation
23
+
24
+ ::
25
+
26
+ sage: # needs sage.rings.function_field
27
+ sage: K.<x> = FunctionField(QQ)
28
+ sage: K.valuation(x)
29
+ (x)-adic valuation
30
+ sage: K.valuation(x^2 + 1)
31
+ (x^2 + 1)-adic valuation
32
+ sage: K.valuation(1/x)
33
+ Valuation at the infinite place
34
+
35
+ ::
36
+
37
+ sage: R.<x> = QQ[]
38
+ sage: v = QQ.valuation(2)
39
+ sage: w = GaussValuation(R, v)
40
+ sage: w.augmentation(x, 3)
41
+ [ Gauss valuation induced by 2-adic valuation, v(x) = 3 ]
42
+
43
+ We can also define discrete pseudo-valuations, i.e., discrete valuations that
44
+ send more than just zero to infinity::
45
+
46
+ sage: w.augmentation(x, infinity)
47
+ [ Gauss valuation induced by 2-adic valuation, v(x) = +Infinity ]
48
+ """
49
+ # ****************************************************************************
50
+ # Copyright (C) 2013-2017 Julian Rüth <julian.rueth@fsfe.org>
51
+ #
52
+ # Distributed under the terms of the GNU General Public License (GPL)
53
+ # as published by the Free Software Foundation; either version 2 of
54
+ # the License, or (at your option) any later version.
55
+ # https://www.gnu.org/licenses/
56
+ # ****************************************************************************
57
+
58
+ from sage.categories.morphism import Morphism
59
+ from sage.structure.richcmp import op_EQ, op_NE, op_LE, op_LT, op_GE, op_GT
60
+
61
+ from sage.misc.cachefunc import cached_method
62
+
63
+
64
+ class DiscretePseudoValuation(Morphism):
65
+ r"""
66
+ Abstract base class for discrete pseudo-valuations, i.e., discrete
67
+ valuations which might send more that just zero to infinity.
68
+
69
+ INPUT:
70
+
71
+ - ``domain`` -- an integral domain
72
+
73
+ EXAMPLES::
74
+
75
+ sage: v = ZZ.valuation(2); v # indirect doctest
76
+ 2-adic valuation
77
+
78
+ TESTS::
79
+
80
+ sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron
81
+ """
82
+ def __init__(self, parent):
83
+ r"""
84
+ TESTS::
85
+
86
+ sage: from sage.rings.valuation.valuation import DiscretePseudoValuation
87
+ sage: isinstance(ZZ.valuation(2), DiscretePseudoValuation)
88
+ True
89
+ """
90
+ Morphism.__init__(self, parent=parent)
91
+
92
+ def is_equivalent(self, f, g):
93
+ r"""
94
+ Return whether ``f`` and ``g`` are equivalent.
95
+
96
+ EXAMPLES::
97
+
98
+ sage: v = QQ.valuation(2)
99
+ sage: v.is_equivalent(2, 1)
100
+ False
101
+ sage: v.is_equivalent(2, -2)
102
+ True
103
+ sage: v.is_equivalent(2, 0)
104
+ False
105
+ sage: v.is_equivalent(0, 0)
106
+ True
107
+ """
108
+ from sage.rings.infinity import infinity
109
+ if self(f) is infinity:
110
+ return self(g) is infinity
111
+
112
+ return self(f - g) > self(f)
113
+
114
+ def __hash__(self):
115
+ r"""
116
+ The hash value of this valuation.
117
+
118
+ We redirect to :meth:`_hash_`, so that subclasses can only override
119
+ :meth:`_hash_` and :meth:`_eq_` if they want to provide a different
120
+ notion of equality but they can leave the partial and total operators
121
+ untouched.
122
+
123
+ EXAMPLES::
124
+
125
+ sage: v = QQ.valuation(2)
126
+ sage: hash(v) == hash(v) # indirect doctest
127
+ True
128
+ """
129
+ return self._hash_()
130
+
131
+ def _hash_(self):
132
+ r"""
133
+ Return a hash value for this valuation.
134
+
135
+ We override the strange default provided by
136
+ :class:`sage.categories.morphism.Morphism` here and implement equality by
137
+ ``id``. This works fine for objects which use unique representation.
138
+
139
+ Note that the vast majority of valuations come out of a
140
+ :class:`sage.structure.factory.UniqueFactory` and therefore override
141
+ our implementation of :meth:`__hash__` and :meth:`__eq__`.
142
+
143
+ EXAMPLES::
144
+
145
+ sage: v = QQ.valuation(2)
146
+ sage: hash(v) == hash(v) # indirect doctest
147
+ True
148
+ """
149
+ return id(self)
150
+
151
+ def _richcmp_(self, other, op):
152
+ r"""
153
+ Compare this element to ``other``.
154
+
155
+ We redirect to methods :meth:`_eq_`, :meth:`_lt_`, and :meth:`_gt_` to
156
+ make it easier for subclasses to override only parts of this
157
+ functionality.
158
+
159
+ Note that valuations usually implement ``x == y`` as ``x`` and ``y``
160
+ are indistinguishable. Whereas ``x <= y`` and ``x >= y`` are
161
+ implemented with respect to the natural partial order of valuations.
162
+ As a result, ``x <= y and x >= y`` does not imply ``x == y``.
163
+
164
+ EXAMPLES::
165
+
166
+ sage: v = QQ.valuation(2)
167
+ sage: v == v
168
+ True
169
+ sage: v != v
170
+ False
171
+ sage: w = QQ.valuation(3)
172
+ sage: v == w
173
+ False
174
+ sage: v != w
175
+ True
176
+ """
177
+ if op == op_LT:
178
+ return self <= other and not (self >= other)
179
+ if op == op_LE:
180
+ return self._le_(other)
181
+ if op == op_EQ:
182
+ return self._eq_(other)
183
+ if op == op_NE:
184
+ return not self == other
185
+ if op == op_GT:
186
+ return self >= other and not (self <= other)
187
+ if op == op_GE:
188
+ return self._ge_(other)
189
+ raise NotImplementedError("Operator not implemented for this valuation")
190
+
191
+ def _eq_(self, other):
192
+ r"""
193
+ Return whether this valuation and ``other`` are indistinguishable.
194
+
195
+ We override the strange default provided by
196
+ :class:`sage.categories.morphism.Morphism` here and implement equality by
197
+ ``id``. This is the right behaviour in many cases.
198
+
199
+ Note that the vast majority of valuations come out of a
200
+ :class:`sage.structure.factory.UniqueFactory` and therefore override
201
+ our implementation of :meth:`__hash__` and :meth:`__eq__`.
202
+
203
+ When overriding this method, you can assume that ``other`` is a
204
+ (pseudo-)valuation on the same domain.
205
+
206
+ EXAMPLES::
207
+
208
+ sage: v = valuations.TrivialValuation(QQ)
209
+ sage: v == v
210
+ True
211
+ """
212
+ return self is other
213
+
214
+ def _le_(self, other):
215
+ r"""
216
+ Return whether this valuation is less than or equal to ``other``
217
+ pointwise.
218
+
219
+ When overriding this method, you can assume that ``other`` is a
220
+ (pseudo-)valuation on the same domain.
221
+
222
+ EXAMPLES::
223
+
224
+ sage: v = valuations.TrivialValuation(QQ)
225
+ sage: w = QQ.valuation(2)
226
+ sage: v <= w
227
+ True
228
+ """
229
+ return other >= self
230
+
231
+ def _ge_(self, other):
232
+ r"""
233
+ Return whether this valuation is greater than or equal to ``other``
234
+ pointwise.
235
+
236
+ When overriding this method, you can assume that ``other`` is a
237
+ (pseudo-)valuation on the same domain.
238
+
239
+ EXAMPLES::
240
+
241
+ sage: v = valuations.TrivialValuation(QQ)
242
+ sage: w = QQ.valuation(2)
243
+ sage: v >= w
244
+ False
245
+ """
246
+ if self == other:
247
+ return True
248
+ from .scaled_valuation import ScaledValuation_generic
249
+ if isinstance(other, ScaledValuation_generic):
250
+ return other <= self
251
+ raise NotImplementedError("Operator not implemented for this valuation")
252
+
253
+ # Remove the default implementation of Map.__reduce__ that does not play
254
+ # nice with factories (a factory, does not override Map.__reduce__ because
255
+ # it is not the generic reduce of object) and that does not match equality
256
+ # by id.
257
+ __reduce__ = object.__reduce__
258
+
259
+ def _test_valuation_inheritance(self, **options):
260
+ r"""
261
+ Test that every instance of this class is either a
262
+ :class:`InfiniteDiscretePseudoValuation` or a
263
+ :class:`DiscreteValuation`.
264
+
265
+ EXAMPLES::
266
+
267
+ sage: QQ.valuation(2)._test_valuation_inheritance()
268
+ """
269
+ tester = self._tester(**options)
270
+ tester.assertNotEqual(isinstance(self, InfiniteDiscretePseudoValuation),
271
+ isinstance(self, DiscreteValuation))
272
+
273
+
274
+ class InfiniteDiscretePseudoValuation(DiscretePseudoValuation):
275
+ r"""
276
+ Abstract base class for infinite discrete pseudo-valuations, i.e., discrete
277
+ pseudo-valuations which are not discrete valuations.
278
+
279
+ EXAMPLES::
280
+
281
+ sage: v = QQ.valuation(2)
282
+ sage: R.<x> = QQ[]
283
+ sage: v = GaussValuation(R, v)
284
+ sage: w = v.augmentation(x, infinity); w # indirect doctest
285
+ [ Gauss valuation induced by 2-adic valuation, v(x) = +Infinity ]
286
+
287
+ TESTS::
288
+
289
+ sage: from sage.rings.valuation.valuation import InfiniteDiscretePseudoValuation
290
+ sage: isinstance(w, InfiniteDiscretePseudoValuation)
291
+ True
292
+ sage: TestSuite(w).run() # long time # needs sage.geometry.polyhedron sage.rings.padics
293
+ """
294
+ def is_discrete_valuation(self):
295
+ r"""
296
+ Return whether this valuation is a discrete valuation.
297
+
298
+ EXAMPLES::
299
+
300
+ sage: v = QQ.valuation(2)
301
+ sage: R.<x> = QQ[]
302
+ sage: v = GaussValuation(R, v)
303
+ sage: v.is_discrete_valuation()
304
+ True
305
+ sage: w = v.augmentation(x, infinity)
306
+ sage: w.is_discrete_valuation()
307
+ False
308
+ """
309
+ return False
310
+
311
+
312
+ class NegativeInfiniteDiscretePseudoValuation(InfiniteDiscretePseudoValuation):
313
+ r"""
314
+ Abstract base class for pseudo-valuations which attain the value `\infty`
315
+ and `-\infty`, i.e., whose domain contains an element of valuation `\infty`
316
+ and its inverse.
317
+
318
+ EXAMPLES::
319
+
320
+ sage: R.<x> = QQ[]
321
+ sage: v = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x, infinity)
322
+ sage: K.<x> = FunctionField(QQ)
323
+ sage: w = K.valuation(v)
324
+
325
+ TESTS::
326
+
327
+ sage: TestSuite(w).run() # long time
328
+ """
329
+ def is_negative_pseudo_valuation(self):
330
+ r"""
331
+ Return whether this valuation attains the value `-\infty`.
332
+
333
+ EXAMPLES::
334
+
335
+ sage: R.<x> = QQ[]
336
+ sage: u = GaussValuation(R, valuations.TrivialValuation(QQ))
337
+ sage: v = u.augmentation(x, infinity)
338
+ sage: v.is_negative_pseudo_valuation()
339
+ False
340
+ sage: K.<x> = FunctionField(QQ)
341
+ sage: w = K.valuation(v)
342
+ sage: w.is_negative_pseudo_valuation()
343
+ True
344
+ """
345
+ return True
346
+
347
+
348
+ class DiscreteValuation(DiscretePseudoValuation):
349
+ r"""
350
+ Abstract base class for discrete valuations.
351
+
352
+ EXAMPLES::
353
+
354
+ sage: v = QQ.valuation(2)
355
+ sage: R.<x> = QQ[]
356
+ sage: v = GaussValuation(R, v)
357
+ sage: w = v.augmentation(x, 1337); w # indirect doctest
358
+ [ Gauss valuation induced by 2-adic valuation, v(x) = 1337 ]
359
+
360
+ TESTS::
361
+
362
+ sage: from sage.rings.valuation.valuation import DiscreteValuation
363
+ sage: isinstance(w, DiscreteValuation)
364
+ True
365
+ sage: TestSuite(w).run() # long time # needs sage.geometry.polyhedron sage.rings.padics
366
+ """
367
+ def is_discrete_valuation(self):
368
+ r"""
369
+ Return whether this valuation is a discrete valuation.
370
+
371
+ EXAMPLES::
372
+
373
+ sage: v = valuations.TrivialValuation(ZZ)
374
+ sage: v.is_discrete_valuation()
375
+ True
376
+ """
377
+ return True
378
+
379
+ def mac_lane_approximants(self, G, assume_squarefree=False, require_final_EF=True, required_precision=-1, require_incomparability=False, require_maximal_degree=False, algorithm='serial'):
380
+ r"""
381
+ Return approximants on `K[x]` for the extensions of this valuation to
382
+ `L=K[x]/(G)`.
383
+
384
+ If `G` is an irreducible polynomial, then this corresponds to
385
+ extensions of this valuation to the completion of `L`.
386
+
387
+ INPUT:
388
+
389
+ - ``G`` -- a monic squarefree integral polynomial in a
390
+ univariate polynomial ring over the domain of this valuation
391
+
392
+ - ``assume_squarefree`` -- boolean (default: ``False``); whether to
393
+ assume that ``G`` is squarefree. If ``True``, the squafreeness of
394
+ ``G`` is not verified though it is necessary when
395
+ ``require_final_EF`` is set for the algorithm to terminate.
396
+
397
+ - ``require_final_EF`` -- boolean (default: ``True``); whether to
398
+ require the returned key polynomials to be in one-to-one
399
+ correspondence to the extensions of this valuation to ``L`` and
400
+ require them to have the ramification index and residue degree of the
401
+ valuations they correspond to.
402
+
403
+ - ``required_precision`` -- a number or infinity (default: -1); whether
404
+ to require the last key polynomial of the returned valuations to have
405
+ at least that valuation.
406
+
407
+ - ``require_incomparability`` -- boolean (default: ``False``);
408
+ whether to require the returned valuations to be incomparable
409
+ (with respect to the partial order on valuations defined by comparing
410
+ them pointwise.)
411
+
412
+ - ``require_maximal_degree`` -- boolean (default: ``False``); whether
413
+ to require the last key polynomial of the returned valuation to have
414
+ maximal degree. This is most relevant when using this algorithm to
415
+ compute approximate factorizations of ``G``, when set to ``True``,
416
+ the last key polynomial has the same degree as the corresponding
417
+ factor.
418
+
419
+ - ``algorithm`` -- one of ``'serial'`` or ``'parallel'`` (default:
420
+ ``'serial'``); whether or not to parallelize the algorithm
421
+
422
+ EXAMPLES::
423
+
424
+ sage: v = QQ.valuation(2)
425
+ sage: R.<x> = QQ[]
426
+ sage: v.mac_lane_approximants(x^2 + 1) # needs sage.geometry.polyhedron
427
+ [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 ]]
428
+ sage: v.mac_lane_approximants(x^2 + 1, required_precision=infinity) # needs sage.geometry.polyhedron
429
+ [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2,
430
+ v(x^2 + 1) = +Infinity ]]
431
+ sage: v.mac_lane_approximants(x^2 + x + 1)
432
+ [[ Gauss valuation induced by 2-adic valuation, v(x^2 + x + 1) = +Infinity ]]
433
+
434
+ Note that ``G`` does not need to be irreducible. Here, we detect a
435
+ factor `x + 1` and an approximate factor `x + 1` (which is an
436
+ approximation to `x - 1`)::
437
+
438
+ sage: v.mac_lane_approximants(x^2 - 1) # needs sage.geometry.polyhedron sage.rings.padics
439
+ [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = +Infinity ],
440
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1 ]]
441
+
442
+ However, it needs to be squarefree::
443
+
444
+ sage: v.mac_lane_approximants(x^2)
445
+ Traceback (most recent call last):
446
+ ...
447
+ ValueError: G must be squarefree
448
+
449
+ TESTS:
450
+
451
+ Some difficult cases provided by Mark van Hoeij::
452
+
453
+ sage: # needs sage.rings.finite_rings sage.rings.function_field
454
+ sage: k = GF(2)
455
+ sage: K.<x> = FunctionField(k)
456
+ sage: R.<y> = K[]
457
+ sage: F = y^21 + x*y^20 + (x^3 + x + 1)*y^18 + (x^3 + 1)*y^17 + (x^4 + x)*y^16 + (x^7 + x^6 + x^3 + x + 1)*y^15 + x^7*y^14 + (x^8 + x^7 + x^6 + x^4 + x^3 + 1)*y^13 + (x^9 + x^8 + x^4 + 1)*y^12 + (x^11 + x^9 + x^8 + x^5 + x^4 + x^3 + x^2)*y^11 + (x^12 + x^9 + x^8 + x^7 + x^5 + x^3 + x + 1)*y^10 + (x^14 + x^13 + x^10 + x^9 + x^8 + x^7 + x^6 + x^3 + x^2 + 1)*y^9 + (x^13 + x^9 + x^8 + x^6 + x^4 + x^3 + x)*y^8 + (x^16 + x^15 + x^13 + x^12 + x^11 + x^7 + x^3 + x)*y^7 + (x^17 + x^16 + x^13 + x^9 + x^8 + x)*y^6 + (x^17 + x^16 + x^12 + x^7 + x^5 + x^2 + x + 1)*y^5 + (x^19 + x^16 + x^15 + x^12 + x^6 + x^5 + x^3 + 1)*y^4 + (x^18 + x^15 + x^12 + x^10 + x^9 + x^7 + x^4 + x)*y^3 + (x^22 + x^21 + x^20 + x^18 + x^13 + x^12 + x^9 + x^8 + x^7 + x^5 + x^4 + x^3)*y^2 + (x^23 + x^22 + x^20 + x^17 + x^15 + x^14 + x^12 + x^9)*y + x^25 + x^23 + x^19 + x^17 + x^15 + x^13 + x^11 + x^5
458
+ sage: x = K._ring.gen()
459
+ sage: v0 = K.valuation(GaussValuation(K._ring, valuations.TrivialValuation(k)).augmentation(x,1))
460
+ sage: v0.mac_lane_approximants(F, assume_squarefree=True) # assumes squarefree for speed # needs sage.geometry.polyhedron
461
+ [[ Gauss valuation induced by (x)-adic valuation, v(y + x + 1) = 3/2 ],
462
+ [ Gauss valuation induced by (x)-adic valuation, v(y) = 1 ],
463
+ [ Gauss valuation induced by (x)-adic valuation, v(y) = 4/3 ],
464
+ [ Gauss valuation induced by (x)-adic valuation, v(y^15 + y^13 + y^12 + y^10 + y^9 + y^8 + y^4 + y^3 + y^2 + y + 1) = 1 ]]
465
+ sage: v0 = K.valuation(GaussValuation(K._ring, valuations.TrivialValuation(k)).augmentation(x+1,1))
466
+ sage: v0.mac_lane_approximants(F, assume_squarefree=True) # assumes squarefree for speed # needs sage.geometry.polyhedron
467
+ [[ Gauss valuation induced by (x + 1)-adic valuation, v(y + x^2 + 1) = 7/2 ],
468
+ [ Gauss valuation induced by (x + 1)-adic valuation, v(y) = 3/4 ],
469
+ [ Gauss valuation induced by (x + 1)-adic valuation, v(y) = 7/2 ],
470
+ [ Gauss valuation induced by (x + 1)-adic valuation, v(y^13 + y^12 + y^10 + y^7 + y^6 + y^3 + 1) = 1 ]]
471
+ sage: v0 = valuations.FunctionFieldValuation(K, GaussValuation(K._ring, valuations.TrivialValuation(k)).augmentation(x^3+x^2+1,1))
472
+ sage: v0.mac_lane_approximants(F, assume_squarefree=True) # assumes squarefree for speed # needs sage.geometry.polyhedron
473
+ [[ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y + x^3 + x^2 + x) = 2, v(y^2 + (x^6 + x^4 + 1)*y + x^14 + x^10 + x^9 + x^8 + x^5 + x^4 + x^3 + x^2 + x) = 5 ],
474
+ [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^2 + (x^2 + x)*y + 1) = 1 ],
475
+ [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^3 + (x + 1)*y^2 + (x + 1)*y + x^2 + x + 1) = 1 ],
476
+ [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^3 + x^2*y + x) = 1 ],
477
+ [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^4 + (x + 1)*y^3 + x^2*y^2 + (x^2 + x)*y + x) = 1 ],
478
+ [ Gauss valuation induced by (x^3 + x^2 + 1)-adic valuation, v(y^7 + x^2*y^6 + (x + 1)*y^4 + x^2*y^3 + (x^2 + x + 1)*y^2 + x^2*y + x) = 1 ]]
479
+
480
+ Cases with trivial residue field extensions::
481
+
482
+ sage: K.<x> = FunctionField(QQ)
483
+ sage: S.<y> = K[]
484
+ sage: F = y^2 - x^2 - x^3 - 3
485
+ sage: v0 = GaussValuation(K._ring, QQ.valuation(3))
486
+ sage: v1 = v0.augmentation(K._ring.gen(),1/3)
487
+ sage: mu0 = valuations.FunctionFieldValuation(K, v1)
488
+ sage: mu0.mac_lane_approximants(F) # needs sage.geometry.polyhedron
489
+ [[ Gauss valuation induced by Valuation on rational function field induced by [ Gauss valuation induced by 3-adic valuation, v(x) = 1/3 ], v(y + 2*x) = 2/3 ],
490
+ [ Gauss valuation induced by Valuation on rational function field induced by [ Gauss valuation induced by 3-adic valuation, v(x) = 1/3 ], v(y + x) = 2/3 ]]
491
+
492
+ Over a complete base field::
493
+
494
+ sage: # needs sage.libs.ntl
495
+ sage: k = Qp(2,10)
496
+ sage: v = k.valuation()
497
+ sage: R.<x> = k[]
498
+ sage: G = x
499
+ sage: v.mac_lane_approximants(G)
500
+ [Gauss valuation induced by 2-adic valuation]
501
+ sage: v.mac_lane_approximants(G, required_precision=infinity)
502
+ [[ Gauss valuation induced by 2-adic valuation, v((1 + O(2^10))*x) = +Infinity ]]
503
+ sage: G = x^2 + 1
504
+ sage: v.mac_lane_approximants(G) # needs sage.geometry.polyhedron
505
+ [[ Gauss valuation induced by 2-adic valuation, v((1 + O(2^10))*x + 1 + O(2^10)) = 1/2 ]]
506
+ sage: v.mac_lane_approximants(G, required_precision=infinity) # needs sage.geometry.polyhedron
507
+ [[ Gauss valuation induced by 2-adic valuation, v((1 + O(2^10))*x + 1 + O(2^10)) = 1/2,
508
+ v((1 + O(2^10))*x^2 + 1 + O(2^10)) = +Infinity ]]
509
+ sage: G = x^4 + 2*x^3 + 2*x^2 - 2*x + 2
510
+ sage: v.mac_lane_approximants(G) # needs sage.geometry.polyhedron
511
+ [[ Gauss valuation induced by 2-adic valuation, v((1 + O(2^10))*x) = 1/4 ]]
512
+ sage: v.mac_lane_approximants(G, required_precision=infinity) # needs sage.geometry.polyhedron
513
+ [[ Gauss valuation induced by 2-adic valuation, v((1 + O(2^10))*x) = 1/4,
514
+ v((1 + O(2^10))*x^4 + (2 + O(2^11))*x^3 + (2 + O(2^11))*x^2 + (2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + 2^10 + O(2^11))*x + 2 + O(2^11)) = +Infinity ]]
515
+
516
+ The factorization of primes in the Gaussian integers can be read off
517
+ the Mac Lane approximants::
518
+
519
+ sage: v0 = QQ.valuation(2)
520
+ sage: R.<x> = QQ[]
521
+ sage: G = x^2 + 1
522
+ sage: v0.mac_lane_approximants(G) # needs sage.geometry.polyhedron sage.rings.padics
523
+ [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 ]]
524
+
525
+ sage: v0 = QQ.valuation(3)
526
+ sage: v0.mac_lane_approximants(G)
527
+ [[ Gauss valuation induced by 3-adic valuation, v(x^2 + 1) = +Infinity ]]
528
+
529
+ sage: v0 = QQ.valuation(5)
530
+ sage: v0.mac_lane_approximants(G) # needs sage.geometry.polyhedron sage.rings.padics
531
+ [[ Gauss valuation induced by 5-adic valuation, v(x + 2) = 1 ],
532
+ [ Gauss valuation induced by 5-adic valuation, v(x + 3) = 1 ]]
533
+ sage: v0.mac_lane_approximants(G, required_precision=10) # needs sage.geometry.polyhedron sage.rings.padics
534
+ [[ Gauss valuation induced by 5-adic valuation, v(x + 3116/237) = 10 ],
535
+ [ Gauss valuation induced by 5-adic valuation, v(x - 3116/237) = 10 ]]
536
+
537
+ The same example over the 5-adic numbers. In the quadratic extension
538
+ `\QQ[x]/(x^2+1)`, 5 factors `-(x - 2)(x + 2)`, this behaviour can be
539
+ read off the Mac Lane approximants::
540
+
541
+ sage: # needs sage.rings.padics
542
+ sage: k = Qp(5,4)
543
+ sage: v = k.valuation()
544
+ sage: R.<x> = k[] # needs sage.libs.ntl
545
+ sage: G = x^2 + 1
546
+ sage: v1,v2 = v.mac_lane_approximants(G); v1,v2 # needs sage.geometry.polyhedron
547
+ ([ Gauss valuation induced by 5-adic valuation,
548
+ v((1 + O(5^4))*x + 2 + O(5^4)) = 1 ],
549
+ [ Gauss valuation induced by 5-adic valuation,
550
+ v((1 + O(5^4))*x + 3 + O(5^4)) = 1 ])
551
+ sage: w1, w2 = v.mac_lane_approximants(G, required_precision=2); w1, w2 # needs sage.geometry.polyhedron
552
+ ([ Gauss valuation induced by 5-adic valuation,
553
+ v((1 + O(5^4))*x + 2 + 5 + O(5^4)) = 2 ],
554
+ [ Gauss valuation induced by 5-adic valuation,
555
+ v((1 + O(5^4))*x + 3 + 3*5 + O(5^4)) = 2 ])
556
+
557
+ Note how the latter give a better approximation to the factors of `x^2 + 1`::
558
+
559
+ sage: # needs sage.geometry.polyhedron sage.rings.padics
560
+ sage: v1.phi() * v2.phi() - G
561
+ O(5^4)*x^2 + (5 + O(5^4))*x + 5 + O(5^4)
562
+ sage: w1.phi() * w2.phi() - G
563
+ O(5^4)*x^2 + (5^2 + O(5^4))*x + 5^3 + O(5^4)
564
+
565
+ In this example, the process stops with a factorization of `x^2 + 1`::
566
+
567
+ sage: # needs sage.geometry.polyhedron sage.rings.padics
568
+ sage: v.mac_lane_approximants(G, required_precision=infinity)
569
+ [[ Gauss valuation induced by 5-adic valuation,
570
+ v((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4)) = +Infinity ],
571
+ [ Gauss valuation induced by 5-adic valuation,
572
+ v((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)) = +Infinity ]]
573
+
574
+ This obviously cannot happen over the rationals where we only get an
575
+ approximate factorization::
576
+
577
+ sage: v = QQ.valuation(5)
578
+ sage: R.<x> = QQ[]
579
+ sage: G = x^2 + 1
580
+ sage: v.mac_lane_approximants(G) # needs sage.geometry.polyhedron
581
+ [[ Gauss valuation induced by 5-adic valuation, v(x + 2) = 1 ],
582
+ [ Gauss valuation induced by 5-adic valuation, v(x + 3) = 1 ]]
583
+ sage: v.mac_lane_approximants(G, required_precision=5) # needs sage.geometry.polyhedron
584
+ [[ Gauss valuation induced by 5-adic valuation, v(x + 79/3) = 5 ],
585
+ [ Gauss valuation induced by 5-adic valuation, v(x - 79/3) = 5 ]]
586
+
587
+ Initial versions ran into problems with the trivial residue field
588
+ extensions in this case::
589
+
590
+ sage: # needs sage.libs.ntl
591
+ sage: K = Qp(3, 20, print_mode='digits')
592
+ sage: R.<T> = K[]
593
+ sage: alpha = T^3/4
594
+ sage: G = 3^3*T^3*(alpha^4 - alpha)^2 - (4*alpha^3 - 1)^3
595
+ sage: G = G/G.leading_coefficient()
596
+ sage: K.valuation().mac_lane_approximants(G) # needs sage.geometry.polyhedron
597
+ [[ Gauss valuation induced by 3-adic valuation, v(...1*T + ...2) = 1/9,
598
+ v(...1*T^9 + ...20*T^8 + ...210*T^7 + ...20*T^6 + ...20*T^5 + ...10*T^4
599
+ + ...220*T^3 + ...20*T^2 + ...110*T + ...122) = 55/27 ]]
600
+
601
+ A similar example::
602
+
603
+ sage: R.<x> = QQ[]
604
+ sage: v = QQ.valuation(3)
605
+ sage: G = (x^3 + 3)^3 - 81
606
+ sage: v.mac_lane_approximants(G) # needs sage.geometry.polyhedron sage.rings.padics
607
+ [[ Gauss valuation induced by 3-adic valuation,
608
+ v(x) = 1/3, v(x^3 + 3*x + 3) = 13/9 ]]
609
+
610
+ Another problematic case::
611
+
612
+ sage: # needs sage.geometry.polyhedron sage.rings.number_field sage.rings.padics
613
+ sage: R.<x> = QQ[]
614
+ sage: Delta = (x^12 + 20*x^11 + 154*x^10 + 664*x^9 + 1873*x^8 + 3808*x^7 + 5980*x^6
615
+ ....: + 7560*x^5 + 7799*x^4 + 6508*x^3 + 4290*x^2 + 2224*x + 887)
616
+ sage: K.<theta> = NumberField(x^6 + 108)
617
+ sage: K.is_galois() # needs sage.groups
618
+ True
619
+ sage: vK = QQ.valuation(2).extension(K)
620
+ sage: vK(2)
621
+ 1
622
+ sage: vK(theta)
623
+ 1/3
624
+ sage: G = Delta.change_ring(K)
625
+ sage: vK.mac_lane_approximants(G)
626
+ [[ Gauss valuation induced by 2-adic valuation,
627
+ v(x + 1) = 1/4, v(x^4 + 1/2*theta^4 + 3*theta + 1) = 3/2 ],
628
+ [ Gauss valuation induced by 2-adic valuation,
629
+ v(x + 1) = 1/4, v(x^4 + 1/2*theta^4 + theta + 1) = 3/2 ],
630
+ [ Gauss valuation induced by 2-adic valuation,
631
+ v(x + 1) = 1/4, v(x^4 + 2*theta + 1) = 3/2 ]]
632
+
633
+ An easy case that produced the wrong error at some point::
634
+
635
+ sage: R.<x> = QQ[]
636
+ sage: v = QQ.valuation(2)
637
+ sage: v.mac_lane_approximants(x^2 - 1/2)
638
+ Traceback (most recent call last):
639
+ ...
640
+ ValueError: G must be integral
641
+
642
+ Some examples that Sebastian Pauli used in a talk at Sage Days 87.
643
+ Here we use ``assume_squarefree=True`` because :meth:`is_squarefree`
644
+ is not properly implemented yet.
645
+
646
+ ::
647
+
648
+ sage: R = ZpFM(3, 7, print_mode='terse')
649
+ sage: S.<x> = R[]
650
+ sage: v = R.valuation()
651
+ sage: f = x^4 + 234
652
+ sage: len(v.mac_lane_approximants(f, assume_squarefree=True)) # needs sage.geometry.polyhedron
653
+ ....:
654
+ 2
655
+
656
+ ::
657
+
658
+ sage: R = ZpFM(2, 50, print_mode='terse')
659
+ sage: S.<x> = R[]
660
+ sage: f = (x^32 + 16)*(x^32 + 16 + 2^16*x^2) + 2^34
661
+ sage: v = R.valuation()
662
+ sage: len(v.mac_lane_approximants(f, assume_squarefree=True)) # needs sage.geometry.polyhedron
663
+ ....:
664
+ 2
665
+
666
+ A case that triggered an assertion at some point::
667
+
668
+ sage: v = QQ.valuation(3)
669
+ sage: R.<x> = QQ[]
670
+ sage: f = (x^36 + 60552000*x^33 + 268157412*x^30 + 173881701*x^27 + 266324841*x^24
671
+ ....: + 83125683*x^21 + 111803814*x^18 + 31925826*x^15 + 205726716*x^12
672
+ ....: + 17990262*x^9 + 351459648*x^6 + 127014399*x^3 + 359254116)
673
+ sage: v.mac_lane_approximants(f) # needs sage.geometry.polyhedron
674
+ [[ Gauss valuation induced by 3-adic valuation,
675
+ v(x) = 1/3,
676
+ v(x^3 - 3) = 3/2,
677
+ v(x^12 - 3*x^9 + 54*x^6 + 27/2*x^3 + 405/2) = 13/2,
678
+ v(x^36 + 60552000*x^33 + 268157412*x^30 + 173881701*x^27 + 266324841*x^24
679
+ + 83125683*x^21 + 111803814*x^18 + 31925826*x^15 + 205726716*x^12
680
+ + 17990262*x^9 + 351459648*x^6 + 127014399*x^3 + 359254116) = +Infinity ]]
681
+ """
682
+ R = G.parent()
683
+ if R.base_ring() is not self.domain():
684
+ raise ValueError("G must be defined over the domain of this valuation")
685
+
686
+ from sage.misc.verbose import verbose
687
+ verbose("Approximants of %r on %r towards %r" % (self, self.domain(), G), level=3)
688
+
689
+ from sage.rings.valuation.gauss_valuation import GaussValuation
690
+
691
+ if not all(self(c) >= 0 for c in G.coefficients()):
692
+ raise ValueError("G must be integral")
693
+
694
+ if require_maximal_degree:
695
+ # we can only assert maximality of degrees when E and F are final
696
+ require_final_EF = True
697
+
698
+ if not assume_squarefree:
699
+ if require_final_EF and not G.is_squarefree():
700
+ raise ValueError("G must be squarefree")
701
+ else:
702
+ # if only required_precision is set, we do not need to check
703
+ # whether G is squarefree. If G is not squarefree, we compute
704
+ # valuations corresponding to approximants for all the
705
+ # squarefree factors of G (up to required_precision.)
706
+ pass
707
+
708
+ def is_sufficient(leaf, others):
709
+ if leaf.valuation.mu() < required_precision:
710
+ return False
711
+ if require_final_EF and not leaf.ef:
712
+ return False
713
+ if require_maximal_degree and leaf.valuation.phi().degree() != leaf.valuation.E() * leaf.valuation.F():
714
+ return False
715
+ if require_incomparability:
716
+ if any(leaf.valuation <= o.valuation for o in others):
717
+ return False
718
+ return True
719
+
720
+ seed = MacLaneApproximantNode(GaussValuation(R, self), None, G.degree() == 1, G.degree(), None, None)
721
+ seed.forced_leaf = is_sufficient(seed, [])
722
+
723
+ def create_children(node):
724
+ new_leafs = []
725
+ if node.forced_leaf:
726
+ return new_leafs
727
+ augmentations = node.valuation.mac_lane_step(G,
728
+ report_degree_bounds_and_caches=True,
729
+ coefficients=node.coefficients,
730
+ valuations=node.valuations,
731
+ check=False,
732
+ # We do not want to see augmentations that are
733
+ # already part of other branches of the tree of
734
+ # valuations for obvious performance reasons and
735
+ # also because the principal_part_bound would be
736
+ # incorrect for these.
737
+ allow_equivalent_key=node.valuation.is_gauss_valuation(),
738
+ # The length of an edge in the Newton polygon in
739
+ # one MacLane step bounds the length of the
740
+ # principal part (i.e., the part with negative
741
+ # slopes) of the Newton polygons in the next
742
+ # MacLane step. Therefore, mac_lane_step does not
743
+ # need to compute valuations for coefficients
744
+ # beyond that bound as they do not contribute any
745
+ # augmentations.
746
+ principal_part_bound=node.principal_part_bound)
747
+ for w, bound, principal_part_bound, coefficients, valuations in augmentations:
748
+ ef = bound == w.E()*w.F()
749
+ new_leafs.append(MacLaneApproximantNode(w, node, ef, principal_part_bound, coefficients, valuations))
750
+ for leaf in new_leafs:
751
+ if is_sufficient(leaf, [l for l in new_leafs if l is not leaf]):
752
+ leaf.forced_leaf = True
753
+ return new_leafs
754
+
755
+ def reduce_tree(v, w):
756
+ return v + w
757
+
758
+ from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet
759
+ tree = RecursivelyEnumeratedSet([seed],
760
+ successors=create_children,
761
+ structure='forest',
762
+ enumeration='breadth')
763
+ # this is a tad faster but annoying for profiling / debugging
764
+ if algorithm == 'parallel':
765
+ nodes = tree.map_reduce(map_function=lambda x: [x],
766
+ reduce_init=[])
767
+ elif algorithm == 'serial':
768
+ from sage.parallel.map_reduce import RESetMapReduce
769
+ nodes = RESetMapReduce(forest=tree,
770
+ map_function=lambda x: [x],
771
+ reduce_init=[]).run_serial()
772
+ else:
773
+ raise NotImplementedError(algorithm)
774
+ leafs = {node.valuation for node in nodes}
775
+ for node in nodes:
776
+ if node.parent is None:
777
+ continue
778
+ v = node.parent.valuation
779
+ if v in leafs:
780
+ leafs.remove(v)
781
+
782
+ # The order of the leafs is not predictable in parallel mode and in
783
+ # serial mode it depends on the hash functions and so on the underlying
784
+ # architecture (32/64 bit). There is no natural ordering on these
785
+ # valuations but it is very convenient for doctesting to return them in
786
+ # some stable order, so we just order them by their string
787
+ # representation which should be very fast.
788
+ try:
789
+ ret = sorted(leafs, key=str)
790
+ except Exception:
791
+ # if for some reason the valuation can not be printed, we leave them unsorted
792
+ ret = list(leafs)
793
+
794
+ return ret
795
+
796
+ @cached_method
797
+ def _pow(self, x, e, error):
798
+ r"""
799
+ Return `x^e`.
800
+
801
+ This method does not compute the exact value of `x^e` but only an
802
+ element that differs from the correct result by an error with valuation
803
+ at least ``error``.
804
+
805
+ EXAMPLES::
806
+
807
+ sage: v = QQ.valuation(2)
808
+ sage: v._pow(2, 2, error=4)
809
+ 4
810
+ sage: v._pow(2, 1000, error=4)
811
+ 0
812
+ """
813
+ if e == 0:
814
+ return self.domain().one()
815
+ if e == 1:
816
+ return self.simplify(x, error=error)
817
+ if e % 2 == 0:
818
+ return self._pow(self.simplify(x*x, error=error*2/e), e//2, error=error)
819
+ else:
820
+ return self.simplify(x*self._pow(x, e-1, error=error*(e-1)/e), error=error)
821
+
822
+ def mac_lane_approximant(self, G, valuation, approximants=None):
823
+ r"""
824
+ Return the approximant from :meth:`mac_lane_approximants` for ``G``
825
+ which is approximated by or approximates ``valuation``.
826
+
827
+ INPUT:
828
+
829
+ - ``G`` -- a monic squarefree integral polynomial in a univariate
830
+ polynomial ring over the domain of this valuation
831
+
832
+ - ``valuation`` -- a valuation on the parent of ``G``
833
+
834
+ - ``approximants`` -- the output of :meth:`mac_lane_approximants`;
835
+ if not given, it is computed
836
+
837
+ EXAMPLES::
838
+
839
+ sage: v = QQ.valuation(2)
840
+ sage: R.<x> = QQ[]
841
+ sage: G = x^2 + 1
842
+
843
+ We can select an approximant by approximating it::
844
+
845
+ sage: w = GaussValuation(R, v).augmentation(x + 1, 1/2)
846
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
847
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 ]
848
+
849
+ As long as this is the only matching approximant, the approximation can
850
+ be very coarse::
851
+
852
+ sage: w = GaussValuation(R, v)
853
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
854
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 ]
855
+
856
+ Or it can be very specific::
857
+
858
+ sage: w = GaussValuation(R, v).augmentation(x + 1, 1/2).augmentation(G, infinity)
859
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
860
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 ]
861
+
862
+ But it must be an approximation of an approximant::
863
+
864
+ sage: w = GaussValuation(R, v).augmentation(x, 1/2)
865
+ sage: v.mac_lane_approximant(G, w)
866
+ Traceback (most recent call last):
867
+ ...
868
+ ValueError: The valuation
869
+ [ Gauss valuation induced by 2-adic valuation, v(x) = 1/2 ] is
870
+ not an approximant for a valuation which extends 2-adic valuation
871
+ with respect to x^2 + 1 since the valuation of x^2 + 1
872
+ does not increase in every step
873
+
874
+ The ``valuation`` must single out one approximant::
875
+
876
+ sage: G = x^2 - 1
877
+ sage: w = GaussValuation(R, v)
878
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
879
+ Traceback (most recent call last):
880
+ ...
881
+ ValueError: The valuation Gauss valuation induced by 2-adic valuation
882
+ does not approximate a unique extension of 2-adic valuation
883
+ with respect to x^2 - 1
884
+
885
+ sage: w = GaussValuation(R, v).augmentation(x + 1, 1)
886
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
887
+ Traceback (most recent call last):
888
+ ...
889
+ ValueError: The valuation
890
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1 ] does not
891
+ approximate a unique extension of 2-adic valuation with respect to x^2 - 1
892
+
893
+ sage: w = GaussValuation(R, v).augmentation(x + 1, 2)
894
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
895
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = +Infinity ]
896
+
897
+ sage: w = GaussValuation(R, v).augmentation(x + 3, 2)
898
+ sage: v.mac_lane_approximant(G, w) # needs sage.geometry.polyhedron sage.rings.padics
899
+ [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1 ]
900
+ """
901
+ if valuation.restriction(valuation.domain().base_ring()) is not self:
902
+ raise ValueError
903
+
904
+ # Check that valuation is an approximant for a valuation
905
+ # on domain that extends its restriction to the base field.
906
+ from sage.rings.infinity import infinity
907
+ if valuation(G) is not infinity:
908
+ v = valuation
909
+ while not v.is_gauss_valuation():
910
+ if v(G) <= v._base_valuation(G):
911
+ raise ValueError("The valuation %r is not an approximant for a valuation which extends %r with respect to %r since the valuation of %r does not increase in every step" % (valuation, self, G, G))
912
+ v = v._base_valuation
913
+
914
+ if approximants is None:
915
+ approximants = self.mac_lane_approximants(G)
916
+
917
+ assert all(approximant.domain() is valuation.domain() for approximant in approximants)
918
+
919
+ greater_approximants = [w for w in approximants if w >= valuation]
920
+ if len(greater_approximants) > 1:
921
+ raise ValueError("The valuation %r does not approximate a unique extension of %r with respect to %r" % (valuation, self, G))
922
+ if len(greater_approximants) == 1:
923
+ return greater_approximants[0]
924
+
925
+ smaller_approximants = [w for w in approximants if w <= valuation]
926
+ if len(smaller_approximants) > 1:
927
+ raise ValueError("The valuation %r is not approximated by a unique extension of %r with respect to %r" % (valuation, self, G))
928
+ if len(smaller_approximants) == 0:
929
+ raise ValueError("The valuation %r is not related to an extension of %r with respect to %r" % (valuation, self, G))
930
+ return smaller_approximants[0]
931
+
932
+ def montes_factorization(self, G, assume_squarefree=False, required_precision=None):
933
+ """
934
+ Factor ``G`` over the completion of the domain of this valuation.
935
+
936
+ INPUT:
937
+
938
+ - ``G`` -- a monic polynomial over the domain of this valuation
939
+
940
+ - ``assume_squarefree`` -- boolean (default: ``False``); whether to
941
+ assume ``G`` to be squarefree
942
+
943
+ - ``required_precision`` -- a number or infinity (default:
944
+ infinity); if ``infinity``, the returned polynomials are actual factors of
945
+ ``G``, otherwise they are only factors with precision at least
946
+ ``required_precision``.
947
+
948
+ ALGORITHM:
949
+
950
+ We compute :meth:`mac_lane_approximants` with ``required_precision``.
951
+ The key polynomials approximate factors of ``G``. This can be very
952
+ slow unless ``required_precision`` is set to zero. Single factor
953
+ lifting could improve this significantly.
954
+
955
+ EXAMPLES::
956
+
957
+ sage: # needs sage.libs.ntl
958
+ sage: k = Qp(5,4)
959
+ sage: v = k.valuation()
960
+ sage: R.<x> = k[]
961
+ sage: G = x^2 + 1
962
+ sage: v.montes_factorization(G) # needs sage.geometry.polyhedron
963
+ ((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))
964
+ * ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))
965
+
966
+ The computation might not terminate over incomplete fields (in
967
+ particular because the factors can not be represented there)::
968
+
969
+ sage: R.<x> = QQ[]
970
+ sage: v = QQ.valuation(2)
971
+ sage: v.montes_factorization(x^6 - 1) # needs sage.geometry.polyhedron sage.rings.padics
972
+ (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1)
973
+
974
+ sage: v.montes_factorization(x^7 - 1) # not tested # needs sage.rings.padics
975
+
976
+ sage: v.montes_factorization(x^7 - 1, required_precision=5) # needs sage.geometry.polyhedron sage.rings.padics
977
+ (x - 1) * (x^3 - 5*x^2 - 6*x - 1) * (x^3 + 6*x^2 + 5*x - 1)
978
+
979
+ TESTS:
980
+
981
+ Some examples that Sebastian Pauli used in a talk at Sage Days 87.
982
+
983
+ In this example, ``f`` factors as three factors of degree 50 over an
984
+ unramified extension::
985
+
986
+ sage: # needs sage.libs.flint
987
+ sage: R.<u> = ZqFM(125)
988
+ sage: S.<x> = R[]
989
+ sage: f = (x^6+2)^25 + 5
990
+ sage: v = R.valuation()
991
+ sage: v.montes_factorization(f, assume_squarefree=True, required_precision=0) # needs sage.geometry.polyhedron
992
+ (x^50 + 2*5*x^45 + 5*x^40 + 5*x^30 + 2*x^25 + 3*5*x^20 + 2*5*x^10 + 2*5*x^5 + 5*x + 3 + 5) * (x^50 + 3*5*x^45 + 5*x^40 + 5*x^30 + (3 + 4*5)*x^25 + 3*5*x^20 + 2*5*x^10 + 3*5*x^5 + 4*5*x + 3 + 5) * (x^50 + 3*5*x^40 + 3*5*x^30 + 4*5*x^20 + 5*x^10 + 3 + 5)
993
+
994
+ In this case, ``f`` factors into degrees 1, 2, and 5 over a totally ramified extension::
995
+
996
+ sage: # needs sage.libs.ntl
997
+ sage: R = Zp(5)
998
+ sage: S.<w> = R[]
999
+ sage: R.<w> = R.extension(w^3 + 5)
1000
+ sage: S.<x> = R[]
1001
+ sage: f = (x^3 + 5)*(x^5 + w) + 625
1002
+ sage: v = R.valuation()
1003
+ sage: v.montes_factorization(f, assume_squarefree=True, required_precision=0) # needs sage.geometry.polyhedron sage.libs.flint
1004
+ ((1 + O(w^60))*x + 4*w + O(w^61)) * ((1 + O(w^60))*x^2 + (w + O(w^61))*x + w^2 + O(w^62)) * ((1 + O(w^60))*x^5 + w + O(w^61))
1005
+
1006
+ REFERENCES:
1007
+
1008
+ The underlying algorithm is described in [Mac1936II]_ and thoroughly
1009
+ analyzed in [GMN2008]_.
1010
+ """
1011
+ if required_precision is None:
1012
+ from sage.rings.infinity import infinity
1013
+ required_precision = infinity
1014
+
1015
+ R = G.parent()
1016
+ if R.base_ring() is not self.domain():
1017
+ raise ValueError("G must be defined over the domain of this valuation")
1018
+ if not G.is_monic():
1019
+ raise ValueError("G must be monic")
1020
+ if not all(self(c) >= 0 for c in G.coefficients()):
1021
+ raise ValueError("G must be integral")
1022
+
1023
+ # W contains approximate factors of G
1024
+ W = self.mac_lane_approximants(G, required_precision=required_precision, require_maximal_degree=True, assume_squarefree=assume_squarefree)
1025
+ ret = [w.phi() for w in W]
1026
+
1027
+ from sage.structure.factorization import Factorization
1028
+ return Factorization([(g, 1) for g in ret], simplify=False)
1029
+
1030
+ def _ge_(self, other):
1031
+ r"""
1032
+ Return whether this valuation is greater than or equal to ``other``
1033
+ pointwise.
1034
+
1035
+ EXAMPLES::
1036
+
1037
+ sage: v = valuations.TrivialValuation(QQ)
1038
+ sage: w = QQ.valuation(2)
1039
+ sage: v >= w
1040
+ False
1041
+ """
1042
+ if other.is_trivial():
1043
+ return other.is_discrete_valuation()
1044
+ return super()._ge_(other)
1045
+
1046
+
1047
+ class MacLaneApproximantNode:
1048
+ r"""
1049
+ A node in the tree computed by :meth:`DiscreteValuation.mac_lane_approximants`.
1050
+
1051
+ Leaves in the computation of the tree of approximants
1052
+ :meth:`~DiscreteValuation.mac_lane_approximants`. Each vertex consists of a
1053
+ tuple ``(v,ef,p,coeffs,vals)`` where ``v`` is an approximant, i.e., a
1054
+ valuation, ef is a boolean, ``p`` is the parent of this vertex, and
1055
+ ``coeffs`` and ``vals`` are cached values. (Only ``v`` and ``ef`` are
1056
+ relevant, everything else are caches/debug info.) The boolean ``ef``
1057
+ denotes whether ``v`` already has the final ramification index E and
1058
+ residue degree F of this approximant. An edge V -- P represents the
1059
+ relation ``P.v`` `≤` ``V.v`` (pointwise on the polynomial ring K[x]) between the
1060
+ valuations.
1061
+
1062
+ TESTS::
1063
+
1064
+ sage: v = ZZ.valuation(3)
1065
+ sage: v.extension(GaussianIntegers()) # indirect doctest # needs sage.rings.number_field sage.rings.padics
1066
+ 3-adic valuation
1067
+ """
1068
+ def __init__(self, valuation, parent, ef, principal_part_bound, coefficients, valuations):
1069
+ r"""
1070
+ TESTS::
1071
+
1072
+ sage: from sage.rings.valuation.valuation import MacLaneApproximantNode
1073
+ sage: node = MacLaneApproximantNode(QQ.valuation(2), None, 1, None, None, None)
1074
+ sage: TestSuite(node).run()
1075
+ """
1076
+ self.valuation = valuation
1077
+ self.parent = parent
1078
+ self.ef = ef
1079
+ self.principal_part_bound = principal_part_bound
1080
+ self.coefficients = coefficients
1081
+ self.valuations = valuations
1082
+ self.forced_leaf = False
1083
+
1084
+ def __eq__(self, other):
1085
+ r"""
1086
+ Return whether this node is equal to ``other``.
1087
+
1088
+ EXAMPLES::
1089
+
1090
+ sage: from sage.rings.valuation.valuation import MacLaneApproximantNode
1091
+ sage: n = MacLaneApproximantNode(QQ.valuation(2), None, 1, None, None, None)
1092
+ sage: m = MacLaneApproximantNode(QQ.valuation(3), None, 1, None, None, None)
1093
+ sage: n == m
1094
+ False
1095
+ sage: n == n
1096
+ True
1097
+ """
1098
+ if type(self) is not type(other):
1099
+ return False
1100
+ return (self.valuation, self.parent, self.ef, self.principal_part_bound, self.coefficients, self.valuations, self.forced_leaf) == (other.valuation, other.parent, other.ef, other.principal_part_bound, other.coefficients, other.valuations, other.forced_leaf)
1101
+
1102
+ def __ne__(self, other):
1103
+ r"""
1104
+ Return whether this node is not equal to ``other``.
1105
+
1106
+ EXAMPLES::
1107
+
1108
+ sage: from sage.rings.valuation.valuation import MacLaneApproximantNode
1109
+ sage: n = MacLaneApproximantNode(QQ.valuation(2), None, 1, None, None, None)
1110
+ sage: m = MacLaneApproximantNode(QQ.valuation(3), None, 1, None, None, None)
1111
+ sage: n != m
1112
+ True
1113
+ sage: n != n
1114
+ False
1115
+ """
1116
+ return not (self == other)
1117
+
1118
+ # mutable object - not hashable
1119
+ __hash__ = None