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,4229 @@
1
+ # sage_setup: distribution = sagemath-pari
2
+ # sage.doctest: needs sage.libs.flint
3
+ r"""
4
+ Template for relaxed `p`-adic rings and fields.
5
+
6
+ In order to use this template you need to write a linkage file and
7
+ gluing file.
8
+
9
+ The linkage file implements a common API that is then used in the
10
+ class FMElement defined here.
11
+ See sage/libs/linkages/padics/relaxed/API.pxi for the functions needed.
12
+
13
+ The gluing file does the following:
14
+ - ctypedef's ``cdigit``, ``cdigit_ptr``, ``celement`` and ``randgen``
15
+ to be the appropriate types
16
+ - includes the linkage file
17
+ - includes this template
18
+ - defines classes inheriting for classes defined in this file,
19
+ and implements any desired extra methods
20
+ See padic_relaxed_element.pxd and padic_relaxed_element.pyx for an example.
21
+
22
+ AUTHOR:
23
+
24
+ - Xavier Caruso (2021-02): initial version
25
+ """
26
+
27
+ # ****************************************************************************
28
+ # Copyright (C) 2021 Xavier Caruso <xavier.caruso@normalesup.org>
29
+ #
30
+ # This program is free software: you can redistribute it and/or modify
31
+ # it under the terms of the GNU General Public License as published by
32
+ # the Free Software Foundation, either version 2 of the License, or
33
+ # (at your option) any later version.
34
+ # http://www.gnu.org/licenses/
35
+ # ****************************************************************************
36
+
37
+ import re
38
+ from sage.misc import persist
39
+
40
+ from libc.stdlib cimport malloc, free
41
+ from sage.libs.gmp.mpz cimport mpz_sizeinbase, mpz_tstbit
42
+
43
+ from sage.structure.element import coerce_binop
44
+ from sage.structure.element cimport have_same_parent
45
+ from sage.structure.coerce cimport coercion_model
46
+ from sage.misc.prandom import randint
47
+
48
+ from sage.rings.integer_ring import ZZ
49
+ from sage.rings.integer cimport Integer
50
+ from sage.rings.infinity import Infinity
51
+
52
+ from sage.rings.padics.pow_computer cimport PowComputer_class
53
+ from sage.rings.padics.padic_generic_element cimport pAdicGenericElement
54
+ from sage.rings.padics.precision_error import PrecisionError
55
+ from sage.rings.padics.padic_relaxed_errors cimport *
56
+ from sage.rings.padics.padic_relaxed_errors import raise_error
57
+
58
+ cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) - 1
59
+
60
+
61
+ cdef cdigit tmp_digit
62
+ cdef celement tmp_poly
63
+ digit_init(tmp_digit)
64
+ element_init(tmp_poly)
65
+
66
+
67
+ cdef class RelaxedElement(pAdicGenericElement):
68
+ r"""
69
+ Template class for relaxed `p`-adic elements.
70
+
71
+ EXAMPLES:
72
+
73
+ sage: from sage.rings.padics.padic_relaxed_element import RelaxedElement
74
+ sage: R = ZpER(5)
75
+ sage: a = R(1)
76
+ sage: isinstance(a, RelaxedElement)
77
+ True
78
+ """
79
+ def __init__(self, parent):
80
+ r"""
81
+ Initialize this element.
82
+
83
+ TESTS::
84
+
85
+ sage: R = ZpER(5)
86
+ sage: a = R(1/2) # indirect doctest
87
+ sage: TestSuite(a).run()
88
+ """
89
+ pAdicGenericElement.__init__(self, parent)
90
+ self.prime_pow = <PowComputer_class>self._parent.prime_pow
91
+ self._valuation = 0
92
+ self._precrel = 0
93
+ self._precbound = maxordp
94
+
95
+ def __reduce__(self):
96
+ r"""
97
+ Return a tuple of a function and data that can be used to unpickle
98
+ this element.
99
+
100
+ TESTS::
101
+
102
+ sage: R = ZpER(5)
103
+ sage: a = R(0)
104
+ sage: loads(dumps(a)) == a
105
+ True
106
+ """
107
+ raise NotImplementedError("must be implemented in subclasses")
108
+
109
+ cpdef bint _is_base_elt(self, p) except -1:
110
+ r"""
111
+ Return ``True`` if this element is an element of Zp or Qp (rather than
112
+ an extension).
113
+
114
+ INPUT:
115
+
116
+ - ``p`` -- a prime, which is compared with the parent of this element
117
+
118
+ EXAMPLES::
119
+
120
+ sage: a = ZpER(5)(3)
121
+ sage: a._is_base_elt(5)
122
+ True
123
+ sage: a._is_base_elt(17)
124
+ False
125
+ """
126
+ return p == self._parent.prime()
127
+
128
+ cdef cdigit_ptr _getdigit_relative(self, long i) noexcept:
129
+ r"""
130
+ Return a pointer on the `i`-th significant digit of this number.
131
+
132
+ .. NOTE::
133
+
134
+ This function does not check that the requested digit
135
+ has been already computed.
136
+
137
+ INPUT:
138
+
139
+ - ``i`` -- positive integer
140
+ """
141
+ pass
142
+
143
+ cdef cdigit_ptr _getdigit_absolute(self, long i) noexcept:
144
+ r"""
145
+ Return a pointer on the digit in position `i` of
146
+ this number.
147
+
148
+ .. NOTE::
149
+
150
+ This function do not check that the requested digit
151
+ has been already computed.
152
+
153
+ INPUT:
154
+
155
+ - ``i`` -- integer
156
+ """
157
+ pass
158
+
159
+ cdef void _getslice_relative(self, celement slice, long start, long length) noexcept:
160
+ r"""
161
+ Select a slice of the digits of this number.
162
+
163
+ INPUT:
164
+
165
+ - ``slice`` -- a ``celement`` to store the slice
166
+
167
+ - ``start`` -- positive integer; the starting position of the slice
168
+ in relative precision
169
+
170
+ - ``length`` -- positive integer; the length of the slice
171
+
172
+ .. NOTE::
173
+
174
+ This methods only sets up a pointer to the requested slice
175
+ (the slice is not copied). Hence any future modification
176
+ of the slice ``slice`` will affect this number.
177
+ """
178
+ pass
179
+
180
+ cdef int _next_c(self) noexcept:
181
+ r"""
182
+ Compute the next digit of this number.
183
+
184
+ OUTPUT: an error code which is a superposition of the following:
185
+
186
+ - ``0`` -- no error
187
+ - ``ERROR_ABANDON = 1`` -- computation has been abandoned
188
+ - ``ERROR_NOTDEFINED = 2`` -- a number is not defined
189
+ - ``ERROR_PRECISION = 4`` -- not enough precision
190
+ - ``ERROR_OVERFLOW = 8`` -- overflow
191
+ - ``ERROR_NOTSQUARE = 16`` -- not a square
192
+ - ``ERROR_INTEGRAL = 32`` -- not in the integer ring
193
+ - ``ERROR_DIVISION = 64`` -- division by zero (or something indistinguishable from zero)
194
+ - ``ERROR_CIRCULAR = 128`` -- circular definition
195
+ """
196
+ raise NotImplementedError("must be implemented in subclasses")
197
+
198
+ cdef int _jump_c(self, long prec) noexcept:
199
+ r"""
200
+ Compute the digits of this number until the absolute precision ``prec``.
201
+
202
+ INPUT:
203
+
204
+ - ``prec`` -- integer
205
+
206
+ OUTPUT:
207
+
208
+ An error code (see :meth:`_next_c` for details).
209
+ """
210
+ cdef int error
211
+ cdef long pr = min(prec, self._precbound)
212
+ while self._precrel + self._valuation < pr:
213
+ error = self._next_c()
214
+ if error:
215
+ return error
216
+ if prec > self._precbound:
217
+ return ERROR_PRECISION
218
+ return 0
219
+
220
+ cdef int _jump_relative_c(self, long prec, long halt) noexcept:
221
+ r"""
222
+ Compute the digits of this number until the relative precision
223
+ ``prec``.
224
+
225
+ INPUT:
226
+
227
+ - ``prec`` -- integer
228
+
229
+ - ``halt`` -- integer; the absolute precision after which the
230
+ computation is abandoned if the first significant digit has not
231
+ been found yet
232
+
233
+ OUTPUT:
234
+
235
+ An error code (see :meth:`_next_c` for details).
236
+ """
237
+ if self._valuation >= maxordp:
238
+ return 0
239
+ cdef int error = 0
240
+ if self._valuation <= -maxordp:
241
+ error = self._next_c()
242
+ cdef long valhalt = min(halt, self._precbound)
243
+ while not error and self._valuation < valhalt and self._precrel == 0:
244
+ error = self._next_c()
245
+ if self._valuation >= self._precbound:
246
+ error |= ERROR_PRECISION
247
+ elif self._valuation >= halt:
248
+ error |= ERROR_ABANDON
249
+ if not error:
250
+ error = self._jump_c(self._valuation + prec)
251
+ return error
252
+
253
+ cdef int _init_jump(self) except -1:
254
+ r"""
255
+ Start the computation of the digits of this number.
256
+ This method should be called at initialization.
257
+
258
+ OUTPUT:
259
+
260
+ An error code (see :meth:`_next_c` for details).
261
+ """
262
+ cdef int error = 0
263
+ if self._precbound < maxordp:
264
+ error = self._jump_c(self._precbound)
265
+ raise_error(error, True)
266
+ return error
267
+
268
+ def digit(self, i):
269
+ r"""
270
+ Return the coefficient of `p^i` in the `p`-adic expansion
271
+ of this number.
272
+
273
+ INPUT:
274
+
275
+ - ``i`` -- integer
276
+
277
+ EXAMPLES::
278
+
279
+ sage: R = ZpER(5, prec=10)
280
+ sage: a = R(20/21)
281
+ sage: a
282
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
283
+ sage: a.digit(0)
284
+ 0
285
+ sage: a.digit(1)
286
+ 4
287
+ sage: a.digit(7)
288
+ 3
289
+ sage: a.digit(100)
290
+ 1
291
+
292
+ As a shortcut, one can use the bracket operator::
293
+
294
+ sage: a[100]
295
+ 1
296
+
297
+ If the digit is not known, an error is raised::
298
+
299
+ sage: b = a.add_bigoh(10)
300
+ sage: b.digit(20)
301
+ Traceback (most recent call last):
302
+ ...
303
+ PrecisionError: not enough precision
304
+
305
+ TESTS::
306
+
307
+ sage: a.digit(-1)
308
+ 0
309
+ """
310
+ cdef int error = self._jump_c(i+1)
311
+ raise_error(error)
312
+ cdef cdigit_ptr coeff = self._getdigit_absolute(i)
313
+ return digit_get_sage(coeff)
314
+
315
+ def expansion(self, n=None, lift_mode='simple', start_val=None):
316
+ r"""
317
+ Return an iterator over the list of coefficients in a `p`-adic
318
+ expansion of this element, that is the list of `a_i` so that
319
+ this element can be expressed as
320
+
321
+ .. MATH::
322
+
323
+ \pi^v \cdot \sum_{i=0}^\infty a_i \pi^i
324
+
325
+ where `v` is the valuation of this element when the parent is
326
+ a field, and `v = 0` otherwise and the `a_i` are between `0`
327
+ and `p - 1`.
328
+
329
+ INPUT:
330
+
331
+ - ``n`` -- integer or ``None`` (default: ``None``); if
332
+ given, return the corresponding entries in the expansion
333
+
334
+ - ``lift_mode`` -- ``'simple'``, ``'smallest'`` or
335
+ ``'teichmuller'`` (default: ``'simple'``)
336
+
337
+ - ``start_val`` -- start at this valuation rather than the
338
+ default (`0` or the valuation of this element)
339
+
340
+ OUTPUT:
341
+
342
+ - If ``n`` is ``None``, an iterable giving the `p`-adic expansion
343
+ of this element.
344
+
345
+ - If ``n`` is an integer, the coefficient of `p^n` in the
346
+ `p`-adic expansion of this element.
347
+
348
+ EXAMPLES::
349
+
350
+ sage: R = ZpER(7, print_mode='digits')
351
+ sage: a = R(1/2021); a
352
+ ...23615224635636163463
353
+
354
+ Without any argument, this method returns an iterator over the
355
+ digits of this number::
356
+
357
+ sage: E = a.expansion()
358
+ sage: E
359
+ 7-adic expansion of ...23615224635636163463
360
+ sage: next(E)
361
+ 3
362
+ sage: next(E)
363
+ 6
364
+ sage: next(E)
365
+ 4
366
+
367
+ On the contrary, passing in an integer returns the digit at the
368
+ given position::
369
+
370
+ sage: a.expansion(5)
371
+ 1
372
+
373
+ Over a field, the expansion starts at the valuation of the element::
374
+
375
+ sage: K = R.fraction_field()
376
+ sage: b = K(20/21); b
377
+ ...2222222222222222223.2
378
+ sage: E = b.expansion()
379
+ sage: next(E)
380
+ 2
381
+ sage: next(E)
382
+ 3
383
+
384
+ sage: c = 1/b; c
385
+ ...564356435643564356440
386
+ sage: E = c.expansion()
387
+ sage: next(E)
388
+ 4
389
+ sage: next(E)
390
+ 4
391
+
392
+ When ``start_val`` is given, the expansion starts at this position
393
+ instead:
394
+
395
+ sage: E = c.expansion(start_val=0)
396
+ sage: next(E)
397
+ 0
398
+ sage: next(E)
399
+ 4
400
+
401
+ sage: E = c.expansion(start_val=5)
402
+ sage: next(E)
403
+ 3
404
+ sage: next(E)
405
+ 4
406
+ """
407
+ if lift_mode == 'simple':
408
+ mode = simple_mode
409
+ elif lift_mode == 'smallest':
410
+ mode = smallest_mode
411
+ elif lift_mode == 'teichmuller':
412
+ mode = teichmuller_mode
413
+ else:
414
+ raise ValueError("unknown lift mode")
415
+ if n is None:
416
+ if start_val is not None:
417
+ start = start_val
418
+ elif self.prime_pow.in_field:
419
+ start = self.valuation()
420
+ else:
421
+ start = 0
422
+ return ExpansionIter(self, mode, start, self._precbound)
423
+ else:
424
+ n = Integer(n)
425
+ if n >= self._precbound:
426
+ raise_error(ERROR_PRECISION)
427
+ if n >= maxordp:
428
+ raise OverflowError("beyond maximum precision (which is %s)" % maxordp)
429
+ if mode == simple_mode:
430
+ return self.digit(n)
431
+ else:
432
+ E = ExpansionIter(self, mode, n, n+1)
433
+ return next(E)
434
+
435
+ def __getitem__(self, n):
436
+ r"""
437
+ Return the `n`-th digit of this relaxed `p`-adic number if `n` is an integer
438
+ or return a bounded relaxed `p`-adic corresponding to the given slice if `n` is a slice.
439
+
440
+ INPUT:
441
+
442
+ - ``n`` -- integer or a slice
443
+
444
+ EXAMPLES::
445
+
446
+ sage: R = ZpER(7, 10)
447
+ sage: a = R(1/2021); a
448
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
449
+
450
+ sage: a[3]
451
+ 3
452
+ sage: a[3:6]
453
+ 3*7^3 + 6*7^4 + 7^5 + O(7^6)
454
+
455
+ Unbounded slices are allowed::
456
+
457
+ sage: a[:3]
458
+ 3 + 6*7 + 4*7^2 + O(7^3)
459
+ sage: a[3:]
460
+ 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
461
+
462
+ .. SEEALSO::
463
+
464
+ :meth:`digit`, :meth:`slice`
465
+
466
+ TESTS::
467
+
468
+ sage: a[3:6:2]
469
+ Traceback (most recent call last):
470
+ ...
471
+ NotImplementedError: step is not allowed
472
+ """
473
+ if isinstance(n, slice):
474
+ if n.step is not None:
475
+ raise NotImplementedError("step is not allowed")
476
+ return self.slice(n.start, n.stop, True)
477
+ else:
478
+ n = Integer(n)
479
+ if n >= maxordp:
480
+ raise OverflowError("beyond maximum precision (which is %s)" % maxordp)
481
+ return self.digit(n)
482
+
483
+ def slice(self, start=None, stop=None, bound=False):
484
+ r"""
485
+ Return a slice of this number.
486
+
487
+ INPUT:
488
+
489
+ - ``start`` -- integer or ``None`` (default: ``None``);
490
+ the first position of the slice
491
+
492
+ - ``stop`` -- integer or ``None`` (default: ``None``);
493
+ the first position not included in the slice
494
+
495
+ - ``bound`` -- boolean (default: ``False``); whether the
496
+ precision on the output should be bounded or unbounded
497
+
498
+ EXAMPLES::
499
+
500
+ sage: K = QpER(7, prec=10)
501
+ sage: a = K(1/2021); a
502
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
503
+
504
+ sage: s = a.slice(3, 6)
505
+ sage: s
506
+ 3*7^3 + 6*7^4 + 7^5 + ...
507
+
508
+ In the above example, the precision on `b` remains unbounded::
509
+
510
+ sage: s.precision_absolute()
511
+ +Infinity
512
+
513
+ Passing in ``bound=True`` changes this behaviour::
514
+
515
+ sage: a.slice(3, 6, bound=True)
516
+ 3*7^3 + 6*7^4 + 7^5 + O(7^6)
517
+
518
+ When ``start`` is omitted, the slice starts at the beginning of the number:
519
+
520
+ sage: a.slice(stop=6)
521
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + ...
522
+
523
+ sage: b = K(20/21); b
524
+ 2*7^-1 + 3 + 2*7 + 2*7^2 + 2*7^3 + 2*7^4 + 2*7^5 + 2*7^6 + 2*7^7 + 2*7^8 + ...
525
+ sage: b.slice(stop=6)
526
+ 2*7^-1 + 3 + 2*7 + 2*7^2 + 2*7^3 + 2*7^4 + 2*7^5 + ...
527
+
528
+ As a shortcut, one can use the bracket operator.
529
+ However, in this case, the precision is bounded::
530
+
531
+ sage: a[3:6]
532
+ 3*7^3 + 6*7^4 + 7^5 + O(7^6)
533
+ sage: b[:6]
534
+ 2*7^-1 + 3 + 2*7 + 2*7^2 + 2*7^3 + 2*7^4 + 2*7^5 + O(7^6)
535
+
536
+ TESTS::
537
+
538
+ sage: x = a[:3]
539
+ sage: x.slice(stop=3)
540
+ 3 + 6*7 + 4*7^2 + ...
541
+ sage: x.slice(stop=4)
542
+ 3 + 6*7 + 4*7^2 + O(7^3)
543
+
544
+ Taking slices of slices work as expected::
545
+
546
+ sage: a1 = a.slice(5, 10); a1
547
+ 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
548
+ sage: a2 = a1.slice(3, 8); a2
549
+ 7^5 + 6*7^6 + 3*7^7 + ...
550
+ sage: a2 == a.slice(5, 8)
551
+ True
552
+ """
553
+ if start is None:
554
+ start = -maxordp
555
+ elif start >= maxordp:
556
+ raise OverflowError("beyond maximum precision (which is %s)" % maxordp)
557
+ if stop is None:
558
+ stop = maxordp
559
+ elif stop >= maxordp:
560
+ raise OverflowError("beyond maximum precision (which is %s)" % maxordp)
561
+ cdef RelaxedElement x = element_class_slice(self._parent, self, start, stop, 0)
562
+ if bound and x._precbound > stop:
563
+ x = element_class_bound(self._parent, x, stop)
564
+ return x
565
+
566
+ def _repr_(self):
567
+ r"""
568
+ Return a string representation of this element.
569
+
570
+ EXAMPLES:
571
+
572
+ For unbounded elements, the number of printed terms is given by
573
+ the default precision of the ring::
574
+
575
+ sage: R = ZpER(5, 10)
576
+ sage: a = R(1/2021)
577
+ sage: a # indirect doctest
578
+ 1 + 5 + 3*5^3 + 3*5^4 + 5^5 + 4*5^6 + 4*5^7 + 2*5^8 + 3*5^9 + ...
579
+
580
+ sage: S = ZpER(5, 5)
581
+ sage: b = S(1/2021)
582
+ sage: b # indirect doctest
583
+ 1 + 5 + 3*5^3 + 3*5^4 + ...
584
+
585
+ On the contrary, bounded elements are printed until their own
586
+ precision, regardless the default precision of the parent::
587
+
588
+ sage: a[:15] # indirect doctest
589
+ 1 + 5 + 3*5^3 + 3*5^4 + 5^5 + 4*5^6 + 4*5^7 + 2*5^8 + 3*5^9 + 2*5^10 + 5^11 + 5^12 + 5^13 + O(5^15)
590
+
591
+ sage: b[:15] # indirect doctest
592
+ 1 + 5 + 3*5^3 + 3*5^4 + 5^5 + 4*5^6 + 4*5^7 + 2*5^8 + 3*5^9 + 2*5^10 + 5^11 + 5^12 + 5^13 + O(5^15)
593
+ """
594
+ # This code should be integrated to the p-adic printer
595
+ if self._valuation <= -maxordp:
596
+ return "O(%s^-Infinity)" % self._parent.prime()
597
+ if self._is_exact_zero():
598
+ return "0"
599
+ if self._precbound >= maxordp:
600
+ unbounded = True
601
+ try:
602
+ if self.prime_pow.in_field:
603
+ x = self.at_precision_relative(permissive=False)
604
+ else:
605
+ x = self.at_precision_absolute(permissive=False)
606
+ except (ValueError, PrecisionError, RecursionError):
607
+ unbounded = False
608
+ x = element_class_bound(self._parent, self, self._valuation + self._precrel)
609
+ else:
610
+ unbounded = False
611
+ x = self
612
+ s = pAdicGenericElement._repr_(x)
613
+ mode = self._parent._printer.dict()['mode']
614
+ if unbounded:
615
+ s = re.sub(r'O\(.*\)$', '...', s)
616
+ elif mode == "digits":
617
+ s = re.sub(r'^\.\.\.\??', '...?', s)
618
+ elif mode == "bars":
619
+ s = re.sub(r'^\.\.\.\|?', '...?|', s)
620
+ if s == "" or s == "...":
621
+ s = "0 + ..."
622
+ return s
623
+
624
+ cdef bint _is_equal(self, RelaxedElement right, long prec, bint permissive) except -1:
625
+ r"""
626
+ C function for checking equality at a given precision.
627
+
628
+ INPUT:
629
+
630
+ - ``right`` -- the second element involved in the comparison
631
+
632
+ - ``prec`` -- integer; the precision at which the equality is checked
633
+
634
+ - ``permissive`` -- boolean; if ``True``, be silent if the precision
635
+ on one input is less than ``prec``. Otherwise, raise an error.
636
+ """
637
+ cdef int error
638
+ cdef long i
639
+ if self._valuation <= -maxordp:
640
+ error = self._next_c()
641
+ raise_error(error)
642
+ if right._valuation <= -maxordp:
643
+ error = right._next_c()
644
+ raise_error(error)
645
+ for i in range(min(self._valuation, right._valuation), prec):
646
+ error = self._jump_c(i+1)
647
+ raise_error(error, permissive)
648
+ if error: # not enough precision
649
+ return True
650
+ error = right._jump_c(i+1)
651
+ raise_error(error, permissive)
652
+ if error: # not enough precision
653
+ return True
654
+ if not digit_equal(self._getdigit_absolute(i), right._getdigit_absolute(i)):
655
+ return False
656
+ return True
657
+
658
+ @coerce_binop
659
+ def is_equal_at_precision(self, right, prec):
660
+ r"""
661
+ Compare this element with ``right`` at precision ``prec``.
662
+
663
+ INPUT:
664
+
665
+ - ``right`` -- a relaxed `p`-adic number
666
+
667
+ - ``prec`` -- integer
668
+
669
+ EXAMPLES::
670
+
671
+ sage: R = ZpER(7, prec=10)
672
+ sage: a = R(1/2); a
673
+ 4 + 3*7 + 3*7^2 + 3*7^3 + 3*7^4 + 3*7^5 + 3*7^6 + 3*7^7 + 3*7^8 + 3*7^9 + ...
674
+ sage: b = R(99/2); b
675
+ 4 + 3*7 + 4*7^2 + 3*7^3 + 3*7^4 + 3*7^5 + 3*7^6 + 3*7^7 + 3*7^8 + 3*7^9 + ...
676
+
677
+ sage: a.is_equal_at_precision(b, 1)
678
+ True
679
+ sage: a.is_equal_at_precision(b, 2)
680
+ True
681
+ sage: a.is_equal_at_precision(b, 3)
682
+ False
683
+ """
684
+ return self._is_equal(right, min(prec, maxordp), False)
685
+
686
+ @coerce_binop
687
+ def is_equal_to(self, RelaxedElement right, prec=None, secure=None):
688
+ r"""
689
+ Compare this element with ``right``.
690
+
691
+ INPUT:
692
+
693
+ - ``right`` -- a relaxed `p`-adic number
694
+
695
+ - ``prec`` -- integer or ``None`` (default: ``None``); if
696
+ given, compare the two elements at this precision. Otherwise
697
+ use the default halting precision of the parent.
698
+
699
+ - ``secure`` -- boolean (default: ``False`` if ``prec`` is given,
700
+ ``True`` otherwise); when the elements cannot be distinguished
701
+ at the given precision, raise an error if ``secure`` is ``True``,
702
+ return ``True`` otherwise.
703
+
704
+ EXAMPLES::
705
+
706
+ sage: R = ZpER(7)
707
+ sage: a = R(1/2)
708
+ sage: b = R(1/3)
709
+ sage: c = R(1/6)
710
+
711
+ sage: a.is_equal_to(b)
712
+ False
713
+
714
+ When equality indeed holds, it is not possible to conclude by
715
+ comparing more and more accurate approximations.
716
+ In this case, an error is raised::
717
+
718
+ sage: a.is_equal_to(b + c)
719
+ Traceback (most recent call last):
720
+ ...
721
+ PrecisionError: unable to decide equality; try to bound precision
722
+
723
+ You can get around this behaviour by passing ``secure=False``::
724
+
725
+ sage: a.is_equal_to(b + c, secure=False)
726
+ True
727
+
728
+ Another option (which is actually recommended) is to provide an explicit
729
+ bound on the precision::
730
+
731
+ sage: s = b + c + 7^50
732
+ sage: a.is_equal_to(s, prec=20)
733
+ True
734
+ sage: a.is_equal_to(s, prec=100)
735
+ False
736
+ """
737
+ cdef long halt
738
+ if self is right:
739
+ return True
740
+ if self._valuation >= maxordp and right._valuation >= maxordp:
741
+ return True
742
+ if prec is None:
743
+ if secure is None:
744
+ secure = True
745
+ prec = min(self._precbound, right._precbound)
746
+ else:
747
+ if secure is None:
748
+ secure = False
749
+ prec = Integer(prec)
750
+ if prec < maxordp:
751
+ return self._is_equal(right, prec, True)
752
+ prec = min(self._valuation + self._precrel, right._valuation + right._precrel)
753
+ halt = min(self._parent.halting_prec(), maxordp)
754
+ eq = self._is_equal(right, max(prec, halt), True)
755
+ if secure and eq:
756
+ raise PrecisionError("unable to decide equality; try to bound precision")
757
+ return eq
758
+
759
+ def __eq__(self, other):
760
+ r"""
761
+ Return ``True`` of this element is equal to ``other``.
762
+
763
+ TESTS::
764
+
765
+ sage: R = ZpER(5)
766
+ sage: x = R(1/2)
767
+ sage: y = R(1/3)
768
+ sage: z = R(1/6)
769
+
770
+ sage: x == y + z
771
+ True
772
+
773
+ We illustrate the effect of the keyword ``secure``::
774
+
775
+ sage: R.is_secure()
776
+ False
777
+ sage: s = y + z + 5^50
778
+ sage: x == s
779
+ True
780
+
781
+ sage: S = ZpER(5, secure=True)
782
+ sage: S(x) == S(s)
783
+ Traceback (most recent call last):
784
+ ...
785
+ PrecisionError: unable to decide equality; try to bound precision
786
+
787
+ Note that, when ``secure=False``, once more digits have been
788
+ computed, the answer can change::
789
+
790
+ sage: x[:100] == s
791
+ False
792
+ sage: x == s
793
+ False
794
+
795
+ .. SEEALSO::
796
+
797
+ :meth:`is_equal_to`
798
+ """
799
+ if not have_same_parent(self, other):
800
+ try:
801
+ a, b = coercion_model.canonical_coercion(self, other)
802
+ except TypeError:
803
+ return False
804
+ return a == b
805
+ return self.is_equal_to(other, secure=self._parent.is_secure())
806
+
807
+ def __bool__(self):
808
+ r"""
809
+ Return ``True`` if this element is distinguishable from zero.
810
+
811
+ TESTS::
812
+
813
+ sage: R = ZpER(5)
814
+ sage: x = R(1)
815
+ sage: bool(x)
816
+ True
817
+
818
+ In the next example, only `40` digits (which is the default halting
819
+ precision) are computed so `x` is considered as indistinguishable from
820
+ `0`::
821
+
822
+ sage: x = R(5^41)
823
+ sage: bool(x)
824
+ False
825
+ """
826
+ cdef int error = 0
827
+ cdef long prec, halt
828
+ if self._precrel:
829
+ return True
830
+ prec = self._precbound
831
+ if prec >= maxordp:
832
+ halt = min(self._parent.halting_prec(), maxordp)
833
+ prec = max(self._valuation + self._precrel, halt)
834
+ while not error and self._precrel == 0 and self._valuation < prec:
835
+ error = self._next_c()
836
+ return bool(self._precrel)
837
+
838
+ cpdef bint _is_exact_zero(self) except -1:
839
+ r"""
840
+ Return ``True`` if this element is an exact zero.
841
+
842
+ EXAMPLES::
843
+
844
+ sage: R = ZpER(5)
845
+ sage: a = R(0); a
846
+ 0
847
+ sage: a._is_exact_zero()
848
+ True
849
+
850
+ sage: b = a.add_bigoh(20)
851
+ sage: b
852
+ O(5^20)
853
+ sage: b._is_exact_zero()
854
+ False
855
+ """
856
+ return self._valuation >= maxordp
857
+
858
+ cpdef bint _is_inexact_zero(self) except -1:
859
+ r"""
860
+ Return ``True`` if, at the current stage of computations, this
861
+ number cannot be distinguished from zero.
862
+
863
+ EXAMPLES::
864
+
865
+ sage: R = ZpER(5, print_mode='digits')
866
+ sage: a = R(20/21)
867
+
868
+ Computations have not started yet; hence we are not able
869
+ to distinguish `a` from zero so far::
870
+
871
+ sage: a._is_inexact_zero()
872
+ True
873
+
874
+ When we print `a`, the first digits are computed, after what
875
+ we know that `a` is not zero::
876
+
877
+ sage: a
878
+ ...34010434010434010440
879
+ sage: a._is_inexact_zero()
880
+ False
881
+ """
882
+ return self._precrel == 0
883
+
884
+ def is_exact(self):
885
+ r"""
886
+ Return ``True`` if this element is exact, that is if its
887
+ precision is unbounded.
888
+
889
+ EXAMPLES::
890
+
891
+ sage: R = ZpER(5, prec=10)
892
+ sage: a = R(20/21)
893
+ sage: a
894
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
895
+ sage: a.is_exact()
896
+ True
897
+
898
+ sage: b = a.add_bigoh(10)
899
+ sage: b
900
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + O(5^10)
901
+ sage: b.is_exact()
902
+ False
903
+ """
904
+ return self._precbound >= maxordp
905
+
906
+ def precision_absolute(self):
907
+ r"""
908
+ Return the absolute precision of this element.
909
+
910
+ This is the power of `p` modulo which this element is known.
911
+ For unbounded elements, this methods return `+\infty`.
912
+
913
+ EXAMPLES::
914
+
915
+ sage: R = ZpER(5, prec=10)
916
+ sage: a = R(20/21)
917
+ sage: a
918
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
919
+ sage: a.precision_absolute()
920
+ +Infinity
921
+
922
+ sage: b = a.add_bigoh(10)
923
+ sage: b
924
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + O(5^10)
925
+ sage: b.precision_absolute()
926
+ 10
927
+
928
+ TESTS::
929
+
930
+ sage: s = R.unknown()
931
+ sage: (1/s).precision_absolute()
932
+ Traceback (most recent call last):
933
+ ...
934
+ PrecisionError: no lower bound on the valuation is known
935
+ """
936
+ if self._is_exact_zero():
937
+ return Infinity
938
+ if self._valuation <= -maxordp:
939
+ raise PrecisionError("no lower bound on the valuation is known")
940
+ if self._precbound >= maxordp:
941
+ return Infinity
942
+ return Integer(self._precrel + self._valuation)
943
+
944
+ def precision_relative(self):
945
+ r"""
946
+ Return the relative precision of this element.
947
+
948
+ This is the power of `p` modulo which the unit part of this
949
+ element is known.
950
+
951
+ For unbounded nonzero elements, this methods return `+\infty`.
952
+
953
+ EXAMPLES::
954
+
955
+ sage: R = ZpER(5, prec=10)
956
+ sage: a = R(20/21)
957
+ sage: a
958
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
959
+ sage: a.precision_relative()
960
+ +Infinity
961
+
962
+ sage: b = a.add_bigoh(10)
963
+ sage: b
964
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + O(5^10)
965
+ sage: b.precision_relative()
966
+ 9
967
+
968
+ The relative precision of (exact and inexact) `0` is `0`::
969
+
970
+ sage: x = R(0); x
971
+ 0
972
+ sage: x.precision_relative()
973
+ 0
974
+
975
+ sage: y = R(0, 10); y
976
+ O(5^10)
977
+ sage: y.precision_relative()
978
+ 0
979
+
980
+ TESTS::
981
+
982
+ sage: s = R.unknown()
983
+ sage: (1/s).precision_relative()
984
+ Traceback (most recent call last):
985
+ ...
986
+ PrecisionError: no lower bound on the valuation is known
987
+ """
988
+ if self._valuation <= -maxordp:
989
+ raise PrecisionError("no lower bound on the valuation is known")
990
+ if self._precbound >= maxordp and self._valuation < maxordp:
991
+ return Infinity
992
+ return Integer(self._precrel)
993
+
994
+ def precision_current(self):
995
+ r"""
996
+ Return the internal absolute precision at which this relaxed `p`-adic
997
+ number is known at the current stage of the computation.
998
+
999
+ EXAMPLES::
1000
+
1001
+ sage: R = ZpER(5, prec=10)
1002
+ sage: x = R(20/21)
1003
+ sage: y = R(21/22)
1004
+ sage: z = x + y
1005
+
1006
+ When the elements are just defined, the computation has not started::
1007
+
1008
+ sage: x.precision_current()
1009
+ 0
1010
+ sage: y.precision_current()
1011
+ 0
1012
+ sage: z.precision_current()
1013
+ 0
1014
+
1015
+ When elements are printed, the relevant digits are computed::
1016
+
1017
+ sage: x
1018
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1019
+ sage: x.precision_current()
1020
+ 10
1021
+
1022
+ If we ask for more digits of `z`, the current precision of `z`
1023
+ increases accordingly::
1024
+
1025
+ sage: z[:15]
1026
+ 3 + 2*5 + 2*5^3 + 5^4 + 2*5^5 + 2*5^6 + 4*5^7 + 5^9 + 3*5^10 + 3*5^11 + 4*5^12 + 4*5^13 + 4*5^14 + O(5^15)
1027
+ sage: z.precision_current()
1028
+ 15
1029
+
1030
+ and similarly the current precision of `x` and `y` increases because
1031
+ those digits are needed to carry out the computation::
1032
+
1033
+ sage: x.precision_current()
1034
+ 15
1035
+ sage: y.precision_current()
1036
+ 15
1037
+ """
1038
+ if self._valuation <= -maxordp:
1039
+ return -Infinity
1040
+ if self._valuation >= maxordp:
1041
+ return Infinity
1042
+ return Integer(self._valuation + self._precrel)
1043
+
1044
+ def at_precision_absolute(self, prec=None, permissive=None):
1045
+ r"""
1046
+ Return this element bounded at the given precision.
1047
+
1048
+ INPUT:
1049
+
1050
+ - ``prec`` -- integer or ``None`` (default: ``None``);
1051
+ if ``None``, use the default precision of the parent
1052
+
1053
+ - ``permissive`` -- boolean (default: ``False`` if ``prec``
1054
+ is given, ``True`` otherwise); if ``False``, raise an error
1055
+ if the precision of this element is not sufficient
1056
+
1057
+ EXAMPLES::
1058
+
1059
+ sage: R = ZpER(7, prec=10)
1060
+ sage: a = R(1/2021); a
1061
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
1062
+ sage: a.at_precision_absolute(5)
1063
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + O(7^5)
1064
+ sage: a.at_precision_absolute(10)
1065
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + O(7^10)
1066
+
1067
+ sage: b = a.add_bigoh(5)
1068
+ sage: b.at_precision_absolute(10)
1069
+ Traceback (most recent call last):
1070
+ ...
1071
+ PrecisionError: not enough precision
1072
+
1073
+ sage: b.at_precision_absolute(10, permissive=True)
1074
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + O(7^5)
1075
+
1076
+ Bounding at a negative precision is not permitted over `\ZZ_p`::
1077
+
1078
+ sage: a.at_precision_absolute(-1)
1079
+ Traceback (most recent call last):
1080
+ ...
1081
+ ValueError: precision must be nonnegative
1082
+
1083
+ but, of course, it is over `\QQ_p`::
1084
+
1085
+ sage: K = R.fraction_field()
1086
+ sage: K(a).at_precision_absolute(-1)
1087
+ O(7^-1)
1088
+
1089
+ .. SEEALSO::
1090
+
1091
+ :meth:`at_precision_relative`, :meth:`add_bigoh`
1092
+ """
1093
+ if prec is Infinity:
1094
+ if not permissive and self._precbound < maxordp:
1095
+ raise_error(ERROR_PRECISION)
1096
+ return self
1097
+ if prec is None:
1098
+ if permissive is None:
1099
+ permissive = True
1100
+ prec = self._parent.default_prec()
1101
+ else:
1102
+ prec = Integer(prec)
1103
+ if not self.prime_pow.in_field and prec < 0:
1104
+ raise ValueError("precision must be nonnegative")
1105
+ if prec > maxordp:
1106
+ raise OverflowError("beyond maximal precision (which is %s)" % maxordp)
1107
+ error = self._jump_c(prec)
1108
+ if permissive is None:
1109
+ permissive = False
1110
+ raise_error(error, permissive)
1111
+ return element_class_bound((<RelaxedElement>self)._parent, self, prec)
1112
+
1113
+ def add_bigoh(self, absprec):
1114
+ r"""
1115
+ Return a new element with absolute precision decreased to ``absprec``.
1116
+
1117
+ INPUT:
1118
+
1119
+ - ``absprec`` -- integer or infinity
1120
+
1121
+ EXAMPLES::
1122
+
1123
+ sage: R = ZpER(7, prec=10)
1124
+ sage: a = R(1/2021); a
1125
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
1126
+ sage: a.add_bigoh(5)
1127
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + O(7^5)
1128
+
1129
+ When ``absprec`` is negative, we return an element in the fraction
1130
+ field::
1131
+
1132
+ sage: b = a.add_bigoh(-1)
1133
+ sage: b
1134
+ O(7^-1)
1135
+ sage: b.parent()
1136
+ 7-adic Field handled with relaxed arithmetics
1137
+
1138
+ .. SEEALSO::
1139
+
1140
+ :meth:`at_precision_absolute`, :meth:`at_precision_relative`
1141
+ """
1142
+ if absprec < 0 and (not self.prime_pow.in_field):
1143
+ self = element_class_bound(self._parent.fraction_field(), self)
1144
+ return self.at_precision_absolute(absprec, True)
1145
+
1146
+ def at_precision_relative(self, prec=None, halt=True, permissive=None):
1147
+ r"""
1148
+ Return this element bounded at the given precision.
1149
+
1150
+ INPUT:
1151
+
1152
+ - ``prec`` -- integer or ``None`` (default: ``None``);
1153
+ if ``None``, use the default precision of the parent
1154
+
1155
+ - ``halt`` -- integer or boolean (default: ``True``);
1156
+ the absolute precision after which the computation is abandoned
1157
+ if the first significant digit has not been found yet.
1158
+ If ``True``, the default halting precision of the parent is used.
1159
+ If ``False``, the computation is never abandoned.
1160
+
1161
+ - ``permissive`` -- boolean (default: ``False`` if ``prec``
1162
+ is given, ``True`` otherwise); if ``False``, raise an error
1163
+ if the precision of this element is not sufficient
1164
+
1165
+ EXAMPLES::
1166
+
1167
+ sage: R = ZpER(5, prec=10, halt=10)
1168
+ sage: a = R(20/21); a
1169
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1170
+ sage: a.at_precision_relative(5)
1171
+ 4*5 + 4*5^2 + 5^4 + O(5^6)
1172
+
1173
+ We illustrate the behaviour of the parameter ``halt``.
1174
+ We create a very small number whose first significant is far beyond
1175
+ the default precision::
1176
+
1177
+ sage: b = R(5^20)
1178
+ sage: b
1179
+ 0 + ...
1180
+
1181
+ Without any help, Sage does not run the computation far enough to determine
1182
+ the valuation and an error is raised::
1183
+
1184
+ sage: b.at_precision_relative(5)
1185
+ Traceback (most recent call last):
1186
+ ...
1187
+ PrecisionError: computation has been abandoned; try to increase precision
1188
+
1189
+ By setting the argument ``halt``, one can force the computation to continue
1190
+ until a prescribed limit::
1191
+
1192
+ sage: b.at_precision_relative(5, halt=20) # not enough to find the valuation
1193
+ Traceback (most recent call last):
1194
+ ...
1195
+ PrecisionError: computation has been abandoned; try to increase precision
1196
+
1197
+ sage: b.at_precision_relative(5, halt=21) # now, we're okay
1198
+ 5^20 + O(5^25)
1199
+
1200
+ .. NOTE::
1201
+
1202
+ It is also possible to pass in ``halt=False`` but it is not recommended
1203
+ because the computation can hang forever if this element is `0`.
1204
+
1205
+ .. SEEALSO::
1206
+
1207
+ :meth:`at_precision_absolute`, :meth:`add_bigoh`
1208
+
1209
+ TESTS::
1210
+
1211
+ sage: a.at_precision_relative(-1)
1212
+ Traceback (most recent call last):
1213
+ ...
1214
+ ValueError: precision must be nonnegative
1215
+ """
1216
+ if prec is Infinity:
1217
+ if not permissive and self._precbound < maxordp:
1218
+ raise_error(ERROR_PRECISION)
1219
+ return self
1220
+ default_prec = self._parent.default_prec()
1221
+ if prec is None:
1222
+ if permissive is None:
1223
+ permissive = True
1224
+ prec = default_prec
1225
+ else:
1226
+ prec = Integer(prec)
1227
+ if prec < 0:
1228
+ raise ValueError("precision must be nonnegative")
1229
+ if prec > maxordp:
1230
+ raise OverflowError("beyond maximal precision (which is %s)" % maxordp)
1231
+ if halt is True:
1232
+ halt = self._parent.halting_prec()
1233
+ elif halt is False:
1234
+ halt = maxordp
1235
+ else:
1236
+ halt = min(maxordp, halt)
1237
+ error = self._jump_relative_c(prec, halt)
1238
+ if permissive is None:
1239
+ permissive = False
1240
+ raise_error(error, permissive)
1241
+ return element_class_bound((<RelaxedElement>self)._parent, self, self._valuation + prec)
1242
+
1243
+ def lift_to_precision(self, absprec=None):
1244
+ """
1245
+ Return another element of the same parent, lifting this element
1246
+ and having absolute precision at least ``absprec``.
1247
+
1248
+ INPUT:
1249
+
1250
+ - ``absprec`` -- integer or ``None`` (default: ``None``); the
1251
+ absolute precision of the result. If ``None``, the default
1252
+ precision of the parent is used.
1253
+
1254
+ EXAMPLES::
1255
+
1256
+ sage: R = ZpER(5, prec=10)
1257
+ sage: a = R(20/21, 5); a
1258
+ 4*5 + 4*5^2 + 5^4 + O(5^5)
1259
+
1260
+ sage: a.lift_to_precision(20)
1261
+ 4*5 + 4*5^2 + 5^4 + O(5^20)
1262
+
1263
+ When the precision is omitted, the default precision of the parent
1264
+ is used::
1265
+
1266
+ sage: a.lift_to_precision()
1267
+ 4*5 + 4*5^2 + 5^4 + O(5^10)
1268
+
1269
+ When the parent is a field, the behaviour is slightly different since
1270
+ the default precision of the parent becomes the relative precision
1271
+ of the lifted element::
1272
+
1273
+ sage: K = R.fraction_field()
1274
+ sage: K(a).lift_to_precision()
1275
+ 4*5 + 4*5^2 + 5^4 + O(5^11)
1276
+
1277
+ Note that the precision never decreases::
1278
+
1279
+ sage: a.lift_to_precision(2)
1280
+ 4*5 + 4*5^2 + 5^4 + O(5^5)
1281
+
1282
+ In particular, unbounded element are not affected by this method::
1283
+
1284
+ sage: b = R(20/21); b
1285
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1286
+ sage: b.lift_to_precision()
1287
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1288
+ sage: b.lift_to_precision(2)
1289
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1290
+ """
1291
+ if self._precbound >= maxordp:
1292
+ return self
1293
+ cdef long prec
1294
+ cdef long default_prec = self._parent.default_prec()
1295
+ if absprec is None:
1296
+ if self.prime_pow.in_field:
1297
+ self._jump_relative_c(1, self._precbound)
1298
+ if self._precrel == 0:
1299
+ return self._parent.zero()
1300
+ prec = self._valuation + default_prec
1301
+ else:
1302
+ prec = default_prec
1303
+ else:
1304
+ if absprec > maxordp:
1305
+ raise OverflowError("beyond the maximal precision (which is %s)" % maxordp)
1306
+ prec = absprec
1307
+ if prec <= self._precbound:
1308
+ return self
1309
+ cdef RelaxedElement ans = element_class_slice(self._parent, self, -maxordp, self._precbound, 0)
1310
+ ans._precbound = prec
1311
+ ans._init_jump()
1312
+ return ans
1313
+
1314
+ cdef long valuation_c(self, long halt=-maxordp) noexcept:
1315
+ r"""
1316
+ Return the best lower bound we have on the valuation of
1317
+ this element at the current stage of the computation.
1318
+
1319
+ INPUT:
1320
+
1321
+ - ``halt`` -- integer; if given, allow to increase the
1322
+ absolute precision on this element up to ``halt`` in order
1323
+ to get a better lower bound
1324
+ """
1325
+ cdef int error = 0
1326
+ while not error and self._precrel == 0 and self._valuation < halt:
1327
+ error = self._next_c()
1328
+ return self._valuation
1329
+
1330
+ def valuation(self, halt=True, secure=None):
1331
+ r"""
1332
+ Return the valuation of this element.
1333
+
1334
+ INPUT:
1335
+
1336
+ - ``halt`` -- integer or boolean (default: ``True``);
1337
+ the absolute precision after which the computation is abandoned
1338
+ if the first significant digit has not been found yet.
1339
+ If ``True``, the default halting precision of the parent is used.
1340
+ If ``False``, the computation is never abandoned.
1341
+
1342
+ - ``secure`` -- boolean (default: the value given at the creation
1343
+ of the parent); when the valuation cannot be determined for sure,
1344
+ raise an error if ``secure`` is ``True``, return the best known
1345
+ lower bound on the valuation otherwise
1346
+
1347
+ EXAMPLES::
1348
+
1349
+ sage: R = ZpER(5, prec=10, halt=10)
1350
+ sage: a = R(2001); a
1351
+ 1 + 5^3 + 3*5^4 + ...
1352
+ sage: a.valuation()
1353
+ 0
1354
+
1355
+ sage: b = a - 1/a; b
1356
+ 2*5^3 + 5^4 + 5^5 + 4*5^6 + 3*5^7 + 4*5^8 + 3*5^9 + 3*5^10 + 3*5^11 + 5^12 + ...
1357
+ sage: b.valuation()
1358
+ 3
1359
+
1360
+ The valuation of an exact zero is `+\infty`::
1361
+
1362
+ sage: R(0).valuation()
1363
+ +Infinity
1364
+
1365
+ The valuation of an inexact zero is its absolute precision::
1366
+
1367
+ sage: R(0, 20).valuation()
1368
+ 20
1369
+
1370
+ We illustrate the behaviour of the parameter ``halt``.
1371
+ We create a very small number whose first significant is far beyond
1372
+ the default precision::
1373
+
1374
+ sage: z = R(5^20)
1375
+ sage: z
1376
+ 0 + ...
1377
+
1378
+ Without any help, Sage does not run the computation far enough to determine
1379
+ the valuation and outputs only a lower bound::
1380
+
1381
+ sage: z.valuation()
1382
+ 10
1383
+
1384
+ With ``secure=True``, an error is raised::
1385
+
1386
+ sage: z.valuation(secure=True)
1387
+ Traceback (most recent call last):
1388
+ ...
1389
+ PrecisionError: cannot determine the valuation; try to increase the halting precision
1390
+
1391
+ By setting the argument ``halt``, one can force the computation to continue
1392
+ until a prescribed limit::
1393
+
1394
+ sage: z.valuation(halt=15) # not enough to find the correct valuation
1395
+ 15
1396
+ sage: z.valuation(halt=20, secure=True)
1397
+ Traceback (most recent call last):
1398
+ ...
1399
+ PrecisionError: cannot determine the valuation; try to increase the halting precision
1400
+
1401
+ sage: z.valuation(halt=21) # now, we're okay
1402
+ 20
1403
+
1404
+ .. NOTE::
1405
+
1406
+ It is also possible to pass in ``halt=False`` but it is not recommended
1407
+ because the computation can hang forever if this element is `0`.
1408
+
1409
+ TESTS::
1410
+
1411
+ sage: x = R.unknown()
1412
+ sage: (~x).valuation()
1413
+ Traceback (most recent call last):
1414
+ ...
1415
+ PrecisionError: no lower bound on the valuation is known
1416
+ """
1417
+ if self._is_exact_zero():
1418
+ return Infinity
1419
+ if self._valuation <= -maxordp:
1420
+ raise PrecisionError("no lower bound on the valuation is known")
1421
+ if halt is True:
1422
+ halt = self._parent.halting_prec()
1423
+ elif halt is False:
1424
+ halt = maxordp
1425
+ else:
1426
+ halt = min(maxordp, halt)
1427
+ cdef val = self.valuation_c(halt)
1428
+ if secure is None:
1429
+ secure = self._parent.is_secure()
1430
+ if secure and self._precbound >= maxordp and self._precrel == 0:
1431
+ raise PrecisionError("cannot determine the valuation; try to increase the halting precision")
1432
+ return Integer(val)
1433
+
1434
+ def unit_part(self, halt=True):
1435
+ r"""
1436
+ Return the unit part of this element.
1437
+
1438
+ INPUT:
1439
+
1440
+ - ``halt`` -- integer or boolean (default: ``True``);
1441
+ the absolute precision after which the computation is abandoned
1442
+ if the first significant digit has not been found yet.
1443
+ If ``True``, the default halting precision of the parent is used.
1444
+ If ``False``, the computation is never abandoned.
1445
+
1446
+ EXAMPLES::
1447
+
1448
+ sage: R = ZpER(5, prec=10, halt=10)
1449
+ sage: a = R(20/21); a
1450
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1451
+ sage: a.unit_part()
1452
+ 4 + 4*5 + 5^3 + 4*5^5 + 3*5^6 + 4*5^7 + 5^9 + ...
1453
+
1454
+ sage: b = 1/a; b
1455
+ 4*5^-1 + 4 + 3*5 + 3*5^2 + 3*5^3 + 3*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 3*5^8 + ...
1456
+ sage: b.unit_part()
1457
+ 4 + 4*5 + 3*5^2 + 3*5^3 + 3*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 3*5^8 + 3*5^9 + ...
1458
+
1459
+ The unit part of `0` is not defined::
1460
+
1461
+ sage: R(0).unit_part()
1462
+ Traceback (most recent call last):
1463
+ ...
1464
+ ValueError: unit part of 0 not defined
1465
+
1466
+ sage: R(0, 20).unit_part()
1467
+ Traceback (most recent call last):
1468
+ ...
1469
+ ValueError: unit part of 0 not defined
1470
+
1471
+ See :meth:`valuation` for more details on the parameter ``halt``.
1472
+ """
1473
+ val = self.valuation(halt)
1474
+ if self._valuation >= self._precbound:
1475
+ raise ValueError("unit part of 0 not defined")
1476
+ return self >> val
1477
+
1478
+ def val_unit(self, halt=True):
1479
+ r"""
1480
+ Return the valuation and the unit part of this element.
1481
+
1482
+ INPUT:
1483
+
1484
+ - ``halt`` -- integer or boolean (default: ``True``);
1485
+ the absolute precision after which the computation is abandoned
1486
+ if the first significant digit has not been found yet.
1487
+ If ``True``, the default halting precision of the parent is used.
1488
+ If ``False``, the computation is never abandoned.
1489
+
1490
+ EXAMPLES::
1491
+
1492
+ sage: R = ZpER(5, 10)
1493
+ sage: a = R(20/21); a
1494
+ 4*5 + 4*5^2 + 5^4 + 4*5^6 + 3*5^7 + 4*5^8 + ...
1495
+ sage: a.val_unit()
1496
+ (1, 4 + 4*5 + 5^3 + 4*5^5 + 3*5^6 + 4*5^7 + 5^9 + ...)
1497
+
1498
+ sage: b = 1/a; b
1499
+ 4*5^-1 + 4 + 3*5 + 3*5^2 + 3*5^3 + 3*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 3*5^8 + ...
1500
+ sage: b.val_unit()
1501
+ (-1, 4 + 4*5 + 3*5^2 + 3*5^3 + 3*5^4 + 3*5^5 + 3*5^6 + 3*5^7 + 3*5^8 + 3*5^9 + ...)
1502
+
1503
+ If this element is indistinguishable from zero, an error is raised
1504
+ since the unit part of `0` is not defined::
1505
+
1506
+ sage: R(0).unit_part()
1507
+ Traceback (most recent call last):
1508
+ ...
1509
+ ValueError: unit part of 0 not defined
1510
+
1511
+ sage: R(0, 20).unit_part()
1512
+ Traceback (most recent call last):
1513
+ ...
1514
+ ValueError: unit part of 0 not defined
1515
+
1516
+ See :meth:`valuation` for more details on the parameter ``halt``.
1517
+ """
1518
+ val = self.valuation(halt)
1519
+ if self._valuation >= self._precbound:
1520
+ raise ValueError("unit part of 0 not defined")
1521
+ return val, self >> val
1522
+
1523
+ def residue(self, absprec=1, field=True, check_prec=True):
1524
+ r"""
1525
+ Return the image of this element in the quotient
1526
+ `\ZZ/p^\mathrm{absprec}\ZZ`.
1527
+
1528
+ INPUT:
1529
+
1530
+ - ``absprec`` -- nonnegative integer (default: 1)
1531
+
1532
+ - ``field`` -- boolean (default: ``True``); when ``absprec`` is ``1``,
1533
+ whether to return an element of GF(p) or Zmod(p)
1534
+
1535
+ - ``check_prec`` -- boolean (default: ``True``); whether to raise an error
1536
+ if this element has insufficient precision to determine the reduction
1537
+
1538
+ EXAMPLES::
1539
+
1540
+ sage: R = ZpER(7, 10)
1541
+ sage: a = R(1/2021); a
1542
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + 7^5 + 6*7^6 + 3*7^7 + 6*7^8 + 5*7^9 + ...
1543
+ sage: a.residue()
1544
+ 3
1545
+ sage: a.residue(2)
1546
+ 45
1547
+
1548
+ If this element has negative valuation, an error is raised::
1549
+
1550
+ sage: K = R.fraction_field()
1551
+ sage: b = K(20/21)
1552
+ sage: b.residue()
1553
+ Traceback (most recent call last):
1554
+ ...
1555
+ ValueError: element must have nonnegative valuation in order to compute residue
1556
+ """
1557
+ if absprec >= maxordp:
1558
+ raise OverflowError
1559
+ if absprec < 0:
1560
+ raise ValueError("cannot reduce modulo a negative power of p")
1561
+ error = self._jump_c(absprec)
1562
+ raise_error(error, not check_prec)
1563
+ if self._valuation < 0:
1564
+ raise ValueError("element must have nonnegative valuation in order to compute residue")
1565
+ cdef celement digits
1566
+ cdef Integer ans
1567
+ if absprec <= self._valuation:
1568
+ ans = ZZ(0)
1569
+ else:
1570
+ self._getslice_relative(digits, 0, min(self._precrel, absprec - self._valuation))
1571
+ ans = element_get_sage(digits, self.prime_pow) * self.prime_pow(self._valuation)
1572
+ if field and absprec == 1:
1573
+ return self._parent.residue_class_field()(ans)
1574
+ else:
1575
+ return self._parent.residue_ring(absprec)(ans)
1576
+
1577
+ def lift(self, absprec=None):
1578
+ r"""
1579
+ Return a rational number which is congruent to this element modulo
1580
+ `p^\mathrm{prec}`.
1581
+
1582
+ INPUT:
1583
+
1584
+ - ``absprec`` -- integer or ``None`` (default: ``None``); if ``None``,
1585
+ the absolute precision of this element is used
1586
+
1587
+ EXAMPLES::
1588
+
1589
+ sage: R = ZpER(7, 10)
1590
+ sage: a = R(1/2021, 5); a
1591
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + O(7^5)
1592
+ sage: a.lift()
1593
+ 15676
1594
+ sage: a.lift(2)
1595
+ 45
1596
+
1597
+ Here is another example with an element of negative valuation::
1598
+
1599
+ sage: K = R.fraction_field()
1600
+ sage: b = K(20/21, 5); b
1601
+ 2*7^-1 + 3 + 2*7 + 2*7^2 + 2*7^3 + 2*7^4 + O(7^5)
1602
+ sage: b.lift()
1603
+ 39223/7
1604
+
1605
+ For unbounded elements, we must specify a precision::
1606
+
1607
+ sage: c = R(1/2021)
1608
+ sage: c.lift()
1609
+ Traceback (most recent call last):
1610
+ ...
1611
+ ValueError: you must specify a precision for unbounded elements
1612
+
1613
+ sage: c.lift(5)
1614
+ 15676
1615
+ """
1616
+ if absprec is None:
1617
+ if self._precbound < maxordp:
1618
+ absprec = self._precbound
1619
+ else:
1620
+ raise ValueError("you must specify a precision for unbounded elements")
1621
+ else:
1622
+ absprec = Integer(absprec)
1623
+ cdef int error = self._jump_c(absprec)
1624
+ raise_error(error)
1625
+ if absprec < self._valuation:
1626
+ return Integer(0)
1627
+ cdef celement digits
1628
+ self._getslice_relative(digits, 0, absprec - self._valuation)
1629
+ ans = element_get_sage(digits, self.prime_pow)
1630
+ if self._valuation:
1631
+ ans *= self._parent.prime() ** self._valuation
1632
+ return ans
1633
+
1634
+ def __rshift__(self, s):
1635
+ r"""
1636
+ Return this element divided by `\pi^s`, and truncated
1637
+ if the parent is not a field.
1638
+
1639
+ EXAMPLES::
1640
+
1641
+ sage: R = ZpER(997)
1642
+ sage: K = R.fraction_field()
1643
+ sage: a = R(123456878908); a
1644
+ 964*997 + 572*997^2 + 124*997^3 + ...
1645
+
1646
+ Shifting to the right divides by a power of `p`, but drops
1647
+ terms with negative valuation::
1648
+
1649
+ sage: a >> 3
1650
+ 124 + ...
1651
+
1652
+ If the parent is a field no truncation is performed::
1653
+
1654
+ sage: K(a) >> 3
1655
+ 964*997^-2 + 572*997^-1 + 124 + ...
1656
+
1657
+ A negative shift multiplies by that power of `p`::
1658
+
1659
+ sage: a >> -3
1660
+ 964*997^4 + 572*997^5 + 124*997^6 + ...
1661
+ """
1662
+ cdef long start
1663
+ cdef long shift = s
1664
+ if shift:
1665
+ if (<RelaxedElement>self)._parent.is_field():
1666
+ start = -maxordp
1667
+ else:
1668
+ start = shift
1669
+ return element_class_slice((<pAdicRelaxedElement>self)._parent, self, start, maxordp, shift)
1670
+ else:
1671
+ return self
1672
+
1673
+ def __lshift__(self, s):
1674
+ r"""
1675
+ Return this element multiplied by `\pi^s`.
1676
+
1677
+ If `s` is negative and this element does not lie in a field,
1678
+ digits may be truncated. See ``__rshift__`` for details.
1679
+
1680
+ EXAMPLES::
1681
+
1682
+ sage: R = ZpER(997)
1683
+ sage: K = R.fraction_field()
1684
+ sage: a = R(123456878908); a
1685
+ 964*997 + 572*997^2 + 124*997^3 + ...
1686
+
1687
+ Shifting to the right divides by a power of `p`, but drops
1688
+ terms with negative valuation::
1689
+
1690
+ sage: a << 2
1691
+ 964*997^3 + 572*997^4 + 124*997^5 + ...
1692
+
1693
+ A negative shift may result in a truncation when the base
1694
+ ring is not a field::
1695
+
1696
+ sage: a << -3
1697
+ 124 + ...
1698
+
1699
+ sage: K(a) << -3
1700
+ 964*997^-2 + 572*997^-1 + 124 + ...
1701
+ """
1702
+ return self.__rshift__(-s)
1703
+
1704
+ cpdef _add_(self, other):
1705
+ r"""
1706
+ Return the sum of this element with ``other``.
1707
+
1708
+ TESTS::
1709
+
1710
+ sage: R = ZpER(7, 10)
1711
+ sage: R(1/3) + R(1/6)
1712
+ 4 + 3*7 + 3*7^2 + 3*7^3 + 3*7^4 + 3*7^5 + 3*7^6 + 3*7^7 + 3*7^8 + 3*7^9 + ...
1713
+
1714
+ sage: R(1/3, 5) + R(1/6, 10)
1715
+ 4 + 3*7 + 3*7^2 + 3*7^3 + 3*7^4 + O(7^5)
1716
+ """
1717
+ if isinstance(self, RelaxedElement_zero):
1718
+ return other
1719
+ if isinstance(other, RelaxedElement_zero):
1720
+ return self
1721
+ return element_class_add(self._parent, self, <RelaxedElement>other)
1722
+
1723
+ cpdef _sub_(self, other):
1724
+ r"""
1725
+ Return the difference of this element and ``other``.
1726
+
1727
+ EXAMPLES::
1728
+
1729
+ sage: R = ZpER(7, 10)
1730
+ sage: R(1/3) - R(1/6)
1731
+ 6 + 5*7 + 5*7^2 + 5*7^3 + 5*7^4 + 5*7^5 + 5*7^6 + 5*7^7 + 5*7^8 + 5*7^9 + ...
1732
+
1733
+ sage: R(1/3, 5) - R(1/6, 10)
1734
+ 6 + 5*7 + 5*7^2 + 5*7^3 + 5*7^4 + O(7^5)
1735
+ """
1736
+ if self is other:
1737
+ ans = self._parent.zero()
1738
+ if self._precbound < maxordp:
1739
+ ans = element_class_bound(self._parent, ans, self._precbound)
1740
+ return ans
1741
+ if isinstance(other, RelaxedElement_zero):
1742
+ return self
1743
+ return element_class_sub(self._parent, self, <RelaxedElement>other)
1744
+
1745
+ cpdef _neg_(self):
1746
+ r"""
1747
+ Return the opposite of this element.
1748
+
1749
+ EXAMPLES::
1750
+
1751
+ sage: R = ZpER(7, 10)
1752
+ sage: -R(1)
1753
+ 6 + 6*7 + 6*7^2 + 6*7^3 + 6*7^4 + 6*7^5 + 6*7^6 + 6*7^7 + 6*7^8 + 6*7^9 + ...
1754
+
1755
+ sage: -R(1,5)
1756
+ 6 + 6*7 + 6*7^2 + 6*7^3 + 6*7^4 + O(7^5)
1757
+ """
1758
+ if isinstance(self, RelaxedElement_zero):
1759
+ return self
1760
+ return element_class_sub(self._parent, self._parent.zero(), self)
1761
+
1762
+ cpdef _mul_(self, other):
1763
+ r"""
1764
+ Return the product of this element with ``other``.
1765
+
1766
+ EXAMPLES::
1767
+
1768
+ sage: R = ZpER(7, 10)
1769
+ sage: R(1/2) * R(2/3)
1770
+ 5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + 4*7^5 + 4*7^6 + 4*7^7 + 4*7^8 + 4*7^9 + ...
1771
+
1772
+ sage: R(1/2, 5) * R(2/3, 10)
1773
+ 5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + O(7^5)
1774
+
1775
+ sage: R(49, 5) * R(14, 4)
1776
+ 2*7^3 + O(7^6)
1777
+ """
1778
+ if isinstance(self, RelaxedElement_zero) or isinstance(other, RelaxedElement_one):
1779
+ return self
1780
+ if isinstance(self, RelaxedElement_one) or isinstance(other, RelaxedElement_zero):
1781
+ return other
1782
+ return element_class_mul(self._parent, self, <RelaxedElement>other)
1783
+
1784
+ cpdef _div_(self, other):
1785
+ r"""
1786
+ Return the quotient if this element by ``other``.
1787
+
1788
+ .. NOTE::
1789
+
1790
+ The result always lives in the fraction field, even if ``other`` is
1791
+ a unit.
1792
+
1793
+ EXAMPLES::
1794
+
1795
+ sage: R = ZpER(7, 10)
1796
+ sage: x = R(2) / R(3)
1797
+ sage: x
1798
+ 3 + 2*7 + 2*7^2 + 2*7^3 + 2*7^4 + 2*7^5 + 2*7^6 + 2*7^7 + 2*7^8 + 2*7^9 + ...
1799
+ sage: x.parent()
1800
+ 7-adic Field handled with relaxed arithmetics
1801
+
1802
+ TESTS::
1803
+
1804
+ sage: x / R(0)
1805
+ Traceback (most recent call last):
1806
+ ...
1807
+ ZeroDivisionError: cannot divide by zero
1808
+
1809
+ sage: x / R(0, 10)
1810
+ Traceback (most recent call last):
1811
+ ...
1812
+ ZeroDivisionError: cannot divide by something indistinguishable from zero
1813
+
1814
+ sage: y = R.unknown()
1815
+ sage: x / y
1816
+ O(7^-Infinity)
1817
+ """
1818
+ if isinstance(other, RelaxedElement_one):
1819
+ if self.prime_pow.in_field:
1820
+ return self
1821
+ else:
1822
+ return element_class_bound(self._parent.fraction_field(), self)
1823
+ return element_class_div(self._parent.fraction_field(), self, <RelaxedElement>other, -maxordp)
1824
+
1825
+ def __invert__(self):
1826
+ r"""
1827
+ Return the multiplicative inverse of this element.
1828
+
1829
+ .. NOTE::
1830
+
1831
+ The result always lives in the fraction field, even if this element
1832
+ is a unit.
1833
+
1834
+ EXAMPLES::
1835
+
1836
+ sage: R = ZpER(7, 10)
1837
+ sage: x = ~R(3)
1838
+ sage: x
1839
+ 5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + 4*7^5 + 4*7^6 + 4*7^7 + 4*7^8 + 4*7^9 + ...
1840
+ sage: x.parent()
1841
+ 7-adic Field handled with relaxed arithmetics
1842
+
1843
+ TESTS::
1844
+
1845
+ sage: ~R(0)
1846
+ Traceback (most recent call last):
1847
+ ...
1848
+ ZeroDivisionError: cannot divide by zero
1849
+
1850
+ sage: ~R(0, 10)
1851
+ Traceback (most recent call last):
1852
+ ...
1853
+ ZeroDivisionError: cannot divide by something indistinguishable from zero
1854
+
1855
+ sage: y = R.unknown()
1856
+ sage: ~y
1857
+ O(7^-Infinity)
1858
+ """
1859
+ if isinstance(self, RelaxedElement_one):
1860
+ return self
1861
+ return element_class_div(self._parent.fraction_field(), self._parent.one(), self, -maxordp)
1862
+
1863
+ def inverse_of_unit(self):
1864
+ r"""
1865
+ Return the multiplicative inverse of this element if
1866
+ it is a unit.
1867
+
1868
+ EXAMPLES::
1869
+
1870
+ sage: R = ZpER(3, 5)
1871
+ sage: a = R(2)
1872
+ sage: b = a.inverse_of_unit()
1873
+ sage: b
1874
+ 2 + 3 + 3^2 + 3^3 + 3^4 + ...
1875
+
1876
+ A :exc:`ZeroDivisionError` is raised if an element has no inverse in the
1877
+ ring::
1878
+
1879
+ sage: R(3).inverse_of_unit()
1880
+ Traceback (most recent call last):
1881
+ ...
1882
+ ZeroDivisionError: denominator is not invertible
1883
+
1884
+ Unlike the usual inverse of an element, the result is in the same ring
1885
+ as this element and not in its fraction field (for fields this does of
1886
+ course not make any difference)::
1887
+
1888
+ sage: c = ~a; c
1889
+ 2 + 3 + 3^2 + 3^3 + 3^4 + ...
1890
+ sage: a.parent()
1891
+ 3-adic Ring handled with relaxed arithmetics
1892
+ sage: b.parent()
1893
+ 3-adic Ring handled with relaxed arithmetics
1894
+ sage: c.parent()
1895
+ 3-adic Field handled with relaxed arithmetics
1896
+
1897
+ This method also works for self-referent numbers
1898
+ (see :meth:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric.unknown`)::
1899
+
1900
+ sage: x = R.unknown(); x
1901
+ O(3^0)
1902
+ sage: x.inverse_of_unit()
1903
+ O(3^0)
1904
+ sage: x.set(1 + 3 * x.inverse_of_unit())
1905
+ True
1906
+ sage: x
1907
+ 1 + 3 + 2*3^2 + 3^3 + 3^4 + ...
1908
+
1909
+ Actually, in many cases, it is preferable to use it than an actual
1910
+ division. Indeed, compare::
1911
+
1912
+ sage: y = R.unknown()
1913
+ sage: y.set(1 + 3/y)
1914
+ Traceback (most recent call last):
1915
+ ...
1916
+ RecursionError: definition looks circular
1917
+ """
1918
+ if isinstance(self, RelaxedElement_one):
1919
+ return self
1920
+ if self.prime_pow.in_field:
1921
+ return element_class_div(self._parent, self._parent.one(), self, -maxordp)
1922
+ else:
1923
+ return element_class_div(self._parent, self._parent.one(), self, 0)
1924
+
1925
+ def sqrt(self):
1926
+ r"""
1927
+ Return the square root of this element.
1928
+
1929
+ EXAMPLES::
1930
+
1931
+ sage: R = ZpER(7, 10)
1932
+ sage: x = R(8)
1933
+ sage: x.sqrt()
1934
+ 1 + 4*7 + 2*7^2 + 7^3 + 3*7^4 + 2*7^5 + 4*7^6 + 2*7^7 + 5*7^8 + ...
1935
+
1936
+ When the element is not a square, an error is raised::
1937
+
1938
+ sage: x = R(10)
1939
+ sage: x.sqrt()
1940
+ Traceback (most recent call last):
1941
+ ...
1942
+ ValueError: not a square
1943
+
1944
+ For bounded elements, the precision is tracked::
1945
+
1946
+ sage: x = R(8, 5); x
1947
+ 1 + 7 + O(7^5)
1948
+ sage: x.sqrt()
1949
+ 1 + 4*7 + 2*7^2 + 7^3 + 3*7^4 + O(7^5)
1950
+
1951
+ Note that, when `p = 2`, a digit of precision is lost::
1952
+
1953
+ sage: S = ZpER(2)
1954
+ sage: x = S(17, 5)
1955
+ sage: x.sqrt()
1956
+ 1 + 2^3 + O(2^4)
1957
+
1958
+ This method also work for self-referent numbers
1959
+ (see :meth:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric.unknown`)::
1960
+
1961
+ sage: x = R.unknown(); x
1962
+ O(7^0)
1963
+ sage: x.sqrt()
1964
+ O(7^0)
1965
+ sage: x.set(1 + 7*sqrt(x))
1966
+ True
1967
+ sage: x
1968
+ 1 + 7 + 4*7^2 + 4*7^3 + 2*7^4 + 3*7^8 + 3*7^9 + ...
1969
+
1970
+ TESTS::
1971
+
1972
+ sage: for p in [ 7, 11, 1009 ]:
1973
+ ....: R = ZpER(p)
1974
+ ....: x = 1 + p * R.random_element()
1975
+ ....: y = x.sqrt()
1976
+ ....: assert(x == y^2)
1977
+ """
1978
+ return element_class_sqrt(self._parent, self)
1979
+
1980
+ def _test_pickling(self, **options):
1981
+ r"""
1982
+ Check that this object can be pickled and unpickled properly.
1983
+
1984
+ TESTS::
1985
+
1986
+ sage: R = ZpER(7)
1987
+ sage: x = R.random_element()
1988
+ sage: x._test_pickling()
1989
+
1990
+ sage: x[:20]._test_pickling()
1991
+
1992
+ .. SEEALSO::
1993
+
1994
+ :func:`dumps`, :func:`loads`
1995
+ """
1996
+ tester = self._tester(**options)
1997
+ from sage.misc.persist import loads, dumps
1998
+ if self._precbound >= maxordp:
1999
+ tester.assertEqual(loads(dumps(self)), self.at_precision_relative())
2000
+ else:
2001
+ tester.assertEqual(loads(dumps(self)), self)
2002
+
2003
+ def _test_nonzero_equal(self, **options):
2004
+ r"""
2005
+ Test that ``.__bool__()`` behave consistently with `` == 0``.
2006
+
2007
+ TESTS::
2008
+
2009
+ sage: R = ZpER(5)
2010
+ sage: #R(0)._test_nonzero_equal()
2011
+ sage: #R(5^30)._test_nonzero_equal()
2012
+ sage: #R.unknown()._test_nonzero_equal()
2013
+ """
2014
+ tester = self._tester(**options)
2015
+ try:
2016
+ tester.assertEqual(self != self.parent().zero(), bool(self))
2017
+ tester.assertEqual(self == self.parent().zero(), not self)
2018
+ except PrecisionError:
2019
+ pass
2020
+
2021
+
2022
+ cdef class RelaxedElement_abandon(RelaxedElement):
2023
+ r"""
2024
+ A special class for relaxed `p`-adic with all digits unknown.
2025
+
2026
+ This class is used for setting temporary definition of
2027
+ some self-referent numbers.
2028
+ """
2029
+ def __init__(self):
2030
+ r"""
2031
+ Initialize this element.
2032
+
2033
+ TESTS::
2034
+
2035
+ sage: from sage.rings.padics.padic_relaxed_element import RelaxedElement_abandon
2036
+ sage: x = RelaxedElement_abandon()
2037
+ sage: x.valuation()
2038
+ Traceback (most recent call last):
2039
+ ...
2040
+ PrecisionError: no lower bound on the valuation is known
2041
+
2042
+ sage: x[0]
2043
+ Traceback (most recent call last):
2044
+ ...
2045
+ PrecisionError: computation has been abandoned; try to increase precision
2046
+ """
2047
+ self._valuation = -maxordp
2048
+
2049
+ cdef int _next_c(self) noexcept:
2050
+ r"""
2051
+ Compute the next digit of this element.
2052
+
2053
+ Here, we just abandon the computation.
2054
+ """
2055
+ return ERROR_ABANDON
2056
+
2057
+ cdef relaxedelement_abandon = RelaxedElement_abandon()
2058
+
2059
+
2060
+ cdef class RelaxedElementWithDigits(RelaxedElement):
2061
+ r"""
2062
+ A generic class for relaxed `p`-adic elements that stores
2063
+ the sequence of its digits.
2064
+ """
2065
+ def __cinit__(self):
2066
+ r"""
2067
+ Allocate memory for storing digits.
2068
+ """
2069
+ element_init(self._digits)
2070
+
2071
+ def __dealloc__(self):
2072
+ r"""
2073
+ Deallocate memory used for digits.
2074
+ """
2075
+ element_clear(self._digits)
2076
+
2077
+ cdef cdigit_ptr _getdigit_relative(self, long i) noexcept:
2078
+ r"""
2079
+ Return a pointer on the `i`-th digit of this number
2080
+ in relative precision.
2081
+ """
2082
+ return element_get_digit(self._digits, i)
2083
+
2084
+ cdef cdigit_ptr _getdigit_absolute(self, long i) noexcept:
2085
+ r"""
2086
+ Return a pointer on the `i`-th digit of this number
2087
+ in absolute precision.
2088
+ """
2089
+ return element_get_digit(self._digits, i - self._valuation)
2090
+
2091
+ cdef void _getslice_relative(self, celement slice, long start, long length) noexcept:
2092
+ r"""
2093
+ Select a slice of the sequence of digits of this element.
2094
+
2095
+ INPUT:
2096
+
2097
+ - ``slice`` -- a ``celement`` to store the slice
2098
+
2099
+ - ``start`` -- integer; the start position of the slice
2100
+
2101
+ - ``length`` -- integer; the length of the slice
2102
+
2103
+ .. NOTE::
2104
+
2105
+ This function only sets up a pointer to the requested slice
2106
+ (the slice is not copied). Hence any future modification
2107
+ of the slice will modify this element as well.
2108
+ """
2109
+ element_get_slice(slice, self._digits, start, length)
2110
+
2111
+
2112
+ # Assignment
2113
+ ############
2114
+
2115
+ # Zero
2116
+
2117
+ cdef class RelaxedElement_zero(RelaxedElement):
2118
+ r"""
2119
+ A class for representation a relaxed `p`-adic number which is
2120
+ exactly zero.
2121
+
2122
+ TESTS::
2123
+
2124
+ sage: R = ZpER(7)
2125
+ sage: a = R.zero()
2126
+ sage: TestSuite(a).run()
2127
+ """
2128
+ def __init__(self, parent):
2129
+ r"""
2130
+ Initialize this element.
2131
+
2132
+ INPUT:
2133
+
2134
+ - ``parent`` -- the parent of this element
2135
+
2136
+ TESTS::
2137
+
2138
+ sage: R = ZpER(5)
2139
+ sage: x = R(0) # indirect doctest
2140
+ sage: x
2141
+ 0
2142
+
2143
+ sage: type(x)
2144
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_zero'>
2145
+ """
2146
+ RelaxedElement.__init__(self, parent)
2147
+ self._valuation = maxordp
2148
+
2149
+ def __reduce__(self):
2150
+ r"""
2151
+ Return a tuple of a function and data that can be used to unpickle this
2152
+ element.
2153
+
2154
+ TESTS::
2155
+
2156
+ sage: a = ZpER(5)(0)
2157
+ sage: type(a)
2158
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_zero'>
2159
+ sage: loads(dumps(a)) == a # indirect doctest
2160
+ True
2161
+ """
2162
+ return self.__class__, (self._parent,)
2163
+
2164
+ cdef cdigit_ptr _getdigit_relative(self, long i) noexcept:
2165
+ r"""
2166
+ Return a pointer on the `i`-th digit of this number
2167
+ in relative precision.
2168
+ """
2169
+ return digit_zero
2170
+
2171
+ cdef cdigit_ptr _getdigit_absolute(self, long i) noexcept:
2172
+ r"""
2173
+ Return a pointer on the `i`-th digit of this number
2174
+ in absolute precision.
2175
+ """
2176
+ return digit_zero
2177
+
2178
+ cdef void _getslice_relative(self, celement slice, long start, long length) noexcept:
2179
+ r"""
2180
+ Select a slice of the sequence of digits of this element.
2181
+
2182
+ INPUT:
2183
+
2184
+ - ``slice`` -- a ``celement`` to store the slice
2185
+
2186
+ - ``start`` -- integer; the start position of the slice
2187
+
2188
+ - ``length`` -- integer; the length of the slice
2189
+ """
2190
+ element_init(slice)
2191
+
2192
+ cdef int _jump_c(self, long prec) noexcept:
2193
+ r"""
2194
+ Compute the digits of this number until the absolute precision ``prec``.
2195
+
2196
+ INPUT:
2197
+
2198
+ - ``prec`` -- integer
2199
+
2200
+ OUTPUT:
2201
+
2202
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2203
+ """
2204
+ return 0
2205
+
2206
+ cdef int _next_c(self) noexcept:
2207
+ r"""
2208
+ Compute the next digit of this number.
2209
+
2210
+ OUTPUT:
2211
+
2212
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2213
+ """
2214
+ return 0
2215
+
2216
+
2217
+ # One
2218
+
2219
+ cdef class RelaxedElement_one(RelaxedElementWithDigits):
2220
+ r"""
2221
+ A class for representation a relaxed `p`-adic number which is
2222
+ exactly one.
2223
+
2224
+ TESTS::
2225
+
2226
+ sage: R = ZpER(7)
2227
+ sage: a = R.one()
2228
+ sage: TestSuite(a).run()
2229
+ """
2230
+ def __init__(self, parent):
2231
+ r"""
2232
+ Initialize this element.
2233
+
2234
+ INPUT:
2235
+
2236
+ - ``parent`` -- the parent of this element
2237
+
2238
+ TESTS::
2239
+
2240
+ sage: R = ZpER(5)
2241
+ sage: x = R(1) # indirect doctest
2242
+ sage: x
2243
+ 1 + ...
2244
+
2245
+ sage: type(x)
2246
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_one'>
2247
+ """
2248
+ RelaxedElement.__init__(self, parent)
2249
+ element_set_digit_ui(self._digits, 1, 0)
2250
+ self._precrel = 1
2251
+
2252
+ def __reduce__(self):
2253
+ r"""
2254
+ Return a tuple of a function and data that can be used to unpickle this
2255
+ element.
2256
+
2257
+ TESTS::
2258
+
2259
+ sage: a = ZpER(5)(1)
2260
+ sage: type(a)
2261
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_one'>
2262
+ sage: a[:20] == loads(dumps(a)) # indirect doctest
2263
+ True
2264
+ """
2265
+ return self.__class__, (self._parent,)
2266
+
2267
+ cdef int _jump_c(self, long prec) noexcept:
2268
+ r"""
2269
+ Compute the digits of this number until the absolute precision ``prec``.
2270
+
2271
+ INPUT:
2272
+
2273
+ - ``prec`` -- integer
2274
+
2275
+ OUTPUT:
2276
+
2277
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2278
+ """
2279
+ if prec > self._precrel:
2280
+ self._precrel = prec
2281
+ return 0
2282
+
2283
+ cdef int _next_c(self) noexcept:
2284
+ r"""
2285
+ Compute the next digit of this number.
2286
+
2287
+ OUTPUT:
2288
+
2289
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2290
+ """
2291
+ self._precrel += 1
2292
+ return 0
2293
+
2294
+
2295
+ # Bound
2296
+
2297
+ cdef class RelaxedElement_bound(RelaxedElement):
2298
+ r"""
2299
+ A class for `p`-adic relaxed elements which are defined by bounding the
2300
+ precision of another `p`-adic relaxed element.
2301
+
2302
+ TESTS::
2303
+
2304
+ sage: R = ZpER(5)
2305
+ sage: x = R.random_element()
2306
+ sage: y = x[:20]
2307
+ sage: TestSuite(y).run()
2308
+ """
2309
+ def __init__(self, parent, RelaxedElement x, precbound=None):
2310
+ r"""
2311
+ Initialize this element.
2312
+
2313
+ INPUT:
2314
+
2315
+ - ``parent`` -- the parent of this element
2316
+
2317
+ - ``x`` -- a relaxed `p`-adics, the element to bound
2318
+
2319
+ - ``precbound`` -- integer or ``None`` (default: ``None``);
2320
+ the bound on the precision
2321
+
2322
+ .. NOTE::
2323
+
2324
+ The digits of ``x`` are not copied!
2325
+
2326
+ TESTS::
2327
+
2328
+ sage: R = ZpER(5)
2329
+ sage: x = R(20/21)
2330
+ sage: y = x.add_bigoh(20)
2331
+ sage: type(y)
2332
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_bound'>
2333
+ """
2334
+ RelaxedElement.__init__(self, parent)
2335
+ self._x = x
2336
+ if precbound is None:
2337
+ self._precbound = x._precbound
2338
+ else:
2339
+ self._precbound = min(x._precbound, precbound)
2340
+ self._valuation = min(x._valuation, self._precbound)
2341
+ self._precrel = min(x._precrel, self._precbound - self._valuation)
2342
+ self._init_jump()
2343
+
2344
+ def __reduce__(self):
2345
+ r"""
2346
+ Return a tuple of a function and data that can be used to unpickle this
2347
+ element.
2348
+
2349
+ TESTS::
2350
+
2351
+ sage: a = ZpER(5)(1).add_bigoh(20)
2352
+ sage: type(a)
2353
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_bound'>
2354
+ sage: a == loads(dumps(a)) # indirect doctest
2355
+ True
2356
+ """
2357
+ return self.__class__, (self._parent, self._x, self._precbound)
2358
+
2359
+ cdef cdigit_ptr _getdigit_relative(self, long i) noexcept:
2360
+ r"""
2361
+ Return a pointer on the `i`-th digit of this number
2362
+ in relative precision.
2363
+ """
2364
+ return self._x._getdigit_relative(i)
2365
+
2366
+ cdef cdigit_ptr _getdigit_absolute(self, long i) noexcept:
2367
+ r"""
2368
+ Return a pointer on the `i`-th digit of this number
2369
+ in absolute precision.
2370
+ """
2371
+ return self._x._getdigit_absolute(i)
2372
+
2373
+ cdef void _getslice_relative(self, celement slice, long start, long length) noexcept:
2374
+ r"""
2375
+ Select a slice of the digits of this number.
2376
+
2377
+ INPUT:
2378
+
2379
+ - ``slice`` -- a ``celement`` to store the slice
2380
+
2381
+ - ``start`` -- positive integer; the starting position of the slice
2382
+ in relative precision
2383
+
2384
+ - ``length`` -- positive integer; the length of the slice
2385
+
2386
+ .. NOTE::
2387
+
2388
+ This methods only sets up a pointer to the requested slice
2389
+ (the slice is not copied). Hence any future modification
2390
+ of the slice ``slice`` will affect this number.
2391
+ """
2392
+ self._x._getslice_relative(slice, start, length)
2393
+
2394
+ cdef int _jump_c(self, long prec) noexcept:
2395
+ r"""
2396
+ Jump to the absolute precision ``prec``.
2397
+
2398
+ INPUT:
2399
+
2400
+ - ``prec`` -- integer
2401
+
2402
+ OUTPUT:
2403
+
2404
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2405
+ """
2406
+ cdef RelaxedElement x = self._x
2407
+ cdef int error
2408
+ if prec > self._precbound:
2409
+ error = ERROR_PRECISION | x._jump_c(self._precbound)
2410
+ else:
2411
+ error = x._jump_c(prec)
2412
+ self._precbound = min(self._precbound, x._precbound)
2413
+ self._valuation = min(x._valuation, self._precbound)
2414
+ self._precrel = min(x._precrel, self._precbound - self._valuation)
2415
+ return error
2416
+
2417
+ cdef int _next_c(self) noexcept:
2418
+ r"""
2419
+ Jump to the next digit.
2420
+
2421
+ OUTPUT:
2422
+
2423
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2424
+ """
2425
+ cdef RelaxedElement x = self._x
2426
+ if self._valuation + self._precrel >= self._precbound:
2427
+ return ERROR_PRECISION
2428
+ cdef int error = x._next_c()
2429
+ self._precbound = min(self._precbound, x._precbound)
2430
+ self._valuation = min(x._valuation, self._precbound)
2431
+ self._precrel = min(x._precrel, self._precbound - self._valuation)
2432
+ return error
2433
+
2434
+
2435
+ # Value
2436
+
2437
+ cdef class RelaxedElement_value(RelaxedElementWithDigits):
2438
+ r"""
2439
+ A class for relaxed `p`-adics defined by the datum of a value in
2440
+ the exact subring.
2441
+
2442
+ TESTS::
2443
+
2444
+ sage: R = ZpER(5)
2445
+ sage: x = R(2)
2446
+ sage: TestSuite(x).run()
2447
+ """
2448
+ def __init__(self, parent, value, long shift=0, precbound=None):
2449
+ r"""
2450
+ Initialize this element.
2451
+
2452
+ INPUT:
2453
+
2454
+ - ``parent`` -- the parent of this element
2455
+
2456
+ - ``value`` -- the value in the exact subring
2457
+
2458
+ - ``shift`` -- integer (default: `0`); the position at which
2459
+ the given value is written
2460
+
2461
+ - ``precbound`` -- integer or ``None`` (default: ``None``);
2462
+ the bound on the precision
2463
+
2464
+ TESTS::
2465
+
2466
+ sage: R = ZpER(5)
2467
+ sage: x = R(2)
2468
+ sage: type(x)
2469
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_value'>
2470
+
2471
+ sage: y = R(2, 10)
2472
+ sage: type(y)
2473
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_value'>
2474
+ """
2475
+ RelaxedElement.__init__(self, parent)
2476
+ element_set_digit_sage(self._digits, value, 0)
2477
+ self._value = value
2478
+ self._shift = shift
2479
+ self._valuation = -shift
2480
+ if precbound is not None and precbound is not Infinity:
2481
+ self._precbound = min(maxordp, precbound)
2482
+ self._valuebound = maxordp
2483
+ self._init_jump()
2484
+
2485
+ def __reduce__(self):
2486
+ r"""
2487
+ Return a tuple of a function and data that can be used to unpickle this
2488
+ element.
2489
+
2490
+ TESTS::
2491
+
2492
+ sage: a = ZpER(5)(2, 20)
2493
+ sage: type(a)
2494
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_value'>
2495
+ sage: a == loads(dumps(a)) # indirect doctest
2496
+ True
2497
+ """
2498
+ return self.__class__, (self._parent, self._value, self._shift, self._precbound)
2499
+
2500
+ cdef int _jump_c(self, long prec) noexcept:
2501
+ r"""
2502
+ Compute the digits of this number until the absolute precision ``prec``.
2503
+
2504
+ INPUT:
2505
+
2506
+ - ``prec`` -- integer
2507
+
2508
+ OUTPUT:
2509
+
2510
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2511
+ """
2512
+ if self._valuebound >= maxordp:
2513
+ return RelaxedElement._jump_c(self, prec)
2514
+ if (self._precbound is not None) and (prec > self._precbound):
2515
+ self._precrel = self._precbound - self._valuation
2516
+ return ERROR_PRECISION
2517
+ cdef long precrel = min(prec, maxordp) - self._valuation
2518
+ if precrel > self._precrel:
2519
+ self._precrel = precrel
2520
+ if prec >= maxordp:
2521
+ return ERROR_OVERFLOW
2522
+ return 0
2523
+
2524
+ cdef int _next_c(self) noexcept:
2525
+ r"""
2526
+ Compute the next digit of this number.
2527
+
2528
+ OUTPUT:
2529
+
2530
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2531
+
2532
+ .. NOTE::
2533
+
2534
+ The algorithm is not optimal (quadratic in the precision),
2535
+ but it sounds okay...
2536
+ """
2537
+ if (self._precbound is not None) and (self._valuation + self._precrel >= self._precbound):
2538
+ return ERROR_PRECISION
2539
+ element_reduce_digit(self._digits, self._precrel, self.prime_pow)
2540
+ if self._precrel == 0 and digit_is_zero(self._getdigit_relative(0)):
2541
+ self._valuation += 1
2542
+ element_shift_right(self._digits)
2543
+ else:
2544
+ self._precrel += 1
2545
+ if digit_is_zero(self._getdigit_relative(self._precrel)):
2546
+ self._valuebound = self._valuation + self._precrel
2547
+ if self._precrel == 0:
2548
+ self._valuation = self._precbound
2549
+ elif self._precbound < maxordp:
2550
+ self._precrel = self._precbound - self._valuation
2551
+ return 0
2552
+
2553
+
2554
+ # Random
2555
+
2556
+ cdef class RelaxedElement_random(RelaxedElementWithDigits):
2557
+ r"""
2558
+ A class for random relaxed `p`-adic numbers.
2559
+
2560
+ TESTS::
2561
+
2562
+ sage: R = ZpER(5)
2563
+ sage: x = R.random_element()
2564
+ sage: TestSuite(x).run()
2565
+ """
2566
+ def __init__(self, parent, valuation, precbound=None, seed=None):
2567
+ r"""
2568
+ Initialize this element.
2569
+
2570
+ INPUT:
2571
+
2572
+ - ``parent`` -- the parent of this element
2573
+
2574
+ - ``valuation`` -- integer or ``None``; the position from which
2575
+ random digits are picked;
2576
+ if ``None``, it is randomly chosen if the parent is a field and
2577
+ set to `0` otherwise
2578
+
2579
+ - ``precbound`` -- integer or ``None`` (default: ``None``);
2580
+ the bound on the precision
2581
+
2582
+ - ``seed`` -- integer or ``None`` (default: ``None``); the
2583
+ seed of the random generator
2584
+
2585
+ .. NOTE::
2586
+
2587
+ The argument ``valuation`` can be different from the real
2588
+ valuation of this number since the first randomly picked
2589
+ digit could vanish.
2590
+
2591
+ TESTS::
2592
+
2593
+ sage: R = ZpER(7)
2594
+ sage: x = R.random_element()
2595
+ sage: type(x)
2596
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_random'>
2597
+ """
2598
+ RelaxedElement.__init__(self, parent)
2599
+ if seed is None:
2600
+ self._seed = randint(0, 2*maxordp)
2601
+ else:
2602
+ self._seed = seed
2603
+ digit_random_init(self._generator, self._seed)
2604
+ if valuation is None:
2605
+ self._initialvaluation = ZZ.random_element()
2606
+ else:
2607
+ self._initialvaluation = valuation
2608
+ self._valuation = self._initialvaluation
2609
+ if precbound is not None:
2610
+ self._precbound = min(maxordp, precbound)
2611
+ self._init_jump()
2612
+
2613
+ def __reduce__(self):
2614
+ r"""
2615
+ Return a tuple of a function and data that can be used to unpickle this
2616
+ element.
2617
+
2618
+ TESTS::
2619
+
2620
+ sage: R = ZpER(5, print_mode='digits')
2621
+ sage: a = R.random_element()
2622
+ sage: a # random
2623
+ ...32220241412003314311
2624
+
2625
+ sage: b = loads(dumps(a))
2626
+ sage: b # random
2627
+ ...32220241412003314311
2628
+
2629
+ It is guaranteed that `a` and `b` are equal at any precision::
2630
+
2631
+ sage: a[:30] # random
2632
+ ...?343214211432220241412003314311
2633
+ sage: b[:30] # random
2634
+ ...?343214211432220241412003314311
2635
+
2636
+ sage: a == b
2637
+ True
2638
+ """
2639
+ return self.__class__, (self._parent, self._initialvaluation, self._precbound, self._seed)
2640
+
2641
+ cdef int _next_c(self) noexcept:
2642
+ r"""
2643
+ Generate the next digit of this number at random.
2644
+
2645
+ OUTPUT:
2646
+
2647
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2648
+ """
2649
+ cdef cdigit r
2650
+ digit_init(r)
2651
+ digit_random(r, self.prime_pow, self._generator)
2652
+ if self._precrel == 0 and digit_is_zero(r):
2653
+ self._valuation += 1
2654
+ else:
2655
+ element_set_digit(self._digits, r, self._precrel)
2656
+ self._precrel += 1
2657
+ digit_clear(r)
2658
+ return 0
2659
+
2660
+
2661
+ # Operations
2662
+ ############
2663
+
2664
+ # Slice and shift
2665
+
2666
+ cdef class RelaxedElement_slice(RelaxedElement):
2667
+ r"""
2668
+ A class for relaxed `p`-adic numbers defined as slices.
2669
+
2670
+ TESTS::
2671
+
2672
+ sage: R = ZpER(5)
2673
+ sage: x = R(20/21)
2674
+ sage: y = x.slice(3, 6)
2675
+ sage: TestSuite(y).run()
2676
+ """
2677
+ def __init__(self, parent, RelaxedElement x, long start, long stop, long shift):
2678
+ r"""
2679
+ Initialize this element.
2680
+
2681
+ INPUT:
2682
+
2683
+ - ``parent`` -- the parent of this element
2684
+
2685
+ - ``x`` -- a relaxed `p`-adic element, the element from which the
2686
+ slice is extracted
2687
+
2688
+ - ``start`` -- integer; the position of the first digit of `x`
2689
+ in the slice
2690
+
2691
+ - ``stop`` -- integer; the position of the first digit of `x`
2692
+ after the slice
2693
+
2694
+ - ``shift`` -- integer such that ``self[i] = x[i+shift]``
2695
+
2696
+ .. NOTE::
2697
+
2698
+ The digits of ``x`` are not copied!
2699
+
2700
+ TESTS::
2701
+
2702
+ sage: R = ZpER(5)
2703
+ sage: x = R(20/21)
2704
+ sage: y = x.slice(3, 6)
2705
+ sage: type(y)
2706
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_slice'>
2707
+ """
2708
+ RelaxedElement.__init__(self, parent)
2709
+ self._x = x
2710
+ self._start = start
2711
+ self._shift = shift
2712
+ self._valuation = max(x._valuation, start) - shift
2713
+ self._precrel = min(x._precrel + x._valuation, stop) - self._valuation - shift
2714
+ if x._precbound < stop:
2715
+ self._precbound = min(maxordp, x._precbound - shift)
2716
+ self._stop = stop
2717
+ if self._precrel < 0:
2718
+ self._precrel = 0
2719
+ while self._precrel > 0 and digit_is_zero(self._getdigit_relative(0)):
2720
+ self._precrel -= 1
2721
+ self._valuation += 1
2722
+ self._init_jump()
2723
+
2724
+ def __reduce__(self):
2725
+ r"""
2726
+ Return a tuple of a function and data that can be used to unpickle this
2727
+ element.
2728
+
2729
+ TESTS::
2730
+
2731
+ sage: R = ZpER(5, print_mode='digits')
2732
+ sage: x = R(20/21)
2733
+ sage: y = x.slice(3, 6)
2734
+ sage: y == loads(dumps(y)) # indirect doctest
2735
+ True
2736
+ """
2737
+ return self.__class__, (self._parent, self._x, self._start, self._stop, self._shift)
2738
+
2739
+ cdef cdigit_ptr _getdigit_relative(self, long i) noexcept:
2740
+ r"""
2741
+ Return a pointer on the `i`-th digit of this number
2742
+ in relative precision.
2743
+ """
2744
+ return self._getdigit_absolute(i + self._valuation)
2745
+
2746
+ cdef cdigit_ptr _getdigit_absolute(self, long i) noexcept:
2747
+ r"""
2748
+ Return a pointer on the `i`-th digit of this number
2749
+ in absolute precision.
2750
+ """
2751
+ cdef long j = i + self._shift
2752
+ if j < self._start or j >= self._stop:
2753
+ return digit_zero
2754
+ else:
2755
+ return self._x._getdigit_absolute(j)
2756
+
2757
+ cdef void _getslice_relative(self, celement slice, long start, long length) noexcept:
2758
+ r"""
2759
+ Select a slice of the sequence of digits of this element.
2760
+
2761
+ INPUT:
2762
+
2763
+ - ``slice`` -- a ``celement`` to store the slice
2764
+
2765
+ - ``start`` -- integer; the start position of the slice
2766
+
2767
+ - ``length`` -- integer; the length of the slice
2768
+
2769
+ .. NOTE::
2770
+
2771
+ This function only sets up a pointer to the requested slice
2772
+ (the slice is not copied). Hence any future modification
2773
+ of the slice will modify this element as well.
2774
+ """
2775
+ cdef RelaxedElement x = self._x
2776
+ cdef long s = start + self._valuation + self._shift
2777
+ cdef long start_absolute = max(self._start, s)
2778
+ cdef long stop_absolute = min(self._stop, s + length)
2779
+ x._getslice_relative(slice, start_absolute - x._valuation, stop_absolute - start_absolute)
2780
+
2781
+ cdef int _jump_c(self, long prec) noexcept:
2782
+ r"""
2783
+ Jump to the absolute precision ``prec``.
2784
+
2785
+ INPUT:
2786
+
2787
+ - ``prec`` -- integer
2788
+
2789
+ OUTPUT:
2790
+
2791
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2792
+ """
2793
+ cdef RelaxedElement x = self._x
2794
+ cdef int error = 0
2795
+ cdef long pr
2796
+ if prec <= self._valuation + self._precrel:
2797
+ return 0
2798
+ if prec > self._precbound:
2799
+ prec = self._precbound
2800
+ error = ERROR_PRECISION
2801
+ cdef int errorx = x._jump_c(min(prec + self._shift, self._stop))
2802
+ pr = max(self._valuation, x._valuation + x._precrel - self._shift)
2803
+ if self._precrel == 0:
2804
+ while self._valuation < pr and digit_is_zero(self._getdigit_relative(0)):
2805
+ self._valuation += 1
2806
+ if errorx:
2807
+ self._precrel = pr - self._valuation
2808
+ return errorx
2809
+ else:
2810
+ self._precrel = prec - self._valuation
2811
+ return error
2812
+
2813
+ cdef int _next_c(self) noexcept:
2814
+ r"""
2815
+ Jump to the next digit.
2816
+
2817
+ OUTPUT:
2818
+
2819
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2820
+ """
2821
+ cdef int error
2822
+ cdef long n = self._precrel + self._valuation
2823
+ n += self._shift
2824
+ if n <= self._stop:
2825
+ error = self._x._jump_c(n+1)
2826
+ if error:
2827
+ return error
2828
+ if self._precrel == 0 and (n > self._stop or digit_is_zero(self._getdigit_relative(0))):
2829
+ self._valuation += 1
2830
+ else:
2831
+ self._precrel += 1
2832
+ return 0
2833
+
2834
+
2835
+ # Addition
2836
+
2837
+ cdef class RelaxedElement_add(RelaxedElementWithDigits):
2838
+ r"""
2839
+ A class for relaxed `p`-adic numbers defined as sums.
2840
+
2841
+ TESTS::
2842
+
2843
+ sage: R = ZpER(11)
2844
+ sage: x = R.random_element() + R.random_element()
2845
+ sage: TestSuite(x).run()
2846
+ """
2847
+ def __init__(self, parent, RelaxedElement x, RelaxedElement y):
2848
+ r"""
2849
+ Initialize this element.
2850
+
2851
+ INPUT:
2852
+
2853
+ - ``parent`` -- the parent of this element
2854
+
2855
+ - ``x`` -- a relaxed `p`-adic element, the first summand
2856
+
2857
+ - ``y`` -- a relaxed `p`-adic element, the second summand
2858
+
2859
+ TESTS::
2860
+
2861
+ sage: R = ZpER(11)
2862
+ sage: x = R.random_element() + R.random_element()
2863
+ sage: type(x)
2864
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_add'>
2865
+ """
2866
+ RelaxedElement.__init__(self, parent)
2867
+ self._x = x
2868
+ self._y = y
2869
+ cdef halt = self._parent.default_prec()
2870
+ self._valuation = min(x.valuation_c(0), y.valuation_c(0))
2871
+ self._precbound = min(x._precbound, y._precbound)
2872
+ self._init_jump()
2873
+
2874
+ def __reduce__(self):
2875
+ r"""
2876
+ Return a tuple of a function and data that can be used to unpickle this
2877
+ element.
2878
+
2879
+ TESTS::
2880
+
2881
+ sage: R = ZpER(5)
2882
+ sage: x = R.random_element() + R.random_element()
2883
+ sage: x == loads(dumps(x)) # indirect doctest
2884
+ True
2885
+ """
2886
+ return self.__class__, (self._parent, self._x, self._y)
2887
+
2888
+ cdef int _jump_c(self, long prec) noexcept:
2889
+ r"""
2890
+ Compute the digits of this number until the absolute precision ``prec``.
2891
+
2892
+ INPUT:
2893
+
2894
+ - ``prec`` -- integer
2895
+
2896
+ OUTPUT:
2897
+
2898
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2899
+ """
2900
+ # We reimplement _jump_c for better performance
2901
+ cdef long n = self._valuation + self._precrel
2902
+ cdef RelaxedElement x = self._x
2903
+ cdef RelaxedElement y = self._y
2904
+ cdef int error = x._jump_c(prec) | y._jump_c(prec)
2905
+ prec = min(prec, x._valuation + x._precrel, y._valuation + y._precrel)
2906
+ while n < prec:
2907
+ element_iadd_digit(self._digits, x._getdigit_absolute(n), self._precrel)
2908
+ element_iadd_digit(self._digits, y._getdigit_absolute(n), self._precrel)
2909
+ element_reducesmall_digit(self._digits, self._precrel, self.prime_pow)
2910
+ if self._precrel == 0 and digit_is_zero(self._getdigit_relative(0)):
2911
+ self._valuation += 1
2912
+ element_shift_right(self._digits)
2913
+ else:
2914
+ self._precrel += 1
2915
+ n += 1
2916
+ return error
2917
+
2918
+ cdef int _next_c(self) noexcept:
2919
+ r"""
2920
+ Compute the next digit of this number.
2921
+
2922
+ OUTPUT:
2923
+
2924
+ An error code (see :meth:`RelaxedElement._next_c` for details).
2925
+ """
2926
+ cdef long n = self._valuation + self._precrel
2927
+ cdef RelaxedElement x = self._x
2928
+ cdef RelaxedElement y = self._y
2929
+ cdef int error = x._jump_c(n+1) | y._jump_c(n+1)
2930
+ if error:
2931
+ return error
2932
+ element_iadd_digit(self._digits, x._getdigit_absolute(n), self._precrel)
2933
+ element_iadd_digit(self._digits, y._getdigit_absolute(n), self._precrel)
2934
+ element_reducesmall_digit(self._digits, self._precrel, self.prime_pow)
2935
+ if self._precrel == 0 and digit_is_zero(self._getdigit_relative(0)):
2936
+ self._valuation += 1
2937
+ element_shift_right(self._digits)
2938
+ else:
2939
+ self._precrel += 1
2940
+ return 0
2941
+
2942
+
2943
+ # Subtraction
2944
+
2945
+ cdef class RelaxedElement_sub(RelaxedElementWithDigits):
2946
+ r"""
2947
+ A class for relaxed `p`-adic numbers defined as differences.
2948
+
2949
+ TESTS::
2950
+
2951
+ sage: R = ZpER(11)
2952
+ sage: x = R.random_element() - R.random_element()
2953
+ sage: TestSuite(x).run()
2954
+ """
2955
+ def __init__(self, parent, RelaxedElement x, RelaxedElement y):
2956
+ r"""
2957
+ Initialize this element.
2958
+
2959
+ INPUT:
2960
+
2961
+ - ``parent`` -- the parent of this element
2962
+
2963
+ - ``x`` -- a relaxed `p`-adic element, the minuend
2964
+
2965
+ - ``y`` -- a relaxed `p`-adic element, the subtrahend
2966
+
2967
+ TESTS::
2968
+
2969
+ sage: R = ZpER(11)
2970
+ sage: x = R.random_element() - R.random_element()
2971
+ sage: type(x)
2972
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_sub'>
2973
+ """
2974
+ RelaxedElement.__init__(self, parent)
2975
+ self._x = x
2976
+ self._y = y
2977
+ self._valuation = min(x.valuation_c(0), y.valuation_c(0))
2978
+ self._precbound = min(x._precbound, y._precbound)
2979
+ self._init_jump()
2980
+
2981
+ def __reduce__(self):
2982
+ r"""
2983
+ Return a tuple of a function and data that can be used to unpickle this
2984
+ element.
2985
+
2986
+ TESTS::
2987
+
2988
+ sage: R = ZpER(5)
2989
+ sage: x = R.random_element() - R.random_element()
2990
+ sage: x == loads(dumps(x)) # indirect doctest
2991
+ True
2992
+ """
2993
+ return self.__class__, (self._parent, self._x, self._y)
2994
+
2995
+ cdef int _jump_c(self, long prec) noexcept:
2996
+ r"""
2997
+ Compute the digits of this number until the absolute precision ``prec``.
2998
+
2999
+ INPUT:
3000
+
3001
+ - ``prec`` -- integer
3002
+
3003
+ OUTPUT:
3004
+
3005
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3006
+ """
3007
+ # We reimplement _jump_c for better performances
3008
+ cdef long n = self._valuation + self._precrel
3009
+ cdef RelaxedElement x = self._x
3010
+ cdef RelaxedElement y = self._y
3011
+ cdef int error = x._jump_c(prec) | y._jump_c(prec)
3012
+ prec = min(prec, x._valuation + x._precrel, y._valuation + y._precrel)
3013
+ while n < prec:
3014
+ element_iadd_digit(self._digits, x._getdigit_absolute(n), self._precrel)
3015
+ element_isub_digit(self._digits, y._getdigit_absolute(n), self._precrel)
3016
+ element_reduceneg_digit(self._digits, self._precrel, self.prime_pow)
3017
+ if self._precrel == 0 and digit_is_zero(self._getdigit_relative(0)):
3018
+ self._valuation += 1
3019
+ element_shift_right(self._digits)
3020
+ else:
3021
+ self._precrel += 1
3022
+ n += 1
3023
+ return error
3024
+
3025
+ cdef int _next_c(self) noexcept:
3026
+ r"""
3027
+ Compute the next digit of this number.
3028
+
3029
+ OUTPUT:
3030
+
3031
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3032
+ """
3033
+ cdef long n = self._valuation + self._precrel
3034
+ cdef RelaxedElement x = self._x
3035
+ cdef RelaxedElement y = self._y
3036
+ cdef int error = x._jump_c(n+1) | y._jump_c(n+1)
3037
+ if error:
3038
+ return error
3039
+ element_iadd_digit(self._digits, x._getdigit_absolute(n), self._precrel)
3040
+ element_isub_digit(self._digits, y._getdigit_absolute(n), self._precrel)
3041
+ element_reduceneg_digit(self._digits, self._precrel, self.prime_pow)
3042
+ if self._precrel == 0 and digit_is_zero(self._getdigit_relative(0)):
3043
+ self._valuation += 1
3044
+ element_shift_right(self._digits)
3045
+ else:
3046
+ self._precrel += 1
3047
+ return 0
3048
+
3049
+
3050
+ # Multiplication
3051
+
3052
+ cdef class RelaxedElement_mul(RelaxedElementWithDigits):
3053
+ r"""
3054
+ A class for relaxed `p`-adic numbers defined as products.
3055
+
3056
+ ALGORITHM:
3057
+
3058
+ We compute digits using relaxed arithmetic by var der Hoeven et al.,
3059
+ whose cost is quasi-linear with respect to the precision.
3060
+
3061
+ The algorithm uses the entries behind the current position in the table
3062
+ ``self._digits`` to store carries.
3063
+
3064
+ TESTS::
3065
+
3066
+ sage: R = ZpER(11)
3067
+ sage: x = R.random_element() * R.random_element()
3068
+ sage: TestSuite(x).run()
3069
+ """
3070
+ def __cinit__(self):
3071
+ r"""
3072
+ Allocate memory for temporary variables.
3073
+ """
3074
+ digit_init(self._lastdigit_x)
3075
+ digit_init(self._lastdigit_y)
3076
+
3077
+ def __dealloc__(self):
3078
+ r"""
3079
+ Deallocate memory for temporary variables.
3080
+ """
3081
+ digit_clear(self._lastdigit_x)
3082
+ digit_clear(self._lastdigit_y)
3083
+
3084
+ def __init__(self, parent, RelaxedElement x, RelaxedElement y):
3085
+ r"""
3086
+ Initialize this element.
3087
+
3088
+ INPUT:
3089
+
3090
+ - ``parent`` -- the parent of this element
3091
+
3092
+ - ``x`` -- a relaxed `p`-adic element, the first factor
3093
+
3094
+ - ``y`` -- a relaxed `p`-adic element, the second factor
3095
+
3096
+ TESTS::
3097
+
3098
+ sage: R = ZpER(11)
3099
+ sage: x = R.random_element() * R.random_element()
3100
+ sage: type(x)
3101
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_mul'>
3102
+ """
3103
+ RelaxedElement.__init__(self, parent)
3104
+ self._x = x
3105
+ self._y = y
3106
+ cdef halt = self._parent.default_prec()
3107
+ self._valuation = min(maxordp, x.valuation_c(0) + y.valuation_c(0))
3108
+ if x._precbound < maxordp:
3109
+ y._jump_relative_c(1, y._valuation + self._parent.default_prec())
3110
+ self._precbound = min(self._precbound, y._valuation + x._precbound)
3111
+ if y._precbound < maxordp:
3112
+ x._jump_relative_c(1, x._valuation + self._parent.default_prec())
3113
+ self._precbound = min(self._precbound, x._valuation + y._precbound)
3114
+ self._init_jump()
3115
+
3116
+ def __reduce__(self):
3117
+ r"""
3118
+ Return a tuple of a function and data that can be used to unpickle this
3119
+ element.
3120
+
3121
+ TESTS::
3122
+
3123
+ sage: R = ZpER(5)
3124
+ sage: x = R.random_element() * R.random_element()
3125
+ sage: x == loads(dumps(x)) # indirect doctest
3126
+ True
3127
+ """
3128
+ return self.__class__, (self._parent, self._x, self._y)
3129
+
3130
+ cdef int _next_c(self) noexcept:
3131
+ r"""
3132
+ Compute the next digit of this number.
3133
+
3134
+ OUTPUT:
3135
+
3136
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3137
+ """
3138
+ global tmp_digit, tmp_poly
3139
+ cdef RelaxedElement x = self._x
3140
+ cdef RelaxedElement y = self._y
3141
+ cdef long n = self._valuation + self._precrel
3142
+
3143
+ cdef int errorx = x._jump_c(n - y._valuation + 1)
3144
+ cdef int errory = y._jump_c(n - x._valuation + 1)
3145
+ cdef int error = errorx | errory
3146
+ if self._precrel == 0:
3147
+ self._valuation = x._valuation + y._valuation
3148
+ if self._valuation > n:
3149
+ return 0
3150
+ if self._valuation < n or x._precrel == 0 or y._precrel == 0:
3151
+ return error | ERROR_PRECISION
3152
+ elif error:
3153
+ return error
3154
+
3155
+ n = self._precrel
3156
+ digit_set(self._lastdigit_x, x._getdigit_relative(n))
3157
+ digit_set(self._lastdigit_y, y._getdigit_relative(n))
3158
+ digit_mul(tmp_digit, x._getdigit_relative(0), self._lastdigit_y)
3159
+ element_iadd_digit(self._digits, tmp_digit, n)
3160
+ if n:
3161
+ digit_mul(tmp_digit, self._lastdigit_x, y._getdigit_relative(0))
3162
+ element_iadd_digit(self._digits, tmp_digit, n)
3163
+
3164
+ cdef long m = n + 2
3165
+ cdef long len = 1
3166
+ cdef celement slicex, slicey
3167
+ while (m & 1 == 0) and (m > 3):
3168
+ m >>= 1
3169
+ len <<= 1
3170
+ x._getslice_relative(slicex, len - 1, len)
3171
+ y._getslice_relative(slicey, (m-1)*len - 1, len)
3172
+ element_mul(tmp_poly, slicex, slicey)
3173
+ element_iadd_slice(self._digits, tmp_poly, n)
3174
+ if m > 2:
3175
+ x._getslice_relative(slicex, (m-1)*len - 1, len)
3176
+ y._getslice_relative(slicey, len - 1, len)
3177
+ element_mul(tmp_poly, slicex, slicey)
3178
+ element_iadd_slice(self._digits, tmp_poly, n)
3179
+
3180
+ element_reduce_digit(self._digits, n, self.prime_pow)
3181
+ self._precrel += 1
3182
+ return 0
3183
+
3184
+ cdef int _update_last_digit(self) noexcept:
3185
+ r"""
3186
+ Redo the computation of the last digit and update carries
3187
+ accordingly.
3188
+
3189
+ This method is used for computing Teichmüller representatives.
3190
+ """
3191
+ if self._precrel == 0:
3192
+ return ERROR_UNEXPECTED
3193
+ cdef RelaxedElement x = self._x
3194
+ cdef RelaxedElement y = self._y
3195
+ cdef long n = self._precrel - 1
3196
+ cdef long m = n + 2
3197
+ cdef long len = 2
3198
+ cdef celement slice
3199
+ while (m & 1 == 0) and (m > 3):
3200
+ m >>= 1
3201
+ len <<= 1
3202
+ len -= 1
3203
+
3204
+ digit_sub(tmp_digit, x._getdigit_relative(n), self._lastdigit_x)
3205
+ y._getslice_relative(slice, 0, len)
3206
+ element_scalarmul(tmp_poly, slice, tmp_digit)
3207
+ element_iadd_slice(self._digits, tmp_poly, n)
3208
+ if m == 2:
3209
+ len -= 1
3210
+ digit_sub(tmp_digit, y._getdigit_relative(n), self._lastdigit_y)
3211
+ x._getslice_relative(slice, 0, len)
3212
+ element_scalarmul(tmp_poly, slice, tmp_digit)
3213
+ element_iadd_slice(self._digits, tmp_poly, n)
3214
+ if m == 2:
3215
+ digit_mul(tmp_digit, tmp_digit, self._lastdigit_x)
3216
+ element_iadd_digit(self._digits, tmp_digit, 2*len)
3217
+ element_reduce_digit(self._digits, n, self.prime_pow)
3218
+
3219
+ digit_set(self._lastdigit_x, x._getdigit_relative(n))
3220
+ digit_set(self._lastdigit_y, y._getdigit_relative(n))
3221
+ return 0
3222
+
3223
+
3224
+ cdef class RelaxedElement_muldigit(RelaxedElementWithDigits):
3225
+ r"""
3226
+ A class for relaxed `p`-adic numbers defined as products
3227
+ of a relaxed `p`-adic number by a digit.
3228
+
3229
+ This class is not exposed to the user; it is only used
3230
+ internally for division.
3231
+ """
3232
+ def __init__(self, parent, RelaxedElement_div x, RelaxedElement y):
3233
+ r"""
3234
+ Initialize this element.
3235
+
3236
+ INPUT:
3237
+
3238
+ - ``parent`` -- the parent of this element
3239
+
3240
+ - ``x`` -- a relaxed `p`-adic element, whose first significant
3241
+ digit is the first factor
3242
+
3243
+ - ``y`` -- a relaxed `p`-adic element, the second factor
3244
+ """
3245
+ RelaxedElement.__init__(self, parent)
3246
+ self._x = <cdigit_ptr>x._inverse
3247
+ self._y = y
3248
+ self._valuation = y._valuation
3249
+ self._init_jump()
3250
+
3251
+ cdef int _next_c(self) noexcept:
3252
+ r"""
3253
+ Compute the next digit of this number.
3254
+
3255
+ OUTPUT:
3256
+
3257
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3258
+ """
3259
+ cdef long n = self._valuation + self._precrel
3260
+ cdef int error = self._y._jump_c(n+1)
3261
+ if error:
3262
+ return error
3263
+ digit_mul(tmp_digit, self._x, self._y._getdigit_absolute(n))
3264
+ element_iadd_digit(self._digits, tmp_digit, self._precrel)
3265
+ element_reduce_digit(self._digits, self._precrel, self.prime_pow)
3266
+ self._precrel += 1
3267
+ return 0
3268
+
3269
+
3270
+ # Division
3271
+
3272
+ cdef class RelaxedElement_div(RelaxedElementWithDigits):
3273
+ r"""
3274
+ A class for relaxed `p`-adic numbers defined as quotients.
3275
+
3276
+ ALGORITHM:
3277
+
3278
+ We compute the quotient `x = a/b` as the self-referent number defined by
3279
+
3280
+ .. MATH::
3281
+
3282
+ x = ac + (1 - bc) x
3283
+
3284
+ where `c` is congruent to `b^{-1}` modulo the uniformizer.
3285
+
3286
+ TESTS::
3287
+
3288
+ sage: R = ZpER(5)
3289
+ sage: x = R(20) / R(21)
3290
+ sage: TestSuite(x).run()
3291
+ """
3292
+ def __cinit__(self):
3293
+ r"""
3294
+ Allocate memory for temporary variables.
3295
+ """
3296
+ digit_init(self._inverse)
3297
+
3298
+ def __dealloc__(self):
3299
+ r"""
3300
+ Deallocate memory for temporary variables.
3301
+ """
3302
+ digit_clear(self._inverse)
3303
+
3304
+ def __init__(self, parent, RelaxedElement num, RelaxedElement denom, long minval=-maxordp, precbound=None):
3305
+ r"""
3306
+ Initialize this element.
3307
+
3308
+ INPUT:
3309
+
3310
+ - ``parent`` -- the parent of this element
3311
+
3312
+ - ``num`` -- a relaxed `p`-adic element, the dividend
3313
+
3314
+ - ``denom`` -- a relaxed `p`-adic element, the divisor
3315
+
3316
+ - ``minval`` -- integer; the minimal valuation allowed for this element
3317
+
3318
+ - ``precbound`` -- integer or ``None`` (default: ``None``);
3319
+ the bound on the precision
3320
+
3321
+ TESTS::
3322
+
3323
+ sage: R = ZpER(5)
3324
+ sage: x = R(20) / R(21)
3325
+ sage: type(x)
3326
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_div'>
3327
+
3328
+ sage: y = R.unknown()
3329
+ sage: 1/y
3330
+ O(5^-Infinity)
3331
+ sage: y.inverse_of_unit()
3332
+ O(5^0)
3333
+ """
3334
+ RelaxedElement.__init__(self, parent)
3335
+ if denom._valuation >= maxordp:
3336
+ raise ZeroDivisionError("cannot divide by zero")
3337
+ if denom._precbound < maxordp and denom._precrel == 0:
3338
+ raise ZeroDivisionError("cannot divide by something indistinguishable from zero")
3339
+ self._num = num
3340
+ self._denom = denom
3341
+ if denom._valuation <= -maxordp:
3342
+ self._maxprec = maxordp + 1
3343
+ else:
3344
+ self._maxprec = denom._valuation + max(1, self._parent.default_prec())
3345
+ self._valuation = minval
3346
+ cdef int error = self._bootstrap_c()
3347
+ if precbound is not None:
3348
+ self._precbound = min(maxordp, precbound)
3349
+ if num._precbound < maxordp:
3350
+ self._precbound = min(self._precbound, num._precbound - denom._valuation)
3351
+ if denom._precbound < maxordp:
3352
+ self._precbound = min(self._precbound, denom._precbound + num._valuation - 2*denom._valuation)
3353
+ raise_error(error, permissive=True)
3354
+ if not error:
3355
+ self._init_jump()
3356
+
3357
+ def __reduce__(self):
3358
+ r"""
3359
+ Return a tuple of a function and data that can be used to unpickle this
3360
+ element.
3361
+
3362
+ TESTS::
3363
+
3364
+ sage: R = ZpER(5)
3365
+ sage: x = R(20) / R(21)
3366
+ sage: x == loads(dumps(x)) # indirect doctest
3367
+ True
3368
+ """
3369
+ return self.__class__, (self._parent, self._num, self._denom, self._valuation, self._precbound)
3370
+
3371
+ cdef int _bootstrap_c(self) noexcept:
3372
+ r"""
3373
+ Bootstrap the computation of the digits of this element, that is:
3374
+
3375
+ - find the valuation
3376
+ - compute the first digit, and
3377
+ - set up the recursive definition of the next digits.
3378
+
3379
+ OUTPUT:
3380
+
3381
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3382
+ """
3383
+ cdef int error
3384
+ cdef RelaxedElement num = self._num
3385
+ cdef RelaxedElement denom = self._denom
3386
+
3387
+ while denom._valuation < self._maxprec and denom._precrel == 0:
3388
+ error = denom._next_c()
3389
+ if error:
3390
+ if error & ERROR_PRECISION:
3391
+ error |= ERROR_DIVISION
3392
+ return error
3393
+ if self._maxprec < maxordp and denom._valuation > -maxordp:
3394
+ self._maxprec = denom._valuation + max(1, self._parent.default_prec())
3395
+ if denom._precrel == 0:
3396
+ return ERROR_ABANDON
3397
+
3398
+ cdef long valuation = num._valuation - denom._valuation
3399
+ if valuation < self._valuation:
3400
+ error = num._jump_c(self._valuation + denom._valuation)
3401
+ if error:
3402
+ return error
3403
+ valuation = num._valuation - denom._valuation
3404
+ if valuation < self._valuation:
3405
+ return ERROR_DIVISION
3406
+ self._valuation = valuation
3407
+ digit_inv(self._inverse, denom._getdigit_relative(0), self.prime_pow)
3408
+ self._definition = relaxedelement_abandon
3409
+ cdef parent = self._parent
3410
+ cdef RelaxedElement a = element_class_muldigit(parent, self, num)
3411
+ cdef RelaxedElement b = element_class_muldigit(parent, self, denom)
3412
+ cdef RelaxedElement c = element_class_slice(parent, b, denom._valuation + 1, maxordp, 0)
3413
+ cdef RelaxedElement d = element_class_mul(parent, c, self)
3414
+ self._definition = element_class_sub(parent, a, d)
3415
+ return 0
3416
+
3417
+ cdef int _next_c(self) noexcept:
3418
+ r"""
3419
+ Compute the next digit of this number.
3420
+
3421
+ OUTPUT:
3422
+
3423
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3424
+ """
3425
+ cdef RelaxedElement definition = self._definition
3426
+ if definition is None:
3427
+ return self._bootstrap_c()
3428
+ cdef long val = self._valuation + self._denom._valuation
3429
+ cdef int error = definition._jump_c(val + self._precrel + 1)
3430
+ if error:
3431
+ return error
3432
+ if definition._valuation > val:
3433
+ self._valuation = min(self._precbound, definition._valuation - self._denom._valuation)
3434
+ if definition._precbound < maxordp:
3435
+ self._precbound = min(self._precbound, definition._precbound - self._denom._valuation)
3436
+ else:
3437
+ digit = definition._getdigit_relative(self._precrel)
3438
+ element_set_digit(self._digits, digit, self._precrel)
3439
+ self._precrel += 1
3440
+ return 0
3441
+
3442
+
3443
+ # Square root
3444
+
3445
+ cdef class RelaxedElement_sqrt(RelaxedElementWithDigits):
3446
+ r"""
3447
+ A class for relaxed `p`-adic numbers defined as square roots.
3448
+
3449
+ ALGORITHM:
3450
+
3451
+ When `p \neq 2`, we compute `y = \sqrt{x}` as the self-referent number
3452
+ defined by
3453
+
3454
+ .. MATH::
3455
+
3456
+ y = \frac{x - (y-a)^2 + a^2}{2a}
3457
+
3458
+ where `a^2` is congruent to `x` modulo the uniformizer.
3459
+
3460
+ When `p = 2`, we use a variant of this construction.
3461
+
3462
+ TESTS::
3463
+
3464
+ sage: R = ZpER(5)
3465
+ sage: x = R(6).sqrt()
3466
+ sage: TestSuite(x).run()
3467
+ """
3468
+ def __init__(self, parent, RelaxedElement x):
3469
+ r"""
3470
+ Initialize this element.
3471
+
3472
+ INPUT:
3473
+
3474
+ - ``parent`` -- the parent of this element
3475
+
3476
+ - ``x`` -- a relaxed `p`-adic element
3477
+
3478
+ TESTS::
3479
+
3480
+ sage: R = ZpER(5)
3481
+ sage: x = R(6).sqrt()
3482
+ sage: type(x)
3483
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_sqrt'>
3484
+ """
3485
+ RelaxedElement.__init__(self, parent)
3486
+ self._x = x
3487
+ if x._valuation <= -maxordp:
3488
+ self._valuation = -maxordp
3489
+ else:
3490
+ self._valuation = x._valuation >> 1
3491
+ cdef int error = self._bootstrap_c()
3492
+ if error & ERROR_NOTSQUARE:
3493
+ raise ValueError("not a square")
3494
+ if not error:
3495
+ if x._precbound < maxordp:
3496
+ self._precbound = x._precbound - x._valuation / 2
3497
+ if self._parent.prime() == 2:
3498
+ self._precbound -= 1
3499
+ self._precbound = min(maxordp, self._precbound)
3500
+ self._init_jump()
3501
+
3502
+ def __reduce__(self):
3503
+ r"""
3504
+ Return a tuple of a function and data that can be used to unpickle this
3505
+ element.
3506
+
3507
+ TESTS::
3508
+
3509
+ sage: R = ZpER(5)
3510
+ sage: x = R(6).sqrt()
3511
+ sage: x == loads(dumps(x)) # indirect doctest
3512
+ True
3513
+ """
3514
+ return self.__class__, (self._parent, self._x)
3515
+
3516
+ cdef int _bootstrap_c(self) noexcept:
3517
+ r"""
3518
+ Bootstrap the computation of the digits of this element, that is:
3519
+
3520
+ - find the valuation
3521
+ - compute the first digit, and
3522
+ - set up the recursive definition of the next digits.
3523
+
3524
+ OUTPUT:
3525
+
3526
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3527
+
3528
+ .. NOTE::
3529
+
3530
+ This code does not work for nontrivial extensions of `\QQ_2`.
3531
+ """
3532
+ cdef RelaxedElement x = self._x
3533
+ cdef long maxprec
3534
+ if x._valuation <= -maxordp:
3535
+ return ERROR_ABANDON
3536
+ if self._valuation <= -maxordp:
3537
+ maxprec = x._valuation
3538
+ else:
3539
+ maxprec = (self._valuation + 1) << 1
3540
+ while x._valuation < maxprec and x._precrel == 0:
3541
+ error = x._next_c()
3542
+ if error:
3543
+ return error
3544
+ if x._valuation & 1:
3545
+ self._valuation = (x._valuation + 1) >> 1
3546
+ else:
3547
+ self._valuation = x._valuation >> 1
3548
+ if x._precrel == 0:
3549
+ return 0
3550
+ if x._valuation & 1 != 0:
3551
+ return ERROR_NOTSQUARE
3552
+
3553
+ cdef parent = self._parent
3554
+ cdef long val = self._valuation
3555
+ cdef cdigit digit
3556
+ cdef Integer zd, p = self.prime_pow.prime
3557
+ cdef RelaxedElement u, y, c, d
3558
+
3559
+ if p == 2:
3560
+ element_set_digit_ui(self._digits, 1, 0)
3561
+ self._precrel = 1
3562
+ if x._precrel == 1:
3563
+ error = x._next_c()
3564
+ if error:
3565
+ return error
3566
+ if not digit_equal_ui(x._getdigit_relative(1), 0):
3567
+ return ERROR_NOTSQUARE
3568
+ if x._precrel == 2:
3569
+ error = x._next_c()
3570
+ if error:
3571
+ return error
3572
+ if not digit_equal_ui(x._getdigit_relative(2), 0):
3573
+ return ERROR_NOTSQUARE
3574
+ zd = Integer(1)
3575
+ self._definition = relaxedelement_abandon
3576
+ u = element_class_slice(parent, self, val + 2, maxordp, val)
3577
+ y = element_class_slice(parent, x, -maxordp, maxordp, val + 1)
3578
+ c = element_class_value(parent, zd, shift=-val+1)
3579
+ d = element_class_slice(parent, u*u, -maxordp, maxordp, -val + 1)
3580
+ self._definition = y + c - d
3581
+ else:
3582
+ digit_init(digit)
3583
+ if digit_sqrt(digit, x._getdigit_relative(0), self.prime_pow):
3584
+ digit_clear(digit)
3585
+ return ERROR_NOTSQUARE
3586
+ element_set_digit(self._digits, digit, 0)
3587
+ self._precrel = 1
3588
+ zd = digit_get_sage(digit)
3589
+ self._definition = relaxedelement_abandon
3590
+ u = element_class_slice(parent, self, val + 1, maxordp, val)
3591
+ y = element_class_slice(parent, x, -maxordp, maxordp, 2*val)
3592
+ c = element_class_value(parent, zd*zd)
3593
+ d = element_class_value(parent, 2*zd, shift=val)
3594
+ self._definition = (y + c - u*u) / d
3595
+ return 0
3596
+
3597
+ cdef int _next_c(self) noexcept:
3598
+ r"""
3599
+ Compute the next digit of this number.
3600
+
3601
+ OUTPUT:
3602
+
3603
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3604
+ """
3605
+ cdef RelaxedElement definition = self._definition
3606
+ if definition is None:
3607
+ return self._bootstrap_c()
3608
+ cdef long n = self._valuation + self._precrel
3609
+ cdef int error = definition._jump_c(n+1)
3610
+ if error:
3611
+ return error
3612
+ element_set_digit(self._digits, definition._getdigit_relative(self._precrel), self._precrel)
3613
+ self._precrel += 1
3614
+ return 0
3615
+
3616
+
3617
+ # Teichmüller lifts
3618
+
3619
+ cdef class RelaxedElement_teichmuller(RelaxedElementWithDigits):
3620
+ r"""
3621
+ A class for relaxed `p`-adic numbers defined as teichmüller representatives.
3622
+
3623
+ ALGORITHM:
3624
+
3625
+ We compute `x = [a]` as the unique self-referent number with last
3626
+ digit `a` and `x = x^p`.
3627
+ Note that `x^p` is known with one more digit than `x` itself.
3628
+
3629
+ TESTS::
3630
+
3631
+ sage: R = ZpER(7)
3632
+ sage: x = R.teichmuller(2)
3633
+ sage: TestSuite(x).run()
3634
+ """
3635
+ def __init__(self, parent, xbar):
3636
+ r"""
3637
+ Initialize this element.
3638
+
3639
+ INPUT:
3640
+
3641
+ - ``parent`` -- the parent of this element
3642
+
3643
+ - ``xbar`` -- an element in the exact subring, which is congruent
3644
+ to this Teichmüller modulo this uniformizer
3645
+
3646
+ TESTS::
3647
+
3648
+ sage: R = ZpER(7)
3649
+ sage: x = R.teichmuller(2)
3650
+ sage: type(x)
3651
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_teichmuller'>
3652
+ """
3653
+ RelaxedElement.__init__(self, parent)
3654
+ cdef cdigit digit
3655
+ digit_init(digit)
3656
+ digit_set_sage(digit, xbar)
3657
+ digit_mod(digit, digit, self.prime_pow)
3658
+ if digit_equal_ui(digit, 0):
3659
+ digit_clear(digit)
3660
+ self._trivial = True
3661
+ self._valuation = maxordp
3662
+ else:
3663
+ element_set_digit(self._digits, digit, 0)
3664
+ self._trivial = digit_equal_ui(digit, 1)
3665
+ self._precrel += 1
3666
+
3667
+ cdef RelaxedElement xn
3668
+ cdef Integer p
3669
+ cdef int size, i
3670
+ if not self._trivial:
3671
+ xn = self
3672
+ p = self.prime_pow.prime
3673
+ size = mpz_sizeinbase(p.value, 2)
3674
+ i = size - 2
3675
+ self._xns = []
3676
+ while i >= 0:
3677
+ xn = element_class_mul(parent, xn, xn)
3678
+ self._xns.append(xn)
3679
+ if mpz_tstbit(p.value, i):
3680
+ xn = element_class_mul(parent, xn, self)
3681
+ self._xns.append(xn)
3682
+ i -= 1
3683
+ self._xp = xn
3684
+ self._ready = True
3685
+
3686
+ def __reduce__(self):
3687
+ r"""
3688
+ Return a tuple of a function and data that can be used to unpickle this
3689
+ element.
3690
+
3691
+ TESTS::
3692
+
3693
+ sage: R = ZpER(7)
3694
+ sage: x = R.teichmuller(2)
3695
+ sage: x == loads(dumps(x)) # indirect doctest
3696
+ True
3697
+ """
3698
+ xbar = digit_get_sage(element_get_digit(self._digits, 0))
3699
+ return self.__class__, (self._parent, xbar)
3700
+
3701
+ cdef int _jump_c(self, long prec) noexcept:
3702
+ r"""
3703
+ Compute the digits of this number until the absolute precision ``prec``.
3704
+
3705
+ INPUT:
3706
+
3707
+ - ``prec`` -- integer
3708
+
3709
+ OUTPUT:
3710
+
3711
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3712
+ """
3713
+ if not self._ready:
3714
+ return ERROR_ABANDON
3715
+ if self._trivial:
3716
+ if self._valuation == 0 and self._precrel < prec:
3717
+ self._precrel = prec
3718
+ return 0
3719
+ return RelaxedElement._jump_c(<RelaxedElement>self, prec)
3720
+
3721
+ cdef int _next_c(self) noexcept:
3722
+ r"""
3723
+ Compute the next digit of this number.
3724
+
3725
+ OUTPUT:
3726
+
3727
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3728
+ """
3729
+ if self._trivial:
3730
+ if self._valuation:
3731
+ self._precrel += 1
3732
+ return 0
3733
+ cdef int error
3734
+ cdef RelaxedElement xp = self._xp
3735
+ cdef RelaxedElement_mul xn
3736
+ self._precrel += 1
3737
+ xp._jump_c(self._precrel)
3738
+ element_set_digit(self._digits, xp._getdigit_relative(self._precrel - 1), self._precrel - 1)
3739
+ for xn in self._xns:
3740
+ error = xn._update_last_digit()
3741
+ if error:
3742
+ return error | ERROR_UNEXPECTED
3743
+ return 0
3744
+
3745
+
3746
+ # Self-referent definitions
3747
+ ###########################
3748
+
3749
+ cdef class RelaxedElement_unknown(RelaxedElementWithDigits):
3750
+ r"""
3751
+ A class for self-referent relaxed `p`-adic numbers.
3752
+
3753
+ TESTS::
3754
+
3755
+ sage: R = ZpER(7)
3756
+ sage: x = R.unknown()
3757
+ sage: TestSuite(x).run()
3758
+
3759
+ sage: x.set(1 + 7*x^2)
3760
+ True
3761
+ sage: TestSuite(x).run()
3762
+ """
3763
+ def __init__(self, parent, long valuation, digits=None):
3764
+ r"""
3765
+ Initialize this element.
3766
+
3767
+ INPUT:
3768
+
3769
+ - ``parent`` -- the parent of this element
3770
+
3771
+ - ``valuation`` -- integer; a lower bound on the valuation of
3772
+ this number
3773
+
3774
+ - ``digits`` -- list or ``None`` (default: ``None``); the first
3775
+ significant digits of this number
3776
+
3777
+ TESTS::
3778
+
3779
+ sage: R = ZpER(7)
3780
+ sage: x = R.unknown()
3781
+ sage: type(x)
3782
+ <class 'sage.rings.padics.padic_relaxed_element.pAdicRelaxedElement_unknown'>
3783
+ """
3784
+ RelaxedElement.__init__(self, parent)
3785
+ if valuation >= maxordp:
3786
+ raise OverflowError("valuation is too large (maximum is %s)" % maxordp)
3787
+ self._valuation = valuation
3788
+ self._definition = None
3789
+ self._next = maxordp
3790
+ cdef cdigit digit
3791
+ if digits is not None:
3792
+ digits = [Integer(d) for d in digits]
3793
+ for d in digits:
3794
+ digit_set_sage(digit, d)
3795
+ element_iadd_digit(self._digits, digit, self._precrel)
3796
+ element_reduce_digit(self._digits, self._precrel, self.prime_pow)
3797
+ if self._precrel == 0 and digit_is_zero(element_get_digit(self._digits, 0)):
3798
+ self._valuation += 1
3799
+ element_shift_right(self._digits)
3800
+ else:
3801
+ self._precrel += 1
3802
+ self._initialvaluation = self._valuation
3803
+ self._initialprecrel = self._precrel
3804
+
3805
+ def __reduce__(self):
3806
+ r"""
3807
+ Return a tuple of a function and data that can be used to unpickle this
3808
+ element.
3809
+
3810
+ TESTS::
3811
+
3812
+ sage: R = ZpER(7)
3813
+ sage: x = R.unknown()
3814
+ sage: x.set(1 + 7*x^2)
3815
+ True
3816
+ sage: x == loads(dumps(x)) # indirect doctest
3817
+ True
3818
+ """
3819
+ digits = []
3820
+ for i in range(self._initialprecrel):
3821
+ digits.append(digit_get_sage(element_get_digit(self._digits, i)))
3822
+ definition = None
3823
+ if id(self) not in persist.already_pickled:
3824
+ persist.already_pickled[id(self)] = True
3825
+ definition = self._definition
3826
+ return unpickle_unknown, (id(self), self.__class__, self._parent, self._initialvaluation, digits, definition)
3827
+
3828
+ cpdef set(self, RelaxedElement definition):
3829
+ r"""
3830
+ Set the recursive definition of this self-referent number.
3831
+
3832
+ INPUT:
3833
+
3834
+ - ``definition`` -- a relaxed `p`-adic number, to which this
3835
+ number is equal
3836
+
3837
+ OUTPUT:
3838
+
3839
+ A boolean indicating if the definition is coherent with the
3840
+ already known digits of this number.
3841
+
3842
+ EXAMPLES::
3843
+
3844
+ sage: R = ZpER(5, 10)
3845
+ sage: x = R.unknown()
3846
+ sage: x.set(1 + 5*x)
3847
+ True
3848
+ sage: x
3849
+ 1 + 5 + 5^2 + 5^3 + 5^4 + 5^5 + 5^6 + 5^7 + 5^8 + 5^9 + ...
3850
+
3851
+ The previous construction works because the relation we gave defines
3852
+ the `n`-th digit of `x` in terms of its digits at precision strictly
3853
+ less than `n` (this is due to the multiplication by `5`).
3854
+
3855
+ On the contrary, the following does not work::
3856
+
3857
+ sage: y = R.unknown()
3858
+ sage: y.set(1 + 3*y)
3859
+ True
3860
+ sage: y
3861
+ O(5^0)
3862
+ sage: y[:20]
3863
+ Traceback (most recent call last):
3864
+ ...
3865
+ RecursionError: definition looks circular
3866
+
3867
+ In the next example, we give explicit values for the first digits
3868
+ and then a recursive definition for the next digits. However, the
3869
+ recursive definition does not hold for the first digits; that is the
3870
+ reason why the call to :meth:`set` returns ``False``::
3871
+
3872
+ sage: z = R.unknown(digits=[2])
3873
+ sage: z
3874
+ 2 + O(5)
3875
+ sage: z.set(1 + 5*z)
3876
+ False
3877
+ sage: z
3878
+ 2 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 2*5^8 + 2*5^9 + ...
3879
+
3880
+ .. SEEALSO::
3881
+
3882
+ :meth:`sage.rings.padics.generic_nodes.pAdicRelaxedGeneric.unknown`
3883
+ """
3884
+ if self._definition is not None:
3885
+ raise ValueError("this self-referent number is already defined")
3886
+ self._definition = definition
3887
+ self._precbound = max(self._valuation + self._precrel, definition._precbound)
3888
+ eq = self._is_equal(definition, self._valuation + self._precrel, True)
3889
+ self._init_jump()
3890
+ return eq
3891
+
3892
+ cdef int _next_c(self) noexcept:
3893
+ r"""
3894
+ Compute the next digit of this number.
3895
+
3896
+ OUTPUT:
3897
+
3898
+ An error code (see :meth:`RelaxedElement._next_c` for details).
3899
+ """
3900
+ cdef RelaxedElement definition = self._definition
3901
+ cdef cdigit_ptr digit
3902
+ cdef long n = self._valuation + self._precrel
3903
+ cdef long diffval
3904
+ cdef int error
3905
+
3906
+ if definition is None:
3907
+ return ERROR_NOTDEFINED
3908
+ if n >= self._next:
3909
+ return ERROR_CIRCULAR
3910
+
3911
+ cdef long svenext = self._next
3912
+ self._next = n
3913
+ error = definition._jump_c(n+1)
3914
+ if not error:
3915
+ digit = definition._getdigit_absolute(n)
3916
+ if self._precrel == 0 and digit_is_zero(digit):
3917
+ self._valuation += 1
3918
+ else:
3919
+ element_set_digit(self._digits, digit, self._precrel)
3920
+ self._precrel += 1
3921
+ self._next = svenext
3922
+ return error
3923
+
3924
+
3925
+ def unpickle_unknown(uid, cls, parent, valuation, digits, definition):
3926
+ r"""
3927
+ Unpickle a self-referent relaxed `p`-adic number.
3928
+
3929
+ TESTS:
3930
+
3931
+ Cross definitions involving several self-referent numbers are
3932
+ handled correctly::
3933
+
3934
+ sage: R = ZpER(7)
3935
+ sage: x = R.unknown()
3936
+ sage: y = R.unknown()
3937
+ sage: x.set(1 + 2*y + 7*x*y)
3938
+ True
3939
+ sage: y.set(3 + 14*x^2)
3940
+ True
3941
+
3942
+ sage: x == loads(dumps(x)) # indirect doctest
3943
+ True
3944
+ sage: y == loads(dumps(y)) # indirect doctest
3945
+ True
3946
+ """
3947
+ if uid in persist.already_unpickled:
3948
+ elt = persist.already_unpickled[uid]
3949
+ else:
3950
+ elt = cls(parent, valuation, digits)
3951
+ persist.already_unpickled[uid] = elt
3952
+ if definition is not None:
3953
+ elt.set(definition)
3954
+ return elt
3955
+
3956
+
3957
+ # Expansion
3958
+ ###########
3959
+
3960
+ cdef class RelaxedElement_zeroone(RelaxedElementWithDigits):
3961
+ r"""
3962
+ A special class for `p`-adic relaxed elements with only
3963
+ `0` and `1` as digits.
3964
+
3965
+ This class is used for computing expansion in Teichmuller mode.
3966
+ It is not supposed to be instantiated in other situations.
3967
+ """
3968
+ def __init__(self, parent, long valuation):
3969
+ r"""
3970
+ Instantiate this element.
3971
+
3972
+ INPUT:
3973
+
3974
+ - ``parent`` -- the parent of this element
3975
+
3976
+ - ``valuation`` -- the valuation of this number
3977
+ """
3978
+ RelaxedElement.__init__(self, parent)
3979
+ self._valuation = valuation
3980
+
3981
+ cdef void _setdigit_to_zero(self) noexcept:
3982
+ r"""
3983
+ Append `0` to the list of digits of this element.
3984
+ """
3985
+ self._precrel += 1
3986
+
3987
+ cdef void _setdigit_to_one(self) noexcept:
3988
+ r"""
3989
+ Append `1` to the list of digits of this element.
3990
+ """
3991
+ element_set_digit_ui(self._digits, 1, self._precrel)
3992
+ self._precrel += 1
3993
+
3994
+ cdef int _jump_c(self, long prec) noexcept:
3995
+ r"""
3996
+ Jump to the absolute precision ``prec``.
3997
+
3998
+ INPUT:
3999
+
4000
+ - ``prec`` -- integer
4001
+
4002
+ OUTPUT:
4003
+
4004
+ An error code (see :meth:`RelaxedElement._next_c` for details).
4005
+ """
4006
+ if prec > self._valuation + self._precrel:
4007
+ return ERROR_NOTDEFINED
4008
+ return 0
4009
+
4010
+ cdef int _next_c(self) noexcept:
4011
+ r"""
4012
+ Jump to the next digit.
4013
+
4014
+ OUTPUT:
4015
+
4016
+ An error code (see :meth:`RelaxedElement._next_c` for details).
4017
+ """
4018
+ return ERROR_NOTDEFINED
4019
+
4020
+
4021
+ cdef class ExpansionIter():
4022
+ """
4023
+ An iterator over a `p`-adic expansion.
4024
+
4025
+ This class should not be instantiated directly, but instead using
4026
+ :meth:`RelaxedElement.expansion`.
4027
+ """
4028
+ def __cinit__(self):
4029
+ r"""
4030
+ Allocate memory for temporary variables.
4031
+ """
4032
+ digit_init(self.carry)
4033
+
4034
+ def __dealloc__(self):
4035
+ r"""
4036
+ Deallocate memory for temporary variables.
4037
+ """
4038
+ digit_clear(self.carry)
4039
+
4040
+ def __init__(self, RelaxedElement elt, expansion_mode mode, long start, long stop):
4041
+ r"""
4042
+ Initialize this iterator.
4043
+
4044
+ INPUT:
4045
+
4046
+ - ``elt`` -- a relaxed `p`-adic number
4047
+
4048
+ - ``mode`` -- either ``simple_mode``, ``smallest_mode`` or ``teichmuller_mode``
4049
+
4050
+ - ``start`` -- integer; the position where the expansion starts
4051
+
4052
+ - ``stop`` -- integer; the position where the expansion stops
4053
+
4054
+ TESTS::
4055
+
4056
+ sage: E = ZpER(5,4)(373).expansion()
4057
+ sage: I = iter(E) # indirect doctest
4058
+ sage: type(I)
4059
+ <class 'sage.rings.padics.padic_relaxed_element.ExpansionIter'>
4060
+ """
4061
+ self.elt = elt
4062
+ self.mode = mode
4063
+ self.start = start
4064
+ self.stop = stop
4065
+ self.current = min(start, elt._valuation)
4066
+ digit_init(self.digit)
4067
+ # Compute first digits if needed
4068
+ if self.mode == simple_mode:
4069
+ self.current = self.start
4070
+ elif self.mode == smallest_mode:
4071
+ while self.current < self.start:
4072
+ self._next_smallest()
4073
+ elif self.mode == teichmuller_mode:
4074
+ self.tail = elt
4075
+ self.coefficients = {}
4076
+ while self.current < self.start:
4077
+ self._next_teichmuller()
4078
+
4079
+ def __repr__(self):
4080
+ r"""
4081
+ Return a string representation of this iterator.
4082
+
4083
+ EXAMPLES::
4084
+
4085
+ sage: R = ZpER(7, 5)
4086
+ sage: x = R(1/2021)
4087
+ sage: x.expansion() # indirect doctest
4088
+ 7-adic expansion of 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + ...
4089
+
4090
+ sage: x.expansion(lift_mode='smallest') # indirect doctest
4091
+ 7-adic expansion of 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + ... (balanced)
4092
+
4093
+ sage: x.expansion(lift_mode='teichmuller') # indirect doctest
4094
+ 7-adic expansion of 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + ... (teichmuller)
4095
+ """
4096
+ s = "%s-adic expansion of %s" % (self.elt._parent.prime(), self.elt)
4097
+ if self.mode == smallest_mode:
4098
+ s += " (balanced)"
4099
+ elif self.mode == teichmuller_mode:
4100
+ s += " (teichmuller)"
4101
+ return s
4102
+
4103
+ def __len__(self):
4104
+ r"""
4105
+ Return the length of this expansion.
4106
+
4107
+ EXAMPLES::
4108
+
4109
+ sage: R = ZpER(7)
4110
+ sage: x = R(1/2021, 5)
4111
+ sage: x
4112
+ 3 + 6*7 + 4*7^2 + 3*7^3 + 6*7^4 + O(7^5)
4113
+ sage: E = x.expansion()
4114
+ sage: len(E)
4115
+ 5
4116
+
4117
+ For unbounded elements, the expansion is infinite and this method
4118
+ raises an error::
4119
+
4120
+ sage: y = R(1/2021)
4121
+ sage: E = y.expansion()
4122
+ sage: len(E)
4123
+ Traceback (most recent call last):
4124
+ ...
4125
+ NotImplementedError: infinite sequence
4126
+ """
4127
+ if self.stop >= maxordp:
4128
+ raise NotImplementedError("infinite sequence")
4129
+ return Integer(self.stop - self.start)
4130
+
4131
+ def __iter__(self):
4132
+ r"""
4133
+ Return itself (as any iterator is supposed to do).
4134
+
4135
+ TESTS::
4136
+
4137
+ sage: E = ZpER(5)(373).expansion()
4138
+ sage: I = iter(E)
4139
+ sage: I is iter(I)
4140
+ True
4141
+ """
4142
+ return self
4143
+
4144
+ cdef _next_simple(self):
4145
+ r"""
4146
+ Return the next digit of this expansion (simple mode).
4147
+ """
4148
+ cdef RelaxedElement elt = self.elt
4149
+ elt._jump_c(self.current + 1)
4150
+ digit_set(self.digit, elt._getdigit_absolute(self.current))
4151
+ self.current += 1
4152
+ return digit_get_sage(self.digit)
4153
+
4154
+ cdef _next_smallest(self):
4155
+ r"""
4156
+ Return the next digit of this expansion (smallest mode).
4157
+ """
4158
+ cdef RelaxedElement elt = self.elt
4159
+ elt._jump_c(self.current + 1)
4160
+ digit_add(self.digit, elt._getdigit_absolute(self.current), self.carry)
4161
+ digit_smallest(self.digit, self.carry, self.digit, elt.prime_pow)
4162
+ self.current += 1
4163
+ return digit_get_sage(self.digit)
4164
+
4165
+ cdef _next_teichmuller(self):
4166
+ r"""
4167
+ Return the next digit of this expansion (Teichmüller mode).
4168
+ """
4169
+ cdef RelaxedElement teichmuller, tail = self.tail
4170
+ cdef RelaxedElement_zeroone coeff
4171
+ cdef digit
4172
+ tail._jump_c(self.current + 1)
4173
+ digit_set(self.digit, tail._getdigit_absolute(self.current))
4174
+ digit = digit_get_sage(self.digit)
4175
+ if digit != 0 and digit != 1 and digit not in self.coefficients:
4176
+ parent = tail._parent
4177
+ self.coefficients[digit] = coeff = RelaxedElement_zeroone(parent, self.current)
4178
+ teichmuller = element_class_teichmuller(parent, digit)
4179
+ self.tail = tail - coeff * element_class_slice(parent, teichmuller, 1, maxordp, 0)
4180
+ for d, coeff in self.coefficients.items():
4181
+ if d == digit:
4182
+ coeff._setdigit_to_one()
4183
+ else:
4184
+ coeff._setdigit_to_zero()
4185
+ self.current += 1
4186
+ return digit
4187
+
4188
+ def __next__(self):
4189
+ r"""
4190
+ Return the next digit of this expansion.
4191
+
4192
+ EXAMPLES::
4193
+
4194
+ sage: R = ZpER(11, 10)
4195
+ sage: x = R(20/21); x
4196
+ 2 + 2*11 + 4*11^2 + 8*11^3 + 5*11^4 + 11^6 + 2*11^7 + 4*11^8 + 8*11^9 + ...
4197
+ sage: E = x.expansion()
4198
+ sage: next(E)
4199
+ 2
4200
+ sage: next(E)
4201
+ 2
4202
+
4203
+ TESTS::
4204
+
4205
+ sage: def check_expansion(x, mode):
4206
+ ....: R = x.parent()
4207
+ ....: E = x.expansion(lift_mode=mode)
4208
+ ....: y = 0
4209
+ ....: for i in range(len(E)):
4210
+ ....: digit = next(E)
4211
+ ....: if mode == 'teichmuller':
4212
+ ....: y += R.teichmuller(digit) << i
4213
+ ....: else:
4214
+ ....: y += R(digit) << i
4215
+ ....: assert(x == y)
4216
+
4217
+ sage: for p in primes(100):
4218
+ ....: x = ZpER(p).random_element()[:20]
4219
+ ....: for mode in [ 'simple', 'smallest', 'teichmuller' ]:
4220
+ ....: check_expansion(x, mode)
4221
+ """
4222
+ if self.current >= self.stop:
4223
+ raise StopIteration
4224
+ if self.mode == simple_mode:
4225
+ return self._next_simple()
4226
+ elif self.mode == smallest_mode:
4227
+ return self._next_smallest()
4228
+ elif self.mode == teichmuller_mode:
4229
+ return self._next_teichmuller()