passagemath-ntl 10.6.33__cp313-cp313-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-ntl might be problematic. Click here for more details.

Files changed (163) hide show
  1. passagemath_ntl-10.6.33.dist-info/METADATA +122 -0
  2. passagemath_ntl-10.6.33.dist-info/RECORD +163 -0
  3. passagemath_ntl-10.6.33.dist-info/WHEEL +5 -0
  4. passagemath_ntl-10.6.33.dist-info/top_level.txt +2 -0
  5. passagemath_ntl.libs/libgcc_s-0cd532bd.so.1 +0 -0
  6. passagemath_ntl.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  7. passagemath_ntl.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  8. passagemath_ntl.libs/libmpfi-2153e8c2.so.0.0.0 +0 -0
  9. passagemath_ntl.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  10. passagemath_ntl.libs/libntl-26885ca2.so.44.0.1 +0 -0
  11. passagemath_ntl.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  12. sage/all__sagemath_ntl.py +7 -0
  13. sage/libs/all__sagemath_ntl.py +3 -0
  14. sage/libs/mpfi/__init__.pxd +287 -0
  15. sage/libs/mpfi/types.pxd +10 -0
  16. sage/libs/ntl/GF2.pxd +18 -0
  17. sage/libs/ntl/GF2E.pxd +28 -0
  18. sage/libs/ntl/GF2EX.pxd +12 -0
  19. sage/libs/ntl/GF2X.pxd +81 -0
  20. sage/libs/ntl/ZZ.pxd +93 -0
  21. sage/libs/ntl/ZZX.pxd +85 -0
  22. sage/libs/ntl/ZZ_p.pxd +28 -0
  23. sage/libs/ntl/ZZ_pE.pxd +37 -0
  24. sage/libs/ntl/ZZ_pEX.pxd +106 -0
  25. sage/libs/ntl/ZZ_pX.pxd +122 -0
  26. sage/libs/ntl/__init__.py +4 -0
  27. sage/libs/ntl/all.py +72 -0
  28. sage/libs/ntl/conversion.pxd +106 -0
  29. sage/libs/ntl/convert.cpython-313-x86_64-linux-musl.so +0 -0
  30. sage/libs/ntl/convert.pxd +7 -0
  31. sage/libs/ntl/convert.pyx +38 -0
  32. sage/libs/ntl/decl.pxi +18 -0
  33. sage/libs/ntl/error.cpython-313-x86_64-linux-musl.so +0 -0
  34. sage/libs/ntl/error.pyx +63 -0
  35. sage/libs/ntl/lzz_p.pxd +20 -0
  36. sage/libs/ntl/lzz_pX.pxd +59 -0
  37. sage/libs/ntl/mat_GF2.pxd +30 -0
  38. sage/libs/ntl/mat_GF2E.pxd +30 -0
  39. sage/libs/ntl/mat_ZZ.pxd +59 -0
  40. sage/libs/ntl/misc.pxi +33 -0
  41. sage/libs/ntl/ntl_GF2.cpython-313-x86_64-linux-musl.so +0 -0
  42. sage/libs/ntl/ntl_GF2.pxd +5 -0
  43. sage/libs/ntl/ntl_GF2.pyx +281 -0
  44. sage/libs/ntl/ntl_GF2E.cpython-313-x86_64-linux-musl.so +0 -0
  45. sage/libs/ntl/ntl_GF2E.pxd +8 -0
  46. sage/libs/ntl/ntl_GF2E.pyx +488 -0
  47. sage/libs/ntl/ntl_GF2EContext.cpython-313-x86_64-linux-musl.so +0 -0
  48. sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
  49. sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
  50. sage/libs/ntl/ntl_GF2EX.cpython-313-x86_64-linux-musl.so +0 -0
  51. sage/libs/ntl/ntl_GF2EX.pxd +10 -0
  52. sage/libs/ntl/ntl_GF2EX.pyx +251 -0
  53. sage/libs/ntl/ntl_GF2X.cpython-313-x86_64-linux-musl.so +0 -0
  54. sage/libs/ntl/ntl_GF2X.pxd +5 -0
  55. sage/libs/ntl/ntl_GF2X.pyx +771 -0
  56. sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
  57. sage/libs/ntl/ntl_ZZ.cpython-313-x86_64-linux-musl.so +0 -0
  58. sage/libs/ntl/ntl_ZZ.pxd +7 -0
  59. sage/libs/ntl/ntl_ZZ.pyx +541 -0
  60. sage/libs/ntl/ntl_ZZX.cpython-313-x86_64-linux-musl.so +0 -0
  61. sage/libs/ntl/ntl_ZZX.pxd +7 -0
  62. sage/libs/ntl/ntl_ZZX.pyx +1206 -0
  63. sage/libs/ntl/ntl_ZZ_p.cpython-313-x86_64-linux-musl.so +0 -0
  64. sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
  65. sage/libs/ntl/ntl_ZZ_p.pyx +509 -0
  66. sage/libs/ntl/ntl_ZZ_pContext.cpython-313-x86_64-linux-musl.so +0 -0
  67. sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
  68. sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
  69. sage/libs/ntl/ntl_ZZ_pE.cpython-313-x86_64-linux-musl.so +0 -0
  70. sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
  71. sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
  72. sage/libs/ntl/ntl_ZZ_pEContext.cpython-313-x86_64-linux-musl.so +0 -0
  73. sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
  74. sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
  75. sage/libs/ntl/ntl_ZZ_pEX.cpython-313-x86_64-linux-musl.so +0 -0
  76. sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
  77. sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
  78. sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
  79. sage/libs/ntl/ntl_ZZ_pX.cpython-313-x86_64-linux-musl.so +0 -0
  80. sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
  81. sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
  82. sage/libs/ntl/ntl_lzz_p.cpython-313-x86_64-linux-musl.so +0 -0
  83. sage/libs/ntl/ntl_lzz_p.pxd +8 -0
  84. sage/libs/ntl/ntl_lzz_p.pyx +440 -0
  85. sage/libs/ntl/ntl_lzz_pContext.cpython-313-x86_64-linux-musl.so +0 -0
  86. sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
  87. sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
  88. sage/libs/ntl/ntl_lzz_pX.cpython-313-x86_64-linux-musl.so +0 -0
  89. sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
  90. sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
  91. sage/libs/ntl/ntl_mat_GF2.cpython-313-x86_64-linux-musl.so +0 -0
  92. sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
  93. sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
  94. sage/libs/ntl/ntl_mat_GF2E.cpython-313-x86_64-linux-musl.so +0 -0
  95. sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
  96. sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
  97. sage/libs/ntl/ntl_mat_ZZ.cpython-313-x86_64-linux-musl.so +0 -0
  98. sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
  99. sage/libs/ntl/ntl_mat_ZZ.pyx +1523 -0
  100. sage/libs/ntl/ntl_tools.pxd +3 -0
  101. sage/libs/ntl/ntlwrap.h +53 -0
  102. sage/libs/ntl/ntlwrap_impl.h +743 -0
  103. sage/libs/ntl/types.pxd +157 -0
  104. sage/libs/ntl/vec_GF2.pxd +26 -0
  105. sage/libs/ntl/vec_GF2E.pxd +2 -0
  106. sage/matrix/all__sagemath_ntl.py +1 -0
  107. sage/matrix/matrix_modn_dense_double.pxd +10 -0
  108. sage/matrix/matrix_modn_dense_float.pxd +9 -0
  109. sage/matrix/matrix_modn_dense_template.pxi +3257 -0
  110. sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
  111. sage/matrix/matrix_modn_sparse.pxd +8 -0
  112. sage/misc/all__sagemath_ntl.py +1 -0
  113. sage/rings/all__sagemath_ntl.py +7 -0
  114. sage/rings/bernmm.cpython-313-x86_64-linux-musl.so +0 -0
  115. sage/rings/bernmm.pyx +161 -0
  116. sage/rings/bernoulli_mod_p.cpython-313-x86_64-linux-musl.so +0 -0
  117. sage/rings/bernoulli_mod_p.pyx +313 -0
  118. sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
  119. sage/rings/finite_rings/finite_field_ntl_gf2e.py +305 -0
  120. sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-313-x86_64-linux-musl.so +0 -0
  121. sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
  122. sage/rings/padics/all__sagemath_ntl.py +5 -0
  123. sage/rings/padics/padic_ZZ_pX_CA_element.cpython-313-x86_64-linux-musl.so +0 -0
  124. sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
  125. sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2368 -0
  126. sage/rings/padics/padic_ZZ_pX_CR_element.cpython-313-x86_64-linux-musl.so +0 -0
  127. sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
  128. sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3277 -0
  129. sage/rings/padics/padic_ZZ_pX_FM_element.cpython-313-x86_64-linux-musl.so +0 -0
  130. sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
  131. sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1739 -0
  132. sage/rings/padics/padic_ZZ_pX_element.cpython-313-x86_64-linux-musl.so +0 -0
  133. sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
  134. sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
  135. sage/rings/padics/padic_ext_element.cpython-313-x86_64-linux-musl.so +0 -0
  136. sage/rings/padics/padic_ext_element.pxd +38 -0
  137. sage/rings/padics/padic_ext_element.pyx +512 -0
  138. sage/rings/padics/pow_computer_ext.cpython-313-x86_64-linux-musl.so +0 -0
  139. sage/rings/padics/pow_computer_ext.pxd +107 -0
  140. sage/rings/padics/pow_computer_ext.pyx +2401 -0
  141. sage/rings/polynomial/all__sagemath_ntl.py +1 -0
  142. sage/rings/polynomial/evaluation_ntl.cpython-313-x86_64-linux-musl.so +0 -0
  143. sage/rings/polynomial/evaluation_ntl.pxd +7 -0
  144. sage/rings/polynomial/evaluation_ntl.pyx +70 -0
  145. sage/rings/polynomial/polynomial_gf2x.cpython-313-x86_64-linux-musl.so +0 -0
  146. sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
  147. sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
  148. sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-313-x86_64-linux-musl.so +0 -0
  149. sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
  150. sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
  151. sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-313-x86_64-linux-musl.so +0 -0
  152. sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
  153. sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2049 -0
  154. sage/rings/polynomial/polynomial_template.pxi +842 -0
  155. sage/rings/polynomial/polynomial_template_header.pxi +11 -0
  156. sage/rings/polynomial/polynomial_zz_pex.cpython-313-x86_64-linux-musl.so +0 -0
  157. sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
  158. sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
  159. sage/rings/real_mpfi.pxd +50 -0
  160. sage/schemes/all__sagemath_ntl.py +1 -0
  161. sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
  162. sage/schemes/hyperelliptic_curves/hypellfrob.cpython-313-x86_64-linux-musl.so +0 -0
  163. sage/schemes/hyperelliptic_curves/hypellfrob.pyx +252 -0
@@ -0,0 +1,3277 @@
1
+ # sage_setup: distribution = sagemath-ntl
2
+ # distutils: libraries = NTL_LIBRARIES gmp M_LIBRARIES
3
+ # distutils: extra_compile_args = NTL_CFLAGS
4
+ # distutils: include_dirs = NTL_INCDIR
5
+ # distutils: library_dirs = NTL_LIBDIR
6
+ # distutils: extra_link_args = NTL_LIBEXTRA
7
+ # distutils: language = c++
8
+ # sage.doctest: needs sage.rings.padics
9
+ r"""
10
+ `p`-adic ``ZZ_pX`` CR Element
11
+
12
+ This file implements elements of Eisenstein and unramified extensions
13
+ of `\ZZ_p` and `\QQ_p` with capped relative precision.
14
+
15
+ For the parent class see :mod:`sage.rings.padics.padic_extension_leaves`.
16
+
17
+ The underlying implementation is through NTL's ``ZZ_pX`` class. Each
18
+ element contains the following data:
19
+
20
+ - ``ordp`` -- ``long``; a power of the uniformizer to scale the unit
21
+ by. For unramified extensions this uniformizer is `p`, for Eisenstein
22
+ extensions it is not. A value equal to the maximum value of a ``long``
23
+ indicates that the element is an exact zero.
24
+
25
+ - ``relprec`` -- ``long``; a signed integer giving the precision to
26
+ which this element is defined. For nonzero ``relprec``, the
27
+ absolute value gives the power of the uniformizer modulo which the
28
+ unit is defined. A positive value indicates that the element is
29
+ normalized (ie ``unit`` is actually a unit: in the case of
30
+ Eisenstein extensions the constant term is not divisible by `p`, in
31
+ the case of unramified extensions that there is at least one
32
+ coefficient that is not divisible by `p`). A negative value
33
+ indicates that the element may or may not be normalized. A zero
34
+ value indicates that the element is zero to some precision. If so,
35
+ ``ordp`` gives the absolute precision of the element. If ``ordp``
36
+ is greater than ``maxordp``, then the element is an exact zero.
37
+
38
+ - ``unit`` -- ``ZZ_pX_c``; an ntl ``ZZ_pX`` storing the unit part
39
+ The variable `x` is the uniformizer in the case of Eisenstein
40
+ extensions. If the element is not normalized, the ``unit`` may or
41
+ may not actually be a unit. This ``ZZ_pX`` is created with global
42
+ ntl modulus determined by the absolute value of ``relprec``. If
43
+ ``relprec`` is 0, ``unit`` **is not initialized**, or destructed if
44
+ normalized and found to be zero. Otherwise, let `r` be ``relprec`` and
45
+ `e` be the ramification index over `\QQ_p` or `\ZZ_p`.
46
+ Then the modulus of unit is given by `p^{ceil(r/e)}`. Note that all
47
+ kinds of problems arise if you try to mix moduli.
48
+ ``ZZ_pX_conv_modulus`` gives a semi-safe way to convert between
49
+ different moduli without having to pass through ``ZZX``.
50
+
51
+ - ``prime_pow`` (some subclass of :class:`PowComputer_ZZ_pX`) -- a class,
52
+ identical among all elements with the same parent, holding common
53
+ data.
54
+
55
+ + ``prime_pow.deg`` -- the degree of the extension
56
+
57
+ + ``prime_pow.e`` -- the ramification index
58
+
59
+ + ``prime_pow.f`` -- the inertia degree
60
+
61
+ + ``prime_pow.prec_cap`` -- the unramified precision cap. For
62
+ Eisenstein extensions this is the smallest power of `p` that is
63
+ zero.
64
+
65
+ + ``prime_pow.ram_prec_cap`` -- the ramified precision cap. For
66
+ Eisenstein extensions this will be the smallest power of `x` that
67
+ is indistinguishable from zero.
68
+
69
+ + ``prime_pow.pow_ZZ_tmp``, prime_pow.pow_mpz_t_tmp``,
70
+ ``prime_pow.pow_Integer`` -- functions for accessing powers of
71
+ `p`. The first two return pointers. See
72
+ :mod:`sage.rings.padics.pow_computer_ext` for examples and important
73
+ warnings.
74
+
75
+ + ``prime_pow.get_context``, ``prime_pow.get_context_capdiv``,
76
+ ``prime_pow.get_top_context`` -- obtain an
77
+ ``ntl_ZZ_pContext_class`` corresponding to `p^n`. The capdiv
78
+ version divides by ``prime_pow.e`` as appropriate.
79
+ ``top_context`` corresponds to `p^{\texttt{prec\_cap}}`.
80
+
81
+ + ``prime_pow.restore_context``,
82
+ ``prime_pow.restore_context_capdiv``,
83
+ ``prime_pow.restore_top_context`` -- restores the given context.
84
+
85
+ + ``prime_pow.get_modulus``, ``get_modulus_capdiv``,
86
+ ``get_top_modulus`` -- returns a ``ZZ_pX_Modulus_c*`` pointing to
87
+ a polynomial modulus defined modulo `p^n` (appropriately divided
88
+ by ``prime_pow.e`` in the capdiv case).
89
+
90
+ EXAMPLES:
91
+
92
+ An Eisenstein extension::
93
+
94
+ sage: R = Zp(5,5)
95
+ sage: S.<x> = R[]
96
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
97
+ sage: W.<w> = R.ext(f); W
98
+ 5-adic Eisenstein Extension Ring in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
99
+ sage: z = (1+w)^5; z
100
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
101
+ sage: y = z >> 1; y
102
+ w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
103
+ sage: y.valuation()
104
+ 4
105
+ sage: y.precision_relative()
106
+ 20
107
+ sage: y.precision_absolute()
108
+ 24
109
+ sage: z - (y << 1)
110
+ 1 + O(w^25)
111
+ sage: (1/w)^12+w
112
+ w^-12 + w + O(w^13)
113
+ sage: (1/w).parent()
114
+ 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
115
+
116
+ Unramified extensions::
117
+
118
+ sage: g = x^3 + 3*x + 3
119
+ sage: A.<a> = R.ext(g)
120
+ sage: z = (1+a)^5; z
121
+ (2*a^2 + 4*a) + (3*a^2 + 3*a + 1)*5 + (4*a^2 + 3*a + 4)*5^2 + (4*a^2 + 4*a + 4)*5^3 + (4*a^2 + 4*a + 4)*5^4 + O(5^5)
122
+ sage: z - 1 - 5*a - 10*a^2 - 10*a^3 - 5*a^4 - a^5
123
+ O(5^5)
124
+ sage: y = z >> 1; y
125
+ (3*a^2 + 3*a + 1) + (4*a^2 + 3*a + 4)*5 + (4*a^2 + 4*a + 4)*5^2 + (4*a^2 + 4*a + 4)*5^3 + O(5^4)
126
+ sage: 1/a
127
+ (3*a^2 + 4) + (a^2 + 4)*5 + (3*a^2 + 4)*5^2 + (a^2 + 4)*5^3 + (3*a^2 + 4)*5^4 + O(5^5)
128
+ sage: FFp = R.residue_field()
129
+ sage: R(FFp(3))
130
+ 3 + O(5)
131
+ sage: QQq.<zz> = Qq(25,4)
132
+ sage: QQq(FFp(3))
133
+ 3 + O(5)
134
+ sage: FFq = QQq.residue_field(); QQq(FFq(3))
135
+ 3 + O(5)
136
+ sage: zz0 = FFq.gen(); QQq(zz0^2)
137
+ (zz + 3) + O(5)
138
+
139
+ Different printing modes::
140
+
141
+ sage: R = Zp(5, print_mode='digits'); S.<x> = R[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
142
+ sage: z = (1+w)^5; repr(z)
143
+ '...4110403113210310442221311242000111011201102002023303214332011214403232013144001400444441030421100001'
144
+ sage: R = Zp(5, print_mode='bars'); S.<x> = R[]; g = x^3 + 3*x + 3; A.<a> = R.ext(g)
145
+ sage: z = (1+a)^5; repr(z)
146
+ '...[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 3, 4]|[1, 3, 3]|[0, 4, 2]'
147
+ sage: R = Zp(5, print_mode='terse'); S.<x> = R[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
148
+ sage: z = (1+w)^5; z
149
+ 6 + 95367431640505*w + 25*w^2 + 95367431640560*w^3 + 5*w^4 + O(w^100)
150
+ sage: R = Zp(5, print_mode='val-unit'); S.<x> = R[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
151
+ sage: y = (1+w)^5 - 1; y
152
+ w^5 * (2090041 + 19073486126901*w + 1258902*w^2 + 674*w^3 + 16785*w^4) + O(w^100)
153
+
154
+ You can get at the underlying ntl unit::
155
+
156
+ sage: z._ntl_rep()
157
+ [6 95367431640505 25 95367431640560 5]
158
+ sage: y._ntl_rep()
159
+ [2090041 19073486126901 1258902 674 16785]
160
+ sage: y._ntl_rep_abs()
161
+ ([5 95367431640505 25 95367431640560 5], 0)
162
+
163
+ .. NOTE::
164
+
165
+ If you get an error ``internal error: can't grow this _ntl_gbigint,``
166
+ it indicates that moduli are being mixed inappropriately somewhere.
167
+
168
+ For example, when calling a function with a ``ZZ_pX_c`` as an
169
+ argument, it copies. If the modulus is not
170
+ set to the modulus of the ``ZZ_pX_c``, you can get errors.
171
+
172
+ AUTHORS:
173
+
174
+ - David Roe (2008-01-01): initial version
175
+
176
+ - Robert Harron (2011-09): fixes/enhancements
177
+
178
+ - Julian Rueth (2014-05-09): enable caching through ``_cache_key``
179
+ """
180
+ # ****************************************************************************
181
+ # Copyright (C) 2008 David Roe <roed.math@gmail.com>
182
+ # William Stein <wstein@gmail.com>
183
+ # 2014 Julian Rueth <julian.rueth@fsfe.org>
184
+ #
185
+ # Distributed under the terms of the GNU General Public License (GPL)
186
+ # as published by the Free Software Foundation; either version 2 of
187
+ # the License, or (at your option) any later version.
188
+ #
189
+ # https://www.gnu.org/licenses/
190
+ # ****************************************************************************
191
+
192
+ from cysignals.signals cimport sig_on, sig_off
193
+ from sage.ext.stdsage cimport PY_NEW
194
+ include "sage/libs/ntl/decl.pxi"
195
+
196
+ from sage.rings.integer cimport Integer
197
+ from sage.rings.rational cimport Rational
198
+ from sage.libs.gmp.mpz cimport *
199
+ from sage.libs.gmp.mpq cimport *
200
+ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
201
+ from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
202
+ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p
203
+ from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
204
+ from sage.rings.padics.padic_generic_element cimport pAdicGenericElement
205
+ from cypari2.gen import Gen as pari_gen
206
+ from sage.interfaces.abc import GpElement
207
+ from sage.rings.finite_rings.integer_mod import IntegerMod_abstract
208
+ from sage.rings.padics.padic_ext_element cimport pAdicExtElement
209
+ from sage.rings.padics.precision_error import PrecisionError
210
+
211
+ from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_small_Eis
212
+ from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_big_Eis
213
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
214
+
215
+ cdef object infinity
216
+ from sage.rings.infinity import infinity
217
+
218
+ cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) -1
219
+ cdef long minusmaxordp = -maxordp
220
+
221
+ cdef inline int check_ordp(long a) except -1:
222
+ if a > maxordp or a < minusmaxordp:
223
+ raise ValueError("valuation overflow")
224
+
225
+
226
+ cdef class pAdicZZpXCRElement(pAdicZZpXElement):
227
+ def __init__(self, parent, x, absprec=infinity, relprec=infinity, empty=False):
228
+ r"""
229
+ Create an element of a capped relative precision, unramified
230
+ or Eisenstein extension of `\ZZ_p` or `\QQ_p`.
231
+
232
+ INPUT:
233
+
234
+ - ``parent`` -- either an ``EisensteinRingCappedRelative`` or
235
+ ``UnramifiedRingCappedRelative``
236
+
237
+ - ``x`` -- integer; rational, `p`-adic element, polynomial,
238
+ list, integer_mod, pari int/frac/poly_t/pol_mod, an
239
+ ``ntl_ZZ_pX``, an ``ntl_ZZ``, an ``ntl_ZZ_p``, an
240
+ ``ntl_ZZX``, or something convertible into parent.residue_field()
241
+
242
+ - ``absprec`` -- an upper bound on the absolute precision of the
243
+ element created
244
+
245
+ - ``relprec`` -- an upper bound on the relative precision of
246
+ the element created
247
+
248
+ - ``empty`` -- whether to return after initializing to zero
249
+ (without setting the valuation)
250
+
251
+ EXAMPLES::
252
+
253
+ sage: R = Zp(5,5)
254
+ sage: S.<x> = R[]
255
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
256
+ sage: W.<w> = R.ext(f)
257
+ sage: z = (1+w)^5; z # indirect doctest
258
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
259
+ sage: W(pari('3 + O(5^3)'))
260
+ 3 + O(w^15)
261
+ sage: W(R(3,3))
262
+ 3 + O(w^15)
263
+ sage: W.<w> = R.ext(x^625 + 915*x^17 - 95)
264
+ sage: W(3)
265
+ 3 + O(w^3125)
266
+ sage: W(w, 14)
267
+ w + O(w^14)
268
+
269
+ TESTS:
270
+
271
+ Check that :issue:`3865` is fixed::
272
+
273
+ sage: W(gp('3 + O(5^10)'))
274
+ 3 + O(w^3125)
275
+
276
+
277
+ Check that :issue:`13612` has been fixed::
278
+
279
+ sage: R = Zp(3)
280
+ sage: S.<a> = R[]
281
+ sage: W.<a> = R.extension(a^2 + 1)
282
+ sage: W(W.residue_field().zero())
283
+ O(3)
284
+
285
+ sage: K = Qp(3)
286
+ sage: S.<a> = K[]
287
+ sage: L.<a> = K.extension(a^2 + 1)
288
+ sage: L(L.residue_field().zero())
289
+ O(3)
290
+ """
291
+ pAdicZZpXElement.__init__(self, parent)
292
+ self.relprec = 0
293
+ if empty:
294
+ return
295
+ cdef long aprec, rprec, ctx_prec, ltmp
296
+ if relprec is not infinity and not isinstance(relprec, Integer):
297
+ relprec = Integer(relprec)
298
+ if (relprec is infinity) or (relprec > parent.precision_cap()):
299
+ rprec = self.prime_pow.ram_prec_cap
300
+ else:
301
+ rprec = mpz_get_si((<Integer>relprec).value)
302
+ if rprec < 0:
303
+ rprec = 0
304
+ if absprec is not infinity:
305
+ if not isinstance(absprec, Integer):
306
+ absprec = Integer(absprec)
307
+ if mpz_fits_slong_p((<Integer>absprec).value) == 0:
308
+ absprec = infinity
309
+ else:
310
+ aprec = mpz_get_si((<Integer>absprec).value)
311
+ cdef mpz_t tmp
312
+ cdef ZZ_c tmp_z
313
+ cdef Py_ssize_t i
314
+ cdef Integer tmp_Int
315
+ cdef Rational xlift
316
+ if isinstance(x, pAdicGenericElement):
317
+ if self.prime_pow.in_field == 0 and x.valuation() < 0:
318
+ raise ValueError("element has negative valuation")
319
+ if x._is_base_elt(self.prime_pow.prime):
320
+ xlift = Rational(x.lift())
321
+ if mpq_sgn(xlift.value) == 0:
322
+ if (<pAdicGenericElement>x)._is_exact_zero():
323
+ if absprec is infinity:
324
+ self._set_exact_zero()
325
+ else:
326
+ self._set_inexact_zero(aprec)
327
+ return
328
+ ltmp = mpz_get_si((<Integer>x.precision_absolute()).value) * self.prime_pow.e
329
+ if absprec is infinity or ltmp < aprec:
330
+ aprec = ltmp
331
+ self._set_from_mpq_both(xlift.value, aprec, rprec)
332
+ return
333
+ if isinstance(x, GpElement):
334
+ x = x.__pari__()
335
+ if isinstance(x, pari_gen):
336
+ if x.type() == "t_PADIC":
337
+ if x.variable() != self.prime_pow.prime:
338
+ raise TypeError("cannot coerce a pari p-adic with the wrong prime")
339
+ ltmp = x.padicprec(self.prime_pow.prime) * self.prime_pow.e
340
+ if absprec is infinity or ltmp < aprec:
341
+ aprec = ltmp
342
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
343
+ x = x.lift()
344
+ if x.type() == 't_INT':
345
+ x = Integer(x)
346
+ elif x.type() == 't_FRAC':
347
+ x = Rational(x)
348
+ elif x.type() == 't_POLMOD' or x.type == 't_POL':
349
+ # This code doesn't check to see if the primes are the same.
350
+ L = []
351
+ x = x.lift().lift()
352
+ for i from 0 <= i <= x.poldegree():
353
+ L.append(Integer(x.polcoef(i)))
354
+ x = L
355
+ else:
356
+ raise TypeError("unsupported coercion from pari: only p-adics, integers, rationals, polynomials and pol_mods allowed")
357
+ elif isinstance(x, IntegerMod_abstract):
358
+ mpz_init(tmp)
359
+ ctx_prec = mpz_remove(tmp, (<Integer>x.modulus()).value, self.prime_pow.prime.value)
360
+ if mpz_cmp_ui(tmp, 1) == 0:
361
+ mpz_clear(tmp)
362
+ x = x.lift()
363
+ if absprec is infinity or ctx_prec < aprec:
364
+ aprec = ctx_prec
365
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
366
+ else:
367
+ mpz_clear(tmp)
368
+ raise TypeError("cannot coerce from the given integer mod ring (not a power of the same prime)")
369
+ elif isinstance(x, ntl_ZZ_p):
370
+ ctx_prec = ZZ_remove(tmp_z, (<ntl_ZZ>x.modulus()).x, self.prime_pow.pow_ZZ_tmp(1)[0])
371
+ if ZZ_IsOne(tmp_z):
372
+ x = x.lift()
373
+ tmp_Int = PY_NEW(Integer)
374
+ ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
375
+ x = tmp_Int
376
+ if absprec is infinity or ctx_prec < aprec:
377
+ aprec = ctx_prec
378
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
379
+ else:
380
+ raise TypeError("cannot coerce the given ntl_ZZ_p (modulus not a power of the same prime)")
381
+ elif isinstance(x, ntl_ZZ):
382
+ tmp_Int = PY_NEW(Integer)
383
+ ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
384
+ x = tmp_Int
385
+ elif isinstance(x, int):
386
+ x = Integer(x)
387
+ elif x in parent.residue_field() and x.parent().is_finite():
388
+ # Should only reach here if x is not in F_p
389
+ z = parent.gen()
390
+ poly = x.polynomial().list()
391
+ x = sum([poly[i].lift() * (z ** i) for i in range(len(poly))], parent.zero())
392
+ if absprec is infinity or 1 < aprec:
393
+ aprec = 1
394
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
395
+ cdef pAdicZZpXCRElement _x
396
+ if isinstance(x, Integer):
397
+ if absprec is infinity:
398
+ self._set_from_mpz_rel((<Integer>x).value, rprec)
399
+ else:
400
+ self._set_from_mpz_both((<Integer>x).value, aprec, rprec)
401
+ elif isinstance(x, Rational):
402
+ if absprec is infinity:
403
+ self._set_from_mpq_rel((<Rational>x).value, rprec)
404
+ else:
405
+ self._set_from_mpq_both((<Rational>x).value, aprec, rprec)
406
+ elif isinstance(x, ntl_ZZ_pX):
407
+ if absprec is infinity:
408
+ self._set_from_ZZ_pX_rel(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, rprec)
409
+ else:
410
+ self._set_from_ZZ_pX_both(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, aprec, rprec)
411
+ elif isinstance(x, ntl_ZZX):
412
+ if absprec is infinity:
413
+ self._set_from_ZZX_rel((<ntl_ZZX>x).x, rprec)
414
+ else:
415
+ self._set_from_ZZX_both((<ntl_ZZX>x).x, aprec, rprec)
416
+ elif isinstance(x, pAdicExtElement):
417
+ if x.parent() is parent:
418
+ _x = <pAdicZZpXCRElement>x
419
+ if _x.relprec == 0:
420
+ if absprec is infinity or aprec > _x.ordp:
421
+ self._set_inexact_zero(_x.ordp) # this works for exact zeros too.
422
+ else:
423
+ self._set_inexact_zero(aprec)
424
+ elif _x.relprec < 0:
425
+ if -_x.relprec < rprec:
426
+ rprec = _x.relprec
427
+ else:
428
+ rprec = -rprec
429
+ if absprec is infinity or aprec > _x.ordp - rprec:
430
+ self._set(&_x.unit, _x.ordp, rprec)
431
+ elif aprec > _x.ordp:
432
+ self._set(&_x.unit, _x.ordp, _x.ordp - aprec) #negating relprec to indicate non-normalized.
433
+ else:
434
+ self._set_inexact_zero(aprec)
435
+ else:
436
+ if _x.relprec < rprec:
437
+ rprec = _x.relprec
438
+ if absprec is infinity or aprec > _x.ordp + rprec:
439
+ self._set(&_x.unit, _x.ordp, rprec)
440
+ elif aprec > _x.ordp:
441
+ self._set(&_x.unit, _x.ordp, aprec - _x.ordp)
442
+ else:
443
+ self._set_inexact_zero(aprec)
444
+ elif x.parent().fraction_field() is parent:
445
+ if isinstance(x, pAdicZZpXCRElement):
446
+ _x = <pAdicZZpXCRElement>x
447
+ if _x.relprec < 0:
448
+ _x._normalize()
449
+ if _x._is_exact_zero():
450
+ self._set_exact_zero()
451
+ elif _x._is_inexact_zero():
452
+ self._set_inexact_zero(_x.ordp)
453
+ else:
454
+ if _x.relprec < rprec:
455
+ rprec = _x.relprec
456
+ self._set(&_x.unit, _x.ordp, rprec)
457
+ else:
458
+ # x is a pAdicZZpXCAElement
459
+ xordp = x.valuation()
460
+ xprec = x.precision_absolute()
461
+ if xordp == xprec:
462
+ self._set_inexact_zero(mpz_get_si((<Integer>xordp).value))
463
+ else:
464
+ poly = x._ntl_rep_abs()[0]
465
+ if absprec is infinity:
466
+ self._set_from_ZZ_pX_rel(&(<ntl_ZZ_pX>poly).x,(<ntl_ZZ_pX>poly).c, rprec)
467
+ else:
468
+ self._set_from_ZZ_pX_both(&(<ntl_ZZ_pX>poly).x,(<ntl_ZZ_pX>poly).c, aprec, rprec)
469
+ elif x.parent() is parent.fraction_field():
470
+ _x = <pAdicZZpXCRElement>x
471
+ if _x.relprec < 0:
472
+ _x._normalize()
473
+ if _x._is_exact_zero():
474
+ self._set_exact_zero()
475
+ elif _x._is_inexact_zero():
476
+ self._set_inexact_zero(_x.ordp)
477
+ else:
478
+ if _x.relprec < rprec:
479
+ rprec = _x.relprec
480
+ self._set(&_x.unit, _x.ordp, rprec)
481
+ else:
482
+ raise NotImplementedError("conversion from different p-adic extensions not yet supported")
483
+ else:
484
+ try:
485
+ x = list(x)
486
+ except TypeError:
487
+ try:
488
+ x = x.list()
489
+ except AttributeError:
490
+ raise TypeError("cannot convert x to a p-adic element")
491
+ if absprec is infinity:
492
+ self._set_from_list_rel(x, rprec)
493
+ else:
494
+ self._set_from_list_both(x, aprec, rprec)
495
+
496
+ def _cache_key(self):
497
+ r"""
498
+ Return a hashable key which identifies this element.
499
+
500
+ This makes it possible to use this element in caches such as
501
+ functions or methods decorated with ``@cached_function`` or
502
+ ``@cached_method`` respectively.
503
+
504
+ EXAMPLES:
505
+
506
+ In the following example, ``a`` and ``b`` compare equal. They cannot
507
+ have a meaningful hash value since then their hash value would have to
508
+ be the same::
509
+
510
+ sage: K.<a> = Qq(9)
511
+ sage: b = a + O(3)
512
+ sage: a == b
513
+ True
514
+ sage: hash(a)
515
+ Traceback (most recent call last):
516
+ ...
517
+ TypeError: ...unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement'...
518
+
519
+ However, we want to cache computations which depend on them. Therefore
520
+ they define a ``_cache_key`` which is hashable and uniquely identifies
521
+ them::
522
+
523
+ sage: a._cache_key()
524
+ (..., ((0, 1),), 0, 20)
525
+ sage: b._cache_key()
526
+ (..., ((0, 1),), 0, 1)
527
+
528
+ TESTS:
529
+
530
+ Check that zero values are handled correctly::
531
+
532
+ sage: K.zero()._cache_key()
533
+ (..., 0)
534
+ sage: K(0,1)._cache_key()
535
+ (..., 1, 0)
536
+ """
537
+ if self._is_exact_zero():
538
+ return (self.parent(), 0)
539
+ elif self._is_inexact_zero():
540
+ return (self.parent(), 0, self.valuation())
541
+ else:
542
+ return (self.parent(),
543
+ tuple(tuple(c) if isinstance(c, list) else c
544
+ for c in self.unit_part().expansion()),
545
+ self.valuation(), self.precision_relative())
546
+
547
+ cdef int _set_inexact_zero(self, long absprec) except -1:
548
+ """
549
+ Set ``self`` to be zero with valuation absprec.
550
+
551
+ EXAMPLES::
552
+
553
+ sage: R = Zp(5,5)
554
+ sage: S.<x> = R[]
555
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
556
+ sage: W.<w> = R.ext(f)
557
+ sage: z = W(0,6); z # indirect doctest
558
+ O(w^6)
559
+ sage: z.valuation()
560
+ 6
561
+ sage: z.precision_absolute()
562
+ 6
563
+ sage: z.precision_relative()
564
+ 0
565
+
566
+ TESTS::
567
+
568
+ sage: R = Zp(17, 3)
569
+ sage: S.<x> = R[]
570
+ sage: W.<w> = R.ext(x^34 - 289*x^5 + 17)
571
+ sage: z = W(0, 6); z
572
+ O(w^6)
573
+ sage: z.valuation()
574
+ 6
575
+ sage: z.precision_absolute()
576
+ 6
577
+ sage: z.precision_relative()
578
+ 0
579
+ """
580
+ self.ordp = absprec
581
+ self.relprec = 0
582
+
583
+ cdef int _set_exact_zero(self) except -1:
584
+ """
585
+ Set ``self`` to be an exact zero.
586
+
587
+ EXAMPLES::
588
+
589
+ sage: R = Zp(5,5)
590
+ sage: S.<x> = R[]
591
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
592
+ sage: W.<w> = R.ext(f)
593
+ sage: z = R(0); z # indirect doctest
594
+ 0
595
+ sage: z.valuation()
596
+ +Infinity
597
+ sage: z.precision_absolute()
598
+ +Infinity
599
+ sage: z.precision_relative()
600
+ 0
601
+
602
+ TESTS::
603
+
604
+ sage: R = Zp(89, 3)
605
+ sage: S.<x> = R[]
606
+ sage: W.<w> = R.ext(x^34 - 2*89*x^5 + 89)
607
+ sage: z = R(0); z # indirect doctest
608
+ 0
609
+ sage: z.valuation()
610
+ +Infinity
611
+ sage: z.precision_absolute()
612
+ +Infinity
613
+ sage: z.precision_relative()
614
+ 0
615
+ """
616
+ self.ordp = maxordp
617
+ self.relprec = 0
618
+
619
+ cpdef bint _is_exact_zero(self) except -1:
620
+ """
621
+ Test if ``self`` is an exact zero.
622
+
623
+ EXAMPLES::
624
+
625
+ sage: R = Qp(3,5)
626
+ sage: S.<x> = R[]
627
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
628
+ sage: W.<w> = R.ext(f)
629
+ sage: z = W(0)
630
+ sage: z._is_exact_zero()
631
+ True
632
+ sage: z = W(0,6)
633
+ sage: z._is_exact_zero()
634
+ False
635
+
636
+ TESTS::
637
+
638
+ sage: R = Qp(53, 3)
639
+ sage: S.<x> = R[]
640
+ sage: W.<w> = R.ext(x^34 - 2*53^5*x^9 + 53)
641
+ sage: z = W(0)
642
+ sage: z._is_exact_zero()
643
+ True
644
+ sage: z = W(0,6)
645
+ sage: z._is_exact_zero()
646
+ False
647
+ """
648
+ if self.ordp == maxordp:
649
+ return 1
650
+ else:
651
+ return 0
652
+
653
+ cpdef bint _is_inexact_zero(self) except -1:
654
+ """
655
+ Test if ``self`` is an inexact zero.
656
+
657
+ EXAMPLES::
658
+
659
+ sage: R = Zp(7,5)
660
+ sage: S.<x> = R[]
661
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
662
+ sage: W.<w> = R.ext(f)
663
+ sage: z = W(0)
664
+ sage: z._is_inexact_zero()
665
+ False
666
+ sage: z = W(0,6)
667
+ sage: z._is_inexact_zero()
668
+ True
669
+
670
+ TESTS::
671
+
672
+ sage: R = Qp(29, 3)
673
+ sage: S.<x> = R[]
674
+ sage: W.<w> = R.ext(x^29 - 2*29^5*x - 29)
675
+ sage: z = W(0)
676
+ sage: z._is_inexact_zero()
677
+ False
678
+ sage: z = W(0,6)
679
+ sage: z._is_inexact_zero()
680
+ True
681
+ """
682
+ self._normalize()
683
+ if self.relprec == 0:
684
+ return not self._is_exact_zero()
685
+ else:
686
+ return False
687
+
688
+ cdef int _set(self, ZZ_pX_c* unit, long ordp, long relprec) except -1:
689
+ """
690
+ Set ``unit``, ``ordp`` and ``relprec`` directly.
691
+
692
+ EXAMPLES::
693
+
694
+ sage: R = Zp(5,5)
695
+ sage: S.<x> = R[]
696
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
697
+ sage: W.<w> = R.ext(f)
698
+ sage: F = W.fraction_field()
699
+ sage: z = F(1 + w); z # indirect doctest
700
+ 1 + w + O(w^25)
701
+
702
+ TESTS::
703
+
704
+ sage: R = Zp(17,30)
705
+ sage: S.<x> = R[]
706
+ sage: f = x^51 - 34
707
+ sage: W.<w> = R.ext(f)
708
+ sage: F = W.fraction_field()
709
+ sage: z = F(1 + w); z # indirect doctest
710
+ 1 + w + O(w^1530)
711
+ sage: z = F(w + w^2, relprec=0); z
712
+ O(w)
713
+ """
714
+ self.ordp = ordp
715
+ self._set_prec_rel(relprec)
716
+ if self.relprec != 0:
717
+ ZZ_pX_conv_modulus(self.unit, unit[0], self.prime_pow.get_context_capdiv(relprec).x)
718
+
719
+ cdef int _set_from_mpz_rel(self, mpz_t x, long relprec) except -1:
720
+ """
721
+ Set ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec``.
722
+
723
+ EXAMPLES::
724
+
725
+ sage: R = Zp(5,5)
726
+ sage: S.<x> = R[]
727
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
728
+ sage: W.<w> = R.ext(f)
729
+ sage: W(70, relprec=8) # indirect doctest
730
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
731
+ sage: W(70, relprec=0)
732
+ O(w^5)
733
+
734
+ TESTS::
735
+
736
+ sage: R = Qp(13,50)
737
+ sage: S.<x> = R[]
738
+ sage: f = x^169 - 13
739
+ sage: W.<w> = R.ext(f)
740
+ sage: a = W(65, relprec=8); a.valuation() # indirect doctest
741
+ 169
742
+ sage: W(65, relprec=0)
743
+ O(w^169)
744
+ """
745
+ if mpz_sgn(x) == 0:
746
+ self._set_exact_zero()
747
+ return 0
748
+ cdef mpz_t tmp_m
749
+ cdef ZZ_c tmp_z
750
+ cdef long shift
751
+ mpz_init(tmp_m)
752
+ sig_on()
753
+ shift = mpz_remove(tmp_m, x, self.prime_pow.prime.value)
754
+ sig_off()
755
+ self._set_prec_rel(relprec)
756
+ mpz_to_ZZ(&tmp_z, tmp_m)
757
+ mpz_clear(tmp_m)
758
+ if self.relprec != 0:
759
+ ZZ_pX_SetCoeff(self.unit, 0, ZZ_to_ZZ_p(tmp_z))
760
+ self.ordp = 0
761
+ self._pshift_self(shift)
762
+ else:
763
+ self.ordp = shift * self.prime_pow.e
764
+
765
+ cdef int _set_from_mpz_both(self, mpz_t x, long absprec, long relprec) except -1:
766
+ """
767
+ Set ``self`` from an ``mpz_t`` with relative precision bounded by ``relprec``
768
+ and absolute precision bounded by ``absprec``.
769
+
770
+ EXAMPLES::
771
+
772
+ sage: R = Zp(5,5)
773
+ sage: S.<x> = R[]
774
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
775
+ sage: W.<w> = R.ext(f)
776
+ sage: W(70, 8) # indirect doctest
777
+ 4*w^5 + 3*w^7 + O(w^8)
778
+ sage: W(70, absprec=4)
779
+ O(w^4)
780
+
781
+ TESTS::
782
+
783
+ sage: R = Zp(7,3)
784
+ sage: S.<x> = R[]
785
+ sage: f = x^49 + 7*x^21 - 14
786
+ sage: W.<w> = R.ext(f)
787
+ sage: W(70, 100) # indirect doctest
788
+ 5*w^49 + 6*w^70 + 3*w^91 + O(w^100)
789
+ sage: W(70, absprec=4)
790
+ O(w^4)
791
+ """
792
+ if mpz_sgn(x) == 0:
793
+ self._set_inexact_zero(absprec)
794
+ return 0
795
+ cdef mpz_t tmp_m
796
+ cdef ZZ_c tmp_z
797
+ cdef long shift
798
+ mpz_init(tmp_m)
799
+ sig_on()
800
+ shift = mpz_remove(tmp_m, x, self.prime_pow.prime.value)
801
+ sig_off()
802
+ self.ordp = shift * self.prime_pow.e
803
+ if self._set_prec_both(absprec, relprec) == 1:
804
+ # This indicates that self._set_inexact_zero was called
805
+ mpz_clear(tmp_m)
806
+ return 0
807
+ mpz_to_ZZ(&tmp_z, tmp_m)
808
+ mpz_clear(tmp_m)
809
+ if self.relprec != 0:
810
+ ZZ_pX_SetCoeff(self.unit, 0, ZZ_to_ZZ_p(tmp_z))
811
+ self.ordp = 0
812
+ self._pshift_self(shift)
813
+
814
+ cdef int _set_from_mpq_rel(self, mpq_t x, long relprec) except -1:
815
+ """
816
+ Set ``self`` from an ``mpq_t`` with relative precision
817
+ bounded by ``relprec``.
818
+
819
+ EXAMPLES::
820
+
821
+ sage: R = Zp(5,5)
822
+ sage: S.<x> = R[]
823
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
824
+ sage: W.<w> = R.ext(f)
825
+ sage: z = W(70/3, relprec=9); z # indirect doctest
826
+ 3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + O(w^14)
827
+ sage: z * 3
828
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + O(w^14)
829
+ sage: W(70)
830
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + 3*w^16 + w^17 + w^18 + 4*w^20 + 4*w^21 + w^22 + 2*w^23 + 3*w^25 + w^27 + O(w^30)
831
+ sage: F = W.fraction_field()
832
+ sage: y = F(3/700); y
833
+ w^-10 + w^-8 + 4*w^-6 + w^-3 + 4*w^-2 + 3*w^-1 + 3 + 4*w + w^3 + 4*w^4 + w^5 + 4*w^6 + 2*w^7 + 3*w^8 + 4*w^9 + 3*w^10 + 4*w^11 + w^12 + O(w^15)
834
+ sage: y * 700
835
+ 3 + O(w^25)
836
+ sage: W(70/3, relprec=0)
837
+ O(w^5)
838
+ sage: c = F(5^-1 + O(5^2)); c
839
+ w^-5 + 3*w^-3 + 2*w^3 + 4*w^5 + 4*w^6 + 3*w^7 + w^9 + O(w^10)
840
+ sage: c * 5
841
+ 1 + O(w^15)
842
+
843
+ TESTS::
844
+
845
+ sage: R = Zp(11, 8, print_mode='digits')
846
+ sage: S.<x> = R[]
847
+ sage: f = x^3 + 1331 * x^2 - 11 * x + 11
848
+ sage: W.<w> = R.ext(f)
849
+ sage: z = W(77/3, relprec=11); repr(z)[3:]
850
+ '304107A2555000'
851
+ sage: repr(z*3)[3:]
852
+ '56698765444000'
853
+ sage: repr(W(77))[3:]
854
+ '5800A6604678856698765444000'
855
+ sage: F = W.fraction_field()
856
+ sage: y = F(3/847); repr(y)[3:]
857
+ '5563A4105291255628.148272'
858
+ sage: repr(y*847)[3:]
859
+ '000000000000000000000003'
860
+ sage: repr(W(77/3, relprec=0))[3:]
861
+ '000'
862
+ sage: c = F(11^-1 + O(11^2)); repr(c)[3:]
863
+ '011111.01A'
864
+ sage: repr(c * 11)[3:]
865
+ '000000001'
866
+ """
867
+ if mpq_sgn(x) == 0:
868
+ self._set_exact_zero()
869
+ return 0
870
+ cdef mpz_t num_unit, den_unit
871
+ self._set_from_mpq_part1(num_unit, den_unit, x)
872
+ self._set_prec_rel(relprec)
873
+ self._set_from_mpq_part2(num_unit, den_unit)
874
+
875
+ cdef int _set_from_mpq_both(self, mpq_t x, long absprec, long relprec) except -1:
876
+ """
877
+ Set ``self`` from an ``mpq_t`` with relative precision
878
+ bounded by ``relprec`` and absolute precision bounded by
879
+ ``absprec``.
880
+
881
+ EXAMPLES::
882
+
883
+ sage: R = Zp(5,5)
884
+ sage: S.<x> = R[]
885
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
886
+ sage: W.<w> = R.ext(f)
887
+ sage: z = W(70/3, 14); z # indirect doctest
888
+ 3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + O(w^14)
889
+ sage: z * 3
890
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + O(w^14)
891
+ sage: W(70)
892
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + 3*w^16 + w^17 + w^18 + 4*w^20 + 4*w^21 + w^22 + 2*w^23 + 3*w^25 + w^27 + O(w^30)
893
+ sage: F = W.fraction_field()
894
+ sage: y = F(3/700,-2); y
895
+ w^-10 + w^-8 + 4*w^-6 + w^-3 + O(w^-2)
896
+ sage: y * 700
897
+ 3 + O(w^8)
898
+ sage: W(70/3, absprec=4)
899
+ O(w^4)
900
+ """
901
+ if mpq_sgn(x) == 0:
902
+ self._set_inexact_zero(absprec)
903
+ return 0
904
+ cdef mpz_t num_unit, den_unit
905
+ self._set_from_mpq_part1(num_unit, den_unit, x)
906
+ if self._set_prec_both(absprec, relprec) == 1:
907
+ # indicates an inexact zero
908
+ mpz_clear(num_unit)
909
+ mpz_clear(den_unit)
910
+ return 0
911
+ self._set_from_mpq_part2(num_unit, den_unit)
912
+
913
+ cdef int _set_from_mpq_part1(self, mpz_t num_unit, mpz_t den_unit, mpq_t x) except -1:
914
+ """
915
+ Set ``num_unit`` to be the unit of the numerator, ``den_unit`` to be
916
+ the unit of the denominator and sets ``self.ordp`` correctly.
917
+
918
+ TESTS::
919
+
920
+ sage: R = Zp(5,5)
921
+ sage: S.<x> = R[]
922
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
923
+ sage: W.<w> = R.ext(f)
924
+ sage: z = W(7000/3, 23); z # indirect doctest
925
+ 2*w^15 + 2*w^17 + 3*w^19 + w^22 + O(w^23)
926
+ """
927
+ cdef long num_ordp, den_ordp
928
+ sig_on()
929
+ mpz_init(num_unit)
930
+ mpz_init(den_unit)
931
+ num_ordp = mpz_remove(num_unit, mpq_numref(x), self.prime_pow.prime.value)
932
+ den_ordp = mpz_remove(den_unit, mpq_denref(x), self.prime_pow.prime.value)
933
+ sig_off()
934
+ self.ordp = (num_ordp - den_ordp) * self.prime_pow.e
935
+ if self.ordp < 0 and self.prime_pow.in_field == 0:
936
+ mpz_clear(num_unit)
937
+ mpz_clear(den_unit)
938
+ raise ValueError("p divides the denominator")
939
+
940
+ cdef int _set_from_mpq_part2(self, mpz_t num_unit, mpz_t den_unit) except -1:
941
+ """
942
+ Given that ``self.ordp`` and ``self.relprec`` have been set, takes
943
+ ``num_unit`` and ``den_unit`` and sets ``self.unit``.
944
+
945
+ TESTS::
946
+
947
+ sage: R = Zp(5,5)
948
+ sage: S.<x> = R[]
949
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
950
+ sage: W.<w> = R.ext(f)
951
+ sage: W(QQ(0), 23) # indirect doctest
952
+ O(w^23)
953
+ sage: W(QQ(0))
954
+ 0
955
+ """
956
+ cdef ZZ_c num_zz, den_zz
957
+ cdef ZZ_p_c tmp_zp
958
+ cdef long val = self.ordp / self.prime_pow.e
959
+ cdef mpz_t tmp_m
960
+ if self.relprec != 0:
961
+ mpz_init(tmp_m)
962
+ mpz_set(tmp_m, num_unit)
963
+ mpz_to_ZZ(&num_zz, tmp_m)
964
+ mpz_set(tmp_m, den_unit)
965
+ mpz_to_ZZ(&den_zz, tmp_m)
966
+ mpz_clear(tmp_m)
967
+ #The context has been restored in setting self.relprec
968
+ ZZ_p_div(tmp_zp, ZZ_to_ZZ_p(num_zz), ZZ_to_ZZ_p(den_zz))
969
+ ZZ_pX_SetCoeff(self.unit, 0, tmp_zp)
970
+ self.ordp = 0
971
+ self._pshift_self(val)
972
+
973
+ cdef int _set_from_ZZX_rel(self, ZZX_c poly, long relprec) except -1:
974
+ """
975
+ Set ``self`` from a ``ZZX`` with relative precision bounded by
976
+ ``relprec``.
977
+
978
+ EXAMPLES::
979
+
980
+ sage: R = Zp(5,5)
981
+ sage: S.<x> = R[]
982
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
983
+ sage: W.<w> = R.ext(f)
984
+ sage: z = W(ntl.ZZX([4,1,16]), relprec=14); z # indirect doctest
985
+ 4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + 4*w^13 + O(w^14)
986
+ sage: z._ntl_rep()
987
+ [4 1 16]
988
+ sage: z = W(ntl.ZZX([5^40,5^42,3*5^41]), relprec=14); z
989
+ w^200 + 4*w^207 + 4*w^209 + w^210 + 2*w^211 + 2*w^213 + O(w^214)
990
+ sage: W(5)^40 + w*W(5)^42 + w^2 * W(3) * W(5)^41
991
+ w^200 + 4*w^207 + 4*w^209 + w^210 + 2*w^211 + 2*w^213 + 2*w^215 + w^217 + 2*w^218 + w^220 + w^221 + w^222 + 3*w^224 + O(w^225)
992
+ sage: z = W(ntl.ZZX([5^40,5^42,3*5^41]), relprec=0); z
993
+ O(w^200)
994
+ """
995
+ if ZZX_IsZero(poly):
996
+ self._set_exact_zero()
997
+ return 0
998
+ if ZZX_deg(poly) >= self.prime_pow.deg:
999
+ raise NotImplementedError
1000
+ # the -1 in the next line signals that there is no absprec specified
1001
+ self._set_from_ZZX_part1(poly, -1, relprec)
1002
+ # context was restored in _set_from_ZZX_part1
1003
+ if relprec == 0:
1004
+ self._set_prec_rel(relprec)
1005
+ return 0
1006
+ if self.relprec + self.ordp != 0:
1007
+ self.prime_pow.restore_context_capdiv(self.relprec + self.ordp)
1008
+ ZZX_to_ZZ_pX(self.unit, poly)
1009
+ self._internal_lshift(-self.ordp)
1010
+
1011
+ cdef int _set_from_ZZX_both(self, ZZX_c poly, long absprec, long relprec) except -1:
1012
+ """
1013
+ Set ``self`` from a ``ZZX`` with relative precision bounded by
1014
+ ``relprec`` and absolute precision bounded by ``absprec``.
1015
+
1016
+ EXAMPLES::
1017
+
1018
+ sage: R = Zp(5,5)
1019
+ sage: S.<x> = R[]
1020
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1021
+ sage: W.<w> = R.ext(f)
1022
+ sage: z = W(ntl.ZZX([4,1,16]), 12); z # indirect doctest
1023
+ 4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + O(w^12)
1024
+ sage: z._ntl_rep()
1025
+ [4 1 16]
1026
+ sage: z = W(ntl.ZZX([5^40,5^42,3*5^41]), 212); z
1027
+ w^200 + 4*w^207 + 4*w^209 + w^210 + 2*w^211 + O(w^212)
1028
+ sage: z = W(ntl.ZZX([5^40,5^42,3*5^41]), 197); z
1029
+ O(w^197)
1030
+ """
1031
+ if ZZX_IsZero(poly) or absprec <= 0:
1032
+ self._set_inexact_zero(absprec)
1033
+ return 0
1034
+ if ZZX_deg(poly) >= self.prime_pow.deg:
1035
+ raise NotImplementedError
1036
+ if self._set_from_ZZX_part1(poly, absprec, relprec) == -2:
1037
+ # indicates _set_inexact_zero was called
1038
+ return 0
1039
+ # context was restored in _set_from_ZZX_part1
1040
+ if self.relprec + self.ordp != 0:
1041
+ self.prime_pow.restore_context_capdiv(self.relprec + self.ordp)
1042
+ ZZX_to_ZZ_pX(self.unit, poly)
1043
+ self._internal_lshift(-self.ordp)
1044
+
1045
+ cdef int _set_from_ZZX_part1(self, ZZX_c poly, long absprec, long relprec) except -1:
1046
+ """
1047
+ Set ``self.ordp`` from ``poly`` and restores the context. ``poly`` must
1048
+ have degree less than ``self.prime_pow.deg``.
1049
+
1050
+ TESTS::
1051
+
1052
+ sage: R = Zp(5,5)
1053
+ sage: S.<x> = R[]
1054
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1055
+ sage: W.<w> = R.ext(f)
1056
+ sage: z = W(ntl.ZZX([4,1,16]), 12); z # indirect doctest
1057
+ 4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + O(w^12)
1058
+ """
1059
+ cdef long i = 0
1060
+ cdef long deg = ZZX_deg(poly)
1061
+ cdef long mini = -1
1062
+ cdef long minval
1063
+ cdef long curval
1064
+ cdef ZZ_c tmp_z
1065
+ while mini == -1:
1066
+ if not ZZ_IsZero(ZZX_coeff(poly,i)):
1067
+ minval = ZZ_remove(tmp_z, ZZX_coeff(poly, i), self.prime_pow.pow_ZZ_tmp(1)[0])
1068
+ mini = i
1069
+ i += 1
1070
+ while i <= deg:
1071
+ if not ZZ_IsZero(ZZX_coeff(poly,i)):
1072
+ curval = ZZ_remove(tmp_z, ZZX_coeff(poly, i), self.prime_pow.pow_ZZ_tmp(1)[0])
1073
+ if curval < minval:
1074
+ minval = curval
1075
+ mini = i
1076
+ i += 1
1077
+ if self.prime_pow.e == 1:
1078
+ self.ordp = minval
1079
+ else:
1080
+ self.ordp = minval * self.prime_pow.e + mini
1081
+ if absprec == -1: # indicates that _set_from_ZZX_rel is calling
1082
+ self._set_prec_rel(relprec)
1083
+ elif self._set_prec_both(absprec, relprec):
1084
+ # indicates self._set_inexact_zero was called
1085
+ return -2
1086
+ # _set_prec_rel or both has restored the context so that part2 works.
1087
+
1088
+ cdef int _set_from_ZZ_pX_rel(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long relprec) except -1:
1089
+ """
1090
+ Set ``self`` from a ``ZZ_pX`` with relative precision bounded by
1091
+ ``relprec``.
1092
+
1093
+ If ``ctx`` is ``None`` and ``poly`` is 0 this function will raise an
1094
+ error (a ``ZZ_pX`` cannot represent something with infinite absolute
1095
+ precision).
1096
+
1097
+ EXAMPLES::
1098
+
1099
+ sage: R = Zp(5,5)
1100
+ sage: S.<x> = R[]
1101
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1102
+ sage: W.<w> = R.ext(f)
1103
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2)); z # indirect doctest
1104
+ 4 + w + w^2 + 3*w^7 + w^9 + O(w^10)
1105
+ sage: z._ntl_rep()
1106
+ [4 1 16]
1107
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^44)); z
1108
+ w^200 + 4*w^207 + 4*w^209 + w^210 + 2*w^211 + 2*w^213 + 2*w^215 + w^217 + 2*w^218 + O(w^220)
1109
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^44), relprec=0); z
1110
+ O(w^200)
1111
+ """
1112
+ cdef long ctx_prec = -1
1113
+ if ctx is not None:
1114
+ ctx_prec = self._check_ZZ_pContext(ctx) * self.prime_pow.e
1115
+ if ZZ_pX_IsZero(poly[0]):
1116
+ if ctx_prec == -1:
1117
+ raise ValueError("must specify either a context or an absolute precision bound")
1118
+ else:
1119
+ self._set_inexact_zero(ctx_prec)
1120
+ return 0
1121
+ self._set_from_ZZ_pX_part1(poly)
1122
+ if relprec == 0:
1123
+ self._set_prec_rel(relprec)
1124
+ return 0
1125
+ if ctx_prec == -1:
1126
+ self._set_prec_rel(self.ordp + relprec)
1127
+ else:
1128
+ self._set_prec_rel(min(ctx_prec, self.ordp + relprec))
1129
+ self._set_from_ZZ_pX_part2(poly)
1130
+
1131
+ cdef int _set_from_ZZ_pX_both(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec, long relprec) except -1:
1132
+ """
1133
+ Set ``self`` from a ``ZZ_pX`` with relative precision bounded by
1134
+ ``relprec`` and absolute precision bounded by ``absprec``.
1135
+
1136
+ EXAMPLES::
1137
+
1138
+ sage: R = Zp(5,5)
1139
+ sage: S.<x> = R[]
1140
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1141
+ sage: W.<w> = R.ext(f)
1142
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec=8, relprec=12); z # indirect doctest
1143
+ 4 + w + w^2 + 3*w^7 + O(w^8)
1144
+ sage: z._ntl_rep()
1145
+ [4 1 16]
1146
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^50), 220); z
1147
+ w^200 + 4*w^207 + 4*w^209 + w^210 + 2*w^211 + 2*w^213 + 2*w^215 + w^217 + 2*w^218 + O(w^220)
1148
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^44), absprec=77); z
1149
+ O(w^77)
1150
+ """
1151
+ cdef long ctx_prec
1152
+ if ctx is not None:
1153
+ ctx_prec = self._check_ZZ_pContext(ctx)
1154
+ if ctx_prec * self.prime_pow.e < absprec:
1155
+ absprec = ctx_prec * self.prime_pow.e
1156
+ if ZZ_pX_IsZero(poly[0]):
1157
+ self._set_inexact_zero(absprec)
1158
+ return 0
1159
+ self._set_from_ZZ_pX_part1(poly)
1160
+ if absprec <= self.ordp:
1161
+ self._set_inexact_zero(absprec)
1162
+ else:
1163
+ self._set_prec_rel(min(absprec, self.ordp + relprec))
1164
+ self._set_from_ZZ_pX_part2(poly)
1165
+
1166
+ cdef int _set_from_ZZ_pX_part1(self, ZZ_pX_c* poly) except -1:
1167
+ """
1168
+ Set ``self.ordp`` based on ``poly``. ``poly`` must not be 0.
1169
+
1170
+ TESTS::
1171
+
1172
+ sage: R = Zp(5,5)
1173
+ sage: S.<x> = R[]
1174
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1175
+ sage: W.<w> = R.ext(f)
1176
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec=8, relprec=12); z # indirect doctest
1177
+ 4 + w + w^2 + 3*w^7 + O(w^8)
1178
+ """
1179
+ cdef long val = 0, index = 0
1180
+ ZZ_pX_min_val_coeff(val, index, poly[0], self.prime_pow.pow_ZZ_tmp(1)[0])
1181
+ if self.prime_pow.e == 1:
1182
+ self.ordp = val
1183
+ else:
1184
+ self.ordp = val * self.prime_pow.e + index
1185
+
1186
+ cdef int _set_from_ZZ_pX_part2(self, ZZ_pX_c* poly) except -1:
1187
+ """
1188
+ Assuming that ``self.ordp`` and ``self.relprec`` have been set, sets
1189
+ ``self.unit`` to ``poly`` and then normalizes.
1190
+
1191
+ TESTS::
1192
+
1193
+ sage: R = Zp(5,5)
1194
+ sage: S.<x> = R[]
1195
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1196
+ sage: W.<w> = R.ext(f)
1197
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec=8, relprec=12); z # indirect doctest
1198
+ 4 + w + w^2 + 3*w^7 + O(w^8)
1199
+ """
1200
+ # We've set self.relprec to what is actually the absolute precision.
1201
+ if self.relprec != 0:
1202
+ ZZ_pX_conv_modulus(self.unit, poly[0], self.prime_pow.get_context_capdiv(self.relprec).x)
1203
+ self.relprec -= self.ordp
1204
+ self._internal_lshift(-self.ordp)
1205
+
1206
+ cdef bint _set_prec_rel(self, long relprec) except -1:
1207
+ """
1208
+ Safely set the relative precision of ``self`` to be the absolute
1209
+ value of ``relprec``.
1210
+
1211
+ Returns ``True`` iff ``self.relprec`` was reset.
1212
+
1213
+ Note that this will wipe out anything in ``self.unit``. Be
1214
+ careful resetting ``self.unit`` directly: if you set it to a
1215
+ different modulus, NTL may have problems. The safest way to
1216
+ reset ``self.unit`` to a different modulus is::
1217
+
1218
+ self.prime_pow.restore_context_capdiv(self.relprec)
1219
+ cdef ZZ_pX_c tmp = self.unit
1220
+ self._set_prec_rel(new_rel_prec)
1221
+ ZZ_pX_conv_modulus(self.unit, tmp, self.prime_pow.get_context_capdiv(self.relprec).x)
1222
+
1223
+ You may be able to just set ``self.relprec`` and
1224
+ ``ZZ_pX_conv_modulus`` if you're decreasing precision. I'm
1225
+ not sure.
1226
+
1227
+ TESTS::
1228
+
1229
+ sage: R = Zp(5,5)
1230
+ sage: S.<x> = R[]
1231
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1232
+ sage: W.<w> = R.ext(f)
1233
+ sage: W(70, relprec=8) # indirect doctest
1234
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
1235
+ """
1236
+ if self.relprec == relprec:
1237
+ return False
1238
+ if relprec != 0:
1239
+ self.prime_pow.restore_context_capdiv(relprec)
1240
+ self.unit = ZZ_pX_c()
1241
+ self.relprec = relprec
1242
+ return True
1243
+
1244
+ cdef bint _set_prec_both(self, long absprec, long relprec) except -1:
1245
+ """
1246
+ Assuming ``self.ordp`` is set, sets the relative precision of ``self``
1247
+ to the minimum of ``abs(relprec)`` and ``absprec-self.ordp``.
1248
+
1249
+ If ``relprec`` is negative, will set ``self.relprec`` to be negative
1250
+ (indicating unnormalized unit)
1251
+
1252
+ Returns ``True`` iff ``self.relprec = 0``, ie ``self`` was set to an
1253
+ inexact zero.
1254
+
1255
+ Note that this will wipe out anything in ``self.unit``. Be
1256
+ careful resetting ``self.unit`` directly: if you set it to a
1257
+ different modulus, NTL may have problems. The safest way to
1258
+ reset ``self.unit`` to a different modulus is:
1259
+
1260
+ self.prime_pow.restore_context_capdiv(self.relprec)
1261
+ cdef ZZ_pX_c tmp = self.unit
1262
+ self._set_prec_rel(new_rel_prec)
1263
+ ZZ_pX_conv_modulus(self.unit, tmp, self.prime_pow.get_context_capdiv(self.relprec).x)
1264
+
1265
+ You may be able to just set ``self.relprec`` and
1266
+ ``ZZ_pX_conv_modulus`` if you're decreasing precision. I'm
1267
+ not sure.
1268
+
1269
+ TESTS::
1270
+
1271
+ sage: R = Zp(5,5)
1272
+ sage: S.<x> = R[]
1273
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1274
+ sage: W.<w> = R.ext(f)
1275
+ sage: W(70, 8) # indirect doctest
1276
+ 4*w^5 + 3*w^7 + O(w^8)
1277
+ """
1278
+ self.relprec = absprec - self.ordp
1279
+ cdef long arelprec
1280
+ if relprec < 0:
1281
+ arelprec = -relprec
1282
+ else:
1283
+ arelprec = relprec
1284
+ if self.relprec <= 0:
1285
+ self._set_inexact_zero(absprec)
1286
+ else:
1287
+ if arelprec < self.relprec:
1288
+ self.relprec = arelprec
1289
+ if self.relprec != 0:
1290
+ self.prime_pow.restore_context_capdiv(self.relprec)
1291
+ self.unit = ZZ_pX_c()
1292
+ if relprec < 0:
1293
+ self.relprec = -self.relprec
1294
+ return self.relprec == 0
1295
+
1296
+ cdef int _normalize(self) except -1:
1297
+ """
1298
+ Normalize ``self``, adjusting ``self.ordp``, ``self.relprec``, and
1299
+ ``self.unit`` so that ``self.unit`` actually represents a unit.
1300
+
1301
+ EXAMPLES::
1302
+
1303
+ sage: R = Zp(5,5)
1304
+ sage: S.<x> = R[]
1305
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1306
+ sage: W.<w> = R.ext(f)
1307
+ sage: z = (1+w)^5
1308
+ sage: y = z - 1
1309
+ sage: y._ntl_rep_unnormalized()
1310
+ [5 3005 25 3060 5]
1311
+ sage: y # indirect doctest
1312
+ w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1313
+ sage: y._ntl_rep_unnormalized()
1314
+ [41 26 152 49 535]
1315
+ """
1316
+ cdef long minval = 0, mini = 0, shift
1317
+ if self.relprec < 0:
1318
+ if ZZ_pX_IsZero(self.unit):
1319
+ self.ordp -= self.relprec # note that self.relprec < 0
1320
+ self.relprec = 0
1321
+ else:
1322
+ ZZ_pX_min_val_coeff(minval, mini, self.unit, self.prime_pow.pow_ZZ_tmp(1)[0])
1323
+ if self.prime_pow.e == 1:
1324
+ shift = minval
1325
+ else:
1326
+ shift = minval * self.prime_pow.e + mini
1327
+ if shift >= -self.relprec:
1328
+ self.ordp -= self.relprec # note that self.relprec < 0
1329
+ self.relprec = 0
1330
+ elif shift > 0:
1331
+ self.relprec = -self.relprec - shift
1332
+ self.ordp += shift
1333
+ self._internal_lshift(-shift)
1334
+ else:
1335
+ self.relprec = -self.relprec
1336
+
1337
+ def _is_normalized(self):
1338
+ """
1339
+ Whether this element is currently normalized.
1340
+
1341
+ EXAMPLES::
1342
+
1343
+ sage: R.<a> = ZqCR(125,implementation="NTL"); b = 5*a + 4; c = 10*a^2 + 6; d = b + c
1344
+ sage: d._is_normalized()
1345
+ False
1346
+ sage: d.valuation()
1347
+ 1
1348
+ sage: d._is_normalized()
1349
+ True
1350
+ """
1351
+ return self.relprec >= 0
1352
+
1353
+ cdef int _internal_lshift(self, long shift) except -1:
1354
+ """
1355
+ Multiply ``self.unit`` by ``x^shift``.
1356
+
1357
+ Note that ``self.relprec`` must be set before calling this
1358
+ function and should not be 0, and self.unit must be defined to
1359
+ precision ``self.relprec - shift``
1360
+
1361
+ This function does not alter ``self.ordp`` even though it WILL
1362
+ change the valuation of ``self.unit``
1363
+
1364
+ Also note that if you call this function you should usually
1365
+ manually set ``self.relprec = -self.relprec`` since this function
1366
+ will usually unnormalize ``self``.
1367
+
1368
+ TESTS::
1369
+
1370
+ sage: R = Zp(5,5)
1371
+ sage: S.<x> = R[]
1372
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1373
+ sage: W.<w> = R.ext(f)
1374
+ sage: z = (1+w)^5
1375
+ sage: y = z - 1
1376
+ sage: y # indirect doctest
1377
+ w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1378
+ """
1379
+ if self.relprec == 0:
1380
+ raise ValueError("p-adic Internal l-shift called with relative precision 0")
1381
+ cdef ZZ_pX_c tmpP
1382
+ cdef ZZ_pX_Modulus_c* mod
1383
+ if self.prime_pow.e == 1:
1384
+ if shift > 0:
1385
+ ZZ_pX_left_pshift(self.unit, self.unit, self.prime_pow.pow_ZZ_tmp(shift)[0], self.prime_pow.get_context(self.relprec).x)
1386
+ else:
1387
+ ZZ_pX_right_pshift(self.unit, self.unit, self.prime_pow.pow_ZZ_tmp(-shift)[0], self.prime_pow.get_context(self.relprec).x)
1388
+ else:
1389
+ if shift > 0:
1390
+ self.prime_pow.restore_context_capdiv(self.relprec)
1391
+ mod = self.prime_pow.get_modulus_capdiv(self.relprec)
1392
+ ZZ_pX_PowerXMod_long_pre(tmpP, shift, mod[0])
1393
+ ZZ_pX_MulMod_pre(self.unit, self.unit, tmpP, mod[0])
1394
+ elif shift < 0:
1395
+ self.prime_pow.eis_shift_capdiv(&self.unit, &self.unit, -shift, self.relprec)
1396
+
1397
+ cdef int _pshift_self(self, long shift) except -1:
1398
+ """
1399
+ Multiply ``self`` by ``p^shift``.
1400
+
1401
+ This function assumes that ``self.relprec``, ``self.ordp`` and
1402
+ ``self.unit`` are already set (in the case ``self.prime_pow.e
1403
+ != 1``), and is more reasonable to call externally than
1404
+ ``_internal_lshift``
1405
+
1406
+ EXAMPLES::
1407
+
1408
+ sage: R = Qp(5,5)
1409
+ sage: S.<x> = R[]
1410
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1411
+ sage: W.<w> = R.ext(f)
1412
+ sage: z = W(3/25, relprec=6); z
1413
+ 3*w^-10 + 3*w^-8 + 2*w^-6 + O(w^-4)
1414
+ sage: z * 25
1415
+ 3 + O(w^6)
1416
+ """
1417
+ cdef ZZ_pX_c high_shifter
1418
+ cdef ZZ_pX_Modulus_c *modulus
1419
+ cdef ntl_ZZ_pContext_class c
1420
+ cdef ZZ_pX_c* high_array
1421
+ cdef long i, high_length
1422
+ if self.prime_pow.e == 1:
1423
+ self.ordp += shift
1424
+ else:
1425
+ self.ordp += shift * self.prime_pow.e
1426
+ if shift < 0:
1427
+ shift = -shift
1428
+ c = self.prime_pow.get_context_capdiv(self.relprec)
1429
+ c.restore_c()
1430
+ modulus = self.prime_pow.get_modulus_capdiv(self.relprec)
1431
+ if isinstance(self.prime_pow, PowComputer_ZZ_pX_big_Eis):
1432
+ high_array = (<PowComputer_ZZ_pX_big_Eis>self.prime_pow).high_shifter
1433
+ elif isinstance(self.prime_pow, PowComputer_ZZ_pX_small_Eis):
1434
+ high_array = (<PowComputer_ZZ_pX_small_Eis>self.prime_pow).high_shifter
1435
+ else:
1436
+ raise TypeError("unrecognized PowComputer type")
1437
+ ZZ_pX_conv_modulus(high_shifter, high_array[0], c.x)
1438
+ ZZ_pX_InvMod_newton_ram(high_shifter, high_shifter, modulus[0], c.x)
1439
+ ZZ_pX_PowerMod_long_pre(high_shifter, high_shifter, shift, modulus[0])
1440
+ ZZ_pX_MulMod_pre(self.unit, self.unit, high_shifter, modulus[0])
1441
+ elif shift > 0:
1442
+ i = 0
1443
+ c = self.prime_pow.get_context_capdiv(self.relprec)
1444
+ c.restore_c()
1445
+ modulus = self.prime_pow.get_modulus_capdiv(self.relprec)
1446
+ if isinstance(self.prime_pow, PowComputer_ZZ_pX_big_Eis):
1447
+ high_array = (<PowComputer_ZZ_pX_big_Eis>self.prime_pow).high_shifter
1448
+ high_length = (<PowComputer_ZZ_pX_big_Eis>self.prime_pow).high_length
1449
+ elif isinstance(self.prime_pow, PowComputer_ZZ_pX_small_Eis):
1450
+ high_array = (<PowComputer_ZZ_pX_small_Eis>self.prime_pow).high_shifter
1451
+ high_length = (<PowComputer_ZZ_pX_small_Eis>self.prime_pow).high_length
1452
+ else:
1453
+ raise TypeError("unrecognized PowComputer type")
1454
+ if shift >= self.prime_pow.prec_cap:
1455
+ # high_shifter = p^(2^(high_length - 1))/x^(e*2^(high_length - 1))
1456
+ ZZ_pX_conv_modulus(high_shifter, high_array[high_length-1], c.x)
1457
+ # if shift = r + s * 2^(high_length - 1)
1458
+ # then high_shifter = p^(s*2^(high_length - 1))/x^(e*s*2^(high_length - 1))
1459
+ ZZ_pX_PowerMod_long_pre(high_shifter, high_shifter, (shift / (1L << (high_length - 1))), modulus[0])
1460
+ ZZ_pX_MulMod_pre(self.unit, self.unit, high_shifter, modulus[0])
1461
+ # Now we only need to multiply self.unit by p^r/x^(e*r) where r < 2^(high_length - 1), which is tractable.
1462
+ shift = shift % (1L << (high_length - 1))
1463
+ while shift > 0:
1464
+ if shift & 1:
1465
+ ZZ_pX_conv_modulus(high_shifter, high_array[i], c.x)
1466
+ ZZ_pX_MulMod_pre(self.unit, self.unit, high_shifter, modulus[0])
1467
+ shift = shift >> 1
1468
+ i += 1
1469
+
1470
+ cdef pAdicZZpXCRElement _new_c(self, long relprec):
1471
+ """
1472
+ Return a new element with the same parent as ``self`` and
1473
+ relative precision ``relprec``
1474
+
1475
+ Note that if ``relprec`` is nonpositive, the convention is that
1476
+ ``relprec = 0`` indicates an exact or inexact zero, ``relprec < 0``
1477
+ indicates an unnormalized element.
1478
+
1479
+ EXAMPLES::
1480
+
1481
+ sage: R = Qp(5,5)
1482
+ sage: S.<x> = R[]
1483
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1484
+ sage: W.<w> = R.ext(f)
1485
+ sage: w^5 + 1 # indirect doctest
1486
+ 1 + w^5 + O(w^25)
1487
+ """
1488
+ cdef pAdicZZpXCRElement ans = pAdicZZpXCRElement.__new__(pAdicZZpXCRElement)
1489
+ ans._parent = self._parent
1490
+ ans.prime_pow = self.prime_pow
1491
+ if relprec > 0:
1492
+ self.prime_pow.restore_context_capdiv(relprec)
1493
+ ans.relprec = relprec
1494
+ elif relprec == 0:
1495
+ ans._set_exact_zero()
1496
+ else:
1497
+ self.prime_pow.restore_context_capdiv(-relprec)
1498
+ ans.relprec = relprec
1499
+ return ans
1500
+
1501
+ def __reduce__(self):
1502
+ """
1503
+ Pickles ``self``.
1504
+
1505
+ EXAMPLES::
1506
+
1507
+ sage: R = Qp(5,5)
1508
+ sage: S.<x> = R[]
1509
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1510
+ sage: W.<w> = R.ext(f)
1511
+ sage: z = (1 + w)^5 - 1
1512
+ sage: loads(dumps(z)) == z
1513
+ True
1514
+ """
1515
+ cdef Integer relprec, ordp
1516
+ relprec = PY_NEW(Integer)
1517
+ ordp = PY_NEW(Integer)
1518
+ mpz_set_si(relprec.value, self.relprec)
1519
+ mpz_set_si(ordp.value, self.ordp)
1520
+ if self.relprec == 0:
1521
+ return make_ZZpXCRElement, (self.parent(), None, ordp, relprec, 0)
1522
+ self.prime_pow.restore_context_capdiv(self.relprec)
1523
+ cdef ntl_ZZ_pX holder = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
1524
+ holder.c = self.prime_pow.get_context_capdiv(self.relprec)
1525
+ holder.x = self.unit
1526
+ return make_ZZpXCRElement, (self.parent(), holder, ordp, relprec, 0)
1527
+
1528
+ cdef int _cmp_units(left, pAdicGenericElement right) except -2:
1529
+ """
1530
+ For units ``left`` and ``right``, return 0 if they are equal up to
1531
+ the lesser of the two precisions, or 1 if they are not.
1532
+
1533
+ EXAMPLES::
1534
+
1535
+ sage: R = Qp(5,5)
1536
+ sage: S.<x> = R[]
1537
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1538
+ sage: W.<w> = R.ext(f)
1539
+ sage: w == 1 # indirect doctest
1540
+ False
1541
+ sage: y = 1 + w + O(w^7)
1542
+ sage: z = 1 + w + w^10 + O(w^13)
1543
+ sage: y == z
1544
+ True
1545
+ """
1546
+ # This function needs improvement. In particular, there are a lot of
1547
+ # speed improvements to be had, and it should be changed so that it
1548
+ # returns 1 only half the time (and -1 the other half) when left and
1549
+ # right are not equal.
1550
+ cdef pAdicZZpXCRElement diff = <pAdicZZpXCRElement> (left - right)
1551
+ diff._normalize()
1552
+ if diff.relprec == 0:
1553
+ return 0
1554
+ # for now, just return 1
1555
+ return 1
1556
+
1557
+ def __invert__(self):
1558
+ """
1559
+ Return the inverse of this element.
1560
+
1561
+ EXAMPLES::
1562
+
1563
+ sage: R = Zp(5,5)
1564
+ sage: S.<x> = R[]
1565
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1566
+ sage: W.<w> = R.ext(f)
1567
+ sage: z = (1 + w)^5
1568
+ sage: y = ~z; y # indirect doctest
1569
+ 1 + 4*w^5 + 4*w^6 + 3*w^7 + w^8 + 2*w^10 + w^11 + w^12 + 2*w^14 + 3*w^16 + 3*w^17 + 4*w^18 + 4*w^19 + 2*w^20 + 2*w^21 + 4*w^22 + 3*w^23 + 3*w^24 + O(w^25)
1570
+ sage: y.parent()
1571
+ 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1572
+ sage: z = z - 1
1573
+ sage: ~z
1574
+ w^-5 + 4*w^-4 + 4*w^-3 + 4*w^-2 + 2*w^-1 + 1 + w + 4*w^2 + 4*w^3 + 4*w^4 + w^5 + w^6 + w^7 + 4*w^8 + 4*w^9 + 2*w^10 + w^11 + 2*w^12 + 4*w^13 + 4*w^14 + O(w^15)
1575
+ sage: ~z * z
1576
+ 1 + O(w^20)
1577
+ """
1578
+ if self._is_exact_zero():
1579
+ raise ZeroDivisionError("cannot divide by zero")
1580
+ if self._is_inexact_zero(): # this calls _normalize
1581
+ raise PrecisionError("cannot divide by something indistinguishable from zero")
1582
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
1583
+ if not ans.prime_pow.in_field:
1584
+ ans._parent = self._parent.fraction_field()
1585
+ ans.prime_pow = ans._parent.prime_pow
1586
+ ans.ordp = -self.ordp
1587
+ sig_on()
1588
+ if self.prime_pow.e == 1:
1589
+ ZZ_pX_InvMod_newton_unram(ans.unit, self.unit, self.prime_pow.get_modulus(ans.relprec)[0], self.prime_pow.get_context(ans.relprec).x, self.prime_pow.get_context(1).x)
1590
+ else:
1591
+ ZZ_pX_InvMod_newton_ram(ans.unit, self.unit, self.prime_pow.get_modulus_capdiv(ans.relprec)[0], self.prime_pow.get_context_capdiv(ans.relprec).x)
1592
+ sig_off()
1593
+ return ans
1594
+
1595
+ cdef pAdicZZpXCRElement _lshift_c(self, long n):
1596
+ """
1597
+ Multiply ``self`` by the uniformizer raised to the power ``n``. If
1598
+ ``n`` is negative, right shifts by ``-n``.
1599
+
1600
+ EXAMPLES::
1601
+
1602
+ sage: R = Zp(5,5)
1603
+ sage: S.<x> = R[]
1604
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1605
+ sage: W.<w> = R.ext(f)
1606
+ sage: z = (1 + w)^5
1607
+ sage: z
1608
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1609
+ sage: z << 17 # indirect doctest
1610
+ w^17 + w^22 + w^23 + 2*w^24 + 4*w^25 + 3*w^27 + w^29 + 4*w^30 + 4*w^31 + 4*w^32 + 4*w^33 + 4*w^34 + 4*w^37 + w^38 + 4*w^41 + O(w^42)
1611
+ sage: z << (-1)
1612
+ w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
1613
+ """
1614
+ if not self.prime_pow.in_field and n < -self.ordp:
1615
+ return self._rshift_c(-n)
1616
+ check_ordp(n)
1617
+ cdef pAdicZZpXCRElement ans
1618
+ if self._is_exact_zero() or n == 0:
1619
+ return self
1620
+ elif self._is_inexact_zero():
1621
+ ans = self._new_c(0)
1622
+ else:
1623
+ ans = self._new_c(self.relprec)
1624
+ ans.unit = self.unit
1625
+ ans.ordp = self.ordp + n
1626
+ check_ordp(ans.ordp)
1627
+ return ans
1628
+
1629
+ def __lshift__(pAdicZZpXCRElement self, shift):
1630
+ """
1631
+ Multiply ``self`` by the uniformizer raised to the power ``n``. If
1632
+ ``n`` is negative, right shifts by ``-n``.
1633
+
1634
+ EXAMPLES::
1635
+
1636
+ sage: R = Zp(5,5)
1637
+ sage: S.<x> = R[]
1638
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1639
+ sage: W.<w> = R.ext(f)
1640
+ sage: z = (1 + w)^5
1641
+ sage: z
1642
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1643
+ sage: z << 17 # indirect doctest
1644
+ w^17 + w^22 + w^23 + 2*w^24 + 4*w^25 + 3*w^27 + w^29 + 4*w^30 + 4*w^31 + 4*w^32 + 4*w^33 + 4*w^34 + 4*w^37 + w^38 + 4*w^41 + O(w^42)
1645
+ sage: z << (-1)
1646
+ w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
1647
+ """
1648
+ cdef pAdicZZpXCRElement ans
1649
+ if not isinstance(shift, Integer):
1650
+ shift = Integer(shift)
1651
+ if mpz_fits_slong_p((<Integer>shift).value) == 0:
1652
+ if self._is_exact_zero():
1653
+ return self
1654
+ if self.prime_pow.in_field or mpz_sgn((<Integer>shift).value) > 0:
1655
+ raise ValueError("shift does not fit in long")
1656
+ else:
1657
+ ans = self._new_c(0)
1658
+ ans.ordp = 0
1659
+ return ans
1660
+ return self._lshift_c(mpz_get_si((<Integer>shift).value))
1661
+
1662
+ cdef pAdicZZpXCRElement _rshift_c(self, long n):
1663
+ """
1664
+ Divide ``self`` by the uniformizer raised to the power ``n``. If
1665
+ parent is not a field, throws away the nonpositive part of
1666
+ the series expansion. If ``n`` is negative, left shifts by ``-n``.
1667
+
1668
+ EXAMPLES::
1669
+
1670
+ sage: R = Zp(5,5,print_mode='digits')
1671
+ sage: S.<x> = R[]
1672
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1673
+ sage: W.<w> = R.ext(f)
1674
+ sage: z = (1 + w)^5
1675
+ sage: for m in range(26): repr(z >> m) # indirect doctest
1676
+ '...4001400444441030421100001'
1677
+ '...400140044444103042110000'
1678
+ '...40014004444410304211000'
1679
+ '...4001400444441030421100'
1680
+ '...400140044444103042110'
1681
+ '...40014004444410304211'
1682
+ '...4001400444441030421'
1683
+ '...400140044444103042'
1684
+ '...40014004444410304'
1685
+ '...4001400444441030'
1686
+ '...400140044444103'
1687
+ '...40014004444410'
1688
+ '...4001400444441'
1689
+ '...400140044444'
1690
+ '...40014004444'
1691
+ '...4001400444'
1692
+ '...400140044'
1693
+ '...40014004'
1694
+ '...4001400'
1695
+ '...400140'
1696
+ '...40014'
1697
+ '...4001'
1698
+ '...400'
1699
+ '...40'
1700
+ '...4'
1701
+ '...'
1702
+ sage: repr(z >> (-4))
1703
+ '...40014004444410304211000010000'
1704
+ """
1705
+ if self.prime_pow.in_field or n <= self.ordp:
1706
+ return self._lshift_c(-n)
1707
+ if self._is_exact_zero() or n == 0:
1708
+ return self
1709
+ cdef long arelprec
1710
+ if self.relprec < 0:
1711
+ arelprec = -self.relprec
1712
+ else:
1713
+ arelprec = self.relprec
1714
+ cdef pAdicZZpXCRElement ans
1715
+ if arelprec > n - self.ordp:
1716
+ ans = self._new_c(arelprec - (n - self.ordp))
1717
+ if self.prime_pow.e == 1:
1718
+ ZZ_pX_right_pshift(ans.unit, self.unit, self.prime_pow.pow_ZZ_tmp(n - self.ordp)[0], self.prime_pow.get_context(ans.relprec).x)
1719
+ else:
1720
+ self.prime_pow.eis_shift_capdiv(&ans.unit, &self.unit, n - self.ordp, ans.relprec)
1721
+ else:
1722
+ ans = self._new_c(0)
1723
+ ans.ordp = 0
1724
+ ans.relprec = -ans.relprec
1725
+ return ans
1726
+
1727
+ def __rshift__(pAdicZZpXCRElement self, shift):
1728
+ """
1729
+ Divide ``self`` by the uniformizer raised to the power ``n``. If
1730
+ parent is not a field, throws away the nonpositive part of
1731
+ the series expansion. If ``n`` is negative, left shifts by ``-n``.
1732
+
1733
+ EXAMPLES::
1734
+
1735
+ sage: R = Zp(5,5)
1736
+ sage: S.<x> = R[]
1737
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1738
+ sage: W.<w> = R.ext(f)
1739
+ sage: z = (1 + w)^5
1740
+ sage: z
1741
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1742
+ sage: z >> (6) # indirect doctest
1743
+ 1 + 2*w + 4*w^2 + 3*w^4 + w^6 + 4*w^7 + 4*w^8 + 4*w^9 + 4*w^10 + 4*w^11 + 4*w^14 + w^15 + 4*w^18 + O(w^19)
1744
+ sage: z >> (-4)
1745
+ w^4 + w^9 + w^10 + 2*w^11 + 4*w^12 + 3*w^14 + w^16 + 4*w^17 + 4*w^18 + 4*w^19 + 4*w^20 + 4*w^21 + 4*w^24 + w^25 + 4*w^28 + O(w^29)
1746
+ sage: F = W.fraction_field()
1747
+ sage: z = F(z)
1748
+ sage: z >> 7
1749
+ w^-7 + w^-2 + w^-1 + 2 + 4*w + 3*w^3 + w^5 + 4*w^6 + 4*w^7 + 4*w^8 + 4*w^9 + 4*w^10 + 4*w^13 + w^14 + 4*w^17 + O(w^18)
1750
+ """
1751
+ cdef pAdicZZpXCRElement ans
1752
+ if not isinstance(shift, Integer):
1753
+ shift = Integer(shift)
1754
+ if mpz_fits_slong_p((<Integer>shift).value) == 0:
1755
+ if self._is_exact_zero():
1756
+ return self
1757
+ if self.prime_pow.in_field or mpz_sgn((<Integer>shift).value) < 0:
1758
+ raise ValueError("valuation overflow")
1759
+ else:
1760
+ ans = self._new_c(0)
1761
+ ans.ordp = 0
1762
+ return ans
1763
+ return self._rshift_c(mpz_get_si((<Integer>shift).value))
1764
+
1765
+ cpdef _neg_(self):
1766
+ """
1767
+ Negation.
1768
+
1769
+ EXAMPLES::
1770
+
1771
+ sage: R = Zp(5,5)
1772
+ sage: S.<x> = R[]
1773
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1774
+ sage: W.<w> = R.ext(f)
1775
+ sage: z = (1 + w)^5; z
1776
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1777
+ sage: -z # indirect doctest
1778
+ 4 + 3*w^5 + 4*w^6 + w^7 + w^8 + w^9 + w^10 + w^11 + 2*w^12 + 4*w^13 + 4*w^15 + 3*w^16 + w^17 + 2*w^18 + 3*w^19 + 2*w^21 + 4*w^23 + 4*w^24 + O(w^25)
1779
+ sage: y = z + (-z); y
1780
+ O(w^25)
1781
+ sage: -y
1782
+ O(w^25)
1783
+ sage: -W(0)
1784
+ 0
1785
+ """
1786
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
1787
+ ans.ordp = self.ordp
1788
+ if self.relprec != 0:
1789
+ self.prime_pow.restore_context_capdiv(self.relprec)
1790
+ ZZ_pX_negate(ans.unit, self.unit)
1791
+ return ans
1792
+
1793
+ # / 1 + \alpha^p \pi_K^{p \lambda} mod \mathfrak{p}_K^{p \lambda + 1} if 1 \le \lambda < \frac{e_K}{p-1}
1794
+ # (1 + \alpha \pi^{\lambda})^p \equiv { 1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} mod \mathfrak{p}_K^{p \lambda + 1} if \lambda = \frac{e_K}{p-1}
1795
+ # \ 1 - \epsilon \alpha \pi_K^{\lambda + e} mod \mathfrak{p}_K^{\lambda + e + 1} if \lambda > \frac{e_K}{p-1}
1796
+
1797
+ def __pow__(pAdicZZpXCRElement self, _right, m): # m ignored
1798
+ r"""
1799
+ Compute ``self^right``.
1800
+
1801
+ Note: when ``right`` is divisible by `p` then one can get more
1802
+ precision than expected.
1803
+
1804
+ Lemma 2.1 (Constructing Class Fields over Local Fields, Sebastian Pauli):
1805
+
1806
+ Let `\alpha` be in `\mathcal{O}_K`. Let
1807
+
1808
+ .. MATH::
1809
+
1810
+ p = -\pi_K^{e_K} \epsilon
1811
+
1812
+ be the factorization of `p` where `\epsilon` is a unit. Then
1813
+ the `p`-th power of `1 + \alpha \pi_K^{\lambda}` satisfies
1814
+
1815
+ .. MATH::
1816
+
1817
+ (1 + \alpha \pi^{\lambda})^p \equiv \left{ \begin{array}{lll}
1818
+ 1 + \alpha^p \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $1 \le \lambda < \frac{e_K}{p-1}$} \\
1819
+ 1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $\lambda = \frac{e_K}{p-1}$} \\
1820
+ 1 - \epsilon \alpha \pi_K^{\lambda + e} & \mod \mathfrak{p}_K^{\lambda + e + 1} & \mbox{if $\lambda > \frac{e_K}{p-1}$}
1821
+ \end{array} \right.
1822
+
1823
+
1824
+ So if ``right`` is divisible by `p^k` we can multiply the
1825
+ relative precision by `p` until we exceed `e/(p-1)`, then add
1826
+ `e` until we have done a total of `k` things: the precision of
1827
+ the result can therefore be greater than the precision of
1828
+ ``self``.
1829
+
1830
+ There is also the issue of `p`-adic exponents, and determining
1831
+ how the precision of the exponent affects the precision of the
1832
+ result.
1833
+
1834
+ In computing `(a + O(\pi^k))^{b + O(p^m)}`, one needs that the
1835
+ reduction of `a` mod `\pi` is in the prime field
1836
+ `\GF{p}` (so that the `p^m` power of the Teichmuller
1837
+ part is constant as `m` increases). Given this restriction,
1838
+ we can factor out the Teichmuller part and use the above lemma
1839
+ to find the first spot where
1840
+
1841
+ .. MATH::
1842
+
1843
+ (1 + \alpha \pi^{\lambda})^{p^m}
1844
+
1845
+ differs from 1. We compare this with the precision bound
1846
+ given by computing `(a + O(\pi^k))^b` and take the lesser of
1847
+ the two.
1848
+
1849
+ In order to do this we need to compute the valuation of ``(self
1850
+ / self.parent().teichmuller(self)) - 1``.
1851
+
1852
+ EXAMPLES::
1853
+
1854
+ sage: R = Zp(5,5)
1855
+ sage: S.<x> = R[]
1856
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1857
+ sage: W.<w> = R.ext(f)
1858
+ sage: (1 + w)^5 # indirect doctest
1859
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
1860
+ sage: (1 + w)^-5
1861
+ 1 + 4*w^5 + 4*w^6 + 3*w^7 + w^8 + 2*w^10 + w^11 + w^12 + 2*w^14 + 3*w^16 + 3*w^17 + 4*w^18 + 4*w^19 + 2*w^20 + 2*w^21 + 4*w^22 + 3*w^23 + 3*w^24 + O(w^25)
1862
+ sage: (1 + w + O(w^19))^5
1863
+ 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + O(w^24)
1864
+ sage: (1 + O(w))^5
1865
+ 1 + O(w^5)
1866
+ sage: (1 + w + O(w^3))^25
1867
+ 1 + w^10 + w^11 + 4*w^12 + O(w^13)
1868
+ sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(125))
1869
+ 2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + 4*w^10 + O(w^11)
1870
+ sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(25))
1871
+ 2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + O(w^10)
1872
+ sage: (3 + w^2 + O(w^6))^(15+O(25))
1873
+ 2 + w^5 + 4*w^7 + w^9 + 3*w^10 + O(w^11)
1874
+ sage: R = Zp(2, 10)
1875
+ sage: S.<x> = R[]
1876
+ sage: f = x^34 + 18*x^5 - 72*x^3 + 2
1877
+ sage: W.<w> = R.ext(f)
1878
+ sage: (1+w+O(w^2))^8
1879
+ 1 + w^8 + O(w^16)
1880
+ sage: (1+w+O(w^2))^16
1881
+ 1 + w^16 + O(w^32)
1882
+ sage: (1+w+O(w^2))^32
1883
+ 1 + w^32 + w^50 + w^55 + w^60 + O(w^64)
1884
+ sage: (1+w+O(w^2))^64
1885
+ 1 + w^64 + w^66 + w^71 + w^76 + w^81 + w^84 + w^86 + w^91 + w^94 + w^96 + O(w^98)
1886
+
1887
+ TESTS:
1888
+
1889
+ We define ``0^0`` to be unity, :issue:`13786`::
1890
+
1891
+ sage: R = Zp(5,5)
1892
+ sage: S.<x> = R[]
1893
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1894
+ sage: W.<w> = R.ext(f)
1895
+ sage: type(W(0))
1896
+ <class 'sage.rings.padics.padic_ZZ_pX_CR_element.pAdicZZpXCRElement'>
1897
+ sage: W(0)^0
1898
+ 1 + O(w^25)
1899
+ sage: W(0)^0 == W(1)
1900
+ True
1901
+
1902
+ The value returned from ``0^0`` should belong to our ring::
1903
+
1904
+ sage: R = Zp(5,5)
1905
+ sage: S.<x> = R[]
1906
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1907
+ sage: W.<w> = R.ext(f)
1908
+ sage: type(W(0)^0) == type(W(0))
1909
+ True
1910
+ """
1911
+ self._normalize()
1912
+ cdef Integer right
1913
+ cdef bint padic_exp
1914
+ cdef long exp_prec
1915
+ cdef long exp_val
1916
+ cdef long relprec
1917
+ cdef long threshold # e / (p-1)
1918
+ cdef mpz_t tmp, tmp2
1919
+ if mpz_fits_slong_p(self.prime_pow.prime.value) == 0:
1920
+ threshold = 0
1921
+ else:
1922
+ threshold = self.prime_pow.e / (mpz_get_si(self.prime_pow.prime.value) - 1)
1923
+ cdef Integer base_level
1924
+ cdef pAdicZZpXCRElement ans
1925
+ cdef long i
1926
+ if self._is_exact_zero():
1927
+ # Return 0 except for 0^0 error or type error on the exponent.
1928
+ if isinstance(_right, (Integer, Rational, int)) or (isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime)):
1929
+ if _right == 0:
1930
+ return self.parent(1)
1931
+ return self
1932
+ else:
1933
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1934
+ elif self._is_inexact_zero():
1935
+ # If an integer exponent, return an inexact zero of valuation right * self.ordp. Otherwise raise an error.
1936
+ if isinstance(_right, int):
1937
+ _right = Integer(_right)
1938
+ if isinstance(_right, Integer):
1939
+ ans = self._new_c(0)
1940
+ mpz_init_set_si(tmp, self.ordp)
1941
+ mpz_mul(tmp, tmp, (<Integer>_right).value)
1942
+ if mpz_cmp_si(tmp, maxordp) >= 0 or mpz_cmp_si(tmp, -maxordp) <= 0:
1943
+ raise ValueError("valuation overflow")
1944
+ ans.ordp = mpz_get_si(tmp)
1945
+ mpz_clear(tmp)
1946
+ return ans
1947
+ elif isinstance(_right, Rational) or (isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime)):
1948
+ raise ValueError("Need more precision")
1949
+ else:
1950
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1951
+ if isinstance(_right, int):
1952
+ _right = Integer(_right)
1953
+ if isinstance(_right, Integer):
1954
+ right = <Integer> _right
1955
+ if right == 0:
1956
+ # return 1 to maximum precision
1957
+ ans = self._new_c(self.prime_pow.ram_prec_cap)
1958
+ ans.ordp = 0
1959
+ ZZ_pX_SetCoeff_long(ans.unit, 0, 1)
1960
+ return ans
1961
+ padic_exp = False
1962
+ exp_val = _right.valuation(self.prime_pow.prime) ##
1963
+ elif isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime):
1964
+ if self.ordp != 0:
1965
+ raise ValueError("in order to raise to a p-adic exponent, base must be a unit")
1966
+ right = Integer(_right)
1967
+ padic_exp = True
1968
+ exp_prec = _right.precision_absolute() ##
1969
+ exp_val = _right.valuation() ##
1970
+ if exp_val < 0:
1971
+ raise NotImplementedError("negative valuation exponents not yet supported")
1972
+ # checks to see if the residue of self.unit is in the prime field.
1973
+ if self.prime_pow.e == 1:
1974
+ for i from 1 <= i <= ZZ_pX_deg(self.unit):
1975
+ if not ZZ_divide_test(ZZ_p_rep(ZZ_pX_coeff(self.unit, i)), self.prime_pow.pow_ZZ_tmp(1)[0]):
1976
+ raise ValueError("in order to raise to a p-adic exponent, base must reduce to an element of F_p mod the uniformizer")
1977
+ # compute the "level"
1978
+ teich_part = self.parent().teichmuller(self)
1979
+ base_level = (self / teich_part - 1).valuation() ##
1980
+ elif isinstance(_right, Rational):
1981
+ raise NotImplementedError
1982
+ else:
1983
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1984
+ # Now we compute the increased relprec due to the exponent having positive p-adic valuation
1985
+ if exp_val > 0:
1986
+ mpz_init_set_si(tmp, self.relprec)
1987
+ while mpz_cmp_si(tmp, threshold) <= 0 and exp_val > 0:
1988
+ mpz_mul(tmp, tmp, self.prime_pow.prime.value)
1989
+ exp_val -= 1
1990
+ if exp_val > 0:
1991
+ mpz_init_set_si(tmp2, self.prime_pow.e)
1992
+ mpz_addmul_ui(tmp, tmp2, exp_val)
1993
+ mpz_clear(tmp2)
1994
+ if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) > 0:
1995
+ relprec = self.prime_pow.ram_prec_cap
1996
+ else:
1997
+ relprec = mpz_get_si(tmp)
1998
+ mpz_clear(tmp)
1999
+ else:
2000
+ relprec = self.relprec
2001
+ # Now we compute the limit on relprec due to a non-infinite precision on the exponent.
2002
+ if padic_exp:
2003
+ if exp_prec > 0:
2004
+ # I can freely change base_level, so I use it in place of tmp above.
2005
+ while mpz_cmp_si(base_level.value, threshold) <= 0 and exp_prec > 0:
2006
+ mpz_mul(base_level.value, base_level.value, self.prime_pow.prime.value)
2007
+ exp_prec -= 1
2008
+ if exp_prec > 0:
2009
+ mpz_init_set_si(tmp2, self.prime_pow.e)
2010
+ mpz_addmul_ui(base_level.value, tmp2, exp_prec)
2011
+ mpz_clear(tmp2)
2012
+ if mpz_cmp_si(base_level.value, relprec) < 0:
2013
+ relprec = mpz_get_si(base_level.value)
2014
+ else:
2015
+ ans = self._new_c(0)
2016
+ ans.ordp = 0
2017
+ return ans
2018
+ ans = self._new_c(relprec)
2019
+ if self.ordp == 0:
2020
+ ans.ordp = 0
2021
+ else:
2022
+ mpz_init_set(tmp, right.value)
2023
+ mpz_mul_si(tmp, tmp, self.ordp)
2024
+ if mpz_cmp_si(tmp, maxordp) >= 0 or mpz_cmp_si(tmp, -maxordp) <= 0:
2025
+ raise ValueError("valuation overflow")
2026
+ ans.ordp = mpz_get_si(tmp)
2027
+ mpz_clear(tmp)
2028
+ cdef ntl_ZZ rZZ = ntl_ZZ.__new__(ntl_ZZ)
2029
+ mpz_to_ZZ(&rZZ.x, right.value)
2030
+ sig_on()
2031
+ if mpz_sgn(right.value) < 0:
2032
+ if self.prime_pow.e == 1:
2033
+ ZZ_pX_InvMod_newton_unram(ans.unit, self.unit, self.prime_pow.get_modulus(ans.relprec)[0], self.prime_pow.get_context(ans.relprec).x, self.prime_pow.get_context(1).x)
2034
+ else:
2035
+ ZZ_pX_InvMod_newton_ram(ans.unit, self.unit, self.prime_pow.get_modulus_capdiv(ans.relprec)[0], self.prime_pow.get_context_capdiv(ans.relprec).x)
2036
+ ZZ_negate(rZZ.x, rZZ.x)
2037
+ ZZ_pX_PowerMod_pre(ans.unit, ans.unit, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2038
+ else:
2039
+ ZZ_pX_PowerMod_pre(ans.unit, self.unit, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2040
+ sig_off()
2041
+ return ans
2042
+
2043
+ cpdef _add_(self, _right):
2044
+ """
2045
+ Compute the sum of ``self`` and ``right``.
2046
+
2047
+ EXAMPLES::
2048
+
2049
+ sage: R = Zp(5,5)
2050
+ sage: S.<x> = R[]
2051
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2052
+ sage: W.<w> = R.ext(f)
2053
+ sage: (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)) - 69 # indirect doctest
2054
+ 1 + O(w^13)
2055
+ sage: -69 + (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
2056
+ 1 + O(w^13)
2057
+ sage: y = (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
2058
+ sage: y - 70
2059
+ O(w^13)
2060
+ sage: y + 0
2061
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
2062
+ """
2063
+ cdef pAdicZZpXCRElement right = <pAdicZZpXCRElement>_right
2064
+ cdef pAdicZZpXCRElement ans
2065
+ cdef long tmpL
2066
+ cdef ZZ_pX_c tmpP
2067
+ if self.relprec == 0:
2068
+ if self.ordp >= right.ordp + right.relprec: # or self._is_exact_zero()
2069
+ return right
2070
+ elif self.ordp <= right.ordp:
2071
+ ans = self._new_c(0)
2072
+ ans.ordp = self.ordp
2073
+ else:
2074
+ ans = self._new_c(self.ordp - right.ordp)
2075
+ ZZ_pX_conv_modulus(ans.unit, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2076
+ if right.relprec < 0:
2077
+ ans.relprec = -ans.relprec
2078
+ ans.ordp = right.ordp
2079
+ return ans
2080
+ if right.relprec == 0:
2081
+ if right.ordp >= self.ordp + self.relprec: # or right._is_exact_zero()
2082
+ return self
2083
+ elif right.ordp <= self.ordp:
2084
+ ans = self._new_c(0)
2085
+ ans.ordp = right.ordp
2086
+ else:
2087
+ ans = self._new_c(right.ordp - self.ordp)
2088
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2089
+ if self.relprec < 0:
2090
+ ans.relprec = -ans.relprec
2091
+ ans.ordp = self.ordp
2092
+ return ans
2093
+ cdef long srprec = self.relprec
2094
+ if srprec < 0:
2095
+ srprec = -srprec
2096
+ cdef long rrprec = right.relprec
2097
+ if rrprec < 0:
2098
+ rrprec = -rrprec
2099
+ if self.ordp == right.ordp:
2100
+ # The relative precision of the sum is the minimum of the relative precisions in this case, possibly decreasing if we got cancellation
2101
+ # Since the valuations are the same, we could just add the units, if they had the same modulus.
2102
+ # But they don't necessarily, so we may have to conv_modulus
2103
+ if srprec == rrprec:
2104
+ ans = self._new_c(-srprec) # -srprec indicates that ans is not normalized
2105
+ self.prime_pow.restore_context_capdiv(srprec)
2106
+ ZZ_pX_add(ans.unit, self.unit, right.unit)
2107
+ elif srprec < rrprec:
2108
+ ans = self._new_c(-srprec)
2109
+ ZZ_pX_conv_modulus(ans.unit, right.unit, self.prime_pow.get_context_capdiv(srprec).x)
2110
+ self.prime_pow.restore_context_capdiv(srprec)
2111
+ # conv_modulus should have restored the context, so we don't need to again.
2112
+ ZZ_pX_add(ans.unit, ans.unit, self.unit)
2113
+ else:
2114
+ ans = self._new_c(-rrprec)
2115
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(rrprec).x)
2116
+ self.prime_pow.restore_context_capdiv(rrprec)
2117
+ # conv_modulus should have restored the context, so we don't need to again.
2118
+ ZZ_pX_add(ans.unit, ans.unit, right.unit)
2119
+ ans.ordp = self.ordp
2120
+ elif self.ordp < right.ordp:
2121
+ tmpL = right.ordp - self.ordp
2122
+ if tmpL >= srprec:
2123
+ return self
2124
+ if srprec <= tmpL + rrprec:
2125
+ ans = self._new_c(-srprec)
2126
+ else:
2127
+ ans = self._new_c(-tmpL - rrprec)
2128
+ ans.ordp = self.ordp
2129
+ ZZ_pX_conv_modulus(ans.unit, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2130
+ ans._internal_lshift(tmpL)
2131
+ if srprec <= tmpL + rrprec:
2132
+ ZZ_pX_add(ans.unit, ans.unit, self.unit)
2133
+ else:
2134
+ ZZ_pX_conv_modulus(tmpP, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2135
+ ZZ_pX_add(ans.unit, ans.unit, tmpP)
2136
+ # if self is normalized, then the valuations are actually different so the sum will be normalized.
2137
+ if self.relprec > 0:
2138
+ ans.relprec = -ans.relprec
2139
+ else:
2140
+ tmpL = self.ordp - right.ordp
2141
+ if tmpL >= rrprec:
2142
+ return right
2143
+ if rrprec <= tmpL + srprec:
2144
+ ans = self._new_c(-rrprec)
2145
+ else:
2146
+ ans = self._new_c(-tmpL - srprec)
2147
+ ans.ordp = right.ordp
2148
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2149
+ ans._internal_lshift(tmpL)
2150
+ if rrprec <= tmpL + srprec:
2151
+ ZZ_pX_add(ans.unit, ans.unit, right.unit)
2152
+ else:
2153
+ ZZ_pX_conv_modulus(tmpP, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2154
+ ZZ_pX_add(ans.unit, ans.unit, tmpP)
2155
+ # if right is normalized, then the valuations are actually different so the sum will be normalized.
2156
+ if right.relprec > 0:
2157
+ ans.relprec = -ans.relprec
2158
+ return ans
2159
+
2160
+ cpdef _sub_(self, right):
2161
+ """
2162
+ Return the difference of two elements.
2163
+
2164
+ EXAMPLES::
2165
+
2166
+ sage: R = Zp(5,5)
2167
+ sage: S.<x> = R[]
2168
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2169
+ sage: W.<w> = R.ext(f)
2170
+ sage: a = W(329)
2171
+ sage: b = W(111)
2172
+ sage: a - b # indirect doctest
2173
+ 3 + 3*w^5 + w^7 + 2*w^9 + 3*w^10 + 4*w^11 + 2*w^13 + 2*w^14 + w^15 + 4*w^16 + 2*w^18 + 3*w^19 + 2*w^20 + 3*w^21 + w^22 + w^24 + O(w^25)
2174
+ sage: W(218)
2175
+ 3 + 3*w^5 + w^7 + 2*w^9 + 3*w^10 + 4*w^11 + 2*w^13 + 2*w^14 + w^15 + 4*w^16 + 2*w^18 + 3*w^19 + 2*w^20 + 3*w^21 + w^22 + w^24 + O(w^25)
2176
+ sage: a - O(w^14)
2177
+ 4 + 3*w^10 + 2*w^12 + O(w^14)
2178
+ sage: a - 0
2179
+ 4 + 3*w^10 + 2*w^12 + w^14 + 2*w^15 + w^16 + 3*w^17 + 3*w^18 + w^19 + 2*w^21 + 4*w^22 + w^23 + 4*w^24 + O(w^25)
2180
+ sage: O(w^14) - a
2181
+ 1 + 4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + O(w^14)
2182
+ """
2183
+ # For now, a simple implementation
2184
+ return self + (-right)
2185
+
2186
+ cpdef _mul_(self, _right):
2187
+ """
2188
+ Return the product of two elements.
2189
+
2190
+ EXAMPLES::
2191
+
2192
+ sage: R = Zp(5,5)
2193
+ sage: S.<x> = R[]
2194
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2195
+ sage: W.<w> = R.ext(f)
2196
+ sage: a = W(329)
2197
+ sage: b = W(111)
2198
+ sage: a*b # indirect doctest
2199
+ 4 + 3*w^5 + w^7 + 2*w^9 + 4*w^11 + 3*w^12 + 2*w^13 + w^14 + 2*w^15 + 3*w^16 + 4*w^17 + 4*w^18 + 2*w^19 + 2*w^21 + 4*w^22 + 2*w^23 + w^24 + O(w^25)
2200
+ sage: a * 0
2201
+ 0
2202
+ sage: a * O(w^14)
2203
+ O(w^14)
2204
+ """
2205
+ cdef pAdicZZpXCRElement right = <pAdicZZpXCRElement>_right
2206
+ cdef ZZ_pX_c modulus_corrected
2207
+ cdef pAdicZZpXCRElement ans
2208
+ if self._is_exact_zero():
2209
+ return self
2210
+ if right._is_exact_zero():
2211
+ return right
2212
+ self._normalize()
2213
+ right._normalize()
2214
+ if self.relprec <= right.relprec:
2215
+ ans = self._new_c(self.relprec)
2216
+ else:
2217
+ ans = self._new_c(right.relprec)
2218
+ ans.ordp = self.ordp + right.ordp
2219
+ check_ordp(ans.ordp)
2220
+ if ans.relprec == 0:
2221
+ return ans
2222
+ if self.relprec == right.relprec:
2223
+ self.prime_pow.restore_context_capdiv(ans.relprec)
2224
+ sig_on()
2225
+ ZZ_pX_MulMod_pre(ans.unit, self.unit, right.unit, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2226
+ sig_off()
2227
+ elif self.relprec < right.relprec:
2228
+ sig_on()
2229
+ ZZ_pX_conv_modulus(modulus_corrected, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2230
+ ZZ_pX_MulMod_pre(ans.unit, self.unit, modulus_corrected, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2231
+ sig_off()
2232
+ else:
2233
+ sig_on()
2234
+ ZZ_pX_conv_modulus(modulus_corrected, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2235
+ ZZ_pX_MulMod_pre(ans.unit, right.unit, modulus_corrected, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2236
+ sig_off()
2237
+ return ans
2238
+
2239
+ cpdef _div_(self, right):
2240
+ """
2241
+ Return the quotient of two elements.
2242
+
2243
+ EXAMPLES::
2244
+
2245
+ sage: R = Zp(5,5)
2246
+ sage: S.<x> = R[]
2247
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2248
+ sage: W.<w> = R.ext(f)
2249
+ sage: W(14) / W(125) # indirect doctest
2250
+ 4*w^-15 + w^-13 + 3*w^-11 + 2*w^-10 + 3*w^-9 + 4*w^-8 + 4*w^-7 + 3*w^-6 + 2*w^-5 + 4*w^-4 + 3*w^-3 + 2*w^-2 + 4*w^-1 + 2 + w^2 + w^4 + 4*w^5 + w^6 + w^7 + 3*w^9 + O(w^10)
2251
+ sage: 1 / w
2252
+ w^-1 + O(w^24)
2253
+ sage: W.<w> = R.ext(x^25 - 165*x + 5)
2254
+ sage: a = (1 + w)^25 - 1
2255
+ sage: b = (1 + w)^5 - 1
2256
+ sage: c = (1 + w)^20 + (1 + w)^15 + (1 + w)^10 + (1 + w)^5 + 1
2257
+ sage: d = a / b; d == c
2258
+ True
2259
+ sage: d.precision_absolute()
2260
+ 120
2261
+ sage: c.precision_absolute()
2262
+ 125
2263
+ sage: 1 / a == ~a
2264
+ True
2265
+ """
2266
+ # for now, a simple implementation
2267
+ return self * (~right)
2268
+
2269
+ def __copy__(self):
2270
+ """
2271
+ Return a copy of this element.
2272
+
2273
+ EXAMPLES::
2274
+
2275
+ sage: R = Zp(5,5)
2276
+ sage: S.<x> = R[]
2277
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2278
+ sage: W.<w> = R.ext(f)
2279
+ sage: b = W(45, 17); b
2280
+ 4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + 3*w^14 + w^16 + O(w^17)
2281
+ sage: c = copy(b); c
2282
+ 4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + 3*w^14 + w^16 + O(w^17)
2283
+ sage: c is b
2284
+ False
2285
+ """
2286
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
2287
+ ans.ordp = self.ordp
2288
+ ans.unit = self.unit
2289
+ return ans
2290
+
2291
+ def _integer_(self, Z=None):
2292
+ r"""
2293
+ Return an integer congruent to this element modulo
2294
+ `\pi^{\mathrm{self.absolute_precision()}`, if possible.
2295
+
2296
+ EXAMPLES::
2297
+
2298
+ sage: ZZ(ZqCR(125,names='a')(-1)) # indirect doctest
2299
+ 95367431640624
2300
+ sage: R = Zp(5); S.<x> = ZZ[]; f = x^5 + 25*x^3 - 5; W.<w> = R.ext(f)
2301
+ sage: ZZ(W(-1))
2302
+ 95367431640624
2303
+ sage: ZZ(W(0))
2304
+ 0
2305
+ sage: ZZ(W(0,7))
2306
+ 0
2307
+ sage: ZZ(w)
2308
+ Traceback (most recent call last):
2309
+ ...
2310
+ ValueError: this element not well approximated by an integer
2311
+ sage: ZZ(W(5)) # todo: this should be different...
2312
+ 381469726562505
2313
+ """
2314
+ cdef Integer ans
2315
+ cdef ZZ_c tmp_z
2316
+ if self._is_exact_zero() or self.relprec == 0:
2317
+ ans = PY_NEW(Integer)
2318
+ return ans
2319
+ if self.ordp < 0:
2320
+ self._normalize()
2321
+ if self.ordp < 0:
2322
+ raise ValueError("this element has negative valuation")
2323
+ cdef ntl_ZZ_pX f = <ntl_ZZ_pX>self._ntl_rep_abs()[0]
2324
+ if f.degree() > 0:
2325
+ raise ValueError("this element not well approximated by an integer")
2326
+ ans = PY_NEW(Integer)
2327
+ tmp_z = ZZ_p_rep(ZZ_pX_ConstTerm(f.x))
2328
+ ZZ_to_mpz(ans.value, &tmp_z)
2329
+ return ans
2330
+
2331
+ def is_zero(self, absprec=None):
2332
+ r"""
2333
+ Return whether the valuation of this element is at least
2334
+ ``absprec``. If ``absprec`` is ``None``, checks if this element
2335
+ is indistinguishable from zero.
2336
+
2337
+ If this element is an inexact zero of valuation less than ``absprec``,
2338
+ raises a :exc:`PrecisionError`.
2339
+
2340
+ EXAMPLES::
2341
+
2342
+ sage: R = Zp(5,5)
2343
+ sage: S.<x> = R[]
2344
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2345
+ sage: W.<w> = R.ext(f)
2346
+ sage: O(w^189).is_zero()
2347
+ True
2348
+ sage: W(0).is_zero()
2349
+ True
2350
+ sage: a = W(675)
2351
+ sage: a.is_zero()
2352
+ False
2353
+ sage: a.is_zero(7)
2354
+ True
2355
+ sage: a.is_zero(21)
2356
+ False
2357
+ """
2358
+ cdef bint ans
2359
+ cdef long aprec
2360
+ self._normalize()
2361
+ if self._is_exact_zero():
2362
+ ans = True
2363
+ elif absprec is None:
2364
+ ans = (self.relprec == 0)
2365
+ else:
2366
+ if not isinstance(absprec, Integer):
2367
+ absprec = Integer(absprec)
2368
+ if mpz_fits_slong_p((<Integer>absprec).value) == 0:
2369
+ if mpz_sgn((<Integer>absprec).value) < 0:
2370
+ ans = True
2371
+ elif self.relprec == 0:
2372
+ raise PrecisionError("not enough precision to determine if element is zero")
2373
+ else:
2374
+ ans = False
2375
+ else:
2376
+ aprec = mpz_get_si((<Integer>absprec).value)
2377
+ if self.relprec == 0 and aprec > self.ordp:
2378
+ raise PrecisionError("not enough precision to determine if element is zero")
2379
+ else:
2380
+ ans = (self.ordp >= aprec)
2381
+ return ans
2382
+
2383
+ cpdef ntl_ZZ_pX _ntl_rep_unnormalized(self):
2384
+ """
2385
+ Return an ``ntl_ZZ_pX`` holding the current unit part of this element.
2386
+
2387
+ The element is not normalized before this operation, so the polynomial
2388
+ returned may not actually be a unit.
2389
+
2390
+ EXAMPLES::
2391
+
2392
+ sage: R = Zp(5,5)
2393
+ sage: S.<x> = R[]
2394
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2395
+ sage: W.<w> = R.ext(f)
2396
+ sage: a = W(566); b = W(209)
2397
+ sage: c = a + b; c._ntl_rep_unnormalized()
2398
+ [775]
2399
+ sage: c
2400
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + w^20 + 2*w^21 + 3*w^22 + w^23 + w^24 + O(w^25)
2401
+ sage: c._ntl_rep_unnormalized()
2402
+ [106 60 114 35 112]
2403
+ """
2404
+ if self.relprec == 0:
2405
+ raise ValueError("self == 0")
2406
+ self.prime_pow.restore_context_capdiv(self.relprec)
2407
+ cdef ntl_ZZ_pX ans = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
2408
+ ans.c = self.prime_pow.get_context_capdiv(self.relprec)
2409
+ ans.x = self.unit
2410
+ return ans
2411
+
2412
+ cpdef ntl_ZZ_pX _ntl_rep(self):
2413
+ """
2414
+ Return an ``ntl_ZZ_pX`` that holds the unit part of this element.
2415
+
2416
+ EXAMPLES::
2417
+
2418
+ sage: R = Zp(5,5)
2419
+ sage: S.<x> = R[]
2420
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2421
+ sage: W.<w> = R.ext(f)
2422
+ sage: a = W(566); b = W(209)
2423
+ sage: c = a + b; c._ntl_rep()
2424
+ [106 60 114 35 112]
2425
+ sage: c
2426
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + w^20 + 2*w^21 + 3*w^22 + w^23 + w^24 + O(w^25)
2427
+ sage: c._ntl_rep()
2428
+ [106 60 114 35 112]
2429
+ """
2430
+ self._normalize()
2431
+ return self._ntl_rep_unnormalized()
2432
+
2433
+ cpdef _ntl_rep_abs(self):
2434
+ """
2435
+ Return a pair ``(f, k)`` where ``f`` is an ``ntl_ZZ_pX`` and ``k`` is a
2436
+ nonpositive integer such that ``self = f(self.parent.gen())*p^k``.
2437
+
2438
+ EXAMPLES::
2439
+
2440
+ sage: R = Zp(5,5)
2441
+ sage: S.<x> = R[]
2442
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2443
+ sage: W.<w> = R.ext(f)
2444
+ sage: a = W(566); b = W(209)
2445
+ sage: c = a + b; c._ntl_rep_abs()
2446
+ ([775], 0)
2447
+ sage: c
2448
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + w^20 + 2*w^21 + 3*w^22 + w^23 + w^24 + O(w^25)
2449
+ sage: c._ntl_rep_abs()
2450
+ ([775], 0)
2451
+ sage: (~c)._ntl_rep_abs()
2452
+ ([121], -2)
2453
+ sage: ~c
2454
+ w^-10 + w^-8 + 4*w^-6 + 4*w^-5 + 3*w^-3 + 4*w^-2 + 3*w^-1 + 4 + 4*w + 2*w^2 + 4*w^3 + 3*w^4 + O(w^5)
2455
+ sage: ~c * 25
2456
+ 1 + 4*w^5 + 3*w^7 + w^9 + 4*w^10 + 2*w^11 + 3*w^12 + w^13 + 4*w^14 + O(w^15)
2457
+ sage: W(121)
2458
+ 1 + 4*w^5 + 3*w^7 + w^9 + 4*w^10 + 2*w^11 + 3*w^12 + w^13 + 4*w^14 + 2*w^16 + 3*w^17 + 3*w^18 + 4*w^19 + 4*w^20 + 3*w^21 + w^22 + w^23 + 4*w^24 + O(w^25)
2459
+ """
2460
+ self._normalize()
2461
+ if self.ordp == 0:
2462
+ return self._ntl_rep(), Integer(0)
2463
+ cdef ntl_ZZ_pContext_class ctx
2464
+ cdef long little_shift, ppow
2465
+ if self.ordp > 0:
2466
+ ctx = self.prime_pow.get_context_capdiv(self.ordp + self.relprec)
2467
+ else:
2468
+ little_shift = ((-self.ordp) % self.prime_pow.e)
2469
+ if little_shift != 0:
2470
+ little_shift = self.prime_pow.e - little_shift
2471
+ ctx = self.prime_pow.get_context_capdiv(self.relprec + little_shift)
2472
+ ctx.restore_c()
2473
+ cdef pAdicZZpXCRElement dummy = pAdicZZpXCRElement.__new__(pAdicZZpXCRElement)
2474
+ cdef ntl_ZZ_pX ans = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
2475
+ cdef Integer ans_k = PY_NEW(Integer)
2476
+ dummy.unit = self.unit
2477
+ dummy.prime_pow = self.prime_pow
2478
+ if self.ordp > 0:
2479
+ dummy.relprec = self.ordp + self.relprec
2480
+ dummy._internal_lshift(self.ordp)
2481
+ ans.x = dummy.unit
2482
+ else:
2483
+ ppow = (self.ordp - little_shift) / self.prime_pow.e
2484
+ mpz_set_si(ans_k.value, ppow)
2485
+ dummy.ordp = 0 # _pshift_self wants ordp set
2486
+ dummy.relprec = self.relprec + little_shift
2487
+ # self = x^(self.prime_pow.e * ppow) * x^(little_shift) * self.unit
2488
+ # so we want to _internal_lshift dummy.unit by little_shift
2489
+ dummy._internal_lshift(little_shift)
2490
+ # and then write
2491
+ # self = p^(ppow) * (x^e/p)^(ppow) * dummy.unit
2492
+ # so we need to multiply dummy.unit by (p/x^e)^(-ppow) in the Eisenstein case
2493
+ # which we can do by _pshift_self
2494
+ dummy._pshift_self(-ppow)
2495
+ ans.x = dummy.unit
2496
+ ans.c = ctx
2497
+ return ans, ans_k
2498
+
2499
+ def _polynomial_list(self, pad=False):
2500
+ """
2501
+ Return the coefficient list for a polynomial over the base ring
2502
+ yielding this element.
2503
+
2504
+ INPUT:
2505
+
2506
+ - ``pad`` -- whether to pad the result with zeros of the appropriate precision
2507
+
2508
+ EXAMPLES::
2509
+
2510
+ sage: R.<x> = ZZ[]
2511
+ sage: W.<w> = Qp(5).extension(x^3 - 5)
2512
+ sage: (1 + w + O(w^11))._polynomial_list()
2513
+ [1 + O(5^4), 1 + O(5^4)]
2514
+ sage: (1 + w + O(w^11))._polynomial_list(pad=True)
2515
+ [1 + O(5^4), 1 + O(5^4), O(5^3)]
2516
+ sage: W(0)._polynomial_list()
2517
+ []
2518
+ sage: W(0)._polynomial_list(pad=True)
2519
+ [0, 0, 0]
2520
+ sage: W(O(w^7))._polynomial_list()
2521
+ []
2522
+ sage: W(O(w^7))._polynomial_list(pad=True)
2523
+ [O(5^3), O(5^2), O(5^2)]
2524
+ sage: T.<a> = Qp(5).extension(x^2 - 5)
2525
+ sage: T(1/5)._polynomial_list()
2526
+ [5^-1 + O(5^19)]
2527
+ sage: T(a^-800)._polynomial_list()
2528
+ [5^-400 + O(5^-380)]
2529
+ sage: T(O(a^-2))._polynomial_list()
2530
+ []
2531
+ """
2532
+ R = self.base_ring()
2533
+ if self.is_zero():
2534
+ L = []
2535
+ k = 0
2536
+ else:
2537
+ f, k = self._ntl_rep_abs()
2538
+ L = [Integer(c) for c in f.list()]
2539
+ if pad:
2540
+ n = self.parent().degree()
2541
+ L.extend([R.zero()] * (n - len(L)))
2542
+ if self._is_exact_zero():
2543
+ return L
2544
+ prec = self.relprec + self.ordp
2545
+ e = self.parent().e()
2546
+ if e == 1:
2547
+ return [R(c, prec-k) << k for c in L]
2548
+ else:
2549
+ return [R(c, (((prec - i - 1) // e) + 1) - k) << k for i, c in enumerate(L)]
2550
+
2551
+ def polynomial(self, var='x'):
2552
+ """
2553
+ Return a polynomial over the base ring that yields this element
2554
+ when evaluated at the generator of the parent.
2555
+
2556
+ INPUT:
2557
+
2558
+ - ``var`` -- string, the variable name for the polynomial
2559
+
2560
+ EXAMPLES::
2561
+
2562
+ sage: S.<x> = ZZ[]
2563
+ sage: W.<w> = Zp(5).extension(x^2 - 5)
2564
+ sage: (w + W(5, 7)).polynomial()
2565
+ (1 + O(5^3))*x + 5 + O(5^4)
2566
+ """
2567
+ R = self.base_ring()
2568
+ S = R[var]
2569
+ return S(self._polynomial_list())
2570
+
2571
+ cdef ZZ_p_c _const_term(self) noexcept:
2572
+ """
2573
+ Return the constant term of ``self.unit``.
2574
+
2575
+ Note: this may be divisible by `p` if ``self`` is not normalized.
2576
+
2577
+ EXAMPLES::
2578
+
2579
+ sage: R = Zp(5,5)
2580
+ sage: S.<x> = R[]
2581
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2582
+ sage: W.<w> = R.ext(f)
2583
+ sage: a = W(566)
2584
+ sage: a._const_term_test() # indirect doctest
2585
+ 566
2586
+ """
2587
+ return ZZ_pX_ConstTerm((<pAdicZZpXCRElement>self).unit)
2588
+
2589
+ def is_equal_to(self, right, absprec=None):
2590
+ """
2591
+ Return whether this element is equal to ``right`` modulo ``self.uniformizer()^absprec``.
2592
+
2593
+ If ``absprec`` is ``None``, checks whether this element is equal to ``right``
2594
+ modulo the lower of their two precisions.
2595
+
2596
+ EXAMPLES::
2597
+
2598
+ sage: R = Zp(5,5)
2599
+ sage: S.<x> = R[]
2600
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2601
+ sage: W.<w> = R.ext(f)
2602
+ sage: a = W(47); b = W(47 + 25)
2603
+ sage: a.is_equal_to(b)
2604
+ False
2605
+ sage: a.is_equal_to(b, 7)
2606
+ True
2607
+ """
2608
+ # Should be sped up later
2609
+ return (self - right).is_zero(absprec)
2610
+
2611
+ # def lift(self):
2612
+ # """
2613
+ # Return an element of a number field defined by the same polynomial as
2614
+ # ``self``'s parent that is congruent to self modulo an appropriate ideal.
2615
+
2616
+ # Not currently implemented.
2617
+ # """
2618
+ # raise NotImplementedError
2619
+
2620
+ cpdef pAdicZZpXCRElement lift_to_precision(self, absprec=None):
2621
+ """
2622
+ Return a ``pAdicZZpXCRElement`` congruent to this element but with
2623
+ absolute precision at least ``absprec``.
2624
+
2625
+ INPUT:
2626
+
2627
+ - ``absprec`` -- (default: ``None``) the absolute precision of
2628
+ the result. If ``None``, lifts to the maximum precision
2629
+ allowed.
2630
+
2631
+ .. NOTE::
2632
+
2633
+ If setting ``absprec`` that high would violate the
2634
+ precision cap, raises a precision error. If ``self`` is an
2635
+ inexact zero and ``absprec`` is greater than the maximum
2636
+ allowed valuation, raises an error.
2637
+
2638
+ Note that the new digits will not necessarily be zero.
2639
+
2640
+ EXAMPLES::
2641
+
2642
+ sage: R = Zp(5,5)
2643
+ sage: S.<x> = R[]
2644
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2645
+ sage: W.<w> = R.ext(f)
2646
+ sage: a = W(345, 17); a
2647
+ 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + O(w^17)
2648
+ sage: b = a.lift_to_precision(19); b
2649
+ 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15
2650
+ + w^17 + 2*w^18 + O(w^19)
2651
+ sage: c = a.lift_to_precision(24); c
2652
+ 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15
2653
+ + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24)
2654
+ sage: a._ntl_rep()
2655
+ [19 35 118 60 121]
2656
+ sage: b._ntl_rep()
2657
+ [19 35 118 60 121]
2658
+ sage: c._ntl_rep()
2659
+ [19 35 118 60 121]
2660
+ sage: a.lift_to_precision().precision_relative() == W.precision_cap()
2661
+ True
2662
+ """
2663
+ cdef pAdicZZpXCRElement ans
2664
+ cdef long aprec, rprec
2665
+ self._normalize()
2666
+ if self._is_exact_zero():
2667
+ return self
2668
+ if absprec is not None and not isinstance(absprec, Integer):
2669
+ absprec = Integer(absprec)
2670
+ if absprec is None:
2671
+ if self.relprec == 0:
2672
+ # return an exact zero
2673
+ ans = self._new_c(0)
2674
+ ans._set_exact_zero()
2675
+ return ans
2676
+ aprec = self.prime_pow.ram_prec_cap + self.ordp
2677
+ elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
2678
+ if mpz_sgn((<Integer>absprec).value) < 0 or self.relprec == self.prime_pow.ram_prec_cap:
2679
+ return self
2680
+ else:
2681
+ if self.relprec == 0:
2682
+ raise ValueError("absprec larger than maximum allowable valuation")
2683
+ else:
2684
+ raise PrecisionError("precision higher than allowed by the precision cap")
2685
+ else:
2686
+ aprec = mpz_get_si((<Integer>absprec).value)
2687
+ if aprec <= self.ordp + self.relprec:
2688
+ return self
2689
+ if self.relprec == 0:
2690
+ if self.ordp >= aprec:
2691
+ return self
2692
+ elif aprec >= maxordp:
2693
+ raise ValueError("absprec larger than maximum allowable valuation")
2694
+ else:
2695
+ ans = self._new_c(0)
2696
+ ans._set_inexact_zero(aprec)
2697
+ return ans
2698
+ # Now we're done handling all the special cases.
2699
+ rprec = aprec - self.ordp
2700
+ if rprec > self.prime_pow.ram_prec_cap:
2701
+ raise PrecisionError("precision higher than allowed by the precision cap")
2702
+ ans = self._new_c(rprec)
2703
+ ans.ordp = self.ordp
2704
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(rprec).x)
2705
+ return ans
2706
+
2707
+ def expansion(self, n=None, lift_mode='simple'):
2708
+ """
2709
+ Return a list giving a series representation of ``self``.
2710
+
2711
+ - If ``lift_mode == 'simple'`` or ``'smallest'``, the returned
2712
+ list will consist of integers (in the Eisenstein case) or a
2713
+ list of lists of integers (in the unramified case). ``self``
2714
+ can be reconstructed as a sum of elements of the list times
2715
+ powers of the uniformiser (in the Eisenstein case), or as a
2716
+ sum of powers of the `p` times polynomials in the generator
2717
+ (in the unramified case).
2718
+
2719
+ + If ``lift_mode == 'simple'``, all integers will be in the interval
2720
+ `[0,p-1]`.
2721
+
2722
+ + If ``lift_mode == 'smallest'`` they will be in the
2723
+ interval `[(1-p)/2, p/2]`.
2724
+
2725
+ - If ``lift_mode == 'teichmuller'``, returns a list of
2726
+ ``pAdicZZpXCRElements``, all of which are Teichmuller
2727
+ representatives and such that ``self`` is the sum of that list
2728
+ times powers of the uniformizer.
2729
+
2730
+ Note that zeros are truncated from the returned list if
2731
+ ``self.parent()`` is a field, so you must use the
2732
+ ``valuation`` function to fully reconstruct ``self``.
2733
+
2734
+ INPUT:
2735
+
2736
+ - ``n`` -- integer (default: ``None``); if given, returns the
2737
+ corresponding entry in the expansion
2738
+
2739
+ EXAMPLES::
2740
+
2741
+ sage: R = Zp(5,5)
2742
+ sage: S.<x> = R[]
2743
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2744
+ sage: W.<w> = R.ext(f)
2745
+ sage: y = W(775, 19); y
2746
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
2747
+ sage: (y>>9).expansion()
2748
+ [0, 1, 0, 4, 0, 2, 1, 2, 4, 1]
2749
+ sage: (y>>9).expansion(lift_mode='smallest')
2750
+ [0, 1, 0, -1, 0, 2, 1, 2, 0, 1]
2751
+ sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
2752
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
2753
+ sage: g = x^3 + 3*x + 3
2754
+ sage: A.<a> = R.ext(g)
2755
+ sage: y = 75 + 45*a + 1200*a^2; y
2756
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
2757
+ sage: E = y.expansion(); E
2758
+ 5-adic expansion of 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
2759
+ sage: list(E)
2760
+ [[], [0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1], []]
2761
+ sage: list(y.expansion(lift_mode='smallest'))
2762
+ [[], [0, -1], [-2, 2, -2], [1], [0, 0, 2], []]
2763
+ sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
2764
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
2765
+ sage: list(W(0).expansion())
2766
+ []
2767
+ sage: list(W(0,4).expansion())
2768
+ []
2769
+ sage: list(A(0,4).expansion())
2770
+ []
2771
+
2772
+ TESTS:
2773
+
2774
+ We check that :issue:`24949` is fixed::
2775
+
2776
+ sage: R = Zp(2)
2777
+ sage: S.<x> = R[]
2778
+ sage: A.<a> = R.extension(x^10 + 2)
2779
+ sage: u = a^4 + a^5
2780
+ sage: v = a^2 + a^3
2781
+ sage: w = u - v^2
2782
+ sage: w.expansion(4)
2783
+ 0
2784
+ """
2785
+ self._normalize()
2786
+ if lift_mode == 'teichmuller':
2787
+ zero = self.parent()(0)
2788
+ elif self.prime_pow.e == 1:
2789
+ zero = []
2790
+ else:
2791
+ zero = Integer(0)
2792
+ if isinstance(n, slice):
2793
+ return self.slice(n.start, n.stop, n.step)
2794
+ elif n is not None:
2795
+ if self._is_exact_zero() or n < self.ordp:
2796
+ return zero
2797
+ elif n >= self.ordp + self.relprec:
2798
+ raise PrecisionError
2799
+ if self.relprec == 0: # cannot have n = None
2800
+ return []
2801
+ if lift_mode == 'simple':
2802
+ ulist = self.ext_p_list(pos=True)
2803
+ elif lift_mode == 'smallest':
2804
+ ulist = self.ext_p_list(pos=False)
2805
+ elif lift_mode == 'teichmuller':
2806
+ if n is None:
2807
+ ulist = self.teichmuller_expansion()
2808
+ else:
2809
+ return self.teichmuller_expansion(n)
2810
+ else:
2811
+ raise ValueError("lift mode must be one of 'simple', 'smallest' or 'teichmuller'")
2812
+ if n is not None:
2813
+ try:
2814
+ return ulist[n - self.ordp]
2815
+ except IndexError:
2816
+ return zero
2817
+ if self.prime_pow.in_field == 0 and self.ordp > 0:
2818
+ ulist = [zero] * self.ordp + ulist
2819
+ return ulist
2820
+
2821
+ def matrix_mod_pn(self):
2822
+ r"""
2823
+ Return the matrix of right multiplication by the element on
2824
+ the power basis `1, x, x^2, \ldots, x^{d-1}` for this
2825
+ extension field. Thus the *rows* of this matrix give the
2826
+ images of each of the `x^i`. The entries of the matrices are
2827
+ :class:`IntegerMod` elements, defined modulo `p^{N / e}` where `N` is
2828
+ the absolute precision of this element (unless this element is
2829
+ zero to arbitrary precision; in that case the entries are
2830
+ integer zeros.)
2831
+
2832
+ Raises an error if this element has negative valuation.
2833
+
2834
+ EXAMPLES::
2835
+
2836
+ sage: R = ZpCR(5,5)
2837
+ sage: S.<x> = R[]
2838
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2839
+ sage: W.<w> = R.ext(f)
2840
+ sage: a = (3+w)^7
2841
+ sage: a.matrix_mod_pn()
2842
+ [2757 333 1068 725 2510]
2843
+ [ 50 1507 483 318 725]
2844
+ [ 500 50 3007 2358 318]
2845
+ [1590 1375 1695 1032 2358]
2846
+ [2415 590 2370 2970 1032]
2847
+
2848
+ TESTS:
2849
+
2850
+ Check that :issue:`13617` has been fixed::
2851
+
2852
+ sage: W.zero().matrix_mod_pn()
2853
+ [0 0 0 0 0]
2854
+ [0 0 0 0 0]
2855
+ [0 0 0 0 0]
2856
+ [0 0 0 0 0]
2857
+ [0 0 0 0 0]
2858
+ """
2859
+ if self.valuation_c() < 0:
2860
+ raise ValueError("self must be integral")
2861
+ n = self.prime_pow.deg
2862
+ from sage.matrix.constructor import matrix
2863
+ if self._is_exact_zero():
2864
+ from sage.rings.integer_ring import IntegerRing
2865
+ return matrix(IntegerRing(), n, n)
2866
+ R = IntegerModRing(self.prime_pow.pow_Integer(self.prime_pow.capdiv(self.ordp + self.relprec)))
2867
+ L = []
2868
+ cdef ntl_ZZ_pX cur = <ntl_ZZ_pX>self._ntl_rep_abs()[0]
2869
+ cur.c.restore_c()
2870
+ cdef ZZ_pX_Modulus_c* m = self.prime_pow.get_modulus_capdiv(self.ordp + self.relprec)
2871
+ cdef ZZ_pX_c x
2872
+ ZZ_pX_SetX(x)
2873
+ cdef Py_ssize_t i
2874
+ zero = int(0)
2875
+ for i in range(n):
2876
+ curlist = cur.list()
2877
+ L.extend(curlist + [zero] * (n - len(curlist)))
2878
+ ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0])
2879
+ return matrix(R, n, n, L)
2880
+
2881
+ # def matrix(self, base=None):
2882
+ # """
2883
+ # If base is None, return the matrix of right multiplication by
2884
+ # the element on the power basis `1, x, x^2, \ldots, x^{d-1}`
2885
+ # for this extension field. Thus the \emph{rows} of this matrix
2886
+ # give the images of each of the `x^i`.
2887
+
2888
+ # If base is not None, then base must be either a field that
2889
+ # embeds in the parent of self or a morphism to the parent of
2890
+ # self, in which case this function returns the matrix of
2891
+ # multiplication by self on the power basis, where we view the
2892
+ # parent field as a field over base.
2893
+
2894
+ # INPUT:
2895
+ # base -- field or morphism
2896
+ # """
2897
+ # raise NotImplementedError
2898
+
2899
+ # def multiplicative_order(self, prec=None):
2900
+ # """
2901
+ # Return the multiplicative order of ``self``, ie the smallest
2902
+ # positive `n` so that there is an exact `p`-adic element congruent
2903
+ # to ``self`` modulo ``self``'s precision that is an `n`-th root of unity.
2904
+
2905
+ # Note: unlike the case for Qp and Zp, it is possible to have
2906
+ # non-teichmuller elements with finite orders. This can happen
2907
+ # only if (p-1) divides the ramification index (see the
2908
+ # documentation on __pow__).
2909
+
2910
+ # INPUT:
2911
+
2912
+ # - self -- a `p`-adic element
2913
+ # - ``prec`` -- integer
2914
+
2915
+ # OUTPUT: integer; the multiplicative order of ``self``
2916
+ # """
2917
+ # raise NotImplementedError
2918
+
2919
+ def teichmuller_expansion(self, n=None):
2920
+ r"""
2921
+ Return a list [`a_0`, `a_1`,..., `a_n`] such that:
2922
+
2923
+ - `a_i^q = a_i`
2924
+ - ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a
2925
+ uniformizer of ``self.parent()``
2926
+ - if `a_i \ne 0`, the absolute precision of `a_i` is
2927
+ ``self.precision_relative() - i``
2928
+
2929
+ INPUT:
2930
+
2931
+ - ``n`` -- integer (default: ``None``); if given, returns the
2932
+ corresponding entry in the expansion
2933
+
2934
+ EXAMPLES::
2935
+
2936
+ sage: R.<a> = ZqCR(5^4,4)
2937
+ sage: E = a.teichmuller_expansion(); E
2938
+ 5-adic expansion of a + O(5^4) (teichmuller)
2939
+ sage: list(E)
2940
+ [a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2
2941
+ + (4*a^2 + 2*a + 2)*5^3 + O(5^4),
2942
+ (3*a^3 + 3*a^2 + 2*a + 1) + (a^3 + 4*a^2 + 1)*5 + (a^2 + 4*a + 4)*5^2 + O(5^3),
2943
+ (4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2),
2944
+ (a^3 + a^2 + a + 4) + O(5)]
2945
+ sage: sum([c * 5^i for i, c in enumerate(E)])
2946
+ a + O(5^4)
2947
+ sage: all(c^625 == c for c in E)
2948
+ True
2949
+
2950
+ sage: S.<x> = ZZ[]
2951
+ sage: f = x^3 - 98*x + 7
2952
+ sage: W.<w> = ZpCR(7,3).ext(f)
2953
+ sage: b = (1+w)^5; L = b.teichmuller_expansion(); L
2954
+ [1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7),
2955
+ 3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3),
2956
+ 6 + O(w^2), 6 + O(w)]
2957
+ sage: sum([w^i*L[i] for i in range(9)]) == b
2958
+ True
2959
+ sage: all(L[i]^(7^3) == L[i] for i in range(9))
2960
+ True
2961
+
2962
+ sage: L = W(3).teichmuller_expansion(); L
2963
+ [3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6),
2964
+ O(w^5), O(w^4), 3 + O(w^3), 6 + O(w^2)]
2965
+ sage: sum([w^i*L[i] for i in range(len(L))])
2966
+ 3 + O(w^9)
2967
+ """
2968
+ cdef long rp = self.relprec
2969
+ cdef pAdicZZpXCRElement v
2970
+ if n is None:
2971
+ L = []
2972
+ if rp == 0:
2973
+ return L
2974
+ elif self._is_exact_zero() or n < self.ordp:
2975
+ return self.parent()(0)
2976
+ elif n >= self.ordp + rp:
2977
+ raise PrecisionError
2978
+ else:
2979
+ v = self._new_c(rp)
2980
+ cdef pAdicZZpXCRElement u = self.unit_part()
2981
+ cdef long goal
2982
+ if n is not None: goal = rp - n + self.ordp
2983
+ while u.relprec > 0:
2984
+ v = self._new_c(rp)
2985
+ self.prime_pow.teichmuller_set_c(&v.unit, &u.unit, rp)
2986
+ v.ordp = 0
2987
+ if n is None:
2988
+ L.append(v)
2989
+ elif rp == goal:
2990
+ return v
2991
+ if rp == 1: break
2992
+ ZZ_pX_sub(u.unit, u.unit, v.unit)
2993
+ u.relprec = -u.relprec
2994
+ u._normalize()
2995
+ if u.relprec == 0: break
2996
+ rp -= 1
2997
+ u.ordp -= 1
2998
+ while u.ordp > 0:
2999
+ if n is None:
3000
+ v = self._new_c(0)
3001
+ v._set_inexact_zero(rp)
3002
+ L.append(v)
3003
+ elif rp == goal:
3004
+ v = self._new_c(0)
3005
+ v._set_inexact_zero(rp)
3006
+ return v
3007
+ rp -= 1
3008
+ u.ordp -= 1
3009
+ if n is None:
3010
+ return L
3011
+ else:
3012
+ v = self._new_c(0)
3013
+ v._set_inexact_zero(rp)
3014
+ return v
3015
+
3016
+ def _teichmuller_set_unsafe(self):
3017
+ """
3018
+ Set this element to the Teichmuller representative with the
3019
+ same residue.
3020
+
3021
+ .. WARNING::
3022
+
3023
+ This function modifies the element, which is not safe.
3024
+ Elements are supposed to be immutable.
3025
+
3026
+ EXAMPLES::
3027
+
3028
+ sage: R = Zp(7,5)
3029
+ sage: S.<x> = R[]
3030
+ sage: f = x^5 + 77*x^3 - 98*x^2 - 7
3031
+ sage: W.<w> = R.ext(f)
3032
+ sage: y = W.teichmuller(3, 15); y # indirect doctest
3033
+ 3 + 4*w^5 + 2*w^8 + 6*w^10 + w^11 + 6*w^12 + 5*w^13 + 4*w^14 + O(w^15)
3034
+
3035
+ sage: y^7 == y
3036
+ True
3037
+ sage: g = x^3 + 3*x^2 + 4
3038
+ sage: A.<a> = R.ext(g)
3039
+ sage: b = A.teichmuller(1 + 2*a - a^2); b
3040
+ (6*a^2 + 2*a + 1) + (5*a + 3)*7 + (5*a + 5)*7^2 + (4*a^2 + 4*a + 2)*7^3 + (2*a + 1)*7^4 + O(7^5)
3041
+ sage: b^343 == b
3042
+ True
3043
+
3044
+ TESTS:
3045
+
3046
+ We check that :issue:`8239` is resolved::
3047
+
3048
+ sage: K.<a> = Qq(25)
3049
+ sage: K.teichmuller(K(2/5))
3050
+ Traceback (most recent call last):
3051
+ ...
3052
+ ValueError: cannot set negative valuation element to Teichmuller representative
3053
+ """
3054
+ self._normalize()
3055
+ if self.ordp > 0:
3056
+ self._set_exact_zero()
3057
+ elif self.ordp < 0:
3058
+ raise ValueError("cannot set negative valuation element to Teichmuller representative")
3059
+ elif self.relprec == 0:
3060
+ raise ValueError("not enough precision known")
3061
+ else:
3062
+ self.prime_pow.teichmuller_set_c(&self.unit, &self.unit, self.relprec)
3063
+
3064
+ # def padded_list(self, n, lift_mode='simple'):
3065
+ # """
3066
+ # Return a list of coefficients of pi starting with `pi^0` up to
3067
+ # `pi^n` exclusive (padded with zeros if needed)
3068
+
3069
+ # """
3070
+ # raise NotImplementedError
3071
+
3072
+ def precision_absolute(self):
3073
+ """
3074
+ Return the absolute precision of this element, i.e., the power of the
3075
+ uniformizer modulo which this element is defined.
3076
+
3077
+ EXAMPLES::
3078
+
3079
+ sage: R = Zp(5,5)
3080
+ sage: S.<x> = R[]
3081
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3082
+ sage: W.<w> = R.ext(f)
3083
+ sage: a = W(75, 19); a
3084
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3085
+ sage: a.valuation()
3086
+ 10
3087
+ sage: a.precision_absolute()
3088
+ 19
3089
+ sage: a.precision_relative()
3090
+ 9
3091
+ sage: a.unit_part()
3092
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3093
+ sage: (a.unit_part() - 3).precision_absolute()
3094
+ 9
3095
+ """
3096
+ cdef Integer ans
3097
+ if self.ordp == maxordp:
3098
+ return infinity
3099
+ else:
3100
+ ans = PY_NEW(Integer)
3101
+ if self.relprec > 0:
3102
+ mpz_set_si(ans.value, self.relprec + self.ordp)
3103
+ else:
3104
+ mpz_set_si(ans.value, -self.relprec + self.ordp)
3105
+ return ans
3106
+
3107
+ def precision_relative(self):
3108
+ """
3109
+ Return the relative precision of this element, i.e., the power of the
3110
+ uniformizer modulo which the unit part of ``self`` is defined.
3111
+
3112
+ EXAMPLES::
3113
+
3114
+ sage: R = Zp(5,5)
3115
+ sage: S.<x> = R[]
3116
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3117
+ sage: W.<w> = R.ext(f)
3118
+ sage: a = W(75, 19); a
3119
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3120
+ sage: a.valuation()
3121
+ 10
3122
+ sage: a.precision_absolute()
3123
+ 19
3124
+ sage: a.precision_relative()
3125
+ 9
3126
+ sage: a.unit_part()
3127
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3128
+ """
3129
+ self._normalize()
3130
+ cdef Integer ans = PY_NEW(Integer)
3131
+ mpz_set_ui(ans.value, self.relprec)
3132
+ return ans
3133
+
3134
+ # def residue(self, n=1):
3135
+ # """
3136
+ # Reduces this element modulo pi^n.
3137
+ # """
3138
+ # raise NotImplementedError
3139
+
3140
+ cdef long valuation_c(self) noexcept:
3141
+ """
3142
+ Return the valuation of this element.
3143
+
3144
+ EXAMPLES::
3145
+
3146
+ sage: R = Zp(5,5)
3147
+ sage: S.<x> = R[]
3148
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3149
+ sage: W.<w> = R.ext(f)
3150
+ sage: a = W(75, 19); a
3151
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3152
+ sage: a.valuation() # indirect doctest
3153
+ 10
3154
+ sage: a.precision_absolute()
3155
+ 19
3156
+ sage: a.precision_relative()
3157
+ 9
3158
+ sage: a.unit_part()
3159
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3160
+ """
3161
+ self._normalize()
3162
+ return self.ordp
3163
+
3164
+ cpdef pAdicZZpXCRElement unit_part(self):
3165
+ """
3166
+ Return the unit part of this element, ie ``self / uniformizer^(self.valuation())``.
3167
+
3168
+ EXAMPLES::
3169
+
3170
+ sage: R = Zp(5,5)
3171
+ sage: S.<x> = R[]
3172
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3173
+ sage: W.<w> = R.ext(f)
3174
+ sage: a = W(75, 19); a
3175
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3176
+ sage: a.valuation()
3177
+ 10
3178
+ sage: a.precision_absolute()
3179
+ 19
3180
+ sage: a.precision_relative()
3181
+ 9
3182
+ sage: a.unit_part()
3183
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3184
+
3185
+ TESTS:
3186
+
3187
+ We check that :issue:`13616` is resolved::
3188
+
3189
+ sage: z = (1+w)^5
3190
+ sage: y = z - 1
3191
+ sage: t = y - y
3192
+ sage: t.unit_part()
3193
+ O(w^0)
3194
+ """
3195
+ self._normalize()
3196
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
3197
+ ans.ordp = 0
3198
+ if self.relprec != 0:
3199
+ ans.unit = self.unit
3200
+ return ans
3201
+
3202
+ cdef ext_p_list(self, bint pos):
3203
+ """
3204
+ Return a list of integers (in the Eisenstein case) or a list
3205
+ of lists of integers (in the unramified case). ``self`` can be
3206
+ reconstructed as a sum of elements of the list times powers of
3207
+ the uniformiser (in the Eisenstein case), or as a sum of
3208
+ powers of `p` times polynomials in the generator (in the
3209
+ unramified case).
3210
+
3211
+ If ``pos`` is ``True``, all integers will be in the interval `[0,p-1]`,
3212
+ otherwise they will be in the interval `[(1-p)/2, p/2]`.
3213
+
3214
+ Note that zeros are truncated from the returned list, so you
3215
+ must use the method :meth:`valuation` to completely recover ``self``.
3216
+
3217
+ EXAMPLES::
3218
+
3219
+ sage: R = Zp(5,5)
3220
+ sage: S.<x> = R[]
3221
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3222
+ sage: W.<w> = R.ext(f)
3223
+ sage: y = W(775, 19); y
3224
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3225
+ sage: y._ext_p_list(True)
3226
+ [1, 0, 4, 0, 2, 1, 2, 4, 1]
3227
+ sage: y._ext_p_list(False)
3228
+ [1, 0, -1, 0, 2, 1, 2, 0, 1]
3229
+ sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
3230
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3231
+ sage: g = x^3 + 3*x + 3
3232
+ sage: A.<a> = R.ext(g)
3233
+ sage: y = 75 + 45*a + 1200*a^2; y
3234
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
3235
+ sage: y._ext_p_list(True)
3236
+ [[0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]]
3237
+ sage: y._ext_p_list(False)
3238
+ [[0, -1], [-2, 2, -2], [1], [0, 0, 2]]
3239
+ sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
3240
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
3241
+ """
3242
+ self._normalize()
3243
+ return self.ext_p_list_precs(pos, self.relprec)
3244
+
3245
+
3246
+ def make_ZZpXCRElement(parent, unit, ordp, relprec, version):
3247
+ """
3248
+ Unpickling.
3249
+
3250
+ EXAMPLES::
3251
+
3252
+ sage: R = Zp(5,5)
3253
+ sage: S.<x> = R[]
3254
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3255
+ sage: W.<w> = R.ext(f)
3256
+ sage: y = W(775, 19); y
3257
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3258
+ sage: loads(dumps(y)) # indirect doctest
3259
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3260
+
3261
+ sage: from sage.rings.padics.padic_ZZ_pX_CR_element import make_ZZpXCRElement
3262
+ sage: make_ZZpXCRElement(W, y._ntl_rep(), 3, 9, 0)
3263
+ w^3 + 4*w^5 + 2*w^7 + w^8 + 2*w^9 + 4*w^10 + w^11 + O(w^12)
3264
+ """
3265
+ cdef pAdicZZpXCRElement ans
3266
+ cdef ZZ_pX_c poly
3267
+ if version == 0:
3268
+ ans = pAdicZZpXCRElement(parent, [], empty = True)
3269
+ if relprec == 0:
3270
+ ans._set_inexact_zero(mpz_get_si((<Integer>ordp).value))
3271
+ else:
3272
+ ans.prime_pow.restore_context_capdiv(mpz_get_si((<Integer>relprec).value))
3273
+ poly = (<ntl_ZZ_pX>unit).x
3274
+ ans._set(&poly, mpz_get_si((<Integer>ordp).value), mpz_get_si((<Integer>relprec).value))
3275
+ return ans
3276
+ else:
3277
+ raise ValueError("unknown unpickling version")