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,1423 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ r"""
3
+ `p`-adic Valuations on Number Fields and Their Subrings and Completions
4
+
5
+ EXAMPLES::
6
+
7
+ sage: ZZ.valuation(2)
8
+ 2-adic valuation
9
+ sage: QQ.valuation(3)
10
+ 3-adic valuation
11
+ sage: CyclotomicField(5).valuation(5) # needs sage.geometry.polyhedron sage.rings.number_field
12
+ 5-adic valuation
13
+ sage: GaussianIntegers().valuation(7) # needs sage.rings.number_field
14
+ 7-adic valuation
15
+ sage: Zp(11).valuation()
16
+ 11-adic valuation
17
+
18
+ These valuations can then, e.g., be used to compute approximate factorizations
19
+ in the completion of a ring::
20
+
21
+ sage: v = ZZ.valuation(2)
22
+ sage: R.<x> = ZZ[]
23
+ sage: f = x^5 + x^4 + x^3 + x^2 + x - 1
24
+ sage: v.montes_factorization(f, required_precision=20) # needs sage.geometry.polyhedron
25
+ (x + 676027) * (x^4 + 372550*x^3 + 464863*x^2 + 385052*x + 297869)
26
+
27
+ AUTHORS:
28
+
29
+ - Julian Rüth (2013-03-16): initial version
30
+
31
+ REFERENCES:
32
+
33
+ The theory used here was originally developed in [Mac1936I]_ and [Mac1936II]_. An
34
+ overview can also be found in Chapter 4 of [Rüt2014]_.
35
+ """
36
+ #*****************************************************************************
37
+ # Copyright (C) 2013-2020 Julian Rüth <julian.rueth@fsfe.org>
38
+ #
39
+ # Distributed under the terms of the GNU General Public License (GPL)
40
+ # as published by the Free Software Foundation; either version 2 of
41
+ # the License, or (at your option) any later version.
42
+ # http://www.gnu.org/licenses/
43
+ #*****************************************************************************
44
+ from sage.rings.valuation.valuation import DiscreteValuation
45
+ from sage.rings.valuation.value_group import DiscreteValueSemigroup
46
+ from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation
47
+ from sage.structure.factory import UniqueFactory
48
+ from sage.misc.cachefunc import cached_method
49
+
50
+ from sage.rings.infinity import infinity
51
+
52
+
53
+ class PadicValuationFactory(UniqueFactory):
54
+ r"""
55
+ Create a ``prime``-adic valuation on ``R``.
56
+
57
+ INPUT:
58
+
59
+ - ``R`` -- a subring of a number field or a subring of a local field in
60
+ characteristic zero
61
+
62
+ - ``prime`` -- a prime that does not split, a discrete (pseudo-)valuation,
63
+ a fractional ideal, or ``None`` (default: ``None``)
64
+
65
+ EXAMPLES:
66
+
67
+ For integers and rational numbers, ``prime`` is just a prime of the
68
+ integers::
69
+
70
+ sage: valuations.pAdicValuation(ZZ, 3)
71
+ 3-adic valuation
72
+
73
+ sage: valuations.pAdicValuation(QQ, 3)
74
+ 3-adic valuation
75
+
76
+ ``prime`` may be ``None`` for local rings::
77
+
78
+ sage: valuations.pAdicValuation(Qp(2))
79
+ 2-adic valuation
80
+
81
+ sage: valuations.pAdicValuation(Zp(2))
82
+ 2-adic valuation
83
+
84
+ But it must be specified in all other cases::
85
+
86
+ sage: valuations.pAdicValuation(ZZ)
87
+ Traceback (most recent call last):
88
+ ...
89
+ ValueError: prime must be specified for this ring
90
+
91
+ It can sometimes be beneficial to define a number field extension as a
92
+ quotient of a polynomial ring (since number field extensions always compute
93
+ an absolute polynomial defining the extension which can be very costly)::
94
+
95
+ sage: # needs sage.rings.number_field
96
+ sage: R.<x> = QQ[]
97
+ sage: K.<a> = NumberField(x^2 + 1)
98
+ sage: R.<x> = K[]
99
+ sage: L.<b> = R.quo(x^2 + a)
100
+ sage: valuations.pAdicValuation(L, 2) # needs sage.geometry.polyhedron
101
+ 2-adic valuation
102
+
103
+ .. SEEALSO::
104
+
105
+ :meth:`NumberField_generic.valuation() <sage.rings.number_field.number_field.NumberField_generic.valuation>`,
106
+ :meth:`Order.valuation() <sage.rings.number_field.order.Order.valuation>`,
107
+ :meth:`pAdicGeneric.valuation() <sage.rings.padics.padic_generic.pAdicGeneric.valuation>`,
108
+ :meth:`RationalField.valuation() <sage.rings.rational_field.RationalField.valuation>`,
109
+ :meth:`IntegerRing_class.valuation() <sage.rings.integer_ring.IntegerRing_class.valuation>`.
110
+ """
111
+ def create_key_and_extra_args(self, R, prime=None, approximants=None):
112
+ r"""
113
+ Create a unique key identifying the valuation of ``R`` with respect to
114
+ ``prime``.
115
+
116
+ EXAMPLES::
117
+
118
+ sage: QQ.valuation(2) # indirect doctest
119
+ 2-adic valuation
120
+ """
121
+ from sage.rings.integer_ring import ZZ
122
+ from sage.rings.rational_field import QQ
123
+ from sage.rings.padics.padic_generic import pAdicGeneric
124
+ from sage.rings.number_field.number_field_base import NumberField
125
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
126
+
127
+ if R.characteristic() != 0:
128
+ # We do not support equal characteristic yet
129
+ raise ValueError("R must be a ring of characteristic zero.")
130
+
131
+ if R is ZZ or R is QQ:
132
+ return self.create_key_for_integers(R, prime), {}
133
+ elif isinstance(R, pAdicGeneric):
134
+ return self.create_key_for_local_ring(R, prime), {}
135
+ elif isinstance(R.fraction_field(), NumberField) or isinstance(R, PolynomialQuotientRing_generic):
136
+ return self.create_key_and_extra_args_for_number_field(R, prime, approximants=approximants)
137
+ else:
138
+ raise NotImplementedError("p-adic valuations not implemented for %r" % (R,))
139
+
140
+ def create_key_for_integers(self, R, prime):
141
+ r"""
142
+ Create a unique key identifying the valuation of ``R`` with respect to
143
+ ``prime``.
144
+
145
+ EXAMPLES::
146
+
147
+ sage: QQ.valuation(2) # indirect doctest
148
+ 2-adic valuation
149
+ """
150
+ from sage.rings.integer_ring import ZZ
151
+ if prime is None:
152
+ raise ValueError("prime must be specified for this ring")
153
+ from sage.rings.valuation.valuation import DiscretePseudoValuation
154
+ if isinstance(prime, DiscretePseudoValuation):
155
+ prime = prime.uniformizer()
156
+ if prime not in ZZ or not ZZ(prime).is_prime():
157
+ raise ValueError("prime must be a prime in the integers but %s is not" % (prime,))
158
+ return R, prime
159
+
160
+ def create_key_for_local_ring(self, R, prime):
161
+ r"""
162
+ Create a unique key identifying the valuation of ``R`` with respect to
163
+ ``prime``.
164
+
165
+ EXAMPLES::
166
+
167
+ sage: Qp(2).valuation() # indirect doctest
168
+ 2-adic valuation
169
+ """
170
+ # We do not care much about the value of prime since there is only one
171
+ # reasonable p-adic valuation here
172
+ if prime is not None:
173
+ if prime in R:
174
+ if R(prime).valuation() <= 0:
175
+ raise ValueError("prime must be an element of positive valuation")
176
+ elif prime(R.prime()) <= 0:
177
+ raise ValueError("prime must be an element of positive valuation")
178
+
179
+ return (R,)
180
+
181
+ def create_key_and_extra_args_for_number_field(self, R, prime, approximants):
182
+ r"""
183
+ Create a unique key identifying the valuation of ``R`` with respect to
184
+ ``prime``.
185
+
186
+ EXAMPLES::
187
+
188
+ sage: GaussianIntegers().valuation(2) # indirect doctest # needs sage.geometry.polyhedron sage.rings.number_field
189
+ 2-adic valuation
190
+ """
191
+ K, L, G = self._normalize_number_field_data(R)
192
+
193
+ from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal
194
+ from sage.rings.valuation.valuation import DiscretePseudoValuation
195
+ if isinstance(prime, DiscretePseudoValuation):
196
+ return self.create_key_and_extra_args_for_number_field_from_valuation(R, prime, prime, approximants=approximants)
197
+ elif prime in K:
198
+ return self.create_key_and_extra_args_for_number_field_from_valuation(R, K.valuation(prime), prime, approximants=approximants)
199
+ elif prime in L or isinstance(prime, NumberFieldFractionalIdeal):
200
+ return self.create_key_and_extra_args_for_number_field_from_ideal(R, L.fractional_ideal(prime), prime)
201
+ else:
202
+ raise ValueError("prime must be a discrete pseudo-valuation, a prime in the base ring, or a fractional ideal")
203
+
204
+ def create_key_and_extra_args_for_number_field_from_valuation(self, R, v, prime, approximants):
205
+ r"""
206
+ Create a unique key identifying the valuation of ``R`` with respect to
207
+ ``v``.
208
+
209
+ .. NOTE::
210
+
211
+ ``prime``, the original parameter that was passed to
212
+ :meth:`create_key_and_extra_args`, is only used to provide more
213
+ meaningful error messages
214
+
215
+ EXAMPLES::
216
+
217
+ sage: GaussianIntegers().valuation(ZZ.valuation(2)) # indirect doctest # needs sage.geometry.polyhedron sage.rings.number_field
218
+ 2-adic valuation
219
+
220
+ TESTS:
221
+
222
+ We can extend to the field of fractions of a quotient ring::
223
+
224
+ sage: R.<x> = ZZ[]
225
+ sage: S = R.quo(x^2 + 1)
226
+ sage: v = valuations.pAdicValuation(S, 2) # needs sage.geometry.polyhedron
227
+ sage: R.<x> = QQ[]
228
+ sage: S = R.quo(x^2 + 1)
229
+ sage: v = valuations.pAdicValuation(S, v) # needs sage.geometry.polyhedron
230
+ """
231
+ K, L, G = self._normalize_number_field_data(R)
232
+
233
+ if v.domain().is_subring(G.parent()):
234
+ # v is defined on a subring of K[x].
235
+ # We try to lift v to a pseudo-valuation on K[x].
236
+ if _fraction_field(v.domain()) is not _fraction_field(G.parent()):
237
+ # First, we lift valuations defined on subrings of K to
238
+ # valuations on K[x].
239
+ if v.domain().is_subring(K):
240
+ if v.domain() is not K:
241
+ v = K.valuation(v)
242
+ from sage.rings.valuation.gauss_valuation import GaussValuation
243
+ v = GaussValuation(G.parent(), v)
244
+ if v.domain() != G.parent():
245
+ # Then, we lift valuations defined on polynomial rings which are
246
+ # subrings of K[x] to K[x]
247
+ v = v.extension(G.parent())
248
+ elif _fraction_field(v.domain()) == L:
249
+ # v is defined on a ring whose field of fractions is L
250
+ v = v._base_valuation._initial_approximation.change_domain(G.parent())
251
+ else:
252
+ raise NotImplementedError("cannot rewrite %r which is defined on %r as a pseudo-valuation on %r" % (v, v.domain(), G.parent()))
253
+
254
+ assert (v.domain() is G.parent())
255
+
256
+ # To obtain uniqueness of p-adic valuations, we need a canonical
257
+ # description of v. We consider all extensions of vK to L and select
258
+ # the one approximated by v.
259
+ vK = v.restriction(v.domain().base_ring()).extension(K)
260
+ if approximants is None:
261
+ approximants = vK.mac_lane_approximants(G, require_incomparability=True)
262
+ approximants = [approximant.extension(v.domain()) for approximant in approximants]
263
+ approximant = vK.mac_lane_approximant(G, v, approximants=tuple(approximants))
264
+
265
+ return (R, approximant), {'approximants': approximants}
266
+
267
+ def create_key_and_extra_args_for_number_field_from_ideal(self, R, I, prime):
268
+ r"""
269
+ Create a unique key identifying the valuation of ``R`` with respect to
270
+ ``I``.
271
+
272
+ .. NOTE::
273
+
274
+ ``prime``, the original parameter that was passed to
275
+ :meth:`create_key_and_extra_args`, is only used to provide more
276
+ meaningful error messages
277
+
278
+ EXAMPLES::
279
+
280
+ sage: # needs sage.geometry.polyhedron sage.rings.number_field
281
+ sage: GaussianIntegers().valuation(GaussianIntegers().number_field().fractional_ideal(2)) # indirect doctest
282
+ 2-adic valuation
283
+
284
+ TESTS:
285
+
286
+ Verify that :issue:`28976` has been resolved::
287
+
288
+ sage: # needs sage.rings.number_field
289
+ sage: R.<x> = QQ[]
290
+ sage: K.<a> = NumberField(x^6 - 18*x^4 - 24*x^3 + 27*x^2 + 36*x - 6)
291
+ sage: I = K.fractional_ideal((2, -7/44*a^5 + 19/44*a^4 + 87/44*a^3 - 87/44*a^2 - 5/2*a + 39/22))
292
+ sage: I.norm()
293
+ 2
294
+ sage: I in K.primes_above(2)
295
+ True
296
+ sage: K.valuation(I) # needs sage.geometry.polyhedron
297
+ [ 2-adic valuation, v(x + 1) = 1/2 ]-adic valuation
298
+
299
+ ::
300
+
301
+ sage: # needs sage.rings.number_field
302
+ sage: K.<a, b> = NumberField([x^2 - 2, x^2 + x + 1])
303
+ sage: K.valuation(2) # needs sage.geometry.polyhedron
304
+ 2-adic valuation
305
+ """
306
+ K, L, G = self._normalize_number_field_data(R)
307
+
308
+ # To obtain uniqueness of p-adic valuations, we need a canonical
309
+ # description of v. We consider all extensions of vK to L and select
310
+ # the one approximated by v.
311
+ # Of course, this only works if I comes from a single prime downstairs.
312
+ p = I.relative_norm()
313
+ F = p.factor()
314
+ if len(F) != 1:
315
+ raise ValueError("%r does not lie over a single prime of %r" % (I, K))
316
+ vK = K.valuation(F[0][0])
317
+ approximants = vK.mac_lane_approximants(G, require_incomparability=True)
318
+
319
+ candidates = approximants[:]
320
+
321
+ # The correct approximant has v(g) > 0 for all g in the ideal.
322
+ # Unfortunately, the generators of I, even though defined over K have
323
+ # their polynomial() defined over the rationals so we need to turn them
324
+ # into polynomials over K[x] explicitly.
325
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
326
+ gens = I.gens()
327
+ gens = [PolynomialRing(K, 'x')(list(g.vector())) for g in gens]
328
+
329
+ # Refine candidates until we can detect which valuation corresponds to the ideal I
330
+ while True:
331
+ assert any(candidates), "the defining polynomial of the extension factored but we still could not figure out which valuation corresponds to the given ideal"
332
+
333
+ match = [i for (i, v) in enumerate(candidates) if v and all(v(g) > 0 for g in gens)]
334
+
335
+ if len(match) > 1:
336
+ raise ValueError("%s does not single out a unique extension of %s to %s" % (prime, vK, L))
337
+ if len(match) == 1:
338
+ return (R, approximants[match[0]]), {'approximants': approximants}
339
+
340
+ # We refine candidates which increases v(g) for all g in I;
341
+ # however, we cannot augment the valuations which are already at
342
+ # v(G) = +∞ which we ignore by setting them to None.
343
+ candidates = [v.mac_lane_step(G)[0] if v and v.is_discrete_valuation() else None for v in candidates]
344
+
345
+ def _normalize_number_field_data(self, R):
346
+ r"""
347
+ Helper method which returns the defining data of the number field
348
+ ``R``.
349
+
350
+ EXAMPLES::
351
+
352
+ sage: R.<x> = QQ[]
353
+ sage: K = R.quo(x^2 + 1)
354
+ sage: valuations.pAdicValuation._normalize_number_field_data(K)
355
+ (Rational Field,
356
+ Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1,
357
+ x^2 + 1)
358
+ """
359
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
360
+ from sage.rings.number_field.number_field_base import NumberField
361
+ if isinstance(R.fraction_field(), NumberField):
362
+ L = R.fraction_field()
363
+ G = L.relative_polynomial()
364
+ K = L.base_ring()
365
+ elif isinstance(R, PolynomialQuotientRing_generic):
366
+ from sage.categories.number_fields import NumberFields
367
+ if R.base_ring().fraction_field() not in NumberFields():
368
+ raise NotImplementedError("cannot normalize quotients over %r" % (R.base_ring(),))
369
+ L = R.fraction_field()
370
+ K = R.base_ring().fraction_field()
371
+ G = R.modulus().change_ring(K)
372
+ else:
373
+ raise NotImplementedError("cannot normalize %r" % (R,))
374
+
375
+ return K, L, G
376
+
377
+ def create_object(self, version, key, **extra_args):
378
+ r"""
379
+ Create a `p`-adic valuation from ``key``.
380
+
381
+ EXAMPLES::
382
+
383
+ sage: ZZ.valuation(5) # indirect doctest
384
+ 5-adic valuation
385
+ """
386
+ from sage.rings.integer_ring import ZZ
387
+ from sage.rings.rational_field import QQ
388
+ from sage.rings.padics.padic_generic import pAdicGeneric
389
+ from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
390
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
391
+ from sage.rings.number_field.number_field_base import NumberField
392
+ R = key[0]
393
+ parent = DiscretePseudoValuationSpace(R)
394
+ if isinstance(R, pAdicGeneric):
395
+ assert (len(key) == 1)
396
+ return parent.__make_element_class__(pAdicValuation_padic)(parent)
397
+ elif R is ZZ or R is QQ:
398
+ prime = key[1]
399
+ assert (len(key) == 2)
400
+ return parent.__make_element_class__(pAdicValuation_int)(parent, prime)
401
+ else:
402
+ v = key[1]
403
+ approximants = extra_args['approximants']
404
+ parent = DiscretePseudoValuationSpace(R)
405
+ K = R.fraction_field()
406
+ if isinstance(K, NumberField):
407
+ G = K.relative_polynomial()
408
+ elif isinstance(R, PolynomialQuotientRing_generic):
409
+ G = R.modulus()
410
+ else:
411
+ raise NotImplementedError
412
+ return parent.__make_element_class__(pAdicFromLimitValuation)(parent, v, G.change_ring(R.base_ring()), approximants)
413
+
414
+
415
+ pAdicValuation = PadicValuationFactory("sage.rings.padics.padic_valuation.pAdicValuation")
416
+
417
+
418
+ class pAdicValuation_base(DiscreteValuation):
419
+ r"""
420
+ Abstract base class for `p`-adic valuations.
421
+
422
+ INPUT:
423
+
424
+ - ``ring`` -- an integral domain
425
+
426
+ - ``p`` -- a rational prime over which this valuation lies, not
427
+ necessarily a uniformizer for the valuation
428
+
429
+ EXAMPLES::
430
+
431
+ sage: ZZ.valuation(3)
432
+ 3-adic valuation
433
+
434
+ sage: QQ.valuation(5)
435
+ 5-adic valuation
436
+
437
+ For `p`-adic rings, ``p`` has to match the `p` of the ring. ::
438
+
439
+ sage: v = valuations.pAdicValuation(Zp(3), 2); v
440
+ Traceback (most recent call last):
441
+ ...
442
+ ValueError: prime must be an element of positive valuation
443
+
444
+ TESTS::
445
+
446
+ sage: TestSuite(ZZ.valuation(3)).run() # long time # needs sage.geometry.polyhedron
447
+ sage: TestSuite(QQ.valuation(5)).run() # long time # needs sage.geometry.polyhedron
448
+ sage: TestSuite(Zp(5).valuation()).run() # long time # needs sage.geometry.polyhedron
449
+ """
450
+ def __init__(self, parent, p):
451
+ r"""
452
+ TESTS::
453
+
454
+ sage: from sage.rings.padics.padic_valuation import pAdicValuation_base
455
+ sage: isinstance(ZZ.valuation(3), pAdicValuation_base)
456
+ True
457
+ """
458
+ DiscreteValuation.__init__(self, parent)
459
+
460
+ from sage.rings.integer_ring import ZZ
461
+ self._p = ZZ(p)
462
+
463
+ def p(self):
464
+ r"""
465
+ Return the `p` of this `p`-adic valuation.
466
+
467
+ EXAMPLES::
468
+
469
+ sage: GaussianIntegers().valuation(2).p() # needs sage.geometry.polyhedron sage.rings.number_field
470
+ 2
471
+ """
472
+ return self._p
473
+
474
+ def reduce(self, x):
475
+ r"""
476
+ Reduce ``x`` modulo the ideal of elements of positive valuation.
477
+
478
+ INPUT:
479
+
480
+ - ``x`` -- an element in the domain of this valuation
481
+
482
+ OUTPUT: an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
483
+
484
+ EXAMPLES::
485
+
486
+ sage: v = ZZ.valuation(3)
487
+ sage: v.reduce(4)
488
+ 1
489
+ """
490
+ x = self.domain().coerce(x)
491
+
492
+ if self(x) < 0:
493
+ raise ValueError("reduction is only defined for elements of nonnegative valuation")
494
+
495
+ return self.residue_field()(x)
496
+
497
+ def lift(self, x):
498
+ r"""
499
+ Lift ``x`` from the residue field to the domain of this valuation.
500
+
501
+ INPUT:
502
+
503
+ - ``x`` -- an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
504
+
505
+ EXAMPLES::
506
+
507
+ sage: v = ZZ.valuation(3)
508
+ sage: xbar = v.reduce(4)
509
+ sage: v.lift(xbar)
510
+ 1
511
+ """
512
+ x = self.residue_field().coerce(x)
513
+
514
+ return self.domain()(x)
515
+
516
+ def is_unramified(self, G, include_steps=False, assume_squarefree=False):
517
+ r"""
518
+ Return whether ``G`` defines a single unramified extension of the
519
+ completion of the domain of this valuation.
520
+
521
+ INPUT:
522
+
523
+ - ``G`` -- a monic squarefree polynomial over the domain of this valuation
524
+
525
+ - ``include_steps`` -- boolean (default: ``False``); whether to
526
+ include the approximate valuations that were used to determine the
527
+ result in the return value
528
+
529
+ - ``assume_squarefree`` -- boolean (default: ``False``); whether to
530
+ assume that ``G`` is square-free over the completion of the domain of
531
+ this valuation. Setting this to ``True`` can significantly improve
532
+ the performance.
533
+
534
+ EXAMPLES:
535
+
536
+ We consider an extension as unramified if its ramification index is 1.
537
+ Hence, a trivial extension is unramified::
538
+
539
+ sage: R.<x> = QQ[]
540
+ sage: v = QQ.valuation(2)
541
+ sage: v.is_unramified(x)
542
+ True
543
+
544
+ If ``G`` remains irreducible in reduction, then it defines an
545
+ unramified extension::
546
+
547
+ sage: v.is_unramified(x^2 + x + 1)
548
+ True
549
+
550
+ However, even if ``G`` factors, it might define an unramified
551
+ extension::
552
+
553
+ sage: v.is_unramified(x^2 + 2*x + 4) # needs sage.geometry.polyhedron
554
+ True
555
+ """
556
+ R = G.parent()
557
+
558
+ from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
559
+ if not isinstance(R, PolynomialRing_generic) or R.base_ring() is not self.domain() or not G.is_monic():
560
+ raise ValueError("G must be a monic univariate polynomial over the domain of this valuation")
561
+ if not assume_squarefree and not G.is_squarefree():
562
+ raise ValueError("G must be squarefree")
563
+
564
+ from sage.rings.valuation.gauss_valuation import GaussValuation
565
+
566
+ steps = [ GaussValuation(R, self) ]
567
+ while True:
568
+ v = steps[-1]
569
+ if v.E() > 1:
570
+ ret = False
571
+ break
572
+ if v.F() == G.degree():
573
+ ret = True
574
+ break
575
+
576
+ assert v(G) is not infinity
577
+ if v.is_key(G):
578
+ ret = True
579
+ break
580
+
581
+ next = v.mac_lane_step(G, assume_squarefree=True)
582
+ if len(next) > 1:
583
+ ret = False
584
+ break
585
+ steps.append(next[0])
586
+
587
+ if include_steps:
588
+ return ret, steps
589
+ else:
590
+ return ret
591
+
592
+ def is_totally_ramified(self, G, include_steps=False, assume_squarefree=False):
593
+ r"""
594
+ Return whether ``G`` defines a single totally ramified extension of the
595
+ completion of the domain of this valuation.
596
+
597
+ INPUT:
598
+
599
+ - ``G`` -- a monic squarefree polynomial over the domain of this valuation
600
+
601
+ - ``include_steps`` -- boolean (default: ``False``); where to include
602
+ the valuations produced during the process of checking whether ``G``
603
+ is totally ramified in the return value
604
+
605
+ - ``assume_squarefree`` -- boolean (default: ``False``); whether to
606
+ assume that ``G`` is square-free over the completion of the domain of
607
+ this valuation. Setting this to ``True`` can significantly improve
608
+ the performance.
609
+
610
+ ALGORITHM:
611
+
612
+ This is a simplified version of :meth:`sage.rings.valuation.valuation.DiscreteValuation.mac_lane_approximants`.
613
+
614
+ EXAMPLES::
615
+
616
+ sage: # needs sage.libs.ntl
617
+ sage: k = Qp(5,4)
618
+ sage: v = k.valuation()
619
+ sage: R.<x> = k[]
620
+ sage: G = x^2 + 1
621
+ sage: v.is_totally_ramified(G) # needs sage.geometry.polyhedron
622
+ False
623
+ sage: G = x + 1
624
+ sage: v.is_totally_ramified(G)
625
+ True
626
+ sage: G = x^2 + 2
627
+ sage: v.is_totally_ramified(G)
628
+ False
629
+ sage: G = x^2 + 5
630
+ sage: v.is_totally_ramified(G) # needs sage.geometry.polyhedron
631
+ True
632
+ sage: v.is_totally_ramified(G, include_steps=True) # needs sage.geometry.polyhedron
633
+ (True, [Gauss valuation induced by 5-adic valuation, [ Gauss valuation induced by 5-adic valuation, v((1 + O(5^4))*x) = 1/2 ]])
634
+
635
+ We consider an extension as totally ramified if its ramification index
636
+ matches the degree. Hence, a trivial extension is totally ramified::
637
+
638
+ sage: R.<x> = QQ[]
639
+ sage: v = QQ.valuation(2)
640
+ sage: v.is_totally_ramified(x)
641
+ True
642
+
643
+ TESTS:
644
+
645
+ An example that Sebastian Pauli used at Sage Days 87::
646
+
647
+ sage: R = ZpFM(3, 20)
648
+ sage: S.<x> = R[]
649
+ sage: f = x^9 + 9*x^2 + 3
650
+ sage: R.valuation().is_totally_ramified(f) # needs sage.geometry.polyhedron
651
+ True
652
+ """
653
+ R = G.parent()
654
+
655
+ from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
656
+ if not isinstance(R, PolynomialRing_generic) or R.base_ring() is not self.domain() or not G.is_monic():
657
+ raise ValueError("G must be a monic univariate polynomial over the domain of this valuation")
658
+ if not assume_squarefree and not G.is_squarefree():
659
+ raise ValueError("G must be squarefree")
660
+
661
+ from sage.rings.valuation.gauss_valuation import GaussValuation
662
+
663
+ steps = [ GaussValuation(R, self) ]
664
+ while True:
665
+ v = steps[-1]
666
+ if v.F() > 1:
667
+ ret = False
668
+ break
669
+ if v.E() == G.degree():
670
+ ret = True
671
+ break
672
+
673
+ assert v(G) is not infinity
674
+ if v.is_key(G):
675
+ ret = False
676
+ break
677
+
678
+ next = v.mac_lane_step(G, assume_squarefree=True)
679
+ if len(next) > 1:
680
+ ret = False
681
+ break
682
+ steps.append(next[0])
683
+
684
+ if include_steps:
685
+ return ret, steps
686
+ else:
687
+ return ret
688
+
689
+ def change_domain(self, ring):
690
+ r"""
691
+ Change the domain of this valuation to ``ring`` if possible.
692
+
693
+ EXAMPLES::
694
+
695
+ sage: v = ZZ.valuation(2)
696
+ sage: v.change_domain(QQ).domain()
697
+ Rational Field
698
+ """
699
+ return pAdicValuation(ring, self.p())
700
+
701
+ def _extensions_to_quotient(self, ring, approximants=None):
702
+ r"""
703
+ Return the extensions of this valuation to an integral quotient over
704
+ the domain of this valuation.
705
+
706
+ EXAMPLES::
707
+
708
+ sage: R.<x> = QQ[]
709
+ sage: QQ.valuation(2)._extensions_to_quotient(R.quo(x^2 + x + 1))
710
+ [2-adic valuation]
711
+ """
712
+ approximants = approximants or self.mac_lane_approximants(ring.modulus().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True)
713
+ return [pAdicValuation(ring, approximant, approximants) for approximant in approximants]
714
+
715
+ def extensions(self, ring):
716
+ r"""
717
+ Return the extensions of this valuation to ``ring``.
718
+
719
+ EXAMPLES::
720
+
721
+ sage: v = ZZ.valuation(2)
722
+ sage: v.extensions(GaussianIntegers()) # needs sage.geometry.polyhedron sage.rings.number_field
723
+ [2-adic valuation]
724
+
725
+ TESTS::
726
+
727
+ sage: # needs sage.rings.number_field
728
+ sage: R.<a> = QQ[]
729
+ sage: x = polygen(ZZ, 'x')
730
+ sage: L.<a> = QQ.extension(x^3 - 2)
731
+ sage: R.<b> = L[]
732
+ sage: M.<b> = L.extension(b^2 + 2*b + a)
733
+ sage: M.valuation(2) # needs sage.geometry.polyhedron
734
+ 2-adic valuation
735
+
736
+ Check that we can extend to a field written as a quotient::
737
+
738
+ sage: # needs sage.rings.number_field
739
+ sage: R.<x> = QQ[]
740
+ sage: K.<a> = QQ.extension(x^2 + 1)
741
+ sage: R.<y> = K[]
742
+ sage: L.<b> = R.quo(x^2 + a)
743
+ sage: QQ.valuation(2).extensions(L) # needs sage.geometry.polyhedron
744
+ [2-adic valuation]
745
+
746
+ A case where there was at some point an internal error in the
747
+ approximants code::
748
+
749
+ sage: # needs sage.geometry.polyhedron sage.rings.number_field
750
+ sage: R.<x> = QQ[]
751
+ sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8)
752
+ sage: QQ.valuation(2).extensions(L)
753
+ [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation,
754
+ [ 2-adic valuation, v(x) = 1/2 ]-adic valuation]
755
+
756
+ A case where the extension was incorrect at some point::
757
+
758
+ sage: # needs sage.geometry.polyhedron sage.rings.number_field
759
+ sage: v = QQ.valuation(2)
760
+ sage: L.<a> = NumberField(x^2 + 2)
761
+ sage: M.<b> = L.extension(x^2 + 1)
762
+ sage: w = v.extension(L).extension(M)
763
+ sage: w(w.uniformizer())
764
+ 1/4
765
+
766
+ A case where the extensions could not be separated at some point::
767
+
768
+ sage: # needs sage.geometry.polyhedron sage.rings.number_field
769
+ sage: v = QQ.valuation(2)
770
+ sage: R.<x> = QQ[]
771
+ sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68
772
+ sage: L.<a> = QQ.extension(F)
773
+ sage: v.extensions(L)
774
+ [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation,
775
+ [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation]
776
+ """
777
+ if self.domain() is ring:
778
+ return [self]
779
+ domain_fraction_field = _fraction_field(self.domain())
780
+ if domain_fraction_field is not self.domain():
781
+ if domain_fraction_field.is_subring(ring):
782
+ return pAdicValuation(domain_fraction_field, self).extensions(ring)
783
+ if self.domain().is_subring(ring):
784
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
785
+ if isinstance(ring, PolynomialQuotientRing_generic):
786
+ if isinstance(self.domain(), PolynomialQuotientRing_generic):
787
+ if self.domain().modulus() == ring.modulus():
788
+ base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field()))
789
+ return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions]
790
+ if ring.base_ring() is self.domain():
791
+ from sage.categories.integral_domains import IntegralDomains
792
+ if ring in IntegralDomains():
793
+ return self._extensions_to_quotient(ring)
794
+ elif self.domain().is_subring(ring.base_ring()):
795
+ return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
796
+ from sage.rings.number_field.number_field_base import NumberField
797
+ if isinstance(ring.fraction_field(), NumberField):
798
+ if ring.base_ring().fraction_field() is self.domain().fraction_field():
799
+ approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True)
800
+ return [pAdicValuation(ring, approximant, approximants) for approximant in approximants]
801
+ if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()):
802
+ return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], [])
803
+ return super().extensions(ring)
804
+
805
+ def restriction(self, ring):
806
+ r"""
807
+ Return the restriction of this valuation to ``ring``.
808
+
809
+ EXAMPLES::
810
+
811
+ sage: v = GaussianIntegers().valuation(2) # needs sage.geometry.polyhedron sage.rings.number_field
812
+ sage: v.restriction(ZZ) # needs sage.geometry.polyhedron sage.rings.number_field
813
+ 2-adic valuation
814
+ """
815
+ if ring is self.domain():
816
+ return self
817
+
818
+ if not ring.is_subring(self.domain()):
819
+ raise ValueError("ring must be a subring of the domain of this valuation but %r is not a subring of %r" % (ring, self.domain()))
820
+
821
+ return pAdicValuation(ring, self.p())
822
+
823
+ @cached_method
824
+ def value_semigroup(self):
825
+ r"""
826
+ Return the value semigroup of this valuation.
827
+
828
+ EXAMPLES::
829
+
830
+ sage: v = GaussianIntegers().valuation(2) # needs sage.geometry.polyhedron sage.rings.number_field
831
+ sage: v.value_semigroup() # needs sage.geometry.polyhedron sage.rings.number_field
832
+ Additive Abelian Semigroup generated by 1/2
833
+ """
834
+ from sage.categories.fields import Fields
835
+ v = self(self.uniformizer())
836
+ if self.domain() in Fields():
837
+ return DiscreteValueSemigroup([-v,v])
838
+ else:
839
+ return DiscreteValueSemigroup([v])
840
+
841
+
842
+ class pAdicValuation_padic(pAdicValuation_base):
843
+ """
844
+ The `p`-adic valuation of a complete `p`-adic ring.
845
+
846
+ INPUT:
847
+
848
+ - ``R`` -- a `p`-adic ring
849
+
850
+ EXAMPLES::
851
+
852
+ sage: v = Qp(2).valuation(); v # indirect doctest
853
+ 2-adic valuation
854
+
855
+ TESTS::
856
+
857
+ sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron
858
+ """
859
+ def __init__(self, parent):
860
+ """
861
+ TESTS::
862
+
863
+ sage: from sage.rings.padics.padic_valuation import pAdicValuation_padic
864
+ sage: isinstance(Qp(2).valuation(), pAdicValuation_padic)
865
+ True
866
+ """
867
+ pAdicValuation_base.__init__(self, parent, parent.domain().prime())
868
+
869
+ def reduce(self, x):
870
+ """
871
+ Reduce ``x`` modulo the ideal of elements of positive valuation.
872
+
873
+ INPUT:
874
+
875
+ - ``x`` -- an element of the domain of this valuation
876
+
877
+ OUTPUT: an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
878
+
879
+ EXAMPLES::
880
+
881
+ sage: R = Zp(3)
882
+ sage: Zp(3).valuation().reduce(R(4))
883
+ 1
884
+ """
885
+ x = self.domain().coerce(x)
886
+ return self.residue_field()(x.residue())
887
+
888
+ def lift(self, x):
889
+ """
890
+ Lift ``x`` from the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field` to the domain of this
891
+ valuation.
892
+
893
+ INPUT:
894
+
895
+ - ``x`` -- an element of the residue field of this valuation
896
+
897
+ EXAMPLES::
898
+
899
+ sage: R = Zp(3)
900
+ sage: v = R.valuation()
901
+ sage: xbar = v.reduce(R(4))
902
+ sage: v.lift(xbar)
903
+ 1 + O(3^20)
904
+ """
905
+ x = self.residue_field().coerce(x)
906
+ return self.domain()(x).lift_to_precision()
907
+
908
+ def uniformizer(self):
909
+ """
910
+ Return a uniformizer of this valuation.
911
+
912
+ EXAMPLES::
913
+
914
+ sage: v = Zp(3).valuation()
915
+ sage: v.uniformizer()
916
+ 3 + O(3^21)
917
+ """
918
+ return self.domain().uniformizer()
919
+
920
+ def element_with_valuation(self, v):
921
+ """
922
+ Return an element of valuation ``v``.
923
+
924
+ INPUT:
925
+
926
+ - ``v`` -- an element of the :meth:`pAdicValuation_base.value_semigroup` of this valuation
927
+
928
+ EXAMPLES::
929
+
930
+ sage: R = Zp(3)
931
+ sage: v = R.valuation()
932
+ sage: v.element_with_valuation(3)
933
+ 3^3 + O(3^23)
934
+
935
+ sage: # needs sage.libs.ntl
936
+ sage: K = Qp(3)
937
+ sage: R.<y> = K[]
938
+ sage: L.<y> = K.extension(y^2 + 3*y + 3)
939
+ sage: L.valuation().element_with_valuation(3/2)
940
+ y^3 + O(y^43)
941
+ """
942
+ from sage.rings.integer_ring import ZZ
943
+ from sage.rings.rational_field import QQ
944
+ v = QQ(v)
945
+ if v not in self.value_semigroup():
946
+ raise ValueError("%r is not in the value semigroup of %r" % (v, self))
947
+ v = ZZ(v * self.domain().absolute_e())
948
+ return self.domain().one() << v
949
+
950
+ def _repr_(self):
951
+ """
952
+ Return a printable representation of this valuation.
953
+
954
+ EXAMPLES::
955
+
956
+ sage: ZZ.valuation(3)._repr_()
957
+ '3-adic valuation'
958
+ """
959
+ return "%s-adic valuation" % (self.p())
960
+
961
+ def _call_(self, x):
962
+ r"""
963
+ Evaluate this valuation at ``x``.
964
+
965
+ EXAMPLES::
966
+
967
+ sage: K = Qp(3)
968
+ sage: R.<y> = K[] # needs sage.libs.ntl
969
+ sage: L.<y> = K.extension(y^2 - 3) # needs sage.libs.ntl
970
+ sage: L.valuation()(3) # needs sage.libs.ntl
971
+ 1
972
+ """
973
+ return x.ordp()
974
+
975
+ def residue_ring(self):
976
+ r"""
977
+ Return the residue field of this valuation.
978
+
979
+ EXAMPLES::
980
+
981
+ sage: Qq(9, names='a').valuation().residue_ring() # needs sage.libs.ntl
982
+ Finite Field in a0 of size 3^2
983
+ """
984
+ return self.domain().residue_field()
985
+
986
+ def shift(self, x, s):
987
+ r"""
988
+ Shift ``x`` in its expansion with respect to :meth:`uniformizer` by
989
+ ``s`` "digits".
990
+
991
+ For nonnegative ``s``, this just returns ``x`` multiplied by a
992
+ power of the uniformizer `\pi`.
993
+
994
+ For negative ``s``, it does the same but when not over a field, it
995
+ drops coefficients in the `\pi`-adic expansion which have negative
996
+ valuation.
997
+
998
+ EXAMPLES::
999
+
1000
+ sage: R = ZpCA(2)
1001
+ sage: v = R.valuation()
1002
+ sage: v.shift(R.one(), 1)
1003
+ 2 + O(2^20)
1004
+ sage: v.shift(R.one(), -1)
1005
+ O(2^19)
1006
+
1007
+ sage: # needs sage.libs.ntl sage.rings.padics
1008
+ sage: S.<y> = R[]
1009
+ sage: S.<y> = R.extension(y^3 - 2)
1010
+ sage: v = S.valuation()
1011
+ sage: v.shift(1, 5)
1012
+ y^5 + O(y^60)
1013
+ """
1014
+ x = self.domain().coerce(x)
1015
+ s = self.value_group()(s)
1016
+ return x << s
1017
+
1018
+ def simplify(self, x, error=None, force=False):
1019
+ r"""
1020
+ Return a simplified version of ``x``.
1021
+
1022
+ Produce an element which differs from ``x`` by an element of
1023
+ valuation strictly greater than the valuation of ``x`` (or strictly
1024
+ greater than ``error`` if set.)
1025
+
1026
+ INPUT:
1027
+
1028
+ - ``x`` -- an element in the domain of this valuation
1029
+
1030
+ - ``error`` -- a rational, infinity, or ``None`` (default: ``None``),
1031
+ the error allowed to introduce through the simplification
1032
+
1033
+ - ``force`` -- ignored
1034
+
1035
+ EXAMPLES::
1036
+
1037
+ sage: R = Zp(2)
1038
+ sage: v = R.valuation()
1039
+ sage: v.simplify(6)
1040
+ 2 + O(2^21)
1041
+ sage: v.simplify(6, error=0)
1042
+ 0
1043
+ """
1044
+ x = self.domain().coerce(x)
1045
+
1046
+ if error is None:
1047
+ error = self(x)
1048
+ from sage.rings.infinity import infinity
1049
+ if error is infinity:
1050
+ return x
1051
+ # we need to scale by the ramification index because p-adics use a
1052
+ # different normalization
1053
+ normalized_error = (error / self.value_group().gen()).ceil()
1054
+ return x.add_bigoh(normalized_error + 1).lift_to_precision()
1055
+
1056
+
1057
+ class pAdicValuation_int(pAdicValuation_base):
1058
+ r"""
1059
+ A `p`-adic valuation on the integers or the rationals.
1060
+
1061
+ EXAMPLES::
1062
+
1063
+ sage: v = ZZ.valuation(3); v
1064
+ 3-adic valuation
1065
+
1066
+ TESTS::
1067
+
1068
+ sage: TestSuite(v).run() # long time # needs sage.geometry.polyhedron
1069
+ """
1070
+ def _repr_(self):
1071
+ """
1072
+ Return a printable representation of this valuation.
1073
+
1074
+ EXAMPLES::
1075
+
1076
+ sage: ZZ.valuation(3)._repr_()
1077
+ '3-adic valuation'
1078
+ """
1079
+ return "%s-adic valuation" % (self.p())
1080
+
1081
+ def _call_(self, x):
1082
+ """
1083
+ Evaluate this valuation at ``x``.
1084
+
1085
+ INPUT:
1086
+
1087
+ - ``x`` -- an element in the domain of this valuation
1088
+
1089
+ EXAMPLES::
1090
+
1091
+ sage: ZZ.valuation(3)(9)
1092
+ 2
1093
+ """
1094
+ if x.is_zero():
1095
+ # x.valuation() is a factor 10 slower when computing the valuation
1096
+ # of a rational zero than when computing the valuation of another
1097
+ # small rational. Special casing this is a factor 100 faster.
1098
+ return infinity
1099
+ return x.valuation(self._p)
1100
+
1101
+ def uniformizer(self):
1102
+ """
1103
+ Return a uniformizer of this `p`-adic valuation, i.e., `p` as an
1104
+ element of the domain.
1105
+
1106
+ EXAMPLES::
1107
+
1108
+ sage: v = ZZ.valuation(3)
1109
+ sage: v.uniformizer()
1110
+ 3
1111
+ """
1112
+ return self.domain()(self.p())
1113
+
1114
+ def residue_ring(self):
1115
+ """
1116
+ Return the residue field of this valuation.
1117
+
1118
+ EXAMPLES::
1119
+
1120
+ sage: v = ZZ.valuation(3)
1121
+ sage: v.residue_ring()
1122
+ Finite Field of size 3
1123
+ """
1124
+ from sage.rings.finite_rings.finite_field_constructor import GF
1125
+ return GF(self.p())
1126
+
1127
+ def _ge_(self, other):
1128
+ r"""
1129
+ Return whether this valuation is greater than or equal than ``other``
1130
+ everywhere.
1131
+
1132
+ EXAMPLES::
1133
+
1134
+ sage: v = ZZ.valuation(2)
1135
+ sage: w = valuations.TrivialValuation(ZZ)
1136
+ sage: v >= w
1137
+ True
1138
+ """
1139
+ if other.is_trivial():
1140
+ return other.is_discrete_valuation()
1141
+ if isinstance(other, pAdicValuation_int):
1142
+ return self.p() == other.p()
1143
+ return super(pAdicValuation_base, self)._ge_(other)
1144
+
1145
+ def _relative_size(self, x):
1146
+ r"""
1147
+ Return an estimate on the coefficient size of ``x``.
1148
+
1149
+ The number returned is an estimate on the factor between the number of
1150
+ bits used by ``x`` and the minimal number of bits used by an element
1151
+ congruent to ``x``.
1152
+
1153
+ This is used by :meth:`simplify` to decide whether simplification of
1154
+ coefficients is going to lead to a significant shrinking of the
1155
+ coefficients of ``x``.
1156
+
1157
+ EXAMPLES::
1158
+
1159
+ sage: v = ZZ.valuation(2)
1160
+ sage: v._relative_size(2)
1161
+ 1
1162
+ sage: v._relative_size(2**20)
1163
+ 11
1164
+ """
1165
+ x = self.domain().coerce(x)
1166
+ return (x.numerator().nbits() + x.denominator().nbits())//self.p().nbits()
1167
+
1168
+ def simplify(self, x, error=None, force=False, size_heuristic_bound=32):
1169
+ r"""
1170
+ Return a simplified version of ``x``.
1171
+
1172
+ Produce an element which differs from ``x`` by an element of
1173
+ valuation strictly greater than the valuation of ``x`` (or strictly
1174
+ greater than ``error`` if set.)
1175
+
1176
+ INPUT:
1177
+
1178
+ - ``x`` -- an element in the domain of this valuation
1179
+
1180
+ - ``error`` -- a rational, infinity, or ``None`` (default: ``None``),
1181
+ the error allowed to introduce through the simplification
1182
+
1183
+ - ``force`` -- ignored
1184
+
1185
+ - ``size_heuristic_bound`` -- when ``force`` is not set, the expected
1186
+ factor by which the ``x`` need to shrink to perform an actual
1187
+ simplification (default: 32)
1188
+
1189
+ EXAMPLES::
1190
+
1191
+ sage: v = ZZ.valuation(2)
1192
+ sage: v.simplify(6, force=True)
1193
+ 2
1194
+ sage: v.simplify(6, error=0, force=True)
1195
+ 0
1196
+
1197
+ In this example, the usual rational reconstruction misses a good answer
1198
+ for some moduli (because the absolute value of the numerator is not
1199
+ bounded by the square root of the modulus)::
1200
+
1201
+ sage: v = QQ.valuation(2)
1202
+ sage: v.simplify(110406, error=16, force=True)
1203
+ 562/19
1204
+ sage: Qp(2, 16)(110406).rational_reconstruction()
1205
+ Traceback (most recent call last):
1206
+ ...
1207
+ ArithmeticError: rational reconstruction of 55203 (mod 65536) does not exist
1208
+ """
1209
+ if not force and self._relative_size(x) <= size_heuristic_bound:
1210
+ return x
1211
+
1212
+ x = self.domain().coerce(x)
1213
+
1214
+ v = self(x)
1215
+ if error is None:
1216
+ error = v
1217
+ from sage.rings.infinity import infinity
1218
+ if error is infinity:
1219
+ return x
1220
+ if error < v:
1221
+ return self.domain().zero()
1222
+
1223
+ from sage.rings.rational_field import QQ
1224
+ from sage.rings.padics.factory import Qp
1225
+ precision_ring = Qp(self.p(), QQ(error).floor() + 1 - v)
1226
+ reduced = precision_ring(x)
1227
+ lift = (reduced >> v).lift()
1228
+ best = self.domain()(lift) * self.p()**v
1229
+
1230
+ if self._relative_size(x) < self._relative_size(best):
1231
+ best = x
1232
+
1233
+ # We implement a modified version of the usual rational reconstruction
1234
+ # algorithm (based on the extended Euclidean algorithm) here. We do not
1235
+ # get the uniqueness properties but we do not need them actually.
1236
+ # This is certainly slower than the implementation in Cython.
1237
+ from sage.categories.fields import Fields
1238
+ m = self.p()**(QQ(error).floor() + 1 - v)
1239
+ if self.domain() in Fields():
1240
+ r = (m, lift)
1241
+ s = (0, 1)
1242
+ while r[1]:
1243
+ qq, rr = r[0].quo_rem(r[1])
1244
+ r = r[1], rr
1245
+ s = s[1], s[0] - qq*s[1]
1246
+ from sage.arith.misc import GCD as gcd
1247
+ if s[1] != 0 and gcd(s[1], r[1]) == 1:
1248
+ rational = self.domain()(r[1]) / self.domain()(s[1]) * self.p()**v
1249
+ if self._relative_size(rational) < self._relative_size(best):
1250
+ best = rational
1251
+
1252
+ assert (self(x-best) > error)
1253
+
1254
+ return best
1255
+
1256
+ def inverse(self, x, precision):
1257
+ r"""
1258
+ Return an approximate inverse of ``x``.
1259
+
1260
+ The element returned is such that the product differs from 1 by an
1261
+ element of valuation at least ``precision``.
1262
+
1263
+ INPUT:
1264
+
1265
+ - ``x`` -- an element in the domain of this valuation
1266
+
1267
+ - ``precision`` -- a rational or infinity
1268
+
1269
+ EXAMPLES::
1270
+
1271
+ sage: v = ZZ.valuation(2)
1272
+ sage: x = 3
1273
+ sage: y = v.inverse(3, 2); y
1274
+ 3
1275
+ sage: x*y - 1
1276
+ 8
1277
+
1278
+ This might not be possible for elements of positive valuation::
1279
+
1280
+ sage: v.inverse(2, 2)
1281
+ Traceback (most recent call last):
1282
+ ...
1283
+ ValueError: element has no approximate inverse in this ring
1284
+
1285
+ Unless the precision is very small::
1286
+
1287
+ sage: v.inverse(2, 0)
1288
+ 1
1289
+ """
1290
+ if not x.is_zero():
1291
+ y = ~x
1292
+ if y in self.domain():
1293
+ return self.domain()(y)
1294
+ if precision <= 0:
1295
+ return self.domain().one()
1296
+
1297
+ from sage.rings.infinity import infinity
1298
+ if self(x) > 0 or precision is infinity:
1299
+ raise ValueError("element has no approximate inverse in this ring")
1300
+
1301
+ from sage.rings.integer_ring import ZZ
1302
+ from sage.rings.rational_field import QQ
1303
+ return self.domain()(ZZ(x).inverse_mod(self.p() ** QQ(precision).ceil()))
1304
+
1305
+
1306
+ class pAdicFromLimitValuation(FiniteExtensionFromLimitValuation, pAdicValuation_base):
1307
+ r"""
1308
+ A `p`-adic valuation on a number field or a subring thereof, i.e., a
1309
+ valuation that extends the `p`-adic valuation on the integers.
1310
+
1311
+ EXAMPLES::
1312
+
1313
+ sage: v = GaussianIntegers().valuation(3); v # needs sage.rings.number_field
1314
+ 3-adic valuation
1315
+
1316
+ TESTS::
1317
+
1318
+ sage: TestSuite(v).run(skip='_test_shift') # long time # needs sage.rings.number_field
1319
+
1320
+ The ``_test_shift`` test fails because the parent of the shift is
1321
+ incorrect, see :issue:`23971`::
1322
+
1323
+ sage: v.shift(1, -1).parent() # needs sage.rings.number_field
1324
+ Number Field in I with defining polynomial x^2 + 1 with I = 1*I
1325
+ """
1326
+ def __init__(self, parent, approximant, G, approximants):
1327
+ r"""
1328
+ TESTS::
1329
+
1330
+ sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
1331
+ sage: from sage.rings.padics.padic_valuation import pAdicFromLimitValuation
1332
+ sage: isinstance(v, pAdicFromLimitValuation) # needs sage.rings.number_field
1333
+ True
1334
+ """
1335
+ FiniteExtensionFromLimitValuation.__init__(self, parent, approximant, G, approximants)
1336
+ pAdicValuation_base.__init__(self, parent, approximant.restriction(approximant.domain().base_ring()).p())
1337
+
1338
+ def _to_base_domain(self, f):
1339
+ r"""
1340
+ Return ``f``, an element of the underlying limit valuation, as an
1341
+ element of the domain of this valuation.
1342
+
1343
+ EXAMPLES::
1344
+
1345
+ sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
1346
+ sage: I = GaussianIntegers().fraction_field().gen() # needs sage.rings.number_field
1347
+ sage: v._to_base_domain(I) # needs sage.rings.number_field
1348
+ x
1349
+
1350
+ TESTS:
1351
+
1352
+ Check that this also works for relative extensions::
1353
+
1354
+ sage: # needs sage.rings.number_field
1355
+ sage: v = QQ.valuation(2)
1356
+ sage: x = polygen(ZZ, 'x')
1357
+ sage: L.<a> = NumberField(x^2 + 2)
1358
+ sage: M.<b> = L.extension(x^2 + 1)
1359
+ sage: w = v.extension(L).extension(M) # needs sage.geometry.polyhedron
1360
+ sage: w._to_base_domain(b) # needs sage.geometry.polyhedron
1361
+ x
1362
+ """
1363
+ polynomial = f.lift()
1364
+ return polynomial(self._base_valuation.domain().gen())
1365
+
1366
+ def _from_base_domain(self, f):
1367
+ r"""
1368
+ Return ``f``, an element of the domain of this valuation, as an element
1369
+ of the domain of the underlying limit valuation.
1370
+
1371
+ EXAMPLES::
1372
+
1373
+ sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
1374
+ sage: v._from_base_domain(v._base_valuation.domain().gen()) # needs sage.rings.number_field
1375
+ I
1376
+ """
1377
+ return self.domain()(f)
1378
+
1379
+ def extensions(self, ring):
1380
+ r"""
1381
+ Return the extensions of this valuation to ``ring``.
1382
+
1383
+ EXAMPLES::
1384
+
1385
+ sage: v = GaussianIntegers().valuation(3) # needs sage.rings.number_field
1386
+ sage: v.extensions(v.domain().fraction_field()) # needs sage.rings.number_field
1387
+ [3-adic valuation]
1388
+ """
1389
+ if ring is self.domain().fraction_field():
1390
+ if self.domain() is not self.domain().fraction_field():
1391
+ G = ring.relative_polynomial()
1392
+ approximant = self._base_valuation.change_domain(G.parent())._initial_approximation
1393
+ return [pAdicValuation(ring, approximant)]
1394
+ return super().extensions(ring)
1395
+
1396
+
1397
+ def _fraction_field(ring):
1398
+ r"""
1399
+ Return a fraction field of ``ring``.
1400
+
1401
+ EXAMPLES:
1402
+
1403
+ This works around some annoyances with ``ring.fraction_field()``::
1404
+
1405
+ sage: R.<x> = ZZ[]
1406
+ sage: S = R.quo(x^2 + 1)
1407
+ sage: S.fraction_field()
1408
+ Fraction Field of Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1
1409
+
1410
+ sage: from sage.rings.padics.padic_valuation import _fraction_field
1411
+ sage: _fraction_field(S)
1412
+ Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1
1413
+ """
1414
+ from sage.categories.fields import Fields
1415
+ if ring in Fields():
1416
+ return ring
1417
+
1418
+ from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic
1419
+ if isinstance(ring, PolynomialQuotientRing_generic):
1420
+ from sage.categories.integral_domains import IntegralDomains
1421
+ if ring in IntegralDomains():
1422
+ return ring.base().change_ring(ring.base_ring().fraction_field()).quo(ring.modulus())
1423
+ return ring.fraction_field()