passagemath-ntl 10.8.1a1__cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_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.
Files changed (162) hide show
  1. passagemath_ntl/__init__.py +3 -0
  2. passagemath_ntl-10.8.1a1.dist-info/METADATA +121 -0
  3. passagemath_ntl-10.8.1a1.dist-info/RECORD +162 -0
  4. passagemath_ntl-10.8.1a1.dist-info/WHEEL +6 -0
  5. passagemath_ntl-10.8.1a1.dist-info/top_level.txt +3 -0
  6. passagemath_ntl.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  7. passagemath_ntl.libs/libgmp-6e109695.so.10.5.0 +0 -0
  8. passagemath_ntl.libs/libmpfi-bcd96d8d.so.0.0.0 +0 -0
  9. passagemath_ntl.libs/libmpfr-104d25bb.so.6.2.2 +0 -0
  10. passagemath_ntl.libs/libntl-bacfd860.so.45.0.0 +0 -0
  11. sage/all__sagemath_ntl.py +7 -0
  12. sage/libs/all__sagemath_ntl.py +3 -0
  13. sage/libs/mpfi/__init__.pxd +287 -0
  14. sage/libs/mpfi/types.pxd +10 -0
  15. sage/libs/ntl/GF2.pxd +18 -0
  16. sage/libs/ntl/GF2E.pxd +28 -0
  17. sage/libs/ntl/GF2EX.pxd +12 -0
  18. sage/libs/ntl/GF2X.pxd +81 -0
  19. sage/libs/ntl/ZZ.pxd +93 -0
  20. sage/libs/ntl/ZZX.pxd +85 -0
  21. sage/libs/ntl/ZZ_p.pxd +28 -0
  22. sage/libs/ntl/ZZ_pE.pxd +37 -0
  23. sage/libs/ntl/ZZ_pEX.pxd +106 -0
  24. sage/libs/ntl/ZZ_pX.pxd +122 -0
  25. sage/libs/ntl/__init__.py +4 -0
  26. sage/libs/ntl/all.py +72 -0
  27. sage/libs/ntl/conversion.pxd +106 -0
  28. sage/libs/ntl/convert.cpython-314t-x86_64-linux-gnu.so +0 -0
  29. sage/libs/ntl/convert.pxd +7 -0
  30. sage/libs/ntl/convert.pyx +38 -0
  31. sage/libs/ntl/decl.pxi +18 -0
  32. sage/libs/ntl/error.cpython-314t-x86_64-linux-gnu.so +0 -0
  33. sage/libs/ntl/error.pyx +63 -0
  34. sage/libs/ntl/lzz_p.pxd +20 -0
  35. sage/libs/ntl/lzz_pX.pxd +59 -0
  36. sage/libs/ntl/mat_GF2.pxd +30 -0
  37. sage/libs/ntl/mat_GF2E.pxd +30 -0
  38. sage/libs/ntl/mat_ZZ.pxd +59 -0
  39. sage/libs/ntl/misc.pxi +33 -0
  40. sage/libs/ntl/ntl_GF2.cpython-314t-x86_64-linux-gnu.so +0 -0
  41. sage/libs/ntl/ntl_GF2.pxd +5 -0
  42. sage/libs/ntl/ntl_GF2.pyx +281 -0
  43. sage/libs/ntl/ntl_GF2E.cpython-314t-x86_64-linux-gnu.so +0 -0
  44. sage/libs/ntl/ntl_GF2E.pxd +8 -0
  45. sage/libs/ntl/ntl_GF2E.pyx +488 -0
  46. sage/libs/ntl/ntl_GF2EContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  47. sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
  48. sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
  49. sage/libs/ntl/ntl_GF2EX.cpython-314t-x86_64-linux-gnu.so +0 -0
  50. sage/libs/ntl/ntl_GF2EX.pxd +10 -0
  51. sage/libs/ntl/ntl_GF2EX.pyx +251 -0
  52. sage/libs/ntl/ntl_GF2X.cpython-314t-x86_64-linux-gnu.so +0 -0
  53. sage/libs/ntl/ntl_GF2X.pxd +5 -0
  54. sage/libs/ntl/ntl_GF2X.pyx +771 -0
  55. sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
  56. sage/libs/ntl/ntl_ZZ.cpython-314t-x86_64-linux-gnu.so +0 -0
  57. sage/libs/ntl/ntl_ZZ.pxd +7 -0
  58. sage/libs/ntl/ntl_ZZ.pyx +541 -0
  59. sage/libs/ntl/ntl_ZZX.cpython-314t-x86_64-linux-gnu.so +0 -0
  60. sage/libs/ntl/ntl_ZZX.pxd +7 -0
  61. sage/libs/ntl/ntl_ZZX.pyx +1206 -0
  62. sage/libs/ntl/ntl_ZZ_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  63. sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
  64. sage/libs/ntl/ntl_ZZ_p.pyx +508 -0
  65. sage/libs/ntl/ntl_ZZ_pContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  66. sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
  67. sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
  68. sage/libs/ntl/ntl_ZZ_pE.cpython-314t-x86_64-linux-gnu.so +0 -0
  69. sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
  70. sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
  71. sage/libs/ntl/ntl_ZZ_pEContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  72. sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
  73. sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
  74. sage/libs/ntl/ntl_ZZ_pEX.cpython-314t-x86_64-linux-gnu.so +0 -0
  75. sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
  76. sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
  77. sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
  78. sage/libs/ntl/ntl_ZZ_pX.cpython-314t-x86_64-linux-gnu.so +0 -0
  79. sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
  80. sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
  81. sage/libs/ntl/ntl_lzz_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  82. sage/libs/ntl/ntl_lzz_p.pxd +8 -0
  83. sage/libs/ntl/ntl_lzz_p.pyx +440 -0
  84. sage/libs/ntl/ntl_lzz_pContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  85. sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
  86. sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
  87. sage/libs/ntl/ntl_lzz_pX.cpython-314t-x86_64-linux-gnu.so +0 -0
  88. sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
  89. sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
  90. sage/libs/ntl/ntl_mat_GF2.cpython-314t-x86_64-linux-gnu.so +0 -0
  91. sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
  92. sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
  93. sage/libs/ntl/ntl_mat_GF2E.cpython-314t-x86_64-linux-gnu.so +0 -0
  94. sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
  95. sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
  96. sage/libs/ntl/ntl_mat_ZZ.cpython-314t-x86_64-linux-gnu.so +0 -0
  97. sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
  98. sage/libs/ntl/ntl_mat_ZZ.pyx +1522 -0
  99. sage/libs/ntl/ntl_tools.pxd +3 -0
  100. sage/libs/ntl/ntlwrap.h +53 -0
  101. sage/libs/ntl/ntlwrap_impl.h +743 -0
  102. sage/libs/ntl/types.pxd +157 -0
  103. sage/libs/ntl/vec_GF2.pxd +26 -0
  104. sage/libs/ntl/vec_GF2E.pxd +2 -0
  105. sage/matrix/all__sagemath_ntl.py +1 -0
  106. sage/matrix/matrix_modn_dense_double.pxd +10 -0
  107. sage/matrix/matrix_modn_dense_float.pxd +9 -0
  108. sage/matrix/matrix_modn_dense_template.pxi +3475 -0
  109. sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
  110. sage/matrix/matrix_modn_sparse.pxd +8 -0
  111. sage/misc/all__sagemath_ntl.py +1 -0
  112. sage/rings/all__sagemath_ntl.py +7 -0
  113. sage/rings/bernmm.cpython-314t-x86_64-linux-gnu.so +0 -0
  114. sage/rings/bernmm.pyx +161 -0
  115. sage/rings/bernoulli_mod_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  116. sage/rings/bernoulli_mod_p.pyx +312 -0
  117. sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
  118. sage/rings/finite_rings/finite_field_ntl_gf2e.py +309 -0
  119. sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-314t-x86_64-linux-gnu.so +0 -0
  120. sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
  121. sage/rings/padics/all__sagemath_ntl.py +5 -0
  122. sage/rings/padics/padic_ZZ_pX_CA_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  123. sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
  124. sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2366 -0
  125. sage/rings/padics/padic_ZZ_pX_CR_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  126. sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
  127. sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3282 -0
  128. sage/rings/padics/padic_ZZ_pX_FM_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  129. sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
  130. sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1737 -0
  131. sage/rings/padics/padic_ZZ_pX_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  132. sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
  133. sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
  134. sage/rings/padics/padic_ext_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  135. sage/rings/padics/padic_ext_element.pxd +38 -0
  136. sage/rings/padics/padic_ext_element.pyx +513 -0
  137. sage/rings/padics/pow_computer_ext.cpython-314t-x86_64-linux-gnu.so +0 -0
  138. sage/rings/padics/pow_computer_ext.pxd +107 -0
  139. sage/rings/padics/pow_computer_ext.pyx +2402 -0
  140. sage/rings/polynomial/all__sagemath_ntl.py +1 -0
  141. sage/rings/polynomial/evaluation_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  142. sage/rings/polynomial/evaluation_ntl.pxd +7 -0
  143. sage/rings/polynomial/evaluation_ntl.pyx +70 -0
  144. sage/rings/polynomial/polynomial_gf2x.cpython-314t-x86_64-linux-gnu.so +0 -0
  145. sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
  146. sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
  147. sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  148. sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
  149. sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
  150. sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  151. sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
  152. sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2050 -0
  153. sage/rings/polynomial/polynomial_template.pxi +839 -0
  154. sage/rings/polynomial/polynomial_template_header.pxi +11 -0
  155. sage/rings/polynomial/polynomial_zz_pex.cpython-314t-x86_64-linux-gnu.so +0 -0
  156. sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
  157. sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
  158. sage/rings/real_mpfi.pxd +50 -0
  159. sage/schemes/all__sagemath_ntl.py +1 -0
  160. sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
  161. sage/schemes/hyperelliptic_curves/hypellfrob.cpython-314t-x86_64-linux-gnu.so +0 -0
  162. sage/schemes/hyperelliptic_curves/hypellfrob.pyx +253 -0
@@ -0,0 +1,3282 @@
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
+ x = x.lift().lift()
351
+ L = [Integer(x.polcoef(i)) for i in range(x.poldegree() + 1)]
352
+ x = L
353
+ else:
354
+ raise TypeError("unsupported coercion from pari: only p-adics, integers, rationals, polynomials and pol_mods allowed")
355
+ elif isinstance(x, IntegerMod_abstract):
356
+ mpz_init(tmp)
357
+ ctx_prec = mpz_remove(tmp, (<Integer>x.modulus()).value, self.prime_pow.prime.value)
358
+ if mpz_cmp_ui(tmp, 1) == 0:
359
+ mpz_clear(tmp)
360
+ x = x.lift()
361
+ if absprec is infinity or ctx_prec < aprec:
362
+ aprec = ctx_prec
363
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
364
+ else:
365
+ mpz_clear(tmp)
366
+ raise TypeError("cannot coerce from the given integer mod ring (not a power of the same prime)")
367
+ elif isinstance(x, ntl_ZZ_p):
368
+ ctx_prec = ZZ_remove(tmp_z, (<ntl_ZZ>x.modulus()).x, self.prime_pow.pow_ZZ_tmp(1)[0])
369
+ if ZZ_IsOne(tmp_z):
370
+ x = x.lift()
371
+ tmp_Int = PY_NEW(Integer)
372
+ ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
373
+ x = tmp_Int
374
+ if absprec is infinity or ctx_prec < aprec:
375
+ aprec = ctx_prec
376
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
377
+ else:
378
+ raise TypeError("cannot coerce the given ntl_ZZ_p (modulus not a power of the same prime)")
379
+ elif isinstance(x, ntl_ZZ):
380
+ tmp_Int = PY_NEW(Integer)
381
+ ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
382
+ x = tmp_Int
383
+ elif isinstance(x, int):
384
+ x = Integer(x)
385
+ elif x in parent.residue_field() and x.parent().is_finite():
386
+ # Should only reach here if x is not in F_p
387
+ z = parent.gen()
388
+ poly = x.polynomial().list()
389
+ x = sum([poly[i].lift() * (z ** i) for i in range(len(poly))], parent.zero())
390
+ if absprec is infinity or 1 < aprec:
391
+ aprec = 1
392
+ absprec = 0 # absprec just has to be non-infinite: everything else uses aprec
393
+ cdef pAdicZZpXCRElement _x
394
+ if isinstance(x, Integer):
395
+ if absprec is infinity:
396
+ self._set_from_mpz_rel((<Integer>x).value, rprec)
397
+ else:
398
+ self._set_from_mpz_both((<Integer>x).value, aprec, rprec)
399
+ elif isinstance(x, Rational):
400
+ if absprec is infinity:
401
+ self._set_from_mpq_rel((<Rational>x).value, rprec)
402
+ else:
403
+ self._set_from_mpq_both((<Rational>x).value, aprec, rprec)
404
+ elif isinstance(x, ntl_ZZ_pX):
405
+ if absprec is infinity:
406
+ self._set_from_ZZ_pX_rel(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, rprec)
407
+ else:
408
+ self._set_from_ZZ_pX_both(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, aprec, rprec)
409
+ elif isinstance(x, ntl_ZZX):
410
+ if absprec is infinity:
411
+ self._set_from_ZZX_rel((<ntl_ZZX>x).x, rprec)
412
+ else:
413
+ self._set_from_ZZX_both((<ntl_ZZX>x).x, aprec, rprec)
414
+ elif isinstance(x, pAdicExtElement):
415
+ if x.parent() is parent:
416
+ _x = <pAdicZZpXCRElement>x
417
+ if _x.relprec == 0:
418
+ if absprec is infinity or aprec > _x.ordp:
419
+ self._set_inexact_zero(_x.ordp) # this works for exact zeros too.
420
+ else:
421
+ self._set_inexact_zero(aprec)
422
+ elif _x.relprec < 0:
423
+ if -_x.relprec < rprec:
424
+ rprec = _x.relprec
425
+ else:
426
+ rprec = -rprec
427
+ if absprec is infinity or aprec > _x.ordp - rprec:
428
+ self._set(&_x.unit, _x.ordp, rprec)
429
+ elif aprec > _x.ordp:
430
+ self._set(&_x.unit, _x.ordp, _x.ordp - aprec) #negating relprec to indicate non-normalized.
431
+ else:
432
+ self._set_inexact_zero(aprec)
433
+ else:
434
+ if _x.relprec < rprec:
435
+ rprec = _x.relprec
436
+ if absprec is infinity or aprec > _x.ordp + rprec:
437
+ self._set(&_x.unit, _x.ordp, rprec)
438
+ elif aprec > _x.ordp:
439
+ self._set(&_x.unit, _x.ordp, aprec - _x.ordp)
440
+ else:
441
+ self._set_inexact_zero(aprec)
442
+ elif x.parent().fraction_field() is parent:
443
+ if isinstance(x, pAdicZZpXCRElement):
444
+ _x = <pAdicZZpXCRElement>x
445
+ if _x.relprec < 0:
446
+ _x._normalize()
447
+ if _x._is_exact_zero():
448
+ self._set_exact_zero()
449
+ elif _x._is_inexact_zero():
450
+ self._set_inexact_zero(_x.ordp)
451
+ else:
452
+ if _x.relprec < rprec:
453
+ rprec = _x.relprec
454
+ self._set(&_x.unit, _x.ordp, rprec)
455
+ else:
456
+ # x is a pAdicZZpXCAElement
457
+ xordp = x.valuation()
458
+ xprec = x.precision_absolute()
459
+ if xordp == xprec:
460
+ self._set_inexact_zero(mpz_get_si((<Integer>xordp).value))
461
+ else:
462
+ poly = x._ntl_rep_abs()[0]
463
+ if absprec is infinity:
464
+ self._set_from_ZZ_pX_rel(&(<ntl_ZZ_pX>poly).x,
465
+ (<ntl_ZZ_pX>poly).c, rprec)
466
+ else:
467
+ self._set_from_ZZ_pX_both(&(<ntl_ZZ_pX>poly).x,
468
+ (<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),
1068
+ self.prime_pow.pow_ZZ_tmp(1)[0])
1069
+ mini = i
1070
+ i += 1
1071
+ while i <= deg:
1072
+ if not ZZ_IsZero(ZZX_coeff(poly, i)):
1073
+ curval = ZZ_remove(tmp_z, ZZX_coeff(poly, i),
1074
+ self.prime_pow.pow_ZZ_tmp(1)[0])
1075
+ if curval < minval:
1076
+ minval = curval
1077
+ mini = i
1078
+ i += 1
1079
+ if self.prime_pow.e == 1:
1080
+ self.ordp = minval
1081
+ else:
1082
+ self.ordp = minval * self.prime_pow.e + mini
1083
+ if absprec == -1: # indicates that _set_from_ZZX_rel is calling
1084
+ self._set_prec_rel(relprec)
1085
+ elif self._set_prec_both(absprec, relprec):
1086
+ # indicates self._set_inexact_zero was called
1087
+ return -2
1088
+ # _set_prec_rel or both has restored the context so that part2 works.
1089
+
1090
+ cdef int _set_from_ZZ_pX_rel(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long relprec) except -1:
1091
+ """
1092
+ Set ``self`` from a ``ZZ_pX`` with relative precision bounded by
1093
+ ``relprec``.
1094
+
1095
+ If ``ctx`` is ``None`` and ``poly`` is 0 this function will raise an
1096
+ error (a ``ZZ_pX`` cannot represent something with infinite absolute
1097
+ precision).
1098
+
1099
+ EXAMPLES::
1100
+
1101
+ sage: R = Zp(5,5)
1102
+ sage: S.<x> = R[]
1103
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1104
+ sage: W.<w> = R.ext(f)
1105
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2)); z # indirect doctest
1106
+ 4 + w + w^2 + 3*w^7 + w^9 + O(w^10)
1107
+ sage: z._ntl_rep()
1108
+ [4 1 16]
1109
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^44)); z
1110
+ 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)
1111
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^44), relprec=0); z
1112
+ O(w^200)
1113
+ """
1114
+ cdef long ctx_prec = -1
1115
+ if ctx is not None:
1116
+ ctx_prec = self._check_ZZ_pContext(ctx) * self.prime_pow.e
1117
+ if ZZ_pX_IsZero(poly[0]):
1118
+ if ctx_prec == -1:
1119
+ raise ValueError("must specify either a context or an absolute precision bound")
1120
+ else:
1121
+ self._set_inexact_zero(ctx_prec)
1122
+ return 0
1123
+ self._set_from_ZZ_pX_part1(poly)
1124
+ if relprec == 0:
1125
+ self._set_prec_rel(relprec)
1126
+ return 0
1127
+ if ctx_prec == -1:
1128
+ self._set_prec_rel(self.ordp + relprec)
1129
+ else:
1130
+ self._set_prec_rel(min(ctx_prec, self.ordp + relprec))
1131
+ self._set_from_ZZ_pX_part2(poly)
1132
+
1133
+ cdef int _set_from_ZZ_pX_both(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec, long relprec) except -1:
1134
+ """
1135
+ Set ``self`` from a ``ZZ_pX`` with relative precision bounded by
1136
+ ``relprec`` and absolute precision bounded by ``absprec``.
1137
+
1138
+ EXAMPLES::
1139
+
1140
+ sage: R = Zp(5,5)
1141
+ sage: S.<x> = R[]
1142
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1143
+ sage: W.<w> = R.ext(f)
1144
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec=8, relprec=12); z # indirect doctest
1145
+ 4 + w + w^2 + 3*w^7 + O(w^8)
1146
+ sage: z._ntl_rep()
1147
+ [4 1 16]
1148
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^50), 220); z
1149
+ 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)
1150
+ sage: z = W(ntl.ZZ_pX([5^40,5^42,3*5^41], 5^44), absprec=77); z
1151
+ O(w^77)
1152
+ """
1153
+ cdef long ctx_prec
1154
+ if ctx is not None:
1155
+ ctx_prec = self._check_ZZ_pContext(ctx)
1156
+ if ctx_prec * self.prime_pow.e < absprec:
1157
+ absprec = ctx_prec * self.prime_pow.e
1158
+ if ZZ_pX_IsZero(poly[0]):
1159
+ self._set_inexact_zero(absprec)
1160
+ return 0
1161
+ self._set_from_ZZ_pX_part1(poly)
1162
+ if absprec <= self.ordp:
1163
+ self._set_inexact_zero(absprec)
1164
+ else:
1165
+ self._set_prec_rel(min(absprec, self.ordp + relprec))
1166
+ self._set_from_ZZ_pX_part2(poly)
1167
+
1168
+ cdef int _set_from_ZZ_pX_part1(self, ZZ_pX_c* poly) except -1:
1169
+ """
1170
+ Set ``self.ordp`` based on ``poly``. ``poly`` must not be 0.
1171
+
1172
+ TESTS::
1173
+
1174
+ sage: R = Zp(5,5)
1175
+ sage: S.<x> = R[]
1176
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1177
+ sage: W.<w> = R.ext(f)
1178
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec=8, relprec=12); z # indirect doctest
1179
+ 4 + w + w^2 + 3*w^7 + O(w^8)
1180
+ """
1181
+ cdef long val = 0, index = 0
1182
+ ZZ_pX_min_val_coeff(val, index, poly[0], self.prime_pow.pow_ZZ_tmp(1)[0])
1183
+ if self.prime_pow.e == 1:
1184
+ self.ordp = val
1185
+ else:
1186
+ self.ordp = val * self.prime_pow.e + index
1187
+
1188
+ cdef int _set_from_ZZ_pX_part2(self, ZZ_pX_c* poly) except -1:
1189
+ """
1190
+ Assuming that ``self.ordp`` and ``self.relprec`` have been set, sets
1191
+ ``self.unit`` to ``poly`` and then normalizes.
1192
+
1193
+ TESTS::
1194
+
1195
+ sage: R = Zp(5,5)
1196
+ sage: S.<x> = R[]
1197
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1198
+ sage: W.<w> = R.ext(f)
1199
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec=8, relprec=12); z # indirect doctest
1200
+ 4 + w + w^2 + 3*w^7 + O(w^8)
1201
+ """
1202
+ # We've set self.relprec to what is actually the absolute precision.
1203
+ if self.relprec != 0:
1204
+ ZZ_pX_conv_modulus(self.unit, poly[0], self.prime_pow.get_context_capdiv(self.relprec).x)
1205
+ self.relprec -= self.ordp
1206
+ self._internal_lshift(-self.ordp)
1207
+
1208
+ cdef bint _set_prec_rel(self, long relprec) except -1:
1209
+ """
1210
+ Safely set the relative precision of ``self`` to be the absolute
1211
+ value of ``relprec``.
1212
+
1213
+ Returns ``True`` iff ``self.relprec`` was reset.
1214
+
1215
+ Note that this will wipe out anything in ``self.unit``. Be
1216
+ careful resetting ``self.unit`` directly: if you set it to a
1217
+ different modulus, NTL may have problems. The safest way to
1218
+ reset ``self.unit`` to a different modulus is::
1219
+
1220
+ self.prime_pow.restore_context_capdiv(self.relprec)
1221
+ cdef ZZ_pX_c tmp = self.unit
1222
+ self._set_prec_rel(new_rel_prec)
1223
+ ZZ_pX_conv_modulus(self.unit, tmp, self.prime_pow.get_context_capdiv(self.relprec).x)
1224
+
1225
+ You may be able to just set ``self.relprec`` and
1226
+ ``ZZ_pX_conv_modulus`` if you're decreasing precision. I'm
1227
+ not sure.
1228
+
1229
+ TESTS::
1230
+
1231
+ sage: R = Zp(5,5)
1232
+ sage: S.<x> = R[]
1233
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1234
+ sage: W.<w> = R.ext(f)
1235
+ sage: W(70, relprec=8) # indirect doctest
1236
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
1237
+ """
1238
+ if self.relprec == relprec:
1239
+ return False
1240
+ if relprec != 0:
1241
+ self.prime_pow.restore_context_capdiv(relprec)
1242
+ self.unit = ZZ_pX_c()
1243
+ self.relprec = relprec
1244
+ return True
1245
+
1246
+ cdef bint _set_prec_both(self, long absprec, long relprec) except -1:
1247
+ """
1248
+ Assuming ``self.ordp`` is set, sets the relative precision of ``self``
1249
+ to the minimum of ``abs(relprec)`` and ``absprec-self.ordp``.
1250
+
1251
+ If ``relprec`` is negative, will set ``self.relprec`` to be negative
1252
+ (indicating unnormalized unit)
1253
+
1254
+ Returns ``True`` iff ``self.relprec = 0``, ie ``self`` was set to an
1255
+ inexact zero.
1256
+
1257
+ Note that this will wipe out anything in ``self.unit``. Be
1258
+ careful resetting ``self.unit`` directly: if you set it to a
1259
+ different modulus, NTL may have problems. The safest way to
1260
+ reset ``self.unit`` to a different modulus is:
1261
+
1262
+ self.prime_pow.restore_context_capdiv(self.relprec)
1263
+ cdef ZZ_pX_c tmp = self.unit
1264
+ self._set_prec_rel(new_rel_prec)
1265
+ ZZ_pX_conv_modulus(self.unit, tmp, self.prime_pow.get_context_capdiv(self.relprec).x)
1266
+
1267
+ You may be able to just set ``self.relprec`` and
1268
+ ``ZZ_pX_conv_modulus`` if you're decreasing precision. I'm
1269
+ not sure.
1270
+
1271
+ TESTS::
1272
+
1273
+ sage: R = Zp(5,5)
1274
+ sage: S.<x> = R[]
1275
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1276
+ sage: W.<w> = R.ext(f)
1277
+ sage: W(70, 8) # indirect doctest
1278
+ 4*w^5 + 3*w^7 + O(w^8)
1279
+ """
1280
+ self.relprec = absprec - self.ordp
1281
+ cdef long arelprec
1282
+ if relprec < 0:
1283
+ arelprec = -relprec
1284
+ else:
1285
+ arelprec = relprec
1286
+ if self.relprec <= 0:
1287
+ self._set_inexact_zero(absprec)
1288
+ else:
1289
+ if arelprec < self.relprec:
1290
+ self.relprec = arelprec
1291
+ if self.relprec != 0:
1292
+ self.prime_pow.restore_context_capdiv(self.relprec)
1293
+ self.unit = ZZ_pX_c()
1294
+ if relprec < 0:
1295
+ self.relprec = -self.relprec
1296
+ return self.relprec == 0
1297
+
1298
+ cdef int _normalize(self) except -1:
1299
+ """
1300
+ Normalize ``self``, adjusting ``self.ordp``, ``self.relprec``, and
1301
+ ``self.unit`` so that ``self.unit`` actually represents a unit.
1302
+
1303
+ EXAMPLES::
1304
+
1305
+ sage: R = Zp(5,5)
1306
+ sage: S.<x> = R[]
1307
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1308
+ sage: W.<w> = R.ext(f)
1309
+ sage: z = (1+w)^5
1310
+ sage: y = z - 1
1311
+ sage: y._ntl_rep_unnormalized()
1312
+ [5 3005 25 3060 5]
1313
+ sage: y # indirect doctest
1314
+ 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)
1315
+ sage: y._ntl_rep_unnormalized()
1316
+ [41 26 152 49 535]
1317
+ """
1318
+ cdef long minval = 0, mini = 0, shift
1319
+ if self.relprec < 0:
1320
+ if ZZ_pX_IsZero(self.unit):
1321
+ self.ordp -= self.relprec # note that self.relprec < 0
1322
+ self.relprec = 0
1323
+ else:
1324
+ ZZ_pX_min_val_coeff(minval, mini, self.unit, self.prime_pow.pow_ZZ_tmp(1)[0])
1325
+ if self.prime_pow.e == 1:
1326
+ shift = minval
1327
+ else:
1328
+ shift = minval * self.prime_pow.e + mini
1329
+ if shift >= -self.relprec:
1330
+ self.ordp -= self.relprec # note that self.relprec < 0
1331
+ self.relprec = 0
1332
+ elif shift > 0:
1333
+ self.relprec = -self.relprec - shift
1334
+ self.ordp += shift
1335
+ self._internal_lshift(-shift)
1336
+ else:
1337
+ self.relprec = -self.relprec
1338
+
1339
+ def _is_normalized(self):
1340
+ """
1341
+ Whether this element is currently normalized.
1342
+
1343
+ EXAMPLES::
1344
+
1345
+ sage: R.<a> = ZqCR(125,implementation="NTL"); b = 5*a + 4; c = 10*a^2 + 6; d = b + c
1346
+ sage: d._is_normalized()
1347
+ False
1348
+ sage: d.valuation()
1349
+ 1
1350
+ sage: d._is_normalized()
1351
+ True
1352
+ """
1353
+ return self.relprec >= 0
1354
+
1355
+ cdef int _internal_lshift(self, long shift) except -1:
1356
+ """
1357
+ Multiply ``self.unit`` by ``x^shift``.
1358
+
1359
+ Note that ``self.relprec`` must be set before calling this
1360
+ function and should not be 0, and self.unit must be defined to
1361
+ precision ``self.relprec - shift``
1362
+
1363
+ This function does not alter ``self.ordp`` even though it WILL
1364
+ change the valuation of ``self.unit``
1365
+
1366
+ Also note that if you call this function you should usually
1367
+ manually set ``self.relprec = -self.relprec`` since this function
1368
+ will usually unnormalize ``self``.
1369
+
1370
+ TESTS::
1371
+
1372
+ sage: R = Zp(5,5)
1373
+ sage: S.<x> = R[]
1374
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1375
+ sage: W.<w> = R.ext(f)
1376
+ sage: z = (1+w)^5
1377
+ sage: y = z - 1
1378
+ sage: y # indirect doctest
1379
+ 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)
1380
+ """
1381
+ if self.relprec == 0:
1382
+ raise ValueError("p-adic Internal l-shift called with relative precision 0")
1383
+ cdef ZZ_pX_c tmpP
1384
+ cdef ZZ_pX_Modulus_c* mod
1385
+ if self.prime_pow.e == 1:
1386
+ if shift > 0:
1387
+ ZZ_pX_left_pshift(self.unit, self.unit, self.prime_pow.pow_ZZ_tmp(shift)[0], self.prime_pow.get_context(self.relprec).x)
1388
+ else:
1389
+ ZZ_pX_right_pshift(self.unit, self.unit, self.prime_pow.pow_ZZ_tmp(-shift)[0], self.prime_pow.get_context(self.relprec).x)
1390
+ else:
1391
+ if shift > 0:
1392
+ self.prime_pow.restore_context_capdiv(self.relprec)
1393
+ mod = self.prime_pow.get_modulus_capdiv(self.relprec)
1394
+ ZZ_pX_PowerXMod_long_pre(tmpP, shift, mod[0])
1395
+ ZZ_pX_MulMod_pre(self.unit, self.unit, tmpP, mod[0])
1396
+ elif shift < 0:
1397
+ self.prime_pow.eis_shift_capdiv(&self.unit, &self.unit, -shift, self.relprec)
1398
+
1399
+ cdef int _pshift_self(self, long shift) except -1:
1400
+ """
1401
+ Multiply ``self`` by ``p^shift``.
1402
+
1403
+ This function assumes that ``self.relprec``, ``self.ordp`` and
1404
+ ``self.unit`` are already set (in the case ``self.prime_pow.e
1405
+ != 1``), and is more reasonable to call externally than
1406
+ ``_internal_lshift``
1407
+
1408
+ EXAMPLES::
1409
+
1410
+ sage: R = Qp(5,5)
1411
+ sage: S.<x> = R[]
1412
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1413
+ sage: W.<w> = R.ext(f)
1414
+ sage: z = W(3/25, relprec=6); z
1415
+ 3*w^-10 + 3*w^-8 + 2*w^-6 + O(w^-4)
1416
+ sage: z * 25
1417
+ 3 + O(w^6)
1418
+ """
1419
+ cdef ZZ_pX_c high_shifter
1420
+ cdef ZZ_pX_Modulus_c *modulus
1421
+ cdef ntl_ZZ_pContext_class c
1422
+ cdef ZZ_pX_c* high_array
1423
+ cdef long i, high_length
1424
+ if self.prime_pow.e == 1:
1425
+ self.ordp += shift
1426
+ else:
1427
+ self.ordp += shift * self.prime_pow.e
1428
+ if shift < 0:
1429
+ shift = -shift
1430
+ c = self.prime_pow.get_context_capdiv(self.relprec)
1431
+ c.restore_c()
1432
+ modulus = self.prime_pow.get_modulus_capdiv(self.relprec)
1433
+ if isinstance(self.prime_pow, PowComputer_ZZ_pX_big_Eis):
1434
+ high_array = (<PowComputer_ZZ_pX_big_Eis>self.prime_pow).high_shifter
1435
+ elif isinstance(self.prime_pow, PowComputer_ZZ_pX_small_Eis):
1436
+ high_array = (<PowComputer_ZZ_pX_small_Eis>self.prime_pow).high_shifter
1437
+ else:
1438
+ raise TypeError("unrecognized PowComputer type")
1439
+ ZZ_pX_conv_modulus(high_shifter, high_array[0], c.x)
1440
+ ZZ_pX_InvMod_newton_ram(high_shifter, high_shifter, modulus[0], c.x)
1441
+ ZZ_pX_PowerMod_long_pre(high_shifter, high_shifter, shift, modulus[0])
1442
+ ZZ_pX_MulMod_pre(self.unit, self.unit, high_shifter, modulus[0])
1443
+ elif shift > 0:
1444
+ i = 0
1445
+ c = self.prime_pow.get_context_capdiv(self.relprec)
1446
+ c.restore_c()
1447
+ modulus = self.prime_pow.get_modulus_capdiv(self.relprec)
1448
+ if isinstance(self.prime_pow, PowComputer_ZZ_pX_big_Eis):
1449
+ high_array = (<PowComputer_ZZ_pX_big_Eis>self.prime_pow).high_shifter
1450
+ high_length = (<PowComputer_ZZ_pX_big_Eis>self.prime_pow).high_length
1451
+ elif isinstance(self.prime_pow, PowComputer_ZZ_pX_small_Eis):
1452
+ high_array = (<PowComputer_ZZ_pX_small_Eis>self.prime_pow).high_shifter
1453
+ high_length = (<PowComputer_ZZ_pX_small_Eis>self.prime_pow).high_length
1454
+ else:
1455
+ raise TypeError("unrecognized PowComputer type")
1456
+ if shift >= self.prime_pow.prec_cap:
1457
+ # high_shifter = p^(2^(high_length - 1))/x^(e*2^(high_length - 1))
1458
+ ZZ_pX_conv_modulus(high_shifter, high_array[high_length-1], c.x)
1459
+ # if shift = r + s * 2^(high_length - 1)
1460
+ # then high_shifter = p^(s*2^(high_length - 1))/x^(e*s*2^(high_length - 1))
1461
+ ZZ_pX_PowerMod_long_pre(high_shifter, high_shifter, (shift / (1L << (high_length - 1))), modulus[0])
1462
+ ZZ_pX_MulMod_pre(self.unit, self.unit, high_shifter, modulus[0])
1463
+ # Now we only need to multiply self.unit by p^r/x^(e*r) where r < 2^(high_length - 1), which is tractable.
1464
+ shift = shift % (1L << (high_length - 1))
1465
+ while shift > 0:
1466
+ if shift & 1:
1467
+ ZZ_pX_conv_modulus(high_shifter, high_array[i], c.x)
1468
+ ZZ_pX_MulMod_pre(self.unit, self.unit, high_shifter, modulus[0])
1469
+ shift = shift >> 1
1470
+ i += 1
1471
+
1472
+ cdef pAdicZZpXCRElement _new_c(self, long relprec):
1473
+ """
1474
+ Return a new element with the same parent as ``self`` and
1475
+ relative precision ``relprec``
1476
+
1477
+ Note that if ``relprec`` is nonpositive, the convention is that
1478
+ ``relprec = 0`` indicates an exact or inexact zero, ``relprec < 0``
1479
+ indicates an unnormalized element.
1480
+
1481
+ EXAMPLES::
1482
+
1483
+ sage: R = Qp(5,5)
1484
+ sage: S.<x> = R[]
1485
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1486
+ sage: W.<w> = R.ext(f)
1487
+ sage: w^5 + 1 # indirect doctest
1488
+ 1 + w^5 + O(w^25)
1489
+ """
1490
+ cdef pAdicZZpXCRElement ans = pAdicZZpXCRElement.__new__(pAdicZZpXCRElement)
1491
+ ans._parent = self._parent
1492
+ ans.prime_pow = self.prime_pow
1493
+ if relprec > 0:
1494
+ self.prime_pow.restore_context_capdiv(relprec)
1495
+ ans.relprec = relprec
1496
+ elif relprec == 0:
1497
+ ans._set_exact_zero()
1498
+ else:
1499
+ self.prime_pow.restore_context_capdiv(-relprec)
1500
+ ans.relprec = relprec
1501
+ return ans
1502
+
1503
+ def __reduce__(self):
1504
+ """
1505
+ Pickles ``self``.
1506
+
1507
+ EXAMPLES::
1508
+
1509
+ sage: R = Qp(5,5)
1510
+ sage: S.<x> = R[]
1511
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1512
+ sage: W.<w> = R.ext(f)
1513
+ sage: z = (1 + w)^5 - 1
1514
+ sage: loads(dumps(z)) == z
1515
+ True
1516
+ """
1517
+ cdef Integer relprec, ordp
1518
+ relprec = PY_NEW(Integer)
1519
+ ordp = PY_NEW(Integer)
1520
+ mpz_set_si(relprec.value, self.relprec)
1521
+ mpz_set_si(ordp.value, self.ordp)
1522
+ if self.relprec == 0:
1523
+ return make_ZZpXCRElement, (self.parent(), None, ordp, relprec, 0)
1524
+ self.prime_pow.restore_context_capdiv(self.relprec)
1525
+ cdef ntl_ZZ_pX holder = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
1526
+ holder.c = self.prime_pow.get_context_capdiv(self.relprec)
1527
+ holder.x = self.unit
1528
+ return make_ZZpXCRElement, (self.parent(), holder, ordp, relprec, 0)
1529
+
1530
+ cdef int _cmp_units(left, pAdicGenericElement right) except -2:
1531
+ """
1532
+ For units ``left`` and ``right``, return 0 if they are equal up to
1533
+ the lesser of the two precisions, or 1 if they are not.
1534
+
1535
+ EXAMPLES::
1536
+
1537
+ sage: R = Qp(5,5)
1538
+ sage: S.<x> = R[]
1539
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1540
+ sage: W.<w> = R.ext(f)
1541
+ sage: w == 1 # indirect doctest
1542
+ False
1543
+ sage: y = 1 + w + O(w^7)
1544
+ sage: z = 1 + w + w^10 + O(w^13)
1545
+ sage: y == z
1546
+ True
1547
+ """
1548
+ # This function needs improvement. In particular, there are a lot of
1549
+ # speed improvements to be had, and it should be changed so that it
1550
+ # returns 1 only half the time (and -1 the other half) when left and
1551
+ # right are not equal.
1552
+ cdef pAdicZZpXCRElement diff = <pAdicZZpXCRElement> (left - right)
1553
+ diff._normalize()
1554
+ if diff.relprec == 0:
1555
+ return 0
1556
+ # for now, just return 1
1557
+ return 1
1558
+
1559
+ def __invert__(self):
1560
+ """
1561
+ Return the inverse of this element.
1562
+
1563
+ EXAMPLES::
1564
+
1565
+ sage: R = Zp(5,5)
1566
+ sage: S.<x> = R[]
1567
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1568
+ sage: W.<w> = R.ext(f)
1569
+ sage: z = (1 + w)^5
1570
+ sage: y = ~z; y # indirect doctest
1571
+ 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)
1572
+ sage: y.parent()
1573
+ 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1574
+ sage: z = z - 1
1575
+ sage: ~z
1576
+ 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)
1577
+ sage: ~z * z
1578
+ 1 + O(w^20)
1579
+ """
1580
+ if self._is_exact_zero():
1581
+ raise ZeroDivisionError("cannot divide by zero")
1582
+ if self._is_inexact_zero(): # this calls _normalize
1583
+ raise PrecisionError("cannot divide by something indistinguishable from zero")
1584
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
1585
+ if not ans.prime_pow.in_field:
1586
+ ans._parent = self._parent.fraction_field()
1587
+ ans.prime_pow = ans._parent.prime_pow
1588
+ ans.ordp = -self.ordp
1589
+ sig_on()
1590
+ if self.prime_pow.e == 1:
1591
+ 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)
1592
+ else:
1593
+ 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)
1594
+ sig_off()
1595
+ return ans
1596
+
1597
+ cdef pAdicZZpXCRElement _lshift_c(self, long n):
1598
+ """
1599
+ Multiply ``self`` by the uniformizer raised to the power ``n``. If
1600
+ ``n`` is negative, right shifts by ``-n``.
1601
+
1602
+ EXAMPLES::
1603
+
1604
+ sage: R = Zp(5,5)
1605
+ sage: S.<x> = R[]
1606
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1607
+ sage: W.<w> = R.ext(f)
1608
+ sage: z = (1 + w)^5
1609
+ sage: z
1610
+ 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)
1611
+ sage: z << 17 # indirect doctest
1612
+ 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)
1613
+ sage: z << (-1)
1614
+ 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)
1615
+ """
1616
+ if not self.prime_pow.in_field and n < -self.ordp:
1617
+ return self._rshift_c(-n)
1618
+ check_ordp(n)
1619
+ cdef pAdicZZpXCRElement ans
1620
+ if self._is_exact_zero() or n == 0:
1621
+ return self
1622
+ elif self._is_inexact_zero():
1623
+ ans = self._new_c(0)
1624
+ else:
1625
+ ans = self._new_c(self.relprec)
1626
+ ans.unit = self.unit
1627
+ ans.ordp = self.ordp + n
1628
+ check_ordp(ans.ordp)
1629
+ return ans
1630
+
1631
+ def __lshift__(pAdicZZpXCRElement self, shift):
1632
+ """
1633
+ Multiply ``self`` by the uniformizer raised to the power ``n``. If
1634
+ ``n`` is negative, right shifts by ``-n``.
1635
+
1636
+ EXAMPLES::
1637
+
1638
+ sage: R = Zp(5,5)
1639
+ sage: S.<x> = R[]
1640
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1641
+ sage: W.<w> = R.ext(f)
1642
+ sage: z = (1 + w)^5
1643
+ sage: z
1644
+ 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)
1645
+ sage: z << 17 # indirect doctest
1646
+ 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)
1647
+ sage: z << (-1)
1648
+ 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)
1649
+ """
1650
+ cdef pAdicZZpXCRElement ans
1651
+ if not isinstance(shift, Integer):
1652
+ shift = Integer(shift)
1653
+ if mpz_fits_slong_p((<Integer>shift).value) == 0:
1654
+ if self._is_exact_zero():
1655
+ return self
1656
+ if self.prime_pow.in_field or mpz_sgn((<Integer>shift).value) > 0:
1657
+ raise ValueError("shift does not fit in long")
1658
+ else:
1659
+ ans = self._new_c(0)
1660
+ ans.ordp = 0
1661
+ return ans
1662
+ return self._lshift_c(mpz_get_si((<Integer>shift).value))
1663
+
1664
+ cdef pAdicZZpXCRElement _rshift_c(self, long n):
1665
+ """
1666
+ Divide ``self`` by the uniformizer raised to the power ``n``. If
1667
+ parent is not a field, throws away the nonpositive part of
1668
+ the series expansion. If ``n`` is negative, left shifts by ``-n``.
1669
+
1670
+ EXAMPLES::
1671
+
1672
+ sage: R = Zp(5,5,print_mode='digits')
1673
+ sage: S.<x> = R[]
1674
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1675
+ sage: W.<w> = R.ext(f)
1676
+ sage: z = (1 + w)^5
1677
+ sage: for m in range(26): repr(z >> m) # indirect doctest
1678
+ '...4001400444441030421100001'
1679
+ '...400140044444103042110000'
1680
+ '...40014004444410304211000'
1681
+ '...4001400444441030421100'
1682
+ '...400140044444103042110'
1683
+ '...40014004444410304211'
1684
+ '...4001400444441030421'
1685
+ '...400140044444103042'
1686
+ '...40014004444410304'
1687
+ '...4001400444441030'
1688
+ '...400140044444103'
1689
+ '...40014004444410'
1690
+ '...4001400444441'
1691
+ '...400140044444'
1692
+ '...40014004444'
1693
+ '...4001400444'
1694
+ '...400140044'
1695
+ '...40014004'
1696
+ '...4001400'
1697
+ '...400140'
1698
+ '...40014'
1699
+ '...4001'
1700
+ '...400'
1701
+ '...40'
1702
+ '...4'
1703
+ '...'
1704
+ sage: repr(z >> (-4))
1705
+ '...40014004444410304211000010000'
1706
+ """
1707
+ if self.prime_pow.in_field or n <= self.ordp:
1708
+ return self._lshift_c(-n)
1709
+ if self._is_exact_zero() or n == 0:
1710
+ return self
1711
+ cdef long arelprec
1712
+ if self.relprec < 0:
1713
+ arelprec = -self.relprec
1714
+ else:
1715
+ arelprec = self.relprec
1716
+ cdef pAdicZZpXCRElement ans
1717
+ if arelprec > n - self.ordp:
1718
+ ans = self._new_c(arelprec - (n - self.ordp))
1719
+ if self.prime_pow.e == 1:
1720
+ 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)
1721
+ else:
1722
+ self.prime_pow.eis_shift_capdiv(&ans.unit, &self.unit, n - self.ordp, ans.relprec)
1723
+ else:
1724
+ ans = self._new_c(0)
1725
+ ans.ordp = 0
1726
+ ans.relprec = -ans.relprec
1727
+ return ans
1728
+
1729
+ def __rshift__(pAdicZZpXCRElement self, shift):
1730
+ """
1731
+ Divide ``self`` by the uniformizer raised to the power ``n``. If
1732
+ parent is not a field, throws away the nonpositive part of
1733
+ the series expansion. If ``n`` is negative, left shifts by ``-n``.
1734
+
1735
+ EXAMPLES::
1736
+
1737
+ sage: R = Zp(5,5)
1738
+ sage: S.<x> = R[]
1739
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1740
+ sage: W.<w> = R.ext(f)
1741
+ sage: z = (1 + w)^5
1742
+ sage: z
1743
+ 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)
1744
+ sage: z >> (6) # indirect doctest
1745
+ 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)
1746
+ sage: z >> (-4)
1747
+ 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)
1748
+ sage: F = W.fraction_field()
1749
+ sage: z = F(z)
1750
+ sage: z >> 7
1751
+ 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)
1752
+ """
1753
+ cdef pAdicZZpXCRElement ans
1754
+ if not isinstance(shift, Integer):
1755
+ shift = Integer(shift)
1756
+ if mpz_fits_slong_p((<Integer>shift).value) == 0:
1757
+ if self._is_exact_zero():
1758
+ return self
1759
+ if self.prime_pow.in_field or mpz_sgn((<Integer>shift).value) < 0:
1760
+ raise ValueError("valuation overflow")
1761
+ else:
1762
+ ans = self._new_c(0)
1763
+ ans.ordp = 0
1764
+ return ans
1765
+ return self._rshift_c(mpz_get_si((<Integer>shift).value))
1766
+
1767
+ cpdef _neg_(self):
1768
+ """
1769
+ Negation.
1770
+
1771
+ EXAMPLES::
1772
+
1773
+ sage: R = Zp(5,5)
1774
+ sage: S.<x> = R[]
1775
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1776
+ sage: W.<w> = R.ext(f)
1777
+ sage: z = (1 + w)^5; z
1778
+ 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)
1779
+ sage: -z # indirect doctest
1780
+ 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)
1781
+ sage: y = z + (-z); y
1782
+ O(w^25)
1783
+ sage: -y
1784
+ O(w^25)
1785
+ sage: -W(0)
1786
+ 0
1787
+ """
1788
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
1789
+ ans.ordp = self.ordp
1790
+ if self.relprec != 0:
1791
+ self.prime_pow.restore_context_capdiv(self.relprec)
1792
+ ZZ_pX_negate(ans.unit, self.unit)
1793
+ return ans
1794
+
1795
+ # / 1 + \alpha^p \pi_K^{p \lambda} mod \mathfrak{p}_K^{p \lambda + 1} if 1 \le \lambda < \frac{e_K}{p-1}
1796
+ # (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}
1797
+ # \ 1 - \epsilon \alpha \pi_K^{\lambda + e} mod \mathfrak{p}_K^{\lambda + e + 1} if \lambda > \frac{e_K}{p-1}
1798
+
1799
+ def __pow__(pAdicZZpXCRElement self, _right, m): # m ignored
1800
+ r"""
1801
+ Compute ``self^right``.
1802
+
1803
+ Note: when ``right`` is divisible by `p` then one can get more
1804
+ precision than expected.
1805
+
1806
+ Lemma 2.1 (Constructing Class Fields over Local Fields, Sebastian Pauli):
1807
+
1808
+ Let `\alpha` be in `\mathcal{O}_K`. Let
1809
+
1810
+ .. MATH::
1811
+
1812
+ p = -\pi_K^{e_K} \epsilon
1813
+
1814
+ be the factorization of `p` where `\epsilon` is a unit. Then
1815
+ the `p`-th power of `1 + \alpha \pi_K^{\lambda}` satisfies
1816
+
1817
+ .. MATH::
1818
+
1819
+ (1 + \alpha \pi^{\lambda})^p \equiv \left{ \begin{array}{lll}
1820
+ 1 + \alpha^p \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $1 \le \lambda < \frac{e_K}{p-1}$} \\
1821
+ 1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $\lambda = \frac{e_K}{p-1}$} \\
1822
+ 1 - \epsilon \alpha \pi_K^{\lambda + e} & \mod \mathfrak{p}_K^{\lambda + e + 1} & \mbox{if $\lambda > \frac{e_K}{p-1}$}
1823
+ \end{array} \right.
1824
+
1825
+
1826
+ So if ``right`` is divisible by `p^k` we can multiply the
1827
+ relative precision by `p` until we exceed `e/(p-1)`, then add
1828
+ `e` until we have done a total of `k` things: the precision of
1829
+ the result can therefore be greater than the precision of
1830
+ ``self``.
1831
+
1832
+ There is also the issue of `p`-adic exponents, and determining
1833
+ how the precision of the exponent affects the precision of the
1834
+ result.
1835
+
1836
+ In computing `(a + O(\pi^k))^{b + O(p^m)}`, one needs that the
1837
+ reduction of `a` mod `\pi` is in the prime field
1838
+ `\GF{p}` (so that the `p^m` power of the Teichmuller
1839
+ part is constant as `m` increases). Given this restriction,
1840
+ we can factor out the Teichmuller part and use the above lemma
1841
+ to find the first spot where
1842
+
1843
+ .. MATH::
1844
+
1845
+ (1 + \alpha \pi^{\lambda})^{p^m}
1846
+
1847
+ differs from 1. We compare this with the precision bound
1848
+ given by computing `(a + O(\pi^k))^b` and take the lesser of
1849
+ the two.
1850
+
1851
+ In order to do this we need to compute the valuation of ``(self
1852
+ / self.parent().teichmuller(self)) - 1``.
1853
+
1854
+ EXAMPLES::
1855
+
1856
+ sage: R = Zp(5,5)
1857
+ sage: S.<x> = R[]
1858
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1859
+ sage: W.<w> = R.ext(f)
1860
+ sage: (1 + w)^5 # indirect doctest
1861
+ 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)
1862
+ sage: (1 + w)^-5
1863
+ 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)
1864
+ sage: (1 + w + O(w^19))^5
1865
+ 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)
1866
+ sage: (1 + O(w))^5
1867
+ 1 + O(w^5)
1868
+ sage: (1 + w + O(w^3))^25
1869
+ 1 + w^10 + w^11 + 4*w^12 + O(w^13)
1870
+ sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(125))
1871
+ 2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + 4*w^10 + O(w^11)
1872
+ sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(25))
1873
+ 2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + O(w^10)
1874
+ sage: (3 + w^2 + O(w^6))^(15+O(25))
1875
+ 2 + w^5 + 4*w^7 + w^9 + 3*w^10 + O(w^11)
1876
+ sage: R = Zp(2, 10)
1877
+ sage: S.<x> = R[]
1878
+ sage: f = x^34 + 18*x^5 - 72*x^3 + 2
1879
+ sage: W.<w> = R.ext(f)
1880
+ sage: (1+w+O(w^2))^8
1881
+ 1 + w^8 + O(w^16)
1882
+ sage: (1+w+O(w^2))^16
1883
+ 1 + w^16 + O(w^32)
1884
+ sage: (1+w+O(w^2))^32
1885
+ 1 + w^32 + w^50 + w^55 + w^60 + O(w^64)
1886
+ sage: (1+w+O(w^2))^64
1887
+ 1 + w^64 + w^66 + w^71 + w^76 + w^81 + w^84 + w^86 + w^91 + w^94 + w^96 + O(w^98)
1888
+
1889
+ TESTS:
1890
+
1891
+ We define ``0^0`` to be unity, :issue:`13786`::
1892
+
1893
+ sage: R = Zp(5,5)
1894
+ sage: S.<x> = R[]
1895
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1896
+ sage: W.<w> = R.ext(f)
1897
+ sage: type(W(0))
1898
+ <class 'sage.rings.padics.padic_ZZ_pX_CR_element.pAdicZZpXCRElement'>
1899
+ sage: W(0)^0
1900
+ 1 + O(w^25)
1901
+ sage: W(0)^0 == W(1)
1902
+ True
1903
+
1904
+ The value returned from ``0^0`` should belong to our ring::
1905
+
1906
+ sage: R = Zp(5,5)
1907
+ sage: S.<x> = R[]
1908
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1909
+ sage: W.<w> = R.ext(f)
1910
+ sage: type(W(0)^0) == type(W(0))
1911
+ True
1912
+ """
1913
+ self._normalize()
1914
+ cdef Integer right
1915
+ cdef bint padic_exp
1916
+ cdef long exp_prec
1917
+ cdef long exp_val
1918
+ cdef long relprec
1919
+ cdef long threshold # e / (p-1)
1920
+ cdef mpz_t tmp, tmp2
1921
+ if mpz_fits_slong_p(self.prime_pow.prime.value) == 0:
1922
+ threshold = 0
1923
+ else:
1924
+ threshold = self.prime_pow.e / (mpz_get_si(self.prime_pow.prime.value) - 1)
1925
+ cdef Integer base_level
1926
+ cdef pAdicZZpXCRElement ans
1927
+ cdef long i
1928
+ if self._is_exact_zero():
1929
+ # Return 0 except for 0^0 error or type error on the exponent.
1930
+ if isinstance(_right, (Integer, Rational, int)) or (isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime)):
1931
+ if _right == 0:
1932
+ return self.parent(1)
1933
+ return self
1934
+ else:
1935
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1936
+ elif self._is_inexact_zero():
1937
+ # If an integer exponent, return an inexact zero of valuation right * self.ordp. Otherwise raise an error.
1938
+ if isinstance(_right, int):
1939
+ _right = Integer(_right)
1940
+ if isinstance(_right, Integer):
1941
+ ans = self._new_c(0)
1942
+ mpz_init_set_si(tmp, self.ordp)
1943
+ mpz_mul(tmp, tmp, (<Integer>_right).value)
1944
+ if mpz_cmp_si(tmp, maxordp) >= 0 or mpz_cmp_si(tmp, -maxordp) <= 0:
1945
+ raise ValueError("valuation overflow")
1946
+ ans.ordp = mpz_get_si(tmp)
1947
+ mpz_clear(tmp)
1948
+ return ans
1949
+ elif isinstance(_right, Rational) or (isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime)):
1950
+ raise ValueError("Need more precision")
1951
+ else:
1952
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1953
+ if isinstance(_right, int):
1954
+ _right = Integer(_right)
1955
+ if isinstance(_right, Integer):
1956
+ right = <Integer> _right
1957
+ if right == 0:
1958
+ # return 1 to maximum precision
1959
+ ans = self._new_c(self.prime_pow.ram_prec_cap)
1960
+ ans.ordp = 0
1961
+ ZZ_pX_SetCoeff_long(ans.unit, 0, 1)
1962
+ return ans
1963
+ padic_exp = False
1964
+ exp_val = _right.valuation(self.prime_pow.prime) ##
1965
+ elif isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime):
1966
+ if self.ordp != 0:
1967
+ raise ValueError("in order to raise to a p-adic exponent, base must be a unit")
1968
+ right = Integer(_right)
1969
+ padic_exp = True
1970
+ exp_prec = _right.precision_absolute() ##
1971
+ exp_val = _right.valuation() ##
1972
+ if exp_val < 0:
1973
+ raise NotImplementedError("negative valuation exponents not yet supported")
1974
+ # checks to see if the residue of self.unit is in the prime field.
1975
+ if self.prime_pow.e == 1:
1976
+ for i in range(ZZ_pX_deg(self.unit) + 1):
1977
+ if not ZZ_divide_test(ZZ_p_rep(ZZ_pX_coeff(self.unit, i)), self.prime_pow.pow_ZZ_tmp(1)[0]):
1978
+ raise ValueError("in order to raise to a p-adic exponent, base must reduce to an element of F_p mod the uniformizer")
1979
+ # compute the "level"
1980
+ teich_part = self.parent().teichmuller(self)
1981
+ base_level = (self / teich_part - 1).valuation() ##
1982
+ elif isinstance(_right, Rational):
1983
+ raise NotImplementedError
1984
+ else:
1985
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1986
+ # Now we compute the increased relprec due to the exponent having positive p-adic valuation
1987
+ if exp_val > 0:
1988
+ mpz_init_set_si(tmp, self.relprec)
1989
+ while mpz_cmp_si(tmp, threshold) <= 0 and exp_val > 0:
1990
+ mpz_mul(tmp, tmp, self.prime_pow.prime.value)
1991
+ exp_val -= 1
1992
+ if exp_val > 0:
1993
+ mpz_init_set_si(tmp2, self.prime_pow.e)
1994
+ mpz_addmul_ui(tmp, tmp2, exp_val)
1995
+ mpz_clear(tmp2)
1996
+ if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) > 0:
1997
+ relprec = self.prime_pow.ram_prec_cap
1998
+ else:
1999
+ relprec = mpz_get_si(tmp)
2000
+ mpz_clear(tmp)
2001
+ else:
2002
+ relprec = self.relprec
2003
+ # Now we compute the limit on relprec due to a non-infinite precision on the exponent.
2004
+ if padic_exp:
2005
+ if exp_prec > 0:
2006
+ # I can freely change base_level, so I use it in place of tmp above.
2007
+ while mpz_cmp_si(base_level.value, threshold) <= 0 and exp_prec > 0:
2008
+ mpz_mul(base_level.value, base_level.value, self.prime_pow.prime.value)
2009
+ exp_prec -= 1
2010
+ if exp_prec > 0:
2011
+ mpz_init_set_si(tmp2, self.prime_pow.e)
2012
+ mpz_addmul_ui(base_level.value, tmp2, exp_prec)
2013
+ mpz_clear(tmp2)
2014
+ if mpz_cmp_si(base_level.value, relprec) < 0:
2015
+ relprec = mpz_get_si(base_level.value)
2016
+ else:
2017
+ ans = self._new_c(0)
2018
+ ans.ordp = 0
2019
+ return ans
2020
+ ans = self._new_c(relprec)
2021
+ if self.ordp == 0:
2022
+ ans.ordp = 0
2023
+ else:
2024
+ mpz_init_set(tmp, right.value)
2025
+ mpz_mul_si(tmp, tmp, self.ordp)
2026
+ if mpz_cmp_si(tmp, maxordp) >= 0 or mpz_cmp_si(tmp, -maxordp) <= 0:
2027
+ raise ValueError("valuation overflow")
2028
+ ans.ordp = mpz_get_si(tmp)
2029
+ mpz_clear(tmp)
2030
+ cdef ntl_ZZ rZZ = ntl_ZZ.__new__(ntl_ZZ)
2031
+ mpz_to_ZZ(&rZZ.x, right.value)
2032
+ sig_on()
2033
+ if mpz_sgn(right.value) < 0:
2034
+ if self.prime_pow.e == 1:
2035
+ 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)
2036
+ else:
2037
+ 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)
2038
+ ZZ_negate(rZZ.x, rZZ.x)
2039
+ ZZ_pX_PowerMod_pre(ans.unit, ans.unit, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2040
+ else:
2041
+ ZZ_pX_PowerMod_pre(ans.unit, self.unit, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2042
+ sig_off()
2043
+ return ans
2044
+
2045
+ cpdef _add_(self, _right):
2046
+ """
2047
+ Compute the sum of ``self`` and ``right``.
2048
+
2049
+ EXAMPLES::
2050
+
2051
+ sage: R = Zp(5,5)
2052
+ sage: S.<x> = R[]
2053
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2054
+ sage: W.<w> = R.ext(f)
2055
+ sage: (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)) - 69 # indirect doctest
2056
+ 1 + O(w^13)
2057
+ sage: -69 + (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
2058
+ 1 + O(w^13)
2059
+ sage: y = (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
2060
+ sage: y - 70
2061
+ O(w^13)
2062
+ sage: y + 0
2063
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
2064
+ """
2065
+ cdef pAdicZZpXCRElement right = <pAdicZZpXCRElement>_right
2066
+ cdef pAdicZZpXCRElement ans
2067
+ cdef long tmpL
2068
+ cdef ZZ_pX_c tmpP
2069
+ if self.relprec == 0:
2070
+ if self.ordp >= right.ordp + right.relprec: # or self._is_exact_zero()
2071
+ return right
2072
+ elif self.ordp <= right.ordp:
2073
+ ans = self._new_c(0)
2074
+ ans.ordp = self.ordp
2075
+ else:
2076
+ ans = self._new_c(self.ordp - right.ordp)
2077
+ ZZ_pX_conv_modulus(ans.unit, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2078
+ if right.relprec < 0:
2079
+ ans.relprec = -ans.relprec
2080
+ ans.ordp = right.ordp
2081
+ return ans
2082
+ if right.relprec == 0:
2083
+ if right.ordp >= self.ordp + self.relprec: # or right._is_exact_zero()
2084
+ return self
2085
+ elif right.ordp <= self.ordp:
2086
+ ans = self._new_c(0)
2087
+ ans.ordp = right.ordp
2088
+ else:
2089
+ ans = self._new_c(right.ordp - self.ordp)
2090
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2091
+ if self.relprec < 0:
2092
+ ans.relprec = -ans.relprec
2093
+ ans.ordp = self.ordp
2094
+ return ans
2095
+ cdef long srprec = self.relprec
2096
+ if srprec < 0:
2097
+ srprec = -srprec
2098
+ cdef long rrprec = right.relprec
2099
+ if rrprec < 0:
2100
+ rrprec = -rrprec
2101
+ if self.ordp == right.ordp:
2102
+ # The relative precision of the sum is the minimum of the relative precisions in this case, possibly decreasing if we got cancellation
2103
+ # Since the valuations are the same, we could just add the units, if they had the same modulus.
2104
+ # But they don't necessarily, so we may have to conv_modulus
2105
+ if srprec == rrprec:
2106
+ ans = self._new_c(-srprec) # -srprec indicates that ans is not normalized
2107
+ self.prime_pow.restore_context_capdiv(srprec)
2108
+ ZZ_pX_add(ans.unit, self.unit, right.unit)
2109
+ elif srprec < rrprec:
2110
+ ans = self._new_c(-srprec)
2111
+ ZZ_pX_conv_modulus(ans.unit, right.unit, self.prime_pow.get_context_capdiv(srprec).x)
2112
+ self.prime_pow.restore_context_capdiv(srprec)
2113
+ # conv_modulus should have restored the context, so we don't need to again.
2114
+ ZZ_pX_add(ans.unit, ans.unit, self.unit)
2115
+ else:
2116
+ ans = self._new_c(-rrprec)
2117
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(rrprec).x)
2118
+ self.prime_pow.restore_context_capdiv(rrprec)
2119
+ # conv_modulus should have restored the context, so we don't need to again.
2120
+ ZZ_pX_add(ans.unit, ans.unit, right.unit)
2121
+ ans.ordp = self.ordp
2122
+ elif self.ordp < right.ordp:
2123
+ tmpL = right.ordp - self.ordp
2124
+ if tmpL >= srprec:
2125
+ return self
2126
+ if srprec <= tmpL + rrprec:
2127
+ ans = self._new_c(-srprec)
2128
+ else:
2129
+ ans = self._new_c(-tmpL - rrprec)
2130
+ ans.ordp = self.ordp
2131
+ ZZ_pX_conv_modulus(ans.unit, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2132
+ ans._internal_lshift(tmpL)
2133
+ if srprec <= tmpL + rrprec:
2134
+ ZZ_pX_add(ans.unit, ans.unit, self.unit)
2135
+ else:
2136
+ ZZ_pX_conv_modulus(tmpP, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2137
+ ZZ_pX_add(ans.unit, ans.unit, tmpP)
2138
+ # if self is normalized, then the valuations are actually different so the sum will be normalized.
2139
+ if self.relprec > 0:
2140
+ ans.relprec = -ans.relprec
2141
+ else:
2142
+ tmpL = self.ordp - right.ordp
2143
+ if tmpL >= rrprec:
2144
+ return right
2145
+ if rrprec <= tmpL + srprec:
2146
+ ans = self._new_c(-rrprec)
2147
+ else:
2148
+ ans = self._new_c(-tmpL - srprec)
2149
+ ans.ordp = right.ordp
2150
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2151
+ ans._internal_lshift(tmpL)
2152
+ if rrprec <= tmpL + srprec:
2153
+ ZZ_pX_add(ans.unit, ans.unit, right.unit)
2154
+ else:
2155
+ ZZ_pX_conv_modulus(tmpP, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2156
+ ZZ_pX_add(ans.unit, ans.unit, tmpP)
2157
+ # if right is normalized, then the valuations are actually different so the sum will be normalized.
2158
+ if right.relprec > 0:
2159
+ ans.relprec = -ans.relprec
2160
+ return ans
2161
+
2162
+ cpdef _sub_(self, right):
2163
+ """
2164
+ Return the difference of two elements.
2165
+
2166
+ EXAMPLES::
2167
+
2168
+ sage: R = Zp(5,5)
2169
+ sage: S.<x> = R[]
2170
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2171
+ sage: W.<w> = R.ext(f)
2172
+ sage: a = W(329)
2173
+ sage: b = W(111)
2174
+ sage: a - b # indirect doctest
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: W(218)
2177
+ 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)
2178
+ sage: a - O(w^14)
2179
+ 4 + 3*w^10 + 2*w^12 + O(w^14)
2180
+ sage: a - 0
2181
+ 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)
2182
+ sage: O(w^14) - a
2183
+ 1 + 4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + O(w^14)
2184
+ """
2185
+ # For now, a simple implementation
2186
+ return self + (-right)
2187
+
2188
+ cpdef _mul_(self, _right):
2189
+ """
2190
+ Return the product of two elements.
2191
+
2192
+ EXAMPLES::
2193
+
2194
+ sage: R = Zp(5,5)
2195
+ sage: S.<x> = R[]
2196
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2197
+ sage: W.<w> = R.ext(f)
2198
+ sage: a = W(329)
2199
+ sage: b = W(111)
2200
+ sage: a*b # indirect doctest
2201
+ 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)
2202
+ sage: a * 0
2203
+ 0
2204
+ sage: a * O(w^14)
2205
+ O(w^14)
2206
+ """
2207
+ cdef pAdicZZpXCRElement right = <pAdicZZpXCRElement>_right
2208
+ cdef ZZ_pX_c modulus_corrected
2209
+ cdef pAdicZZpXCRElement ans
2210
+ if self._is_exact_zero():
2211
+ return self
2212
+ if right._is_exact_zero():
2213
+ return right
2214
+ self._normalize()
2215
+ right._normalize()
2216
+ if self.relprec <= right.relprec:
2217
+ ans = self._new_c(self.relprec)
2218
+ else:
2219
+ ans = self._new_c(right.relprec)
2220
+ ans.ordp = self.ordp + right.ordp
2221
+ check_ordp(ans.ordp)
2222
+ if ans.relprec == 0:
2223
+ return ans
2224
+ if self.relprec == right.relprec:
2225
+ self.prime_pow.restore_context_capdiv(ans.relprec)
2226
+ sig_on()
2227
+ ZZ_pX_MulMod_pre(ans.unit, self.unit, right.unit, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2228
+ sig_off()
2229
+ elif self.relprec < right.relprec:
2230
+ sig_on()
2231
+ ZZ_pX_conv_modulus(modulus_corrected, right.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2232
+ ZZ_pX_MulMod_pre(ans.unit, self.unit, modulus_corrected, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2233
+ sig_off()
2234
+ else:
2235
+ sig_on()
2236
+ ZZ_pX_conv_modulus(modulus_corrected, self.unit, self.prime_pow.get_context_capdiv(ans.relprec).x)
2237
+ ZZ_pX_MulMod_pre(ans.unit, right.unit, modulus_corrected, self.prime_pow.get_modulus_capdiv(ans.relprec)[0])
2238
+ sig_off()
2239
+ return ans
2240
+
2241
+ cpdef _div_(self, right):
2242
+ """
2243
+ Return the quotient of two elements.
2244
+
2245
+ EXAMPLES::
2246
+
2247
+ sage: R = Zp(5,5)
2248
+ sage: S.<x> = R[]
2249
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2250
+ sage: W.<w> = R.ext(f)
2251
+ sage: W(14) / W(125) # indirect doctest
2252
+ 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)
2253
+ sage: 1 / w
2254
+ w^-1 + O(w^24)
2255
+ sage: W.<w> = R.ext(x^25 - 165*x + 5)
2256
+ sage: a = (1 + w)^25 - 1
2257
+ sage: b = (1 + w)^5 - 1
2258
+ sage: c = (1 + w)^20 + (1 + w)^15 + (1 + w)^10 + (1 + w)^5 + 1
2259
+ sage: d = a / b; d == c
2260
+ True
2261
+ sage: d.precision_absolute()
2262
+ 120
2263
+ sage: c.precision_absolute()
2264
+ 125
2265
+ sage: 1 / a == ~a
2266
+ True
2267
+ """
2268
+ # for now, a simple implementation
2269
+ return self * (~right)
2270
+
2271
+ def __copy__(self):
2272
+ """
2273
+ Return a copy of this element.
2274
+
2275
+ EXAMPLES::
2276
+
2277
+ sage: R = Zp(5,5)
2278
+ sage: S.<x> = R[]
2279
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2280
+ sage: W.<w> = R.ext(f)
2281
+ sage: b = W(45, 17); b
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 = copy(b); c
2284
+ 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)
2285
+ sage: c is b
2286
+ False
2287
+ """
2288
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
2289
+ ans.ordp = self.ordp
2290
+ ans.unit = self.unit
2291
+ return ans
2292
+
2293
+ def _integer_(self, Z=None):
2294
+ r"""
2295
+ Return an integer congruent to this element modulo
2296
+ `\pi^{\mathrm{self.absolute_precision()}`, if possible.
2297
+
2298
+ EXAMPLES::
2299
+
2300
+ sage: ZZ(ZqCR(125,names='a')(-1)) # indirect doctest
2301
+ 95367431640624
2302
+ sage: R = Zp(5); S.<x> = ZZ[]; f = x^5 + 25*x^3 - 5; W.<w> = R.ext(f)
2303
+ sage: ZZ(W(-1))
2304
+ 95367431640624
2305
+ sage: ZZ(W(0))
2306
+ 0
2307
+ sage: ZZ(W(0,7))
2308
+ 0
2309
+ sage: ZZ(w)
2310
+ Traceback (most recent call last):
2311
+ ...
2312
+ ValueError: this element not well approximated by an integer
2313
+ sage: ZZ(W(5)) # todo: this should be different...
2314
+ 381469726562505
2315
+ """
2316
+ cdef Integer ans
2317
+ cdef ZZ_c tmp_z
2318
+ if self._is_exact_zero() or self.relprec == 0:
2319
+ ans = PY_NEW(Integer)
2320
+ return ans
2321
+ if self.ordp < 0:
2322
+ self._normalize()
2323
+ if self.ordp < 0:
2324
+ raise ValueError("this element has negative valuation")
2325
+ cdef ntl_ZZ_pX f = <ntl_ZZ_pX>self._ntl_rep_abs()[0]
2326
+ if f.degree() > 0:
2327
+ raise ValueError("this element not well approximated by an integer")
2328
+ ans = PY_NEW(Integer)
2329
+ tmp_z = ZZ_p_rep(ZZ_pX_ConstTerm(f.x))
2330
+ ZZ_to_mpz(ans.value, &tmp_z)
2331
+ return ans
2332
+
2333
+ def is_zero(self, absprec=None):
2334
+ r"""
2335
+ Return whether the valuation of this element is at least
2336
+ ``absprec``. If ``absprec`` is ``None``, checks if this element
2337
+ is indistinguishable from zero.
2338
+
2339
+ If this element is an inexact zero of valuation less than ``absprec``,
2340
+ raises a :exc:`PrecisionError`.
2341
+
2342
+ EXAMPLES::
2343
+
2344
+ sage: R = Zp(5,5)
2345
+ sage: S.<x> = R[]
2346
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2347
+ sage: W.<w> = R.ext(f)
2348
+ sage: O(w^189).is_zero()
2349
+ True
2350
+ sage: W(0).is_zero()
2351
+ True
2352
+ sage: a = W(675)
2353
+ sage: a.is_zero()
2354
+ False
2355
+ sage: a.is_zero(7)
2356
+ True
2357
+ sage: a.is_zero(21)
2358
+ False
2359
+ """
2360
+ cdef bint ans
2361
+ cdef long aprec
2362
+ self._normalize()
2363
+ if self._is_exact_zero():
2364
+ ans = True
2365
+ elif absprec is None:
2366
+ ans = (self.relprec == 0)
2367
+ else:
2368
+ if not isinstance(absprec, Integer):
2369
+ absprec = Integer(absprec)
2370
+ if mpz_fits_slong_p((<Integer>absprec).value) == 0:
2371
+ if mpz_sgn((<Integer>absprec).value) < 0:
2372
+ ans = True
2373
+ elif self.relprec == 0:
2374
+ raise PrecisionError("not enough precision to determine if element is zero")
2375
+ else:
2376
+ ans = False
2377
+ else:
2378
+ aprec = mpz_get_si((<Integer>absprec).value)
2379
+ if self.relprec == 0 and aprec > self.ordp:
2380
+ raise PrecisionError("not enough precision to determine if element is zero")
2381
+ else:
2382
+ ans = (self.ordp >= aprec)
2383
+ return ans
2384
+
2385
+ cpdef ntl_ZZ_pX _ntl_rep_unnormalized(self):
2386
+ """
2387
+ Return an ``ntl_ZZ_pX`` holding the current unit part of this element.
2388
+
2389
+ The element is not normalized before this operation, so the polynomial
2390
+ returned may not actually be a unit.
2391
+
2392
+ EXAMPLES::
2393
+
2394
+ sage: R = Zp(5,5)
2395
+ sage: S.<x> = R[]
2396
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2397
+ sage: W.<w> = R.ext(f)
2398
+ sage: a = W(566); b = W(209)
2399
+ sage: c = a + b; c._ntl_rep_unnormalized()
2400
+ [775]
2401
+ sage: c
2402
+ 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)
2403
+ sage: c._ntl_rep_unnormalized()
2404
+ [106 60 114 35 112]
2405
+ """
2406
+ if self.relprec == 0:
2407
+ raise ValueError("self == 0")
2408
+ self.prime_pow.restore_context_capdiv(self.relprec)
2409
+ cdef ntl_ZZ_pX ans = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
2410
+ ans.c = self.prime_pow.get_context_capdiv(self.relprec)
2411
+ ans.x = self.unit
2412
+ return ans
2413
+
2414
+ cpdef ntl_ZZ_pX _ntl_rep(self):
2415
+ """
2416
+ Return an ``ntl_ZZ_pX`` that holds the unit part of this element.
2417
+
2418
+ EXAMPLES::
2419
+
2420
+ sage: R = Zp(5,5)
2421
+ sage: S.<x> = R[]
2422
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2423
+ sage: W.<w> = R.ext(f)
2424
+ sage: a = W(566); b = W(209)
2425
+ sage: c = a + b; c._ntl_rep()
2426
+ [106 60 114 35 112]
2427
+ sage: c
2428
+ 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)
2429
+ sage: c._ntl_rep()
2430
+ [106 60 114 35 112]
2431
+ """
2432
+ self._normalize()
2433
+ return self._ntl_rep_unnormalized()
2434
+
2435
+ cpdef _ntl_rep_abs(self):
2436
+ """
2437
+ Return a pair ``(f, k)`` where ``f`` is an ``ntl_ZZ_pX`` and ``k`` is a
2438
+ nonpositive integer such that ``self = f(self.parent.gen())*p^k``.
2439
+
2440
+ EXAMPLES::
2441
+
2442
+ sage: R = Zp(5,5)
2443
+ sage: S.<x> = R[]
2444
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2445
+ sage: W.<w> = R.ext(f)
2446
+ sage: a = W(566); b = W(209)
2447
+ sage: c = a + b; c._ntl_rep_abs()
2448
+ ([775], 0)
2449
+ sage: c
2450
+ 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)
2451
+ sage: c._ntl_rep_abs()
2452
+ ([775], 0)
2453
+ sage: (~c)._ntl_rep_abs()
2454
+ ([121], -2)
2455
+ sage: ~c
2456
+ 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)
2457
+ sage: ~c * 25
2458
+ 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)
2459
+ sage: W(121)
2460
+ 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)
2461
+ """
2462
+ self._normalize()
2463
+ if self.ordp == 0:
2464
+ return self._ntl_rep(), Integer(0)
2465
+ cdef ntl_ZZ_pContext_class ctx
2466
+ cdef long little_shift, ppow
2467
+ if self.ordp > 0:
2468
+ ctx = self.prime_pow.get_context_capdiv(self.ordp + self.relprec)
2469
+ else:
2470
+ little_shift = ((-self.ordp) % self.prime_pow.e)
2471
+ if little_shift != 0:
2472
+ little_shift = self.prime_pow.e - little_shift
2473
+ ctx = self.prime_pow.get_context_capdiv(self.relprec + little_shift)
2474
+ ctx.restore_c()
2475
+ cdef pAdicZZpXCRElement dummy = pAdicZZpXCRElement.__new__(pAdicZZpXCRElement)
2476
+ cdef ntl_ZZ_pX ans = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
2477
+ cdef Integer ans_k = PY_NEW(Integer)
2478
+ dummy.unit = self.unit
2479
+ dummy.prime_pow = self.prime_pow
2480
+ if self.ordp > 0:
2481
+ dummy.relprec = self.ordp + self.relprec
2482
+ dummy._internal_lshift(self.ordp)
2483
+ ans.x = dummy.unit
2484
+ else:
2485
+ ppow = (self.ordp - little_shift) / self.prime_pow.e
2486
+ mpz_set_si(ans_k.value, ppow)
2487
+ dummy.ordp = 0 # _pshift_self wants ordp set
2488
+ dummy.relprec = self.relprec + little_shift
2489
+ # self = x^(self.prime_pow.e * ppow) * x^(little_shift) * self.unit
2490
+ # so we want to _internal_lshift dummy.unit by little_shift
2491
+ dummy._internal_lshift(little_shift)
2492
+ # and then write
2493
+ # self = p^(ppow) * (x^e/p)^(ppow) * dummy.unit
2494
+ # so we need to multiply dummy.unit by (p/x^e)^(-ppow) in the Eisenstein case
2495
+ # which we can do by _pshift_self
2496
+ dummy._pshift_self(-ppow)
2497
+ ans.x = dummy.unit
2498
+ ans.c = ctx
2499
+ return ans, ans_k
2500
+
2501
+ def _polynomial_list(self, pad=False):
2502
+ """
2503
+ Return the coefficient list for a polynomial over the base ring
2504
+ yielding this element.
2505
+
2506
+ INPUT:
2507
+
2508
+ - ``pad`` -- whether to pad the result with zeros of the appropriate precision
2509
+
2510
+ EXAMPLES::
2511
+
2512
+ sage: R.<x> = ZZ[]
2513
+ sage: W.<w> = Qp(5).extension(x^3 - 5)
2514
+ sage: (1 + w + O(w^11))._polynomial_list()
2515
+ [1 + O(5^4), 1 + O(5^4)]
2516
+ sage: (1 + w + O(w^11))._polynomial_list(pad=True)
2517
+ [1 + O(5^4), 1 + O(5^4), O(5^3)]
2518
+ sage: W(0)._polynomial_list()
2519
+ []
2520
+ sage: W(0)._polynomial_list(pad=True)
2521
+ [0, 0, 0]
2522
+ sage: W(O(w^7))._polynomial_list()
2523
+ []
2524
+ sage: W(O(w^7))._polynomial_list(pad=True)
2525
+ [O(5^3), O(5^2), O(5^2)]
2526
+ sage: T.<a> = Qp(5).extension(x^2 - 5)
2527
+ sage: T(1/5)._polynomial_list()
2528
+ [5^-1 + O(5^19)]
2529
+ sage: T(a^-800)._polynomial_list()
2530
+ [5^-400 + O(5^-380)]
2531
+ sage: T(O(a^-2))._polynomial_list()
2532
+ []
2533
+ """
2534
+ R = self.base_ring()
2535
+ if self.is_zero():
2536
+ L = []
2537
+ k = 0
2538
+ else:
2539
+ f, k = self._ntl_rep_abs()
2540
+ L = [Integer(c) for c in f.list()]
2541
+ if pad:
2542
+ n = self.parent().degree()
2543
+ L.extend([R.zero()] * (n - len(L)))
2544
+ if self._is_exact_zero():
2545
+ return L
2546
+ prec = self.relprec + self.ordp
2547
+ e = self.parent().e()
2548
+ if e == 1:
2549
+ return [R(c, prec-k) << k for c in L]
2550
+ else:
2551
+ return [R(c, (((prec - i - 1) // e) + 1) - k) << k for i, c in enumerate(L)]
2552
+
2553
+ def polynomial(self, var='x'):
2554
+ """
2555
+ Return a polynomial over the base ring that yields this element
2556
+ when evaluated at the generator of the parent.
2557
+
2558
+ INPUT:
2559
+
2560
+ - ``var`` -- string, the variable name for the polynomial
2561
+
2562
+ EXAMPLES::
2563
+
2564
+ sage: S.<x> = ZZ[]
2565
+ sage: W.<w> = Zp(5).extension(x^2 - 5)
2566
+ sage: (w + W(5, 7)).polynomial()
2567
+ (1 + O(5^3))*x + 5 + O(5^4)
2568
+ """
2569
+ R = self.base_ring()
2570
+ S = R[var]
2571
+ return S(self._polynomial_list())
2572
+
2573
+ cdef ZZ_p_c _const_term(self) noexcept:
2574
+ """
2575
+ Return the constant term of ``self.unit``.
2576
+
2577
+ Note: this may be divisible by `p` if ``self`` is not normalized.
2578
+
2579
+ EXAMPLES::
2580
+
2581
+ sage: R = Zp(5,5)
2582
+ sage: S.<x> = R[]
2583
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2584
+ sage: W.<w> = R.ext(f)
2585
+ sage: a = W(566)
2586
+ sage: a._const_term_test() # indirect doctest
2587
+ 566
2588
+ """
2589
+ return ZZ_pX_ConstTerm((<pAdicZZpXCRElement>self).unit)
2590
+
2591
+ def is_equal_to(self, right, absprec=None):
2592
+ """
2593
+ Return whether this element is equal to ``right`` modulo ``self.uniformizer()^absprec``.
2594
+
2595
+ If ``absprec`` is ``None``, checks whether this element is equal to ``right``
2596
+ modulo the lower of their two precisions.
2597
+
2598
+ EXAMPLES::
2599
+
2600
+ sage: R = Zp(5,5)
2601
+ sage: S.<x> = R[]
2602
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2603
+ sage: W.<w> = R.ext(f)
2604
+ sage: a = W(47); b = W(47 + 25)
2605
+ sage: a.is_equal_to(b)
2606
+ False
2607
+ sage: a.is_equal_to(b, 7)
2608
+ True
2609
+ """
2610
+ # Should be sped up later
2611
+ return (self - right).is_zero(absprec)
2612
+
2613
+ # def lift(self):
2614
+ # """
2615
+ # Return an element of a number field defined by the same polynomial as
2616
+ # ``self``'s parent that is congruent to self modulo an appropriate ideal.
2617
+
2618
+ # Not currently implemented.
2619
+ # """
2620
+ # raise NotImplementedError
2621
+
2622
+ cpdef pAdicZZpXCRElement lift_to_precision(self, absprec=None):
2623
+ """
2624
+ Return a ``pAdicZZpXCRElement`` congruent to this element but with
2625
+ absolute precision at least ``absprec``.
2626
+
2627
+ INPUT:
2628
+
2629
+ - ``absprec`` -- (default: ``None``) the absolute precision of
2630
+ the result. If ``None``, lifts to the maximum precision
2631
+ allowed.
2632
+
2633
+ .. NOTE::
2634
+
2635
+ If setting ``absprec`` that high would violate the
2636
+ precision cap, raises a precision error. If ``self`` is an
2637
+ inexact zero and ``absprec`` is greater than the maximum
2638
+ allowed valuation, raises an error.
2639
+
2640
+ Note that the new digits will not necessarily be zero.
2641
+
2642
+ EXAMPLES::
2643
+
2644
+ sage: R = Zp(5,5)
2645
+ sage: S.<x> = R[]
2646
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2647
+ sage: W.<w> = R.ext(f)
2648
+ sage: a = W(345, 17); a
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 + O(w^17)
2650
+ sage: b = a.lift_to_precision(19); b
2651
+ 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
2652
+ + w^17 + 2*w^18 + O(w^19)
2653
+ sage: c = a.lift_to_precision(24); c
2654
+ 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
2655
+ + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24)
2656
+ sage: a._ntl_rep()
2657
+ [19 35 118 60 121]
2658
+ sage: b._ntl_rep()
2659
+ [19 35 118 60 121]
2660
+ sage: c._ntl_rep()
2661
+ [19 35 118 60 121]
2662
+ sage: a.lift_to_precision().precision_relative() == W.precision_cap()
2663
+ True
2664
+ """
2665
+ cdef pAdicZZpXCRElement ans
2666
+ cdef long aprec, rprec
2667
+ self._normalize()
2668
+ if self._is_exact_zero():
2669
+ return self
2670
+ if absprec is not None and not isinstance(absprec, Integer):
2671
+ absprec = Integer(absprec)
2672
+ if absprec is None:
2673
+ if self.relprec == 0:
2674
+ # return an exact zero
2675
+ ans = self._new_c(0)
2676
+ ans._set_exact_zero()
2677
+ return ans
2678
+ aprec = self.prime_pow.ram_prec_cap + self.ordp
2679
+ elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
2680
+ if mpz_sgn((<Integer>absprec).value) < 0 or self.relprec == self.prime_pow.ram_prec_cap:
2681
+ return self
2682
+ else:
2683
+ if self.relprec == 0:
2684
+ raise ValueError("absprec larger than maximum allowable valuation")
2685
+ else:
2686
+ raise PrecisionError("precision higher than allowed by the precision cap")
2687
+ else:
2688
+ aprec = mpz_get_si((<Integer>absprec).value)
2689
+ if aprec <= self.ordp + self.relprec:
2690
+ return self
2691
+ if self.relprec == 0:
2692
+ if self.ordp >= aprec:
2693
+ return self
2694
+ elif aprec >= maxordp:
2695
+ raise ValueError("absprec larger than maximum allowable valuation")
2696
+ else:
2697
+ ans = self._new_c(0)
2698
+ ans._set_inexact_zero(aprec)
2699
+ return ans
2700
+ # Now we're done handling all the special cases.
2701
+ rprec = aprec - self.ordp
2702
+ if rprec > self.prime_pow.ram_prec_cap:
2703
+ raise PrecisionError("precision higher than allowed by the precision cap")
2704
+ ans = self._new_c(rprec)
2705
+ ans.ordp = self.ordp
2706
+ ZZ_pX_conv_modulus(ans.unit, self.unit, self.prime_pow.get_context_capdiv(rprec).x)
2707
+ return ans
2708
+
2709
+ def expansion(self, n=None, lift_mode='simple'):
2710
+ """
2711
+ Return a list giving a series representation of ``self``.
2712
+
2713
+ - If ``lift_mode == 'simple'`` or ``'smallest'``, the returned
2714
+ list will consist of integers (in the Eisenstein case) or a
2715
+ list of lists of integers (in the unramified case). ``self``
2716
+ can be reconstructed as a sum of elements of the list times
2717
+ powers of the uniformiser (in the Eisenstein case), or as a
2718
+ sum of powers of the `p` times polynomials in the generator
2719
+ (in the unramified case).
2720
+
2721
+ + If ``lift_mode == 'simple'``, all integers will be in the interval
2722
+ `[0,p-1]`.
2723
+
2724
+ + If ``lift_mode == 'smallest'`` they will be in the
2725
+ interval `[(1-p)/2, p/2]`.
2726
+
2727
+ - If ``lift_mode == 'teichmuller'``, returns a list of
2728
+ ``pAdicZZpXCRElements``, all of which are Teichmuller
2729
+ representatives and such that ``self`` is the sum of that list
2730
+ times powers of the uniformizer.
2731
+
2732
+ Note that zeros are truncated from the returned list if
2733
+ ``self.parent()`` is a field, so you must use the
2734
+ ``valuation`` function to fully reconstruct ``self``.
2735
+
2736
+ INPUT:
2737
+
2738
+ - ``n`` -- integer (default: ``None``); if given, returns the
2739
+ corresponding entry in the expansion
2740
+
2741
+ EXAMPLES::
2742
+
2743
+ sage: R = Zp(5,5)
2744
+ sage: S.<x> = R[]
2745
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2746
+ sage: W.<w> = R.ext(f)
2747
+ sage: y = W(775, 19); y
2748
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
2749
+ sage: (y>>9).expansion()
2750
+ [0, 1, 0, 4, 0, 2, 1, 2, 4, 1]
2751
+ sage: (y>>9).expansion(lift_mode='smallest')
2752
+ [0, 1, 0, -1, 0, 2, 1, 2, 0, 1]
2753
+ sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
2754
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
2755
+ sage: g = x^3 + 3*x + 3
2756
+ sage: A.<a> = R.ext(g)
2757
+ sage: y = 75 + 45*a + 1200*a^2; y
2758
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
2759
+ sage: E = y.expansion(); E
2760
+ 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)
2761
+ sage: list(E)
2762
+ [[], [0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1], []]
2763
+ sage: list(y.expansion(lift_mode='smallest'))
2764
+ [[], [0, -1], [-2, 2, -2], [1], [0, 0, 2], []]
2765
+ sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
2766
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
2767
+ sage: list(W(0).expansion())
2768
+ []
2769
+ sage: list(W(0,4).expansion())
2770
+ []
2771
+ sage: list(A(0,4).expansion())
2772
+ []
2773
+
2774
+ TESTS:
2775
+
2776
+ We check that :issue:`24949` is fixed::
2777
+
2778
+ sage: R = Zp(2)
2779
+ sage: S.<x> = R[]
2780
+ sage: A.<a> = R.extension(x^10 + 2)
2781
+ sage: u = a^4 + a^5
2782
+ sage: v = a^2 + a^3
2783
+ sage: w = u - v^2
2784
+ sage: w.expansion(4)
2785
+ 0
2786
+ """
2787
+ self._normalize()
2788
+ if lift_mode == 'teichmuller':
2789
+ zero = self.parent()(0)
2790
+ elif self.prime_pow.e == 1:
2791
+ zero = []
2792
+ else:
2793
+ zero = Integer(0)
2794
+ if isinstance(n, slice):
2795
+ return self.slice(n.start, n.stop, n.step)
2796
+ elif n is not None:
2797
+ if self._is_exact_zero() or n < self.ordp:
2798
+ return zero
2799
+ elif n >= self.ordp + self.relprec:
2800
+ raise PrecisionError
2801
+ if self.relprec == 0: # cannot have n = None
2802
+ return []
2803
+ if lift_mode == 'simple':
2804
+ ulist = self.ext_p_list(pos=True)
2805
+ elif lift_mode == 'smallest':
2806
+ ulist = self.ext_p_list(pos=False)
2807
+ elif lift_mode == 'teichmuller':
2808
+ if n is None:
2809
+ ulist = self.teichmuller_expansion()
2810
+ else:
2811
+ return self.teichmuller_expansion(n)
2812
+ else:
2813
+ raise ValueError("lift mode must be one of 'simple', 'smallest' or 'teichmuller'")
2814
+ if n is not None:
2815
+ try:
2816
+ return ulist[n - self.ordp]
2817
+ except IndexError:
2818
+ return zero
2819
+ if self.prime_pow.in_field == 0 and self.ordp > 0:
2820
+ ulist = [zero] * self.ordp + ulist
2821
+ return ulist
2822
+
2823
+ def matrix_mod_pn(self):
2824
+ r"""
2825
+ Return the matrix of right multiplication by the element on
2826
+ the power basis `1, x, x^2, \ldots, x^{d-1}` for this
2827
+ extension field. Thus the *rows* of this matrix give the
2828
+ images of each of the `x^i`. The entries of the matrices are
2829
+ :class:`IntegerMod` elements, defined modulo `p^{N / e}` where `N` is
2830
+ the absolute precision of this element (unless this element is
2831
+ zero to arbitrary precision; in that case the entries are
2832
+ integer zeros.)
2833
+
2834
+ Raises an error if this element has negative valuation.
2835
+
2836
+ EXAMPLES::
2837
+
2838
+ sage: R = ZpCR(5,5)
2839
+ sage: S.<x> = R[]
2840
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2841
+ sage: W.<w> = R.ext(f)
2842
+ sage: a = (3+w)^7
2843
+ sage: a.matrix_mod_pn()
2844
+ [2757 333 1068 725 2510]
2845
+ [ 50 1507 483 318 725]
2846
+ [ 500 50 3007 2358 318]
2847
+ [1590 1375 1695 1032 2358]
2848
+ [2415 590 2370 2970 1032]
2849
+
2850
+ TESTS:
2851
+
2852
+ Check that :issue:`13617` has been fixed::
2853
+
2854
+ sage: W.zero().matrix_mod_pn()
2855
+ [0 0 0 0 0]
2856
+ [0 0 0 0 0]
2857
+ [0 0 0 0 0]
2858
+ [0 0 0 0 0]
2859
+ [0 0 0 0 0]
2860
+ """
2861
+ if self.valuation_c() < 0:
2862
+ raise ValueError("self must be integral")
2863
+ n = self.prime_pow.deg
2864
+ from sage.matrix.constructor import matrix
2865
+ if self._is_exact_zero():
2866
+ from sage.rings.integer_ring import IntegerRing
2867
+ return matrix(IntegerRing(), n, n)
2868
+ R = IntegerModRing(self.prime_pow.pow_Integer(self.prime_pow.capdiv(self.ordp + self.relprec)))
2869
+ L = []
2870
+ cdef ntl_ZZ_pX cur = <ntl_ZZ_pX>self._ntl_rep_abs()[0]
2871
+ cur.c.restore_c()
2872
+ cdef ZZ_pX_Modulus_c* m = self.prime_pow.get_modulus_capdiv(self.ordp + self.relprec)
2873
+ cdef ZZ_pX_c x
2874
+ ZZ_pX_SetX(x)
2875
+ cdef Py_ssize_t i
2876
+ zero = int(0)
2877
+ for i in range(n):
2878
+ curlist = cur.list()
2879
+ L.extend(curlist + [zero] * (n - len(curlist)))
2880
+ ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0])
2881
+ return matrix(R, n, n, L)
2882
+
2883
+ # def matrix(self, base=None):
2884
+ # """
2885
+ # If base is None, return the matrix of right multiplication by
2886
+ # the element on the power basis `1, x, x^2, \ldots, x^{d-1}`
2887
+ # for this extension field. Thus the \emph{rows} of this matrix
2888
+ # give the images of each of the `x^i`.
2889
+
2890
+ # If base is not None, then base must be either a field that
2891
+ # embeds in the parent of self or a morphism to the parent of
2892
+ # self, in which case this function returns the matrix of
2893
+ # multiplication by self on the power basis, where we view the
2894
+ # parent field as a field over base.
2895
+
2896
+ # INPUT:
2897
+ # base -- field or morphism
2898
+ # """
2899
+ # raise NotImplementedError
2900
+
2901
+ # def multiplicative_order(self, prec=None):
2902
+ # """
2903
+ # Return the multiplicative order of ``self``, ie the smallest
2904
+ # positive `n` so that there is an exact `p`-adic element congruent
2905
+ # to ``self`` modulo ``self``'s precision that is an `n`-th root of unity.
2906
+
2907
+ # Note: unlike the case for Qp and Zp, it is possible to have
2908
+ # non-teichmuller elements with finite orders. This can happen
2909
+ # only if (p-1) divides the ramification index (see the
2910
+ # documentation on __pow__).
2911
+
2912
+ # INPUT:
2913
+
2914
+ # - self -- a `p`-adic element
2915
+ # - ``prec`` -- integer
2916
+
2917
+ # OUTPUT: integer; the multiplicative order of ``self``
2918
+ # """
2919
+ # raise NotImplementedError
2920
+
2921
+ def teichmuller_expansion(self, n=None):
2922
+ r"""
2923
+ Return a list [`a_0`, `a_1`,..., `a_n`] such that:
2924
+
2925
+ - `a_i^q = a_i`
2926
+ - ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a
2927
+ uniformizer of ``self.parent()``
2928
+ - if `a_i \ne 0`, the absolute precision of `a_i` is
2929
+ ``self.precision_relative() - i``
2930
+
2931
+ INPUT:
2932
+
2933
+ - ``n`` -- integer (default: ``None``); if given, returns the
2934
+ corresponding entry in the expansion
2935
+
2936
+ EXAMPLES::
2937
+
2938
+ sage: R.<a> = ZqCR(5^4,4)
2939
+ sage: E = a.teichmuller_expansion(); E
2940
+ 5-adic expansion of a + O(5^4) (teichmuller)
2941
+ sage: list(E)
2942
+ [a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2
2943
+ + (4*a^2 + 2*a + 2)*5^3 + O(5^4),
2944
+ (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),
2945
+ (4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2),
2946
+ (a^3 + a^2 + a + 4) + O(5)]
2947
+ sage: sum([c * 5^i for i, c in enumerate(E)])
2948
+ a + O(5^4)
2949
+ sage: all(c^625 == c for c in E)
2950
+ True
2951
+
2952
+ sage: S.<x> = ZZ[]
2953
+ sage: f = x^3 - 98*x + 7
2954
+ sage: W.<w> = ZpCR(7,3).ext(f)
2955
+ sage: b = (1+w)^5; L = b.teichmuller_expansion(); L
2956
+ [1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7),
2957
+ 3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3),
2958
+ 6 + O(w^2), 6 + O(w)]
2959
+ sage: sum([w^i*L[i] for i in range(9)]) == b
2960
+ True
2961
+ sage: all(L[i]^(7^3) == L[i] for i in range(9))
2962
+ True
2963
+
2964
+ sage: L = W(3).teichmuller_expansion(); L
2965
+ [3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6),
2966
+ O(w^5), O(w^4), 3 + O(w^3), 6 + O(w^2)]
2967
+ sage: sum([w^i*L[i] for i in range(len(L))])
2968
+ 3 + O(w^9)
2969
+ """
2970
+ cdef long rp = self.relprec
2971
+ cdef pAdicZZpXCRElement v
2972
+ if n is None:
2973
+ L = []
2974
+ if rp == 0:
2975
+ return L
2976
+ elif self._is_exact_zero() or n < self.ordp:
2977
+ return self.parent()(0)
2978
+ elif n >= self.ordp + rp:
2979
+ raise PrecisionError
2980
+ else:
2981
+ v = self._new_c(rp)
2982
+ cdef pAdicZZpXCRElement u = self.unit_part()
2983
+ cdef long goal
2984
+ if n is not None:
2985
+ goal = rp - n + self.ordp
2986
+ while u.relprec > 0:
2987
+ v = self._new_c(rp)
2988
+ self.prime_pow.teichmuller_set_c(&v.unit, &u.unit, rp)
2989
+ v.ordp = 0
2990
+ if n is None:
2991
+ L.append(v)
2992
+ elif rp == goal:
2993
+ return v
2994
+ if rp == 1:
2995
+ break
2996
+ ZZ_pX_sub(u.unit, u.unit, v.unit)
2997
+ u.relprec = -u.relprec
2998
+ u._normalize()
2999
+ if u.relprec == 0:
3000
+ break
3001
+ rp -= 1
3002
+ u.ordp -= 1
3003
+ while u.ordp > 0:
3004
+ if n is None:
3005
+ v = self._new_c(0)
3006
+ v._set_inexact_zero(rp)
3007
+ L.append(v)
3008
+ elif rp == goal:
3009
+ v = self._new_c(0)
3010
+ v._set_inexact_zero(rp)
3011
+ return v
3012
+ rp -= 1
3013
+ u.ordp -= 1
3014
+ if n is None:
3015
+ return L
3016
+ else:
3017
+ v = self._new_c(0)
3018
+ v._set_inexact_zero(rp)
3019
+ return v
3020
+
3021
+ def _teichmuller_set_unsafe(self):
3022
+ """
3023
+ Set this element to the Teichmuller representative with the
3024
+ same residue.
3025
+
3026
+ .. WARNING::
3027
+
3028
+ This function modifies the element, which is not safe.
3029
+ Elements are supposed to be immutable.
3030
+
3031
+ EXAMPLES::
3032
+
3033
+ sage: R = Zp(7,5)
3034
+ sage: S.<x> = R[]
3035
+ sage: f = x^5 + 77*x^3 - 98*x^2 - 7
3036
+ sage: W.<w> = R.ext(f)
3037
+ sage: y = W.teichmuller(3, 15); y # indirect doctest
3038
+ 3 + 4*w^5 + 2*w^8 + 6*w^10 + w^11 + 6*w^12 + 5*w^13 + 4*w^14 + O(w^15)
3039
+
3040
+ sage: y^7 == y
3041
+ True
3042
+ sage: g = x^3 + 3*x^2 + 4
3043
+ sage: A.<a> = R.ext(g)
3044
+ sage: b = A.teichmuller(1 + 2*a - a^2); b
3045
+ (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)
3046
+ sage: b^343 == b
3047
+ True
3048
+
3049
+ TESTS:
3050
+
3051
+ We check that :issue:`8239` is resolved::
3052
+
3053
+ sage: K.<a> = Qq(25)
3054
+ sage: K.teichmuller(K(2/5))
3055
+ Traceback (most recent call last):
3056
+ ...
3057
+ ValueError: cannot set negative valuation element to Teichmuller representative
3058
+ """
3059
+ self._normalize()
3060
+ if self.ordp > 0:
3061
+ self._set_exact_zero()
3062
+ elif self.ordp < 0:
3063
+ raise ValueError("cannot set negative valuation element to Teichmuller representative")
3064
+ elif self.relprec == 0:
3065
+ raise ValueError("not enough precision known")
3066
+ else:
3067
+ self.prime_pow.teichmuller_set_c(&self.unit, &self.unit, self.relprec)
3068
+
3069
+ # def padded_list(self, n, lift_mode='simple'):
3070
+ # """
3071
+ # Return a list of coefficients of pi starting with `pi^0` up to
3072
+ # `pi^n` exclusive (padded with zeros if needed)
3073
+
3074
+ # """
3075
+ # raise NotImplementedError
3076
+
3077
+ def precision_absolute(self):
3078
+ """
3079
+ Return the absolute precision of this element, i.e., the power of the
3080
+ uniformizer modulo which this element is defined.
3081
+
3082
+ EXAMPLES::
3083
+
3084
+ sage: R = Zp(5,5)
3085
+ sage: S.<x> = R[]
3086
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3087
+ sage: W.<w> = R.ext(f)
3088
+ sage: a = W(75, 19); a
3089
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3090
+ sage: a.valuation()
3091
+ 10
3092
+ sage: a.precision_absolute()
3093
+ 19
3094
+ sage: a.precision_relative()
3095
+ 9
3096
+ sage: a.unit_part()
3097
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3098
+ sage: (a.unit_part() - 3).precision_absolute()
3099
+ 9
3100
+ """
3101
+ cdef Integer ans
3102
+ if self.ordp == maxordp:
3103
+ return infinity
3104
+ else:
3105
+ ans = PY_NEW(Integer)
3106
+ if self.relprec > 0:
3107
+ mpz_set_si(ans.value, self.relprec + self.ordp)
3108
+ else:
3109
+ mpz_set_si(ans.value, -self.relprec + self.ordp)
3110
+ return ans
3111
+
3112
+ def precision_relative(self):
3113
+ """
3114
+ Return the relative precision of this element, i.e., the power of the
3115
+ uniformizer modulo which the unit part of ``self`` is defined.
3116
+
3117
+ EXAMPLES::
3118
+
3119
+ sage: R = Zp(5,5)
3120
+ sage: S.<x> = R[]
3121
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3122
+ sage: W.<w> = R.ext(f)
3123
+ sage: a = W(75, 19); a
3124
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3125
+ sage: a.valuation()
3126
+ 10
3127
+ sage: a.precision_absolute()
3128
+ 19
3129
+ sage: a.precision_relative()
3130
+ 9
3131
+ sage: a.unit_part()
3132
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3133
+ """
3134
+ self._normalize()
3135
+ cdef Integer ans = PY_NEW(Integer)
3136
+ mpz_set_ui(ans.value, self.relprec)
3137
+ return ans
3138
+
3139
+ # def residue(self, n=1):
3140
+ # """
3141
+ # Reduces this element modulo pi^n.
3142
+ # """
3143
+ # raise NotImplementedError
3144
+
3145
+ cdef long valuation_c(self) noexcept:
3146
+ """
3147
+ Return the valuation of this element.
3148
+
3149
+ EXAMPLES::
3150
+
3151
+ sage: R = Zp(5,5)
3152
+ sage: S.<x> = R[]
3153
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3154
+ sage: W.<w> = R.ext(f)
3155
+ sage: a = W(75, 19); a
3156
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3157
+ sage: a.valuation() # indirect doctest
3158
+ 10
3159
+ sage: a.precision_absolute()
3160
+ 19
3161
+ sage: a.precision_relative()
3162
+ 9
3163
+ sage: a.unit_part()
3164
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3165
+ """
3166
+ self._normalize()
3167
+ return self.ordp
3168
+
3169
+ cpdef pAdicZZpXCRElement unit_part(self):
3170
+ """
3171
+ Return the unit part of this element, ie ``self / uniformizer^(self.valuation())``.
3172
+
3173
+ EXAMPLES::
3174
+
3175
+ sage: R = Zp(5,5)
3176
+ sage: S.<x> = R[]
3177
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3178
+ sage: W.<w> = R.ext(f)
3179
+ sage: a = W(75, 19); a
3180
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
3181
+ sage: a.valuation()
3182
+ 10
3183
+ sage: a.precision_absolute()
3184
+ 19
3185
+ sage: a.precision_relative()
3186
+ 9
3187
+ sage: a.unit_part()
3188
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
3189
+
3190
+ TESTS:
3191
+
3192
+ We check that :issue:`13616` is resolved::
3193
+
3194
+ sage: z = (1+w)^5
3195
+ sage: y = z - 1
3196
+ sage: t = y - y
3197
+ sage: t.unit_part()
3198
+ O(w^0)
3199
+ """
3200
+ self._normalize()
3201
+ cdef pAdicZZpXCRElement ans = self._new_c(self.relprec)
3202
+ ans.ordp = 0
3203
+ if self.relprec != 0:
3204
+ ans.unit = self.unit
3205
+ return ans
3206
+
3207
+ cdef ext_p_list(self, bint pos):
3208
+ """
3209
+ Return a list of integers (in the Eisenstein case) or a list
3210
+ of lists of integers (in the unramified case). ``self`` can be
3211
+ reconstructed as a sum of elements of the list times powers of
3212
+ the uniformiser (in the Eisenstein case), or as a sum of
3213
+ powers of `p` times polynomials in the generator (in the
3214
+ unramified case).
3215
+
3216
+ If ``pos`` is ``True``, all integers will be in the interval `[0,p-1]`,
3217
+ otherwise they will be in the interval `[(1-p)/2, p/2]`.
3218
+
3219
+ Note that zeros are truncated from the returned list, so you
3220
+ must use the method :meth:`valuation` to completely recover ``self``.
3221
+
3222
+ EXAMPLES::
3223
+
3224
+ sage: R = Zp(5,5)
3225
+ sage: S.<x> = R[]
3226
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3227
+ sage: W.<w> = R.ext(f)
3228
+ sage: y = W(775, 19); y
3229
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3230
+ sage: y._ext_p_list(True)
3231
+ [1, 0, 4, 0, 2, 1, 2, 4, 1]
3232
+ sage: y._ext_p_list(False)
3233
+ [1, 0, -1, 0, 2, 1, 2, 0, 1]
3234
+ sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
3235
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3236
+ sage: g = x^3 + 3*x + 3
3237
+ sage: A.<a> = R.ext(g)
3238
+ sage: y = 75 + 45*a + 1200*a^2; y
3239
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
3240
+ sage: y._ext_p_list(True)
3241
+ [[0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]]
3242
+ sage: y._ext_p_list(False)
3243
+ [[0, -1], [-2, 2, -2], [1], [0, 0, 2]]
3244
+ sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
3245
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^6)
3246
+ """
3247
+ self._normalize()
3248
+ return self.ext_p_list_precs(pos, self.relprec)
3249
+
3250
+
3251
+ def make_ZZpXCRElement(parent, unit, ordp, relprec, version):
3252
+ """
3253
+ Unpickling.
3254
+
3255
+ EXAMPLES::
3256
+
3257
+ sage: R = Zp(5,5)
3258
+ sage: S.<x> = R[]
3259
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
3260
+ sage: W.<w> = R.ext(f)
3261
+ sage: y = W(775, 19); y
3262
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3263
+ sage: loads(dumps(y)) # indirect doctest
3264
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
3265
+
3266
+ sage: from sage.rings.padics.padic_ZZ_pX_CR_element import make_ZZpXCRElement
3267
+ sage: make_ZZpXCRElement(W, y._ntl_rep(), 3, 9, 0)
3268
+ w^3 + 4*w^5 + 2*w^7 + w^8 + 2*w^9 + 4*w^10 + w^11 + O(w^12)
3269
+ """
3270
+ cdef pAdicZZpXCRElement ans
3271
+ cdef ZZ_pX_c poly
3272
+ if version == 0:
3273
+ ans = pAdicZZpXCRElement(parent, [], empty = True)
3274
+ if relprec == 0:
3275
+ ans._set_inexact_zero(mpz_get_si((<Integer>ordp).value))
3276
+ else:
3277
+ ans.prime_pow.restore_context_capdiv(mpz_get_si((<Integer>relprec).value))
3278
+ poly = (<ntl_ZZ_pX>unit).x
3279
+ ans._set(&poly, mpz_get_si((<Integer>ordp).value), mpz_get_si((<Integer>relprec).value))
3280
+ return ans
3281
+ else:
3282
+ raise ValueError("unknown unpickling version")