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,2366 @@
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`` CA Element
11
+
12
+ This file implements elements of Eisenstein and unramified extensions
13
+ of ``Zp`` with capped absolute precision.
14
+
15
+ For the parent class see padic_extension_leaves.pyx.
16
+
17
+ The underlying implementation is through NTL's ``ZZ_pX`` class. Each
18
+ element contains the following data:
19
+
20
+ - ``absprec`` -- long; an integer giving the precision to which this
21
+ element is defined. This is the power of the uniformizer modulo
22
+ which the element is well defined.
23
+
24
+ - ``value`` -- ``ZZ_pX_c``; an ntl ``ZZ_pX`` storing the value. The
25
+ variable `x` is the uniformizer in the case of Eisenstein extensions
26
+ This ZZ_pX is created with global ntl modulus determined by absprec.
27
+ Let `a` be absprec and `e` be the ramification index over
28
+ `\QQ_p` or `\ZZ_p`. Then the modulus is given by
29
+ `p^{ceil(a/e)}`. Note that all kinds of problems arise if you try
30
+ to mix moduli. ``ZZ_pX_conv_modulus`` gives a semi-safe way to
31
+ convert between different moduli without having to pass through ZZX.
32
+
33
+ - ``prime_pow`` -- (some subclass of ``PowComputer_ZZ_pX``) a class,
34
+ identical among all elements with the same parent, holding common
35
+ data.
36
+
37
+ + ``prime_pow.deg`` -- the degree of the extension
38
+
39
+ + ``prime_pow.e`` -- the ramification index
40
+
41
+ + ``prime_pow.f`` -- the inertia degree
42
+
43
+ + ``prime_pow.prec_cap`` -- the unramified precision cap. For
44
+ Eisenstein extensions this is the smallest power of p that is
45
+ zero.
46
+
47
+ + ``prime_pow.ram_prec_cap`` -- the ramified precision cap. For
48
+ Eisenstein extensions this will be the smallest power of `x` that
49
+ is indistinguishable from zero.
50
+
51
+ + ``prime_pow.pow_ZZ_tmp``, prime_pow.pow_mpz_t_tmp``,
52
+ ``prime_pow.pow_Integer`` -- functions for accessing powers of
53
+ `p`. The first two return pointers. See
54
+ ``sage/rings/padics/pow_computer_ext`` for examples and important
55
+ warnings.
56
+
57
+ + ``prime_pow.get_context``, ``prime_pow.get_context_capdiv``,
58
+ ``prime_pow.get_top_context`` -- obtain an
59
+ ``ntl_ZZ_pContext_class`` corresponding to `p^n`. The capdiv
60
+ version divides by ``prime_pow.e`` as appropriate.
61
+ ``top_context`` corresponds to `p^{\texttt{prec\_cap}}`.
62
+
63
+ + ``prime_pow.restore_context``,
64
+ ``prime_pow.restore_context_capdiv``,
65
+ ``prime_pow.restore_top_context`` -- restores the given context.
66
+
67
+ + ``prime_pow.get_modulus``, ``get_modulus_capdiv``,
68
+ ``get_top_modulus`` -- returns a ``ZZ_pX_Modulus_c*`` pointing to
69
+ a polynomial modulus defined modulo `p^n` (appropriately divided
70
+ by ``prime_pow.e`` in the capdiv case).
71
+
72
+ EXAMPLES:
73
+
74
+ An Eisenstein extension::
75
+
76
+ sage: R = ZpCA(5,5)
77
+ sage: S.<x> = ZZ[]
78
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
79
+ sage: W.<w> = R.ext(f); W
80
+ 5-adic Eisenstein Extension Ring in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
81
+ sage: z = (1+w)^5; z
82
+ 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
83
+ + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
84
+ sage: y = z >> 1; y
85
+ 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
86
+ + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
87
+ sage: y.valuation()
88
+ 4
89
+ sage: y.precision_relative()
90
+ 20
91
+ sage: y.precision_absolute()
92
+ 24
93
+ sage: z - (y << 1)
94
+ 1 + O(w^25)
95
+ sage: (1/w)^12+w
96
+ w^-12 + w + O(w^12)
97
+ sage: (1/w).parent()
98
+ 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
99
+
100
+ An unramified extension::
101
+
102
+ sage: # needs sage.libs.flint
103
+ sage: g = x^3 + 3*x + 3
104
+ sage: A.<a> = R.ext(g)
105
+ sage: z = (1+a)^5; z
106
+ (2*a^2 + 4*a) + (3*a^2 + 3*a + 1)*5 + (4*a^2 + 3*a + 4)*5^2
107
+ + (4*a^2 + 4*a + 4)*5^3 + (4*a^2 + 4*a + 4)*5^4 + O(5^5)
108
+ sage: z - 1 - 5*a - 10*a^2 - 10*a^3 - 5*a^4 - a^5
109
+ O(5^5)
110
+ sage: y = z >> 1; y
111
+ (3*a^2 + 3*a + 1) + (4*a^2 + 3*a + 4)*5 + (4*a^2 + 4*a + 4)*5^2
112
+ + (4*a^2 + 4*a + 4)*5^3 + O(5^4)
113
+ sage: 1/a
114
+ (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)
115
+ sage: FFA = A.residue_field()
116
+ sage: a0 = FFA.gen(); A(a0^3)
117
+ (2*a + 2) + O(5)
118
+
119
+ Different printing modes::
120
+
121
+ sage: # needs sage.libs.flint
122
+ sage: R = ZpCA(5, print_mode='digits'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
123
+ sage: z = (1+w)^5; repr(z)
124
+ '...4110403113210310442221311242000111011201102002023303214332011214403232013144001400444441030421100001'
125
+ sage: R = ZpCA(5, print_mode='bars'); S.<x> = ZZ[]; g = x^3 + 3*x + 3; A.<a> = R.ext(g)
126
+ sage: z = (1+a)^5; repr(z)
127
+ '...[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]'
128
+ sage: R = ZpCA(5, print_mode='terse'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
129
+ sage: z = (1+w)^5; z
130
+ 6 + 95367431640505*w + 25*w^2 + 95367431640560*w^3 + 5*w^4 + O(w^100)
131
+ sage: R = ZpCA(5, print_mode='val-unit'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
132
+ sage: y = (1+w)^5 - 1; y
133
+ w^5 * (2090041 + 19073486126901*w + 1258902*w^2 + 674*w^3 + 16785*w^4) + O(w^100)
134
+
135
+ You can get at the underlying ntl representation::
136
+
137
+ sage: # needs sage.libs.flint
138
+ sage: z._ntl_rep()
139
+ [6 95367431640505 25 95367431640560 5]
140
+ sage: y._ntl_rep()
141
+ [5 95367431640505 25 95367431640560 5]
142
+ sage: y._ntl_rep_abs()
143
+ ([5 95367431640505 25 95367431640560 5], 0)
144
+
145
+ .. NOTE::
146
+
147
+ If you get an error ``internal error: can't grow this _ntl_gbigint,``
148
+ it indicates that moduli are being mixed inappropriately somewhere.
149
+
150
+ For example, when calling a function with a ``ZZ_pX_c`` as an
151
+ argument, it copies. If the modulus is not
152
+ set to the modulus of the ``ZZ_pX_c``, you can get errors.
153
+
154
+ AUTHORS:
155
+
156
+ - David Roe (2008-01-01): initial version
157
+
158
+ - Robert Harron (2011-09): fixes/enhancements
159
+
160
+ - Julian Rueth (2012-10-15): fixed an initialization bug
161
+ """
162
+ # ****************************************************************************
163
+ # Copyright (C) 2008 David Roe <roed.math@gmail.com>
164
+ # William Stein <wstein@gmail.com>
165
+ # 2012 Julian Rueth <julian.rueth@fsfe.org>
166
+ #
167
+ # Distributed under the terms of the GNU General Public License (GPL)
168
+ # as published by the Free Software Foundation; either version 2 of
169
+ # the License, or (at your option) any later version.
170
+ #
171
+ # https://www.gnu.org/licenses/
172
+ # ****************************************************************************
173
+
174
+ from cysignals.signals cimport sig_on, sig_off
175
+ from sage.ext.stdsage cimport PY_NEW
176
+ include "sage/libs/ntl/decl.pxi"
177
+
178
+ from sage.rings.integer cimport Integer
179
+ from sage.rings.rational cimport Rational
180
+ from sage.libs.gmp.mpz cimport *
181
+ from sage.libs.gmp.mpq cimport *
182
+ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
183
+ from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
184
+ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p
185
+ from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
186
+ from sage.rings.padics.padic_generic_element cimport pAdicGenericElement
187
+ from cypari2.gen import Gen as pari_gen
188
+ from sage.interfaces.abc import GpElement
189
+ from sage.rings.finite_rings.integer_mod import IntegerMod_abstract
190
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
191
+ from sage.rings.padics.padic_ext_element cimport pAdicExtElement
192
+ from sage.rings.padics.precision_error import PrecisionError
193
+
194
+ cdef object infinity
195
+ from sage.rings.infinity import infinity
196
+
197
+ cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) -1
198
+
199
+ cdef class pAdicZZpXCAElement(pAdicZZpXElement):
200
+ def __init__(self, parent, x, absprec=infinity, relprec=infinity, empty=False):
201
+ """
202
+ Create an element of a capped absolute precision, unramified or
203
+ Eisenstein extension of Zp or Qp.
204
+
205
+ INPUT:
206
+
207
+ - ``parent`` -- either an ``EisensteinRingCappedAbsolute`` or
208
+ ``UnramifiedRingCappedAbsolute``
209
+
210
+ - ``x`` -- integer, rational, `p`-adic element, polynomial,
211
+ list, integer_mod, pari int/frac/poly_t/pol_mod, an
212
+ ``ntl_ZZ_pX``, an ``ntl_ZZ``, an ``ntl_ZZ_p``, an
213
+ ``ntl_ZZX``, or something convertible into parent.residue_field()
214
+
215
+ - ``absprec`` -- an upper bound on the absolute precision of
216
+ the element created
217
+
218
+ - ``relprec`` -- an upper bound on the relative precision of
219
+ the element created
220
+
221
+ - ``empty`` -- whether to return after initializing to zero
222
+
223
+ EXAMPLES::
224
+
225
+ sage: R = ZpCA(5,5)
226
+ sage: S.<x> = ZZ[]
227
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
228
+ sage: W.<w> = R.ext(f)
229
+ sage: z = (1+w)^5; z # indirect doctest
230
+ 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
231
+ + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
232
+ sage: W(R(3,3))
233
+ 3 + O(w^15)
234
+ sage: W(pari('3 + O(5^3)'))
235
+ 3 + O(w^15)
236
+ sage: W(w, 14)
237
+ w + O(w^14)
238
+
239
+ TESTS:
240
+
241
+ Check that :issue:`13600` is fixed::
242
+
243
+ sage: K = W.fraction_field()
244
+ sage: W(K.zero())
245
+ O(w^25)
246
+ sage: W(K.one())
247
+ 1 + O(w^25)
248
+ sage: W(K.zero().add_bigoh(3))
249
+ O(w^3)
250
+
251
+ Check that :issue:`3865` is fixed:
252
+
253
+ sage: W(gp('5 + O(5^2)'))
254
+ w^5 + 2*w^7 + 4*w^9 + O(w^10)
255
+
256
+ Check that :issue:`13612` has been fixed::
257
+
258
+ sage: # needs sage.libs.flint
259
+ sage: R = ZpCA(3)
260
+ sage: S.<a> = R[]
261
+ sage: W.<a> = R.extension(a^2 + 1)
262
+ sage: W(W.residue_field().zero())
263
+ O(3)
264
+ """
265
+ pAdicZZpXElement.__init__(self, parent)
266
+ cdef long aprec, rprec, ctx_prec
267
+ if empty:
268
+ self.absprec = 0
269
+ return
270
+ self.absprec = -1 # to signal that self is uninitialized
271
+ if absprec is infinity:
272
+ aprec = self.prime_pow.ram_prec_cap
273
+ else:
274
+ if not isinstance(absprec, Integer):
275
+ absprec = Integer(absprec)
276
+ if mpz_sgn((<Integer>absprec).value) < 0:
277
+ aprec = 0
278
+ elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
279
+ aprec = self.prime_pow.ram_prec_cap
280
+ else:
281
+ aprec = mpz_get_si((<Integer>absprec).value)
282
+ if aprec > self.prime_pow.ram_prec_cap:
283
+ aprec = self.prime_pow.ram_prec_cap
284
+ if relprec is infinity:
285
+ # This might not be the right default
286
+ rprec = self.prime_pow.ram_prec_cap
287
+ else:
288
+ if not isinstance(relprec, Integer):
289
+ rprec = Integer(relprec)
290
+ if mpz_cmp_ui((<Integer>relprec).value, aprec) >= 0:
291
+ rprec = self.prime_pow.ram_prec_cap
292
+ elif relprec < 0:
293
+ rprec = 0
294
+ else:
295
+ rprec = mpz_get_si((<Integer>relprec).value)
296
+ cdef mpz_t tmp
297
+ cdef ZZ_c tmp_z
298
+ cdef Py_ssize_t i
299
+ cdef Integer tmp_Int
300
+ cdef Integer xlift
301
+ if isinstance(x, pAdicGenericElement):
302
+ if x.valuation() < 0:
303
+ raise ValueError("element has negative valuation")
304
+ if x._is_base_elt(self.prime_pow.prime):
305
+ xlift = <Integer>x.lift()
306
+ if mpz_sgn(xlift.value) == 0:
307
+ if (<pAdicGenericElement>x)._is_exact_zero():
308
+ self._set_inexact_zero(aprec)
309
+ return
310
+ ltmp = mpz_get_si((<Integer>x.precision_absolute()).value) * self.prime_pow.e
311
+ if ltmp < aprec:
312
+ aprec = ltmp
313
+ if relprec is infinity:
314
+ self._set_from_mpz_abs(xlift.value, aprec)
315
+ else:
316
+ self._set_from_mpz_both(xlift.value, aprec, rprec)
317
+ return
318
+ if parent.prime() != x.parent().prime():
319
+ raise TypeError("cannot coerce between p-adic parents with different primes")
320
+ if isinstance(x, pari_gen) or isinstance(x, GpElement):
321
+ if isinstance(x, GpElement):
322
+ x = x.__pari__()
323
+ if x.type() == "t_PADIC":
324
+ if x.variable() != self.prime_pow.prime:
325
+ raise TypeError("cannot coerce a pari p-adic with the wrong prime")
326
+ ltmp = x.padicprec(self.prime_pow.prime) * self.prime_pow.e
327
+ if ltmp < aprec:
328
+ aprec = ltmp
329
+ x = x.lift()
330
+ if x.type() == 't_INT':
331
+ x = Integer(x)
332
+ elif x.type() == 't_FRAC':
333
+ x = Rational(x)
334
+ elif x.type() == 't_POLMOD' or x.type == 't_POL':
335
+ # This code doesn't check to see if the primes are the same.
336
+ x = x.lift().lift()
337
+ L = [Integer(x.polcoef(i)) for i in range(x.poldegree() + 1)]
338
+ x = L
339
+ else:
340
+ raise TypeError("unsupported coercion from pari: only p-adics, integers, rationals, polynomials and pol_mods allowed")
341
+ elif isinstance(x, IntegerMod_abstract):
342
+ mpz_init(tmp)
343
+ ctx_prec = mpz_remove(tmp, (<Integer>x.modulus()).value, self.prime_pow.prime.value)
344
+ if mpz_cmp_ui(tmp, 1) == 0:
345
+ mpz_clear(tmp)
346
+ x = x.lift()
347
+ if ctx_prec < aprec:
348
+ aprec = ctx_prec
349
+ else:
350
+ mpz_clear(tmp)
351
+ raise TypeError("cannot coerce from the given integer mod ring (not a power of the same prime)")
352
+ elif isinstance(x, ntl_ZZ_p):
353
+ ctx_prec = ZZ_remove(tmp_z, (<ntl_ZZ>x.modulus()).x, self.prime_pow.pow_ZZ_tmp(1)[0])
354
+ if ZZ_IsOne(tmp_z):
355
+ x = x.lift()
356
+ tmp_Int = PY_NEW(Integer)
357
+ ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
358
+ x = tmp_Int
359
+ if ctx_prec < aprec:
360
+ aprec = ctx_prec
361
+ else:
362
+ raise TypeError("cannot coerce the given ntl_ZZ_p (modulus not a power of the same prime)")
363
+ elif isinstance(x, ntl_ZZ):
364
+ tmp_Int = PY_NEW(Integer)
365
+ ZZ_to_mpz(tmp_Int.value, &(<ntl_ZZ>x).x)
366
+ x = tmp_Int
367
+ elif isinstance(x, int):
368
+ x = Integer(x)
369
+ elif x in parent.residue_field() and x.parent().is_finite():
370
+ # Should only reach here if x is not in F_p
371
+ z = parent.gen()
372
+ poly = x.polynomial().list()
373
+ x = sum([poly[i].lift() * (z ** i) for i in range(len(poly))], parent.zero())
374
+ if 1 < aprec:
375
+ aprec = 1
376
+ cdef pAdicZZpXCAElement _x
377
+ cdef pAdicZZpXCRElement __x
378
+ if isinstance(x, Integer):
379
+ if relprec is infinity:
380
+ self._set_from_mpz_abs((<Integer>x).value, aprec)
381
+ else:
382
+ self._set_from_mpz_both((<Integer>x).value, aprec, rprec)
383
+ elif isinstance(x, Rational):
384
+ if relprec is infinity:
385
+ self._set_from_mpq_abs((<Rational>x).value, aprec)
386
+ else:
387
+ self._set_from_mpq_both((<Rational>x).value, aprec, rprec)
388
+ elif isinstance(x, ntl_ZZ_pX):
389
+ if relprec is infinity:
390
+ self._set_from_ZZ_pX_abs(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, aprec)
391
+ else:
392
+ self._set_from_ZZ_pX_both(&(<ntl_ZZ_pX>x).x, (<ntl_ZZ_pX>x).c, aprec, rprec)
393
+ elif isinstance(x, ntl_ZZX):
394
+ if relprec is infinity:
395
+ self._set_from_ZZX_abs((<ntl_ZZX>x).x, aprec)
396
+ else:
397
+ self._set_from_ZZX_both((<ntl_ZZX>x).x, aprec, rprec)
398
+ elif isinstance(x, pAdicExtElement):
399
+ if x.parent() is parent:
400
+ _x = <pAdicZZpXCAElement>x
401
+ if _x.absprec < aprec:
402
+ aprec = _x.absprec
403
+ if rprec < self.prime_pow.ram_prec_cap:
404
+ self._set_from_ZZ_pX_both(&_x.value, None, aprec, rprec)
405
+ else:
406
+ self._set(&_x.value, aprec)
407
+ elif x.parent() is parent.fraction_field():
408
+ __x = <pAdicZZpXCRElement>x
409
+ if __x.relprec < 0:
410
+ __x._normalize()
411
+ if __x._is_exact_zero():
412
+ self._set_inexact_zero(self.prime_pow.ram_prec_cap)
413
+ elif __x.ordp < 0:
414
+ raise ValueError("x has negative valuation")
415
+ elif __x._is_inexact_zero():
416
+ if __x.ordp <= self.prime_pow.ram_prec_cap:
417
+ self._set_inexact_zero(__x.ordp)
418
+ else:
419
+ self._set_inexact_zero(self.prime_pow.ram_prec_cap)
420
+ else:
421
+ poly = __x._ntl_rep_abs()[0]
422
+ if __x.relprec < rprec:
423
+ rprec = __x.relprec
424
+ if rprec + __x.ordp < aprec:
425
+ aprec = rprec + __x.ordp
426
+ self._set(&(<ntl_ZZ_pX>poly).x, aprec)
427
+ else:
428
+ raise NotImplementedError("conversion from different p-adic extensions not yet supported")
429
+ else:
430
+ try:
431
+ x = list(x)
432
+ except TypeError:
433
+ try:
434
+ x = x.list()
435
+ except AttributeError:
436
+ raise TypeError("cannot convert x to a p-adic element")
437
+ self._set_from_list_both(x, aprec, rprec)
438
+
439
+ cdef int _set_inexact_zero(self, long absprec) except -1:
440
+ """
441
+ Set ``self`` to be zero with valuation ``absprec``.
442
+
443
+ EXAMPLES::
444
+
445
+ sage: R = ZpCA(5,5)
446
+ sage: S.<x> = ZZ[]
447
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
448
+ sage: W.<w> = R.ext(f)
449
+ sage: z = W(0,6); z # indirect doctest
450
+ O(w^6)
451
+ sage: z.valuation()
452
+ 6
453
+ sage: z.precision_absolute()
454
+ 6
455
+ sage: z.precision_relative()
456
+ 0
457
+ """
458
+ if absprec == self.absprec:
459
+ ZZ_pX_clear(self.value)
460
+ else:
461
+ self._set_prec_abs(absprec)
462
+
463
+ cpdef bint _is_inexact_zero(self) except -1:
464
+ """
465
+ Test if ``self`` is an inexact zero.
466
+
467
+ EXAMPLES::
468
+
469
+ sage: R = ZpCA(5,5)
470
+ sage: S.<x> = ZZ[]
471
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
472
+ sage: W.<w> = R.ext(f)
473
+ sage: z = W(0)
474
+ sage: z._is_inexact_zero() # indirect doctest
475
+ True
476
+ sage: z = W(0,6)
477
+ sage: z._is_inexact_zero()
478
+ True
479
+ """
480
+ return self.absprec == 0 or ZZ_pX_IsZero(self.value) or self.valuation_c() == self.absprec
481
+
482
+ cdef int _set(self, ZZ_pX_c* value, long absprec) except -1:
483
+ """
484
+ Set ``value`` and ``absprec`` directly.
485
+
486
+ EXAMPLES::
487
+
488
+ sage: R = ZpCA(5,5)
489
+ sage: S.<x> = ZZ[]
490
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
491
+ sage: W.<w> = R.ext(f)
492
+ sage: F = W.fraction_field()
493
+ sage: z = F(1+w); z # indirect doctest
494
+ 1 + w + O(w^25)
495
+ sage: W.precision_cap()
496
+ 25
497
+ sage: F.precision_cap()
498
+ 25
499
+ """
500
+ self._set_prec_abs(absprec) # restores context
501
+ if self.absprec != 0:
502
+ ZZ_pX_conv_modulus(self.value, value[0], self.prime_pow.get_context_capdiv(absprec).x)
503
+
504
+ cdef int _set_from_mpz_abs(self, mpz_t x, long absprec) except -1:
505
+ """
506
+ Set ``self`` from an ``mpz_t`` with absolute precision
507
+ bounded by ``absprec``.
508
+
509
+ EXAMPLES::
510
+
511
+ sage: R = ZpCA(5,5)
512
+ sage: S.<x> = ZZ[]
513
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
514
+ sage: W.<w> = R.ext(f)
515
+ sage: W(70, absprec = 13) # indirect doctest
516
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
517
+ sage: W(70, absprec = 4)
518
+ O(w^4)
519
+ sage: W(70, absprec = 0)
520
+ O(w^0)
521
+ """
522
+ self._set_prec_abs(absprec) # restores context
523
+ cdef mpz_t tmp_m
524
+ cdef ZZ_c tmp_z
525
+ if self.absprec != 0:
526
+ mpz_init_set(tmp_m, x)
527
+ mpz_to_ZZ(&tmp_z, tmp_m)
528
+ mpz_clear(tmp_m)
529
+ ZZ_pX_SetCoeff(self.value, 0, ZZ_to_ZZ_p(tmp_z))
530
+
531
+ cdef int _set_from_mpz_both(self, mpz_t x, long absprec, long relprec) except -1:
532
+ """
533
+ Set ``self`` from an ``mpz_t`` with relative precision
534
+ bounded by ``relprec`` and absolute precision bounded by
535
+ ``absprec``.
536
+
537
+ EXAMPLES::
538
+
539
+ sage: R = ZpCA(5,5)
540
+ sage: S.<x> = ZZ[]
541
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
542
+ sage: W.<w> = R.ext(f)
543
+ sage: W(70, relprec = 3) # indirect doctest
544
+ 4*w^5 + 3*w^7 + O(w^8)
545
+ sage: W(70, absprec = 4, relprec = 2)
546
+ O(w^4)
547
+ sage: W(70, absprec = 0, relprec = 3)
548
+ O(w^0)
549
+ """
550
+ if mpz_sgn(x) == 0:
551
+ self._set_inexact_zero(absprec)
552
+ return 0
553
+ cdef mpz_t tmp_m
554
+ cdef ZZ_c tmp_z
555
+ cdef long shift
556
+ mpz_init(tmp_m)
557
+ sig_on()
558
+ shift = mpz_remove(tmp_m, x, self.prime_pow.prime.value)
559
+ mpz_set(tmp_m, x)
560
+ sig_off()
561
+ self._set_prec_both_with_ordp(shift * self.prime_pow.e, absprec, relprec)
562
+ mpz_to_ZZ(&tmp_z, tmp_m)
563
+ mpz_clear(tmp_m)
564
+ if self.absprec != 0:
565
+ ZZ_pX_SetCoeff(self.value, 0, ZZ_to_ZZ_p(tmp_z))
566
+
567
+ cdef int _set_from_mpq_abs(self, mpq_t x, long absprec) except -1:
568
+ """
569
+ Set ``self`` from an ``mpq_t`` with absolute precision bounded by
570
+ ``absprec``.
571
+
572
+ EXAMPLES::
573
+
574
+ sage: R = ZpCA(5,5)
575
+ sage: S.<x> = ZZ[]
576
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
577
+ sage: W.<w> = R.ext(f)
578
+ sage: z = W(70/3, 14); z # indirect doctest
579
+ 3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + O(w^14)
580
+ sage: z * 3
581
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + O(w^14)
582
+ sage: W(70)
583
+ 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 + O(w^25)
584
+ sage: W(70/3, absprec = 4)
585
+ O(w^4)
586
+ sage: W(70/3, absprec = 0)
587
+ O(w^0)
588
+ """
589
+ if mpq_sgn(x) == 0:
590
+ self._set_inexact_zero(absprec)
591
+ return 0
592
+ if mpz_divisible_p(mpq_denref(x), self.prime_pow.prime.value):
593
+ raise ValueError("p divides the denominator")
594
+ self._set_prec_abs(absprec) # restores context
595
+ self._set_from_mpq_part2(x)
596
+
597
+ cdef int _set_from_mpq_both(self, mpq_t x, long absprec, long relprec) except -1:
598
+ """
599
+ Set ``self`` from an ``mpq_t`` with relative precision bounded by
600
+ ``relprec`` and absolute precision bounded by ``absprec``.
601
+
602
+ EXAMPLES::
603
+
604
+ sage: R = ZpCA(5,5)
605
+ sage: S.<x> = ZZ[]
606
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
607
+ sage: W.<w> = R.ext(f)
608
+ sage: z = W(70/3, 14); z # indirect doctest
609
+ 3*w^5 + w^7 + 2*w^9 + 2*w^10 + 4*w^11 + w^12 + 2*w^13 + O(w^14)
610
+ sage: z * 3
611
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + w^13 + O(w^14)
612
+ sage: W(70)
613
+ 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 + O(w^25)
614
+ sage: W(70/3, absprec = 0, relprec = 1)
615
+ O(w^0)
616
+ """
617
+ if mpq_sgn(x) == 0:
618
+ self._set_inexact_zero(absprec)
619
+ return 0
620
+ cdef long num_ordp
621
+ cdef mpz_t num_unit
622
+ if mpz_divisible_p(mpq_denref(x), self.prime_pow.prime.value):
623
+ raise ValueError("p divides the denominator")
624
+ sig_on()
625
+ mpz_init(num_unit)
626
+ num_ordp = mpz_remove(num_unit, mpq_numref(x), self.prime_pow.prime.value)
627
+ mpz_clear(num_unit)
628
+ sig_off()
629
+ self._set_prec_both_with_ordp(num_ordp * self.prime_pow.e, absprec, relprec) # restores context
630
+ self._set_from_mpq_part2(x)
631
+
632
+ cdef int _set_from_mpq_part2(self, mpq_t x) except -1:
633
+ """
634
+ Given that the appropriate context has been restored, sets
635
+ ``self`` from ``x``.
636
+
637
+ TESTS::
638
+
639
+ sage: R = ZpCA(5,5)
640
+ sage: S.<x> = ZZ[]
641
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
642
+ sage: W.<w> = R.ext(f)
643
+ sage: W(QQ(4), 23) # indirect doctest
644
+ 4 + O(w^23)
645
+ """
646
+ cdef mpz_t tmp_m
647
+ cdef ZZ_c den_z, num_z
648
+ cdef ZZ_p_c value
649
+ if self.absprec != 0:
650
+ mpz_init_set(tmp_m, mpq_numref(x))
651
+ mpz_to_ZZ(&num_z, tmp_m)
652
+ mpz_set(tmp_m, mpq_denref(x))
653
+ mpz_to_ZZ(&den_z, tmp_m)
654
+ mpz_clear(tmp_m)
655
+ ZZ_p_div(value, ZZ_to_ZZ_p(num_z), ZZ_to_ZZ_p(den_z))
656
+ ZZ_pX_SetCoeff(self.value, 0, value)
657
+
658
+ cdef int _set_from_ZZX_abs(self, ZZX_c poly, long absprec) except -1:
659
+ """
660
+ Set ``self`` from a ``ZZX`` with absolute precision bounded by
661
+ ``absprec``.
662
+
663
+ EXAMPLES::
664
+
665
+ sage: R = ZpCA(5,5)
666
+ sage: S.<x> = ZZ[]
667
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
668
+ sage: W.<w> = R.ext(f)
669
+ sage: z = W(ntl.ZZX([4,1,16]), absprec = 14); z # indirect doctest
670
+ 4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + 4*w^13 + O(w^14)
671
+ sage: z._ntl_rep()
672
+ [4 1 16]
673
+ sage: W(ntl.ZZX([4,1,16]), absprec = 0)
674
+ O(w^0)
675
+ """
676
+ self._set_prec_abs(absprec)
677
+ cdef ZZ_pX_c poly_p
678
+ if self.absprec != 0:
679
+ ZZX_to_ZZ_pX(poly_p, poly)
680
+ self._set_from_ZZ_pX_abs(&poly_p, None, absprec)
681
+
682
+ cdef int _set_from_ZZX_both(self, ZZX_c poly, long absprec, long relprec) except -1:
683
+ """
684
+ Set ``self`` from a ``ZZX`` with relative precision bounded by
685
+ ``relprec`` and absolute precision bounded by ``absprec``.
686
+
687
+ EXAMPLES::
688
+
689
+ sage: R = ZpCA(5,5)
690
+ sage: S.<x> = ZZ[]
691
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
692
+ sage: W.<w> = R.ext(f)
693
+ sage: z = W(ntl.ZZX([4,1,16]), relprec = 12); z # indirect doctest
694
+ 4 + w + w^2 + 3*w^7 + w^9 + 2*w^11 + O(w^12)
695
+ sage: z._ntl_rep()
696
+ [4 1 16]
697
+ sage: W(ntl.ZZX([4,1,16]), absprec = 0, relprec = 4)
698
+ O(w^0)
699
+ """
700
+ self._set_prec_abs(absprec)
701
+ cdef ZZ_pX_c poly_p
702
+ if self.absprec != 0:
703
+ ZZX_to_ZZ_pX(poly_p, poly)
704
+ self._set_from_ZZ_pX_both(&poly_p, None, absprec, relprec)
705
+
706
+ cdef int _set_from_ZZ_pX_abs(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec) except -1:
707
+ """
708
+ Set ``self`` from a ``ZZ_pX`` with absolute precision bounded by
709
+ ``absprec`` (and by ``ctx``).
710
+
711
+ EXAMPLES::
712
+
713
+ sage: R = ZpCA(5,5)
714
+ sage: S.<x> = ZZ[]
715
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
716
+ sage: W.<w> = R.ext(f)
717
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2)); z # indirect doctest
718
+ 4 + w + w^2 + 3*w^7 + w^9 + O(w^10)
719
+ sage: z._ntl_rep()
720
+ [4 1 16]
721
+ sage: W(ntl.ZZ_pX([4,1,16],5^2), absprec = 0)
722
+ O(w^0)
723
+ """
724
+ cdef long ctx_prec = -1
725
+ if ctx is not None:
726
+ ctx_prec = self._check_ZZ_pContext(ctx) * self.prime_pow.e
727
+ if ctx_prec < absprec:
728
+ absprec = ctx_prec
729
+ if ZZ_pX_IsZero(poly[0]):
730
+ self._set_inexact_zero(absprec)
731
+ return 0
732
+ self._set_prec_abs(absprec) # restores context
733
+ if self.absprec != 0:
734
+ ZZ_pX_conv_modulus(self.value, poly[0], self.prime_pow.get_context_capdiv(absprec).x)
735
+
736
+ cdef int _set_from_ZZ_pX_both(self, ZZ_pX_c* poly, ntl_ZZ_pContext_class ctx, long absprec, long relprec) except -1:
737
+ """
738
+ Set ``self`` from a ``ZZ_pX`` with relative precision bounded by
739
+ ``relprec`` and absolute precision bounded by ``absprec``.
740
+
741
+ EXAMPLES::
742
+
743
+ sage: R = ZpCA(5,5)
744
+ sage: S.<x> = ZZ[]
745
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
746
+ sage: W.<w> = R.ext(f)
747
+ sage: z = W(ntl.ZZ_pX([4,1,16],5^2), absprec = 8, relprec = 12); z # indirect doctest
748
+ 4 + w + w^2 + 3*w^7 + O(w^8)
749
+ sage: z._ntl_rep()
750
+ [4 1 16]
751
+ sage: W(ntl.ZZ_pX([4,1,16],5^2), absprec = 0, relprec = 5)
752
+ O(w^0)
753
+ """
754
+ cdef long ctx_prec
755
+ if ctx is not None:
756
+ ctx_prec = self._check_ZZ_pContext(ctx)
757
+ if ctx_prec * self.prime_pow.e < absprec:
758
+ absprec = ctx_prec * self.prime_pow.e
759
+ if ZZ_pX_IsZero(poly[0]):
760
+ self._set_inexact_zero(absprec)
761
+ return 0
762
+ cdef long val = 0, index = 0
763
+ ZZ_pX_min_val_coeff(val, index, poly[0], self.prime_pow.pow_ZZ_tmp(1)[0])
764
+ if self.prime_pow.e == 1:
765
+ self._set_prec_both_with_ordp(val, absprec, relprec) #restores context
766
+ else:
767
+ self._set_prec_both_with_ordp(val * self.prime_pow.e + index, absprec, relprec) # restores context
768
+ if self.absprec != 0:
769
+ ZZ_pX_conv_modulus(self.value, poly[0], self.prime_pow.get_context_capdiv(self.absprec).x)
770
+
771
+ cdef bint _set_prec_abs(self, long absprec) except -1:
772
+ """
773
+ Safely set the absolute precision of ``self`` to ``absprec``.
774
+
775
+ Returns ``True`` iff ``self.absprec`` was reset.
776
+
777
+ Note that this will wipe out anything in ``self.value``. Be
778
+ careful resetting ``self.value`` directly: if you set it to a
779
+ different modulus, NTL may have problems. The safest way to
780
+ reset ``self.value`` to a different modulus is::
781
+
782
+ self.prime_pow.restore_context_capdiv(self.absprec)
783
+ cdef ZZ_pX_c tmp = self.value
784
+ self._set_prec_abs(new_abs_prec)
785
+ ZZ_pX_conv_modulus(self.value, tmp, self.prime_pow.get_context_capdiv(self.absprec).x)
786
+
787
+ If you want to speed up this process and you're decreasing
788
+ precision, you may be able to just set ``self.absprec`` and
789
+ ``ZZ_pX_conv_modulus``. I haven't looked into how NTL will be
790
+ have in this case well enough to know if your program will
791
+ segfault in this case or not.
792
+
793
+ TESTS::
794
+
795
+ sage: R = ZpCA(5,5)
796
+ sage: S.<x> = ZZ[]
797
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
798
+ sage: W.<w> = R.ext(f)
799
+ sage: W(70, 13) # indirect doctest
800
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
801
+ """
802
+ if absprec < 0:
803
+ raise ValueError("absprec must be nonnegative")
804
+ if self.absprec == absprec:
805
+ return False
806
+ if absprec > 0:
807
+ self.prime_pow.restore_context_capdiv(absprec)
808
+ self.value = ZZ_pX_c()
809
+ self.absprec = absprec
810
+ return True
811
+
812
+ cdef bint _set_prec_both(self, long absprec, long relprec) except -1:
813
+ raise TypeError("use _set_prec_both_with_ord")
814
+
815
+ cdef bint _set_prec_both_with_ordp(self, long ordp, long absprec, long relprec) except -1:
816
+ """
817
+ Set the absolute precision of ``self`` to the minimum of ``absprec``
818
+ and ``ordp + relprec``.
819
+
820
+ Note that this will wipe out anything in ``self.value``. Be
821
+ careful resetting ``self.value`` directly: if you set it to a
822
+ different modulus, NTL may have problems. The safest way to
823
+ reset ``self.value`` to a different modulus is::
824
+
825
+ self.prime_pow.restore_context_capdiv(self.absprec)
826
+ cdef ZZ_pX_c tmp = self.value
827
+ self._set_prec_abs(new_abs_prec)
828
+ ZZ_pX_conv_modulus(self.value, tmp, self.prime_pow.get_context_capdiv(self.relprec).x)
829
+
830
+ You may be able to just set ``self.absprec`` and
831
+ ``ZZ_pX_conv_modulus`` if you're decreasing precision. I'm not
832
+ sure.
833
+
834
+ TESTS::
835
+
836
+ sage: R = ZpCA(5,5)
837
+ sage: S.<x> = ZZ[]
838
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
839
+ sage: W.<w> = R.ext(f)
840
+ sage: W(70, relprec=3) # indirect doctest
841
+ 4*w^5 + 3*w^7 + O(w^8)
842
+ """
843
+ if absprec <= ordp + relprec:
844
+ self._set_prec_abs(absprec)
845
+ else:
846
+ self._set_prec_abs(ordp + relprec)
847
+
848
+ cdef pAdicZZpXCAElement _new_c(self, long absprec):
849
+ """
850
+ Return a new element with the same parent as ``self`` and
851
+ absolute precision ``absprec``.
852
+
853
+ EXAMPLES::
854
+
855
+ sage: R = ZpCA(5,5)
856
+ sage: S.<x> = ZZ[]
857
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
858
+ sage: W.<w> = R.ext(f)
859
+ sage: w^5 + 1 # indirect doctest
860
+ 1 + w^5 + O(w^25)
861
+ """
862
+ cdef pAdicZZpXCAElement ans = pAdicZZpXCAElement.__new__(pAdicZZpXCAElement)
863
+ ans._parent = self._parent
864
+ ans.prime_pow = self.prime_pow
865
+ ans.absprec = absprec
866
+ if absprec > 0:
867
+ self.prime_pow.restore_context_capdiv(absprec)
868
+ elif absprec < 0:
869
+ raise ValueError("absprec must be positive")
870
+ return ans
871
+
872
+ def __reduce__(self):
873
+ """
874
+ Pickles ``self``.
875
+
876
+ EXAMPLES::
877
+
878
+ sage: R = Qp(5,5)
879
+ sage: S.<x> = ZZ[]
880
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
881
+ sage: W.<w> = R.ext(f)
882
+ sage: z = (1 + w)^5 - 1
883
+ sage: loads(dumps(z)) == z
884
+ True
885
+ """
886
+ cdef Integer absprec
887
+ absprec = PY_NEW(Integer)
888
+ mpz_set_si(absprec.value, self.absprec)
889
+ if self.absprec == 0:
890
+ return make_ZZpXCAElement, (self.parent(), None, absprec, 0)
891
+ self.prime_pow.restore_context_capdiv(self.absprec)
892
+ cdef ntl_ZZ_pX holder = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
893
+ holder.c = self.prime_pow.get_context_capdiv(self.absprec)
894
+ holder.x = self.value
895
+ return make_ZZpXCAElement, (self.parent(), holder, absprec, 0)
896
+
897
+ cdef int _cmp_units(left, pAdicGenericElement right) except -2:
898
+ """
899
+ For units ``left`` and ``right``, returns 0 if they are equal up to
900
+ the lesser of the two precisions, or 1 if they are not.
901
+
902
+ EXAMPLES::
903
+
904
+ sage: R = ZpCA(5,5)
905
+ sage: S.<x> = ZZ[]
906
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
907
+ sage: W.<w> = R.ext(f)
908
+ sage: w == 1 # indirect doctest
909
+ False
910
+ sage: y = 1 + w + O(w^7)
911
+ sage: z = 1 + w + w^10 + O(w^13)
912
+ sage: y == z
913
+ True
914
+ """
915
+ # This function needs improvement. In particular, there are a lot of
916
+ # speed improvements to be had, and it should be changed so that it
917
+ # returns 1 only half the time (and -1 the other half) when left and
918
+ # right are not equal.
919
+ cdef pAdicZZpXCAElement diff = <pAdicZZpXCAElement> (left - right)
920
+ if diff._is_inexact_zero():
921
+ return 0
922
+ # for now, just return 1
923
+ return 1
924
+
925
+ def __invert__(self):
926
+ """
927
+ Return the inverse of ``self``.
928
+
929
+ EXAMPLES::
930
+
931
+ sage: R = ZpCA(5,5)
932
+ sage: S.<x> = ZZ[]
933
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
934
+ sage: W.<w> = R.ext(f)
935
+ sage: z = (1 + w)^5
936
+ sage: y = ~z; y # indirect doctest
937
+ 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)
938
+ sage: y.parent()
939
+ 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
940
+ sage: z = z - 1
941
+ sage: ~z
942
+ 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)
943
+ """
944
+ return ~self.to_fraction_field()
945
+
946
+ cpdef pAdicZZpXCRElement to_fraction_field(self):
947
+ """
948
+ Return ``self`` cast into the fraction field of ``self.parent()``.
949
+
950
+ EXAMPLES::
951
+
952
+ sage: R = ZpCA(5,5)
953
+ sage: S.<x> = ZZ[]
954
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
955
+ sage: W.<w> = R.ext(f)
956
+ sage: z = (1 + w)^5; z
957
+ 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)
958
+ sage: y = z.to_fraction_field(); y # indirect doctest
959
+ 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)
960
+ sage: y.parent()
961
+ 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
962
+ """
963
+ cdef pAdicZZpXCRElement ans = pAdicZZpXCRElement.__new__(pAdicZZpXCRElement)
964
+ ans._parent = self._parent.fraction_field()
965
+ ans.prime_pow = ans._parent.prime_pow
966
+ ans.ordp = 0
967
+ ans.relprec = -self.absprec
968
+ if self.absprec != 0:
969
+ self.prime_pow.restore_context_capdiv(self.absprec)
970
+ ans.unit = self.value
971
+ return ans
972
+
973
+ cdef pAdicZZpXCAElement _lshift_c(self, long n):
974
+ """
975
+ Multiply ``self`` by the uniformizer raised to the power ``n``. If
976
+ ``n`` is negative, right shifts by ``-n``.
977
+
978
+ EXAMPLES::
979
+
980
+ sage: R = ZpCA(5,5)
981
+ sage: S.<x> = ZZ[]
982
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
983
+ sage: W.<w> = R.ext(f)
984
+ sage: z = (1 + w)^5
985
+ sage: z
986
+ 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)
987
+ sage: z << 17 # indirect doctest
988
+ w^17 + w^22 + w^23 + 2*w^24 + O(w^25)
989
+ sage: z << (-1)
990
+ 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)
991
+ """
992
+ self._rshift_c(-n)
993
+
994
+ def __lshift__(pAdicZZpXCAElement self, shift):
995
+ """
996
+ Multiply ``self`` by the uniformizer raised to the power ``n``. If
997
+ ``n`` is negative, right shifts by ``-n``.
998
+
999
+ EXAMPLES::
1000
+
1001
+ sage: R = ZpCA(5,5)
1002
+ sage: S.<x> = ZZ[]
1003
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1004
+ sage: W.<w> = R.ext(f)
1005
+ sage: z = (1 + w)^5
1006
+ sage: z
1007
+ 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)
1008
+ sage: z << 17 # indirect doctest
1009
+ w^17 + w^22 + w^23 + 2*w^24 + O(w^25)
1010
+ sage: z << (-1)
1011
+ 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)
1012
+ """
1013
+ cdef pAdicZZpXCAElement ans
1014
+ if not isinstance(shift, Integer):
1015
+ shift = Integer(shift)
1016
+ if mpz_fits_slong_p((<Integer>shift).value) == 0:
1017
+ if mpz_sgn((<Integer>shift).value) > 0:
1018
+ ans = self._new_c(self.prime_pow.ram_prec_cap)
1019
+ else:
1020
+ ans = self._new_c(0)
1021
+ return ans
1022
+ return self._rshift_c(-mpz_get_si((<Integer>shift).value))
1023
+
1024
+ cdef pAdicZZpXCAElement _rshift_c(self, long n):
1025
+ """
1026
+ Divide ``self`` by the uniformizer raised to the power ``n``. If
1027
+ parent is not a field, throws away the nonpositive part of
1028
+ the series expansion. If ``n`` is negative, left shifts by ``-n``.
1029
+
1030
+ EXAMPLES::
1031
+
1032
+ sage: R = ZpCA(5,5,print_mode='digits')
1033
+ sage: S.<x> = ZZ[]
1034
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1035
+ sage: W.<w> = R.ext(f)
1036
+ sage: z = (1 + w)^5
1037
+ sage: for m in range(26): repr(z >> m) # indirect doctest
1038
+ '...4001400444441030421100001'
1039
+ '...400140044444103042110000'
1040
+ '...40014004444410304211000'
1041
+ '...4001400444441030421100'
1042
+ '...400140044444103042110'
1043
+ '...40014004444410304211'
1044
+ '...4001400444441030421'
1045
+ '...400140044444103042'
1046
+ '...40014004444410304'
1047
+ '...4001400444441030'
1048
+ '...400140044444103'
1049
+ '...40014004444410'
1050
+ '...4001400444441'
1051
+ '...400140044444'
1052
+ '...40014004444'
1053
+ '...4001400444'
1054
+ '...400140044'
1055
+ '...40014004'
1056
+ '...4001400'
1057
+ '...400140'
1058
+ '...40014'
1059
+ '...4001'
1060
+ '...400'
1061
+ '...40'
1062
+ '...4'
1063
+ '...'
1064
+ sage: repr(z >> (-4))
1065
+ '...4004444410304211000010000'
1066
+ """
1067
+ cdef long absprec
1068
+ if n == 0:
1069
+ return self
1070
+ elif n > self.absprec: # we do these checks first in case adding would cause an overflow
1071
+ absprec = 0
1072
+ elif n < self.absprec - self.prime_pow.ram_prec_cap:
1073
+ absprec = self.prime_pow.ram_prec_cap
1074
+ else:
1075
+ absprec = self.absprec - n
1076
+ cdef pAdicZZpXCAElement ans
1077
+ if absprec > 0:
1078
+ ans = self._new_c(absprec)
1079
+ if n > -self.prime_pow.ram_prec_cap: # the result might not be zero.
1080
+ if self.prime_pow.e == 1:
1081
+ if n > 0:
1082
+ ZZ_pX_right_pshift(ans.value, self.value, self.prime_pow.pow_ZZ_tmp(n)[0], self.prime_pow.get_context(ans.absprec).x)
1083
+ else:
1084
+ ZZ_pX_left_pshift(ans.value, self.value, self.prime_pow.pow_ZZ_tmp(-n)[0], self.prime_pow.get_context(ans.absprec).x)
1085
+ else:
1086
+ self.prime_pow.eis_shift_capdiv(&ans.value, &self.value, n, ans.absprec)
1087
+ else:
1088
+ ans = self._new_c(0)
1089
+ return ans
1090
+
1091
+ def __rshift__(pAdicZZpXCAElement self, shift):
1092
+ """
1093
+ Divide ``self`` by the uniformizer raised to the power ``n``. If
1094
+ parent is not a field, throws away the nonpositive part of
1095
+ the series expansion. If ``n`` is negative, left shifts by ``-n``.
1096
+
1097
+ EXAMPLES::
1098
+
1099
+ sage: R = ZpCA(5,5)
1100
+ sage: S.<x> = ZZ[]
1101
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1102
+ sage: W.<w> = R.ext(f)
1103
+ sage: z = (1 + w)^5
1104
+ sage: z
1105
+ 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)
1106
+ sage: z >> (6) # indirect doctest
1107
+ 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)
1108
+ sage: z >> (-4)
1109
+ 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 + O(w^25)
1110
+ """
1111
+ cdef pAdicZZpXCAElement ans
1112
+ if not isinstance(shift, Integer):
1113
+ shift = Integer(shift)
1114
+ if mpz_fits_slong_p((<Integer>shift).value) == 0:
1115
+ if mpz_sgn((<Integer>shift).value) < 0:
1116
+ ans = self._new_c(self.prime_pow.ram_prec_cap)
1117
+ else:
1118
+ ans = self._new_c(0)
1119
+ return ans
1120
+ return self._rshift_c(mpz_get_si((<Integer>shift).value))
1121
+
1122
+ cpdef _neg_(self):
1123
+ """
1124
+ Return ``-self``.
1125
+
1126
+ EXAMPLES::
1127
+
1128
+ sage: R = ZpCA(5,5)
1129
+ sage: S.<x> = ZZ[]
1130
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1131
+ sage: W.<w> = R.ext(f)
1132
+ sage: z = (1 + w)^5; z
1133
+ 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)
1134
+ sage: -z # indirect doctest
1135
+ 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)
1136
+ sage: y = z + (-z); y
1137
+ O(w^25)
1138
+ sage: -y
1139
+ O(w^25)
1140
+ """
1141
+ cdef pAdicZZpXCAElement ans = self._new_c(self.absprec)
1142
+ if self.absprec != 0:
1143
+ self.prime_pow.restore_context_capdiv(self.absprec)
1144
+ ZZ_pX_negate(ans.value, self.value)
1145
+ return ans
1146
+
1147
+ # / 1 + \alpha^p \pi_K^{p \lambda} mod \mathfrak{p}_K^{p \lambda + 1} if 1 \le \lambda < \frac{e_K}{p-1}
1148
+ # (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}
1149
+ # \ 1 - \epsilon \alpha \pi_K^{\lambda + e} mod \mathfrak{p}_K^{\lambda + e + 1} if \lambda > \frac{e_K}{p-1}
1150
+
1151
+ def __pow__(pAdicZZpXCAElement self, _right, m): # m ignored
1152
+ r"""
1153
+ Compute ``self^right``.
1154
+
1155
+ Note: when right is divisible by `p` then one can get more
1156
+ precision than expected.
1157
+
1158
+ Lemma 2.1 (Constructing Class Fields over Local Fields,
1159
+ Sebastian Pauli): Let `\alpha` be in `\mathcal{O}_K`. Let
1160
+
1161
+ .. MATH::
1162
+
1163
+ p = -\pi_K^{e_K} \epsilon
1164
+
1165
+ be the factorization of `p` where `\epsilon` is a unit. Then
1166
+ the `p`-th power of `1 + \alpha \pi_K^{\lambda}` satisfies
1167
+
1168
+ .. MATH::
1169
+
1170
+ (1 + \alpha \pi^{\lambda})^p \equiv \left{ \begin{array}{lll}
1171
+ 1 + \alpha^p \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $1 \le \lambda < \frac{e_K}{p-1}$} \\
1172
+ 1 + (\alpha^p - \epsilon \alpha) \pi_K^{p \lambda} & \mod \mathfrak{p}_K^{p \lambda + 1} & \mbox{if $\lambda = \frac{e_K}{p-1}$} \\
1173
+ 1 - \epsilon \alpha \pi_K^{\lambda + e} & \mod \mathfrak{p}_K^{\lambda + e + 1} & \mbox{if $\lambda > \frac{e_K}{p-1}$}
1174
+ \end{array} \right.
1175
+
1176
+
1177
+ So if right is divisible by `p^k` we can multiply the relative
1178
+ precision by `p` until we exceed `e/(p-1)`, then add `e` until
1179
+ we have done a total of `k` things: the precision of the
1180
+ result can therefore be greater than the precision of ``self``.
1181
+
1182
+ There is also the issue of `p`-adic exponents, and determining
1183
+ how the precision of the exponent affects the precision of the
1184
+ result.
1185
+
1186
+ In computing `(a + O(\pi^k))^{b + O(p^m)}`, one needs that the
1187
+ reduction of `a` mod `\pi` is in the prime field `\GF{p}` (so
1188
+ that the `p^m` power of the Teichmuller part is constant as
1189
+ `m` increases). Given this restriction, we can factor out the
1190
+ Teichmuller part and use the above lemma to find the first
1191
+ spot where
1192
+
1193
+ .. MATH::
1194
+
1195
+ (1 + \alpha \pi^{\lambda})^{p^m}
1196
+
1197
+ differs from 1. We compare this with the precision bound
1198
+ given by computing `(a + O(\pi^k))^b` and take the lesser of
1199
+ the two.
1200
+
1201
+ In order to do this we need to compute the valuation of ``(self
1202
+ / self.parent().teichmuller(self)) - 1``.
1203
+
1204
+ EXAMPLES::
1205
+
1206
+ sage: R = ZpCA(5,5)
1207
+ sage: S.<x> = ZZ[]
1208
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1209
+ sage: W.<w> = R.ext(f)
1210
+ sage: (1 + w)^5 # indirect doctest
1211
+ 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)
1212
+ sage: (1 + w + O(w^19))^5
1213
+ 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)
1214
+ sage: (1 + O(w))^5
1215
+ 1 + O(w^5)
1216
+ sage: (1 + w + O(w^3))^25
1217
+ 1 + w^10 + w^11 + 4*w^12 + O(w^13)
1218
+ sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(125))
1219
+ 2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + 4*w^10 + O(w^11)
1220
+ sage: (3 + 2*w + w^2 + O(w^6))^(15 + O(25))
1221
+ 2 + 4*w^6 + w^7 + 3*w^8 + 3*w^9 + O(w^10)
1222
+ sage: (3 + w^2 + O(w^6))^(15+O(25))
1223
+ 2 + w^5 + 4*w^7 + w^9 + 3*w^10 + O(w^11)
1224
+ sage: R = ZpCA(2, 10)
1225
+ sage: S.<x> = ZZ[]
1226
+ sage: f = x^34 + 18*x^5 - 72*x^3 + 2
1227
+ sage: W.<w> = R.ext(f)
1228
+ sage: (1+w+O(w^2))^8
1229
+ 1 + w^8 + O(w^16)
1230
+ sage: (1+w+O(w^2))^16
1231
+ 1 + w^16 + O(w^32)
1232
+ sage: (1+w+O(w^2))^32
1233
+ 1 + w^32 + w^50 + w^55 + w^60 + O(w^64)
1234
+ sage: (1+w+O(w^2))^64
1235
+ 1 + w^64 + w^66 + w^71 + w^76 + w^81 + w^84 + w^86 + w^91 + w^94 + w^96 + O(w^98)
1236
+ sage: U.<a> = Zq(17^4, 6, print_mode='val-unit'); b = (a^3-a+14)^-6; b
1237
+ 12003242 + 4839703*a + 2697351*a^2 + 11717046*a^3 + O(17^6)
1238
+ sage: b*(a^3-a+14)^6
1239
+ 1 + O(17^6)
1240
+ """
1241
+ cdef Integer right
1242
+ cdef bint padic_exp
1243
+ cdef long exp_prec
1244
+ cdef long exp_val
1245
+ cdef long ans_relprec, ans_ordp
1246
+ cdef long self_ordp = self.valuation_c()
1247
+ cdef long self_relprec = self.absprec - self_ordp
1248
+ cdef long threshold # e / (p-1)
1249
+ cdef mpz_t tmp, tmp2
1250
+ if mpz_fits_slong_p(self.prime_pow.prime.value) == 0:
1251
+ threshold = 0
1252
+ else:
1253
+ threshold = self.prime_pow.e / (mpz_get_si(self.prime_pow.prime.value) - 1)
1254
+ cdef Integer base_level
1255
+ cdef pAdicZZpXCAElement ans
1256
+ cdef long i
1257
+ if self._is_inexact_zero():
1258
+ # If an integer exponent, return an inexact zero of valuation right * self_ordp. Otherwise raise an error.
1259
+ if isinstance(_right, int):
1260
+ _right = Integer(_right)
1261
+ if isinstance(_right, Integer):
1262
+ mpz_init_set_si(tmp, self_ordp)
1263
+ mpz_mul(tmp, tmp, (<Integer>_right).value)
1264
+ if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) >= 0:
1265
+ ans = self._new_c(self.prime_pow.ram_prec_cap)
1266
+ elif mpz_sgn(tmp) <= 0:
1267
+ ans = self._new_c(0)
1268
+ else:
1269
+ ans = self._new_c(mpz_get_si(tmp))
1270
+ mpz_clear(tmp)
1271
+ return ans
1272
+ elif isinstance(_right, Rational) or (isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime)):
1273
+ raise ValueError("need more precision")
1274
+ else:
1275
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1276
+ if isinstance(_right, int):
1277
+ _right = Integer(_right)
1278
+ cdef pAdicZZpXCAElement unit
1279
+ if isinstance(_right, Integer):
1280
+ right = <Integer> _right
1281
+ if right < 0 and self_ordp > 0:
1282
+ return self.to_fraction_field()**right
1283
+ if right == 0:
1284
+ # return 1 to maximum precision
1285
+ ans = self._new_c(self.prime_pow.ram_prec_cap)
1286
+ ZZ_pX_SetCoeff_long(ans.value, 0, 1)
1287
+ return ans
1288
+ padic_exp = False
1289
+ exp_val = _right.valuation(self.prime_pow.prime) ##
1290
+ elif isinstance(_right, pAdicGenericElement) and _right._is_base_elt(self.prime_pow.prime):
1291
+ if self_ordp != 0:
1292
+ raise ValueError("in order to raise to a p-adic exponent, base must be a unit")
1293
+ right = Integer(_right)
1294
+ padic_exp = True
1295
+ exp_prec = _right.precision_absolute() ##
1296
+ exp_val = _right.valuation() ##
1297
+ if exp_val < 0:
1298
+ raise NotImplementedError("negative valuation exponents not yet supported")
1299
+ # checks to see if the residue of self's unit is in the prime field.
1300
+ if self.prime_pow.e == 1:
1301
+ unit = self.unit_part()
1302
+ for i in range(1, ZZ_pX_deg(unit.value) + 1):
1303
+ if not ZZ_divide_test(ZZ_p_rep(ZZ_pX_coeff(unit.value, i)), self.prime_pow.pow_ZZ_tmp(1)[0]):
1304
+ raise ValueError("in order to raise to a p-adic exponent, base must reduce to an element of F_p mod the uniformizer")
1305
+ # compute the "level"
1306
+ teich_part = self.parent().teichmuller(self)
1307
+ base_level = (self / teich_part - 1).valuation() ##
1308
+ elif isinstance(_right, Rational):
1309
+ raise NotImplementedError
1310
+ else:
1311
+ raise TypeError("exponent must be an integer, rational or base p-adic with the same prime")
1312
+ # Now we compute the increased relprec due to the exponent having positive p-adic valuation
1313
+ if exp_val > 0:
1314
+ mpz_init_set_si(tmp, self_relprec)
1315
+ while mpz_cmp_si(tmp, threshold) <= 0 and exp_val > 0:
1316
+ mpz_mul(tmp, tmp, self.prime_pow.prime.value)
1317
+ exp_val -= 1
1318
+ if exp_val > 0:
1319
+ mpz_init_set_si(tmp2, self.prime_pow.e)
1320
+ mpz_addmul_ui(tmp, tmp2, exp_val)
1321
+ mpz_clear(tmp2)
1322
+ if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) > 0:
1323
+ ans_relprec = self.prime_pow.ram_prec_cap
1324
+ else:
1325
+ ans_relprec = mpz_get_si(tmp)
1326
+ mpz_clear(tmp)
1327
+ else:
1328
+ ans_relprec = self_relprec
1329
+ # Now we compute the limit on relprec due to a non-infinite precision on the exponent.
1330
+ if padic_exp:
1331
+ if exp_prec > 0:
1332
+ # I can freely change base_level, so I use it in place of tmp above.
1333
+ while mpz_cmp_si(base_level.value, threshold) <= 0 and exp_prec > 0:
1334
+ mpz_mul(base_level.value, base_level.value, self.prime_pow.prime.value)
1335
+ exp_prec -= 1
1336
+ if exp_prec > 0:
1337
+ mpz_init_set_si(tmp2, self.prime_pow.e)
1338
+ mpz_addmul_ui(base_level.value, tmp2, exp_prec)
1339
+ mpz_clear(tmp2)
1340
+ if mpz_cmp_si(base_level.value, ans_relprec) < 0:
1341
+ ans_relprec = mpz_get_si(base_level.value)
1342
+ else:
1343
+ return self._new_c(0)
1344
+ if self_ordp == 0:
1345
+ ans_ordp = 0
1346
+ else:
1347
+ mpz_init_set(tmp, right.value)
1348
+ mpz_mul_si(tmp, tmp, self_ordp)
1349
+ if mpz_cmp_si(tmp, self.prime_pow.ram_prec_cap) >= 0:
1350
+ return self._new_c(self.prime_pow.ram_prec_cap)
1351
+ # we already checked for negative tmp above
1352
+ ans_ordp = mpz_get_si(tmp)
1353
+ mpz_clear(tmp)
1354
+ if ans_ordp >= self.prime_pow.ram_prec_cap:
1355
+ return self._new_c(self.prime_pow.ram_prec_cap)
1356
+ cdef ntl_ZZ rZZ = ntl_ZZ.__new__(ntl_ZZ)
1357
+ mpz_to_ZZ(&rZZ.x, right.value)
1358
+ if ans_ordp + ans_relprec <= self.prime_pow.ram_prec_cap:
1359
+ ans = self._new_c(ans_ordp + ans_relprec) # restores context
1360
+ else:
1361
+ ans = self._new_c(self.prime_pow.ram_prec_cap) # restores context
1362
+ cdef ZZ_pX_c self_value
1363
+ sig_on()
1364
+ if ans.absprec != self.absprec:
1365
+ ZZ_pX_conv_modulus(self_value, self.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
1366
+ if mpz_sgn(right.value) < 0: # only happens when self.ordp == 0
1367
+ if self.prime_pow.e == 1:
1368
+ ZZ_pX_InvMod_newton_unram(ans.value, self_value, self.prime_pow.get_modulus(ans.absprec)[0], self.prime_pow.get_context(ans.absprec).x, self.prime_pow.get_context(1).x)
1369
+ else:
1370
+ ZZ_pX_InvMod_newton_ram(ans.value, self_value, self.prime_pow.get_modulus_capdiv(ans.absprec)[0], self.prime_pow.get_context_capdiv(ans.absprec).x)
1371
+ ZZ_negate(rZZ.x, rZZ.x)
1372
+ ZZ_pX_PowerMod_pre(ans.value, ans.value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
1373
+ else:
1374
+ ZZ_pX_PowerMod_pre(ans.value, self_value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
1375
+ else:
1376
+ if mpz_sgn(right.value) < 0: # only happens when self.ordp == 0
1377
+ if self.prime_pow.e == 1:
1378
+ ZZ_pX_InvMod_newton_unram(ans.value, self.value, self.prime_pow.get_modulus(ans.absprec)[0], self.prime_pow.get_context(ans.absprec).x, self.prime_pow.get_context(1).x)
1379
+ else:
1380
+ ZZ_pX_InvMod_newton_ram(ans.value, self.value, self.prime_pow.get_modulus_capdiv(ans.absprec)[0], self.prime_pow.get_context_capdiv(ans.absprec).x)
1381
+ ZZ_negate(rZZ.x, rZZ.x)
1382
+ ZZ_pX_PowerMod_pre(ans.value, ans.value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
1383
+ else:
1384
+ ZZ_pX_PowerMod_pre(ans.value, self.value, rZZ.x, self.prime_pow.get_modulus_capdiv(ans.absprec)[0])
1385
+ sig_off()
1386
+ return ans
1387
+
1388
+ cpdef _add_(self, _right):
1389
+ """
1390
+ Compute the sum of ``self`` and ``right``.
1391
+
1392
+ EXAMPLES::
1393
+
1394
+ sage: R = ZpCA(5,5)
1395
+ sage: S.<x> = ZZ[]
1396
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1397
+ sage: W.<w> = R.ext(f)
1398
+ sage: (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)) - 69 # indirect doctest
1399
+ 1 + O(w^13)
1400
+ sage: -69 + (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
1401
+ 1 + O(w^13)
1402
+ sage: y = (4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13))
1403
+ sage: y - 70
1404
+ O(w^13)
1405
+ sage: y + 0
1406
+ 4*w^5 + 3*w^7 + w^9 + 2*w^10 + 2*w^11 + O(w^13)
1407
+ """
1408
+ cdef pAdicZZpXCAElement right = <pAdicZZpXCAElement>_right
1409
+ cdef pAdicZZpXCAElement ans
1410
+ cdef ZZ_pX_c tmpP
1411
+ if self.absprec == 0 or right.absprec == 0:
1412
+ return self._new_c(0)
1413
+ elif self.absprec == right.absprec:
1414
+ ans = self._new_c(self.absprec)
1415
+ ZZ_pX_add(ans.value, self.value, right.value)
1416
+ elif self.absprec < right.absprec:
1417
+ ans = self._new_c(self.absprec)
1418
+ ZZ_pX_conv_modulus(tmpP, right.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
1419
+ ZZ_pX_add(ans.value, self.value, tmpP)
1420
+ else:
1421
+ ans = self._new_c(right.absprec)
1422
+ ZZ_pX_conv_modulus(tmpP, self.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
1423
+ ZZ_pX_add(ans.value, tmpP, right.value)
1424
+ return ans
1425
+
1426
+ cpdef _sub_(self, _right):
1427
+ """
1428
+ Return the difference of ``self`` and ``right``.
1429
+
1430
+ EXAMPLES::
1431
+
1432
+ sage: R = ZpCA(5,5)
1433
+ sage: S.<x> = ZZ[]
1434
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1435
+ sage: W.<w> = R.ext(f)
1436
+ sage: a = W(329)
1437
+ sage: b = W(111)
1438
+ sage: a - b # indirect doctest
1439
+ 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)
1440
+ sage: W(218)
1441
+ 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)
1442
+ sage: a - O(w^14)
1443
+ 4 + 3*w^10 + 2*w^12 + O(w^14)
1444
+ sage: a - 0
1445
+ 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)
1446
+ sage: O(w^14) - a
1447
+ 1 + 4*w^5 + 3*w^7 + w^9 + w^10 + 2*w^11 + w^12 + w^13 + O(w^14)
1448
+ """
1449
+ cdef pAdicZZpXCAElement right = <pAdicZZpXCAElement>_right
1450
+ cdef pAdicZZpXCAElement ans
1451
+ cdef ZZ_pX_c tmpP
1452
+ if self.absprec == 0 or right.absprec == 0:
1453
+ return self._new_c(0)
1454
+ elif self.absprec == right.absprec:
1455
+ ans = self._new_c(self.absprec)
1456
+ ZZ_pX_sub(ans.value, self.value, right.value)
1457
+ elif self.absprec < right.absprec:
1458
+ ans = self._new_c(self.absprec)
1459
+ ZZ_pX_conv_modulus(tmpP, right.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
1460
+ ZZ_pX_sub(ans.value, self.value, tmpP)
1461
+ else:
1462
+ ans = self._new_c(right.absprec)
1463
+ ZZ_pX_conv_modulus(tmpP, self.value, self.prime_pow.get_context_capdiv(ans.absprec).x)
1464
+ ZZ_pX_sub(ans.value, tmpP, right.value)
1465
+ return ans
1466
+
1467
+ cpdef _mul_(self, _right):
1468
+ """
1469
+ Return the product of ``self`` and ``right``.
1470
+
1471
+ EXAMPLES::
1472
+
1473
+ sage: R = ZpCA(5,5)
1474
+ sage: S.<x> = ZZ[]
1475
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1476
+ sage: W.<w> = R.ext(f)
1477
+ sage: a = W(329)
1478
+ sage: b = W(111)
1479
+ sage: a*b # indirect doctest
1480
+ 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)
1481
+ sage: a * 0
1482
+ O(w^25)
1483
+ sage: a * O(w^14)
1484
+ O(w^14)
1485
+ """
1486
+ cdef pAdicZZpXCAElement right = <pAdicZZpXCAElement>_right
1487
+ cdef pAdicZZpXCAElement ans
1488
+ cdef ZZ_pX_c self_adapted, right_adapted
1489
+ cdef long self_ordp = self.valuation_c()
1490
+ cdef long right_ordp = right.valuation_c()
1491
+ cdef long ans_ordp = self_ordp + right_ordp
1492
+ if ans_ordp >= self.prime_pow.ram_prec_cap:
1493
+ return self._new_c(self.prime_pow.ram_prec_cap)
1494
+ if self._is_inexact_zero() or right._is_inexact_zero():
1495
+ return self._new_c(ans_ordp)
1496
+ cdef long self_relprec = self.absprec - self_ordp
1497
+ cdef long right_relprec = right.absprec - right_ordp
1498
+ cdef long ans_absprec
1499
+ if self_relprec <= right_relprec:
1500
+ ans_absprec = ans_ordp + self_relprec
1501
+ else:
1502
+ ans_absprec = ans_ordp + right_relprec
1503
+ if ans_absprec > self.prime_pow.ram_prec_cap:
1504
+ ans_absprec = self.prime_pow.ram_prec_cap
1505
+ ans = self._new_c(ans_absprec) # restores the context
1506
+ if self.absprec == ans_absprec and right.absprec == ans_absprec:
1507
+ ZZ_pX_MulMod_pre(ans.value, self.value, right.value, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
1508
+ elif self.absprec == ans_absprec:
1509
+ ZZ_pX_conv_modulus(right_adapted, right.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
1510
+ ZZ_pX_MulMod_pre(ans.value, self.value, right_adapted, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
1511
+ elif right.absprec == ans_absprec:
1512
+ ZZ_pX_conv_modulus(self_adapted, self.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
1513
+ ZZ_pX_MulMod_pre(ans.value, self_adapted, right.value, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
1514
+ else:
1515
+ ZZ_pX_conv_modulus(self_adapted, self.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
1516
+ ZZ_pX_conv_modulus(right_adapted, right.value, self.prime_pow.get_context_capdiv(ans_absprec).x)
1517
+ ZZ_pX_MulMod_pre(ans.value, self_adapted, right_adapted, self.prime_pow.get_modulus_capdiv(ans_absprec)[0])
1518
+ return ans
1519
+
1520
+ cpdef _div_(self, right):
1521
+ """
1522
+ Return the quotient of ``self`` by ``right``.
1523
+
1524
+ EXAMPLES::
1525
+
1526
+ sage: R = ZpCA(5,5)
1527
+ sage: S.<x> = ZZ[]
1528
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1529
+ sage: W.<w> = R.ext(f)
1530
+ sage: W(14) / W(125) # indirect doctest
1531
+ 4*w^-15 + w^-13 + 3*w^-11 + 2*w^-10 + 3*w^-9 + 4*w^-8 + 4*w^-7 + 3*w^-6 + O(w^-5)
1532
+ sage: 1 / w
1533
+ w^-1 + O(w^23)
1534
+ sage: W.<w> = R.ext(x^20 - 165*x + 5)
1535
+ sage: a = (1 + w)^25 - 1
1536
+ sage: b = (1 + w)^5 - 1
1537
+ sage: c = (1 + w)^20 + (1 + w)^15 + (1 + w)^10 + (1 + w)^5 + 1
1538
+ sage: d = a / b; d == c
1539
+ True
1540
+ sage: d.precision_absolute()
1541
+ 95
1542
+ sage: c.precision_absolute()
1543
+ 100
1544
+ sage: 1 / a == ~a
1545
+ True
1546
+ """
1547
+ return self.to_fraction_field() * (~right)
1548
+
1549
+ def _integer_(self, Z=None):
1550
+ r"""
1551
+ Return an integer congruent to this element modulo
1552
+ `\pi`^``self.absolute_precision()``, if possible.
1553
+
1554
+ EXAMPLES::
1555
+
1556
+ sage: # needs sage.libs.flint
1557
+ sage: ZZ(ZqCA(125,names='a')(-1)) # indirect doctest
1558
+ 95367431640624
1559
+ sage: R = ZpCA(5); S.<x> = ZZ[]; f = x^5 + 25*x^3 - 5; W.<w> = R.ext(f)
1560
+ sage: ZZ(W(-1))
1561
+ 95367431640624
1562
+ sage: ZZ(W(0))
1563
+ 0
1564
+ sage: ZZ(W(0,7))
1565
+ 0
1566
+ sage: ZZ(w)
1567
+ Traceback (most recent call last):
1568
+ ...
1569
+ ValueError: this element not well approximated by an integer
1570
+ sage: ZZ(W(5))
1571
+ 5
1572
+ """
1573
+ cdef Integer ans
1574
+ cdef ZZ_c tmp_z
1575
+ if ZZ_pX_deg(self.value) > 0:
1576
+ raise ValueError("this element not well approximated by an integer")
1577
+ ans = PY_NEW(Integer)
1578
+ tmp_z = ZZ_p_rep(ZZ_pX_ConstTerm(self.value))
1579
+ ZZ_to_mpz(ans.value, &tmp_z)
1580
+ return ans
1581
+
1582
+ def __copy__(self):
1583
+ """
1584
+ Return a copy of ``self``.
1585
+
1586
+ EXAMPLES::
1587
+
1588
+ sage: R = ZpCA(5,5)
1589
+ sage: S.<x> = ZZ[]
1590
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1591
+ sage: W.<w> = R.ext(f)
1592
+ sage: b = W(45, 17); b
1593
+ 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)
1594
+ sage: c = copy(b); c
1595
+ 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)
1596
+ sage: c is b
1597
+ False
1598
+ """
1599
+ cdef pAdicZZpXCAElement ans = self._new_c(self.absprec) # restores context
1600
+ ans.value = self.value
1601
+ return ans
1602
+
1603
+ def is_zero(self, absprec=None):
1604
+ r"""
1605
+ Return whether the valuation of ``self`` is at least ``absprec``.
1606
+
1607
+ If ``absprec`` is ``None``, returns if ``self`` is indistinguishable
1608
+ from zero.
1609
+
1610
+ If ``self`` is an inexact zero of valuation less than ``absprec``,
1611
+ raises a :exc:`PrecisionError`.
1612
+
1613
+ EXAMPLES::
1614
+
1615
+ sage: R = ZpCA(5,5)
1616
+ sage: S.<x> = ZZ[]
1617
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1618
+ sage: W.<w> = R.ext(f)
1619
+ sage: O(w^189).is_zero()
1620
+ True
1621
+ sage: W(0).is_zero()
1622
+ True
1623
+ sage: a = W(675)
1624
+ sage: a.is_zero()
1625
+ False
1626
+ sage: a.is_zero(7)
1627
+ True
1628
+ sage: a.is_zero(21)
1629
+ False
1630
+ """
1631
+ cdef bint ans
1632
+ cdef long aprec
1633
+ if absprec is None:
1634
+ ans = ZZ_pX_IsZero(self.value)
1635
+ else:
1636
+ if not isinstance(absprec, Integer):
1637
+ absprec = Integer(absprec)
1638
+ if mpz_fits_slong_p((<Integer>absprec).value) == 0:
1639
+ if mpz_sgn((<Integer>absprec).value) < 0:
1640
+ ans = True
1641
+ elif ZZ_pX_IsZero(self.value):
1642
+ raise PrecisionError("not enough precision to determine if element is zero")
1643
+ else:
1644
+ ans = False
1645
+ else:
1646
+ aprec = mpz_get_si((<Integer>absprec).value)
1647
+ if ZZ_pX_IsZero(self.value) and aprec > self.absprec:
1648
+ raise PrecisionError("not enough precision to determine if element is zero")
1649
+ else:
1650
+ ans = (self.valuation_c() >= aprec)
1651
+ return ans
1652
+
1653
+ cpdef ntl_ZZ_pX _ntl_rep(self):
1654
+ """
1655
+ Return an ``ntl_ZZ_pX`` that holds the value of ``self``.
1656
+
1657
+ EXAMPLES::
1658
+
1659
+ sage: R = ZpCA(5,5)
1660
+ sage: S.<x> = ZZ[]
1661
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1662
+ sage: W.<w> = R.ext(f)
1663
+ sage: a = W(566); b = W(209)
1664
+ sage: c = a + b; c._ntl_rep() # indirect doctest
1665
+ [775]
1666
+ """
1667
+ if self.absprec == 0:
1668
+ raise ValueError("self has 0 absolute precision")
1669
+ self.prime_pow.restore_context_capdiv(self.absprec)
1670
+ cdef ntl_ZZ_pX ans = ntl_ZZ_pX.__new__(ntl_ZZ_pX)
1671
+ ans.c = self.prime_pow.get_context_capdiv(self.absprec)
1672
+ ans.x = self.value
1673
+ return ans
1674
+
1675
+ cpdef _ntl_rep_abs(self):
1676
+ """
1677
+ Return a pair ``(f, 0)`` where ``f = self._ntl_rep()``.
1678
+
1679
+ EXAMPLES::
1680
+
1681
+ sage: R = ZpCA(5,5)
1682
+ sage: S.<x> = ZZ[]
1683
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1684
+ sage: W.<w> = R.ext(f)
1685
+ sage: a = W(566); b = W(209)
1686
+ sage: c = a + b; c._ntl_rep_abs()
1687
+ ([775], 0)
1688
+ sage: c
1689
+ 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)
1690
+ sage: c._ntl_rep_abs()
1691
+ ([775], 0)
1692
+ """
1693
+ return self._ntl_rep(), Integer(0)
1694
+
1695
+ def _polynomial_list(self, pad=False):
1696
+ """
1697
+ Return the coefficient list for a polynomial over the base ring
1698
+ yielding this element.
1699
+
1700
+ INPUT:
1701
+
1702
+ - ``pad`` -- whether to pad the result with zeros of the appropriate precision
1703
+
1704
+ EXAMPLES::
1705
+
1706
+ sage: R.<x> = ZZ[]
1707
+ sage: W.<w> = ZpCA(5).extension(x^3 - 5)
1708
+ sage: (1 + w + O(w^11))._polynomial_list()
1709
+ [1 + O(5^4), 1 + O(5^4)]
1710
+ sage: (1 + w + O(w^11))._polynomial_list(pad=True)
1711
+ [1 + O(5^4), 1 + O(5^4), O(5^3)]
1712
+ sage: W(0)._polynomial_list()
1713
+ []
1714
+ sage: W(0)._polynomial_list(pad=True)
1715
+ [O(5^20), O(5^20), O(5^20)]
1716
+ sage: W(O(w^7))._polynomial_list()
1717
+ []
1718
+ sage: W(O(w^7))._polynomial_list(pad=True)
1719
+ [O(5^3), O(5^2), O(5^2)]
1720
+ """
1721
+ R = self.base_ring()
1722
+ if self.is_zero():
1723
+ L = []
1724
+ else:
1725
+ L = [Integer(c) for c in self._ntl_rep().list()]
1726
+ if pad:
1727
+ n = self.parent().degree()
1728
+ L.extend([R.zero()] * (n - len(L)))
1729
+ e = self.parent().e()
1730
+ if e == 1:
1731
+ return [R(c, self.absprec) for c in L]
1732
+ else:
1733
+ return [R(c, (self.absprec - i - 1) // e + 1) for i, c in enumerate(L)]
1734
+
1735
+ def polynomial(self, var='x'):
1736
+ """
1737
+ Return a polynomial over the base ring that yields this element
1738
+ when evaluated at the generator of the parent.
1739
+
1740
+ INPUT:
1741
+
1742
+ - ``var`` -- string, the variable name for the polynomial
1743
+
1744
+ EXAMPLES::
1745
+
1746
+ sage: S.<x> = ZZ[]
1747
+ sage: W.<w> = ZpCA(5).extension(x^2 - 5)
1748
+ sage: (w + W(5, 7)).polynomial()
1749
+ (1 + O(5^3))*x + 5 + O(5^4)
1750
+ """
1751
+ R = self.base_ring()
1752
+ S = R[var]
1753
+ return S(self._polynomial_list())
1754
+
1755
+ cdef ZZ_p_c _const_term(self) noexcept:
1756
+ """
1757
+ Return the constant term of ``self.value``.
1758
+
1759
+ EXAMPLES::
1760
+
1761
+ sage: R = ZpCA(5,5)
1762
+ sage: S.<x> = R[]
1763
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1764
+ sage: W.<w> = R.ext(f)
1765
+ sage: a = W(566)
1766
+ sage: a._const_term_test() # indirect doctest
1767
+ 566
1768
+ """
1769
+ return ZZ_pX_ConstTerm(self.value)
1770
+
1771
+ def is_equal_to(self, right, absprec=None):
1772
+ """
1773
+ Return whether ``self`` is equal to ``right`` modulo
1774
+ ``self.uniformizer()^absprec``.
1775
+
1776
+ If ``absprec`` is ``None``, returns if ``self`` is equal to ``right`` modulo
1777
+ the lower of their two precisions.
1778
+
1779
+ EXAMPLES::
1780
+
1781
+ sage: R = ZpCA(5,5)
1782
+ sage: S.<x> = ZZ[]
1783
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1784
+ sage: W.<w> = R.ext(f)
1785
+ sage: a = W(47); b = W(47 + 25)
1786
+ sage: a.is_equal_to(b)
1787
+ False
1788
+ sage: a.is_equal_to(b, 7)
1789
+ True
1790
+ """
1791
+ # Should be sped up later
1792
+ return (self - right).is_zero(absprec)
1793
+
1794
+ cpdef pAdicZZpXCAElement lift_to_precision(self, absprec=None):
1795
+ """
1796
+ Return a ``pAdicZZpXCAElement`` congruent to ``self`` but with
1797
+ absolute precision at least ``absprec``.
1798
+
1799
+ INPUT:
1800
+
1801
+ - ``absprec`` -- (default: ``None``) the absolute precision of
1802
+ the result. If ``None``, lifts to the maximum precision
1803
+ allowed.
1804
+
1805
+ .. NOTE::
1806
+
1807
+ If setting ``absprec`` that high would violate the
1808
+ precision cap, raises a precision error.
1809
+
1810
+ Note that the new digits will not necessarily be zero.
1811
+
1812
+ EXAMPLES::
1813
+
1814
+ sage: R = ZpCA(5,5)
1815
+ sage: S.<x> = ZZ[]
1816
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1817
+ sage: W.<w> = R.ext(f)
1818
+ sage: a = W(345, 17); a
1819
+ 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)
1820
+ sage: b = a.lift_to_precision(19); b # indirect doctest
1821
+ 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 + w^17 + 2*w^18 + O(w^19)
1822
+ sage: c = a.lift_to_precision(24); c
1823
+ 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 + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24)
1824
+ sage: a._ntl_rep()
1825
+ [345]
1826
+ sage: b._ntl_rep()
1827
+ [345]
1828
+ sage: c._ntl_rep()
1829
+ [345]
1830
+ sage: a.lift_to_precision().precision_absolute() == W.precision_cap()
1831
+ True
1832
+ """
1833
+ cdef pAdicZZpXCAElement ans
1834
+ cdef long aprec
1835
+ if absprec is not None and not isinstance(absprec, Integer):
1836
+ absprec = Integer(absprec)
1837
+ if absprec is None:
1838
+ aprec = self.prime_pow.ram_prec_cap
1839
+ elif mpz_fits_slong_p((<Integer>absprec).value) == 0:
1840
+ if mpz_sgn((<Integer>absprec).value) < 0:
1841
+ return self
1842
+ else:
1843
+ raise PrecisionError("precision higher than allowed by the precision cap")
1844
+ else:
1845
+ aprec = mpz_get_si((<Integer>absprec).value)
1846
+ if aprec > self.prime_pow.ram_prec_cap:
1847
+ raise PrecisionError("precision higher than allowed by the precision cap")
1848
+ if aprec <= self.absprec:
1849
+ return self
1850
+ ans = self._new_c(aprec) # restores context
1851
+ ZZ_pX_conv_modulus(ans.value, self.value, self.prime_pow.get_context_capdiv(aprec).x)
1852
+ return ans
1853
+
1854
+ def expansion(self, n=None, lift_mode='simple'):
1855
+ """
1856
+ Return a list giving a series representation of ``self``.
1857
+
1858
+ - If ``lift_mode == 'simple'`` or ``'smallest'``, the returned
1859
+ list will consist of integers (in the Eisenstein case) or a
1860
+ list of lists of integers (in the unramified case).
1861
+ ``self`` can be reconstructed as a sum of elements of the
1862
+ list times powers of the uniformiser (in the Eisenstein
1863
+ case), or as a sum of powers of `p` times polynomials in the
1864
+ generator (in the unramified case).
1865
+
1866
+ + If ``lift_mode == 'simple'``, all integers will be in the
1867
+ interval `[0,p-1]`
1868
+
1869
+ + If ``lift_mod == 'smallest'`` they will be in the
1870
+ interval `[(1-p)/2, p/2]`.
1871
+
1872
+ - If ``lift_mode == 'teichmuller'``, returns a list of
1873
+ ``pAdicZZpXCAElements``, all of which are Teichmuller
1874
+ representatives and such that ``self`` is the sum of that
1875
+ list times powers of the uniformizer.
1876
+
1877
+ INPUT:
1878
+
1879
+ - ``n`` -- integer (default: ``None``); if given, returns the
1880
+ corresponding entry in the expansion
1881
+
1882
+ EXAMPLES::
1883
+
1884
+ sage: R = ZpCA(5,5)
1885
+ sage: S.<x> = ZZ[]
1886
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1887
+ sage: W.<w> = R.ext(f)
1888
+ sage: y = W(775, 19); y
1889
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
1890
+ sage: (y>>9).expansion()
1891
+ [0, 1, 0, 4, 0, 2, 1, 2, 4, 1]
1892
+ sage: (y>>9).expansion(lift_mode='smallest')
1893
+ [0, 1, 0, -1, 0, 2, 1, 2, 0, 1]
1894
+ sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
1895
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
1896
+ sage: g = x^3 + 3*x + 3
1897
+
1898
+ sage: # needs sage.libs.flint
1899
+ sage: A.<a> = R.ext(g)
1900
+ sage: y = 75 + 45*a + 1200*a^2; y
1901
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
1902
+ sage: E = y.expansion(); E
1903
+ 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^5)
1904
+ sage: list(E)
1905
+ [[], [0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]]
1906
+ sage: list(y.expansion(lift_mode='smallest'))
1907
+ [[], [0, -1], [-2, 2, -2], [1], [0, 0, 2]]
1908
+ sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
1909
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
1910
+ sage: W(0).expansion()
1911
+ []
1912
+ sage: list(A(0,4).expansion())
1913
+ []
1914
+
1915
+ Check that :issue:`25879` has been resolved::
1916
+
1917
+ sage: K = ZpCA(3,5)
1918
+ sage: R.<a> = K[]
1919
+ sage: L.<a> = K.extension(a^2 - 3)
1920
+ sage: a.residue()
1921
+ 0
1922
+ """
1923
+ if lift_mode == 'teichmuller':
1924
+ zero = self.parent()(0)
1925
+ elif self.prime_pow.e == 1:
1926
+ zero = []
1927
+ else:
1928
+ zero = Integer(0)
1929
+ ordp = self.valuation()
1930
+ if isinstance(n, slice):
1931
+ return self.slice(n.start, n.stop, n.step)
1932
+ elif n is not None:
1933
+ if self.is_zero() or n < ordp:
1934
+ return zero
1935
+ elif n >= self.absprec:
1936
+ raise PrecisionError
1937
+ if self.is_zero():
1938
+ return []
1939
+ if lift_mode == 'simple':
1940
+ ulist = self.ext_p_list(pos=True)
1941
+ elif lift_mode == 'smallest':
1942
+ ulist = self.ext_p_list(pos=False)
1943
+ elif lift_mode == 'teichmuller':
1944
+ if n is None:
1945
+ ulist = self.teichmuller_expansion()
1946
+ else:
1947
+ return self.teichmuller_expansion(n)
1948
+ else:
1949
+ raise ValueError("lift mode must be one of 'simple', 'smallest' or 'teichmuller'")
1950
+ if n is not None:
1951
+ try:
1952
+ return ulist[n - ordp]
1953
+ except IndexError:
1954
+ return zero
1955
+ return [zero] * ordp + ulist
1956
+
1957
+ def matrix_mod_pn(self):
1958
+ r"""
1959
+ Return the matrix of right multiplication by the element on
1960
+ the power basis `1, x, x^2, \ldots, x^{d-1}` for this
1961
+ extension field. Thus the *rows* of this matrix give the
1962
+ images of each of the `x^i`. The entries of the matrices are
1963
+ ``IntegerMod`` elements, defined modulo ``p^(self.absprec() / e)``.
1964
+
1965
+ EXAMPLES::
1966
+
1967
+ sage: R = ZpCA(5,5)
1968
+ sage: S.<x> = ZZ[]
1969
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
1970
+ sage: W.<w> = R.ext(f)
1971
+ sage: a = (3+w)^7
1972
+ sage: a.matrix_mod_pn() # needs sage.geometry.polyhedron
1973
+ [2757 333 1068 725 2510]
1974
+ [ 50 1507 483 318 725]
1975
+ [ 500 50 3007 2358 318]
1976
+ [1590 1375 1695 1032 2358]
1977
+ [2415 590 2370 2970 1032]
1978
+ """
1979
+ from sage.matrix.constructor import matrix
1980
+ # this may be the wrong precision when ram_prec_cap is not divisible by e.
1981
+ R = IntegerModRing(self.prime_pow.pow_Integer(self.prime_pow.capdiv(self.absprec)))
1982
+ n = self.prime_pow.deg
1983
+ L = []
1984
+ cdef ntl_ZZ_pX cur = <ntl_ZZ_pX>self._ntl_rep()
1985
+ cur.c.restore_c()
1986
+ cdef ZZ_pX_Modulus_c* m = self.prime_pow.get_modulus_capdiv(self.absprec)
1987
+ cdef ZZ_pX_c x
1988
+ ZZ_pX_SetX(x)
1989
+ cdef Py_ssize_t i
1990
+ zero = int(0)
1991
+ for i in range(n):
1992
+ curlist = cur.list()
1993
+ L.extend(curlist + [zero]*(n - len(curlist)))
1994
+ ZZ_pX_MulMod_pre(cur.x, cur.x, x, m[0])
1995
+ return matrix(R, n, n, L)
1996
+
1997
+ # def matrix(self, base=None):
1998
+ # """
1999
+ # If base is None, return the matrix of right multiplication by
2000
+ # the element on the power basis `1, x, x^2, \ldots, x^{d-1}`
2001
+ # for this extension field. Thus the \emph{rows} of this matrix
2002
+ # give the images of each of the `x^i`.
2003
+
2004
+ # If base is not None, then base must be either a field that
2005
+ # embeds in the parent of self or a morphism to the parent of
2006
+ # self, in which case this function returns the matrix of
2007
+ # multiplication by self on the power basis, where we view the
2008
+ # parent field as a field over base.
2009
+
2010
+ # INPUT:
2011
+
2012
+ # - ``base`` -- field or morphism
2013
+ # """
2014
+ # raise NotImplementedError
2015
+
2016
+ # def multiplicative_order(self, prec=None):
2017
+ # """
2018
+ # Returns the multiplicative order of ``self``, ie the smallest
2019
+ # positive `n` so that there is an exact `p`-adic element congruent
2020
+ # to ``self`` modulo ``self``'s precision that is an `n`-th root of unity.
2021
+
2022
+ # Note: unlike the case for Qp and Zp, it is possible to have
2023
+ # non-teichmuller elements with finite orders. This can happen
2024
+ # only if (p-1) divides the ramification index (see the
2025
+ # documentation on __pow__).
2026
+
2027
+ # INPUT:
2028
+
2029
+ # - self -- a `p`-adic element
2030
+ # - ``prec`` -- integer
2031
+
2032
+ # OUTPUT: integer; the multiplicative order of self
2033
+ # """
2034
+ # raise NotImplementedError
2035
+
2036
+ def teichmuller_expansion(self, n=None):
2037
+ r"""
2038
+ Return a list [`a_0`, `a_1`,..., `a_n`] such that:
2039
+
2040
+ - `a_i^q = a_i`
2041
+ - ``self.unit_part()`` = `\sum_{i = 0}^n a_i \pi^i`, where `\pi` is a
2042
+ uniformizer of self.parent()
2043
+ - if `a_i \ne 0`, the absolute precision of `a_i` is
2044
+ ``self.precision_relative() - i``
2045
+
2046
+ INPUT:
2047
+
2048
+ - ``n`` -- integer (default: ``None``); if given, returns the
2049
+ corresponding entry in the expansion
2050
+
2051
+ EXAMPLES::
2052
+
2053
+ sage: R.<a> = Zq(5^4,4)
2054
+ sage: E = a.teichmuller_expansion(); E
2055
+ 5-adic expansion of a + O(5^4) (teichmuller)
2056
+ sage: list(E)
2057
+ [a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2 + (4*a^2 + 2*a + 2)*5^3 + O(5^4),
2058
+ (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),
2059
+ (4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2),
2060
+ (a^3 + a^2 + a + 4) + O(5)]
2061
+ sage: sum([c * 5^i for i, c in enumerate(E)])
2062
+ a + O(5^4)
2063
+ sage: all(c^625 == c for c in E)
2064
+ True
2065
+
2066
+ sage: S.<x> = ZZ[]
2067
+ sage: f = x^3 - 98*x + 7
2068
+ sage: W.<w> = ZpCA(7,3).ext(f)
2069
+ sage: b = (1+w)^5; L = b.teichmuller_expansion(); L
2070
+ [1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7),
2071
+ 3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3), 6 + O(w^2), 6 + O(w)]
2072
+ sage: sum([w^i*L[i] for i in range(9)]) == b
2073
+ True
2074
+ sage: all(L[i]^(7^3) == L[i] for i in range(9))
2075
+ True
2076
+
2077
+ sage: L = W(3).teichmuller_expansion(); L
2078
+ [3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6), O(w^5),
2079
+ O(w^4), 3 + O(w^3), 6 + O(w^2)]
2080
+ sage: sum([w^i*L[i] for i in range(len(L))])
2081
+ 3 + O(w^9)
2082
+ """
2083
+ cdef long ordp = self.valuation_c()
2084
+ cdef long rp = self.absprec - ordp
2085
+ cdef long goal
2086
+ if n is not None:
2087
+ goal = self.absprec - n
2088
+ cdef pAdicZZpXCAElement v
2089
+ if n is None:
2090
+ L = []
2091
+ if rp == 0:
2092
+ return L
2093
+ elif n < ordp:
2094
+ return self.parent()(0)
2095
+ elif n >= self.absprec:
2096
+ raise PrecisionError
2097
+ else:
2098
+ v = self._new_c(rp)
2099
+ cdef pAdicZZpXCAElement u = self.unit_part()
2100
+ if u is self:
2101
+ u = self.__copy__()
2102
+ while not ZZ_pX_IsZero(u.value):
2103
+ v = self._new_c(rp)
2104
+ self.prime_pow.teichmuller_set_c(&v.value, &u.value, rp)
2105
+ if n is None:
2106
+ L.append(v)
2107
+ elif rp == goal:
2108
+ return v
2109
+ if rp == 1:
2110
+ break
2111
+ ZZ_pX_sub(u.value, u.value, v.value)
2112
+ rp -= 1
2113
+ if self.prime_pow.e == 1:
2114
+ ZZ_pX_right_pshift(u.value, u.value, self.prime_pow.pow_ZZ_tmp(1)[0], self.prime_pow.get_context(rp).x)
2115
+ else:
2116
+ self.prime_pow.eis_shift_capdiv(&u.value, &u.value, 1, rp)
2117
+ if n is None:
2118
+ return L
2119
+ else:
2120
+ return self.parent()(0, rp)
2121
+
2122
+ def _teichmuller_set_unsafe(self):
2123
+ """
2124
+ Set this element to the Teichmuller representative with the
2125
+ same residue.
2126
+
2127
+ .. WARNING::
2128
+
2129
+ This function modifies the element, which is not safe.
2130
+ Elements are supposed to be immutable.
2131
+
2132
+ EXAMPLES::
2133
+
2134
+ sage: R = ZpCA(11,5)
2135
+ sage: S.<x> = ZZ[]
2136
+ sage: f = x^5 + 33*x^3 - 121*x^2 - 77
2137
+ sage: W.<w> = R.ext(f)
2138
+ sage: y = W.teichmuller(3, 19); y # indirect doctest
2139
+ 3 + 9*w^10 + 3*w^13 + 3*w^15 + 9*w^16 + 3*w^17 + w^18 + O(w^19)
2140
+ sage: y^11 == y
2141
+ True
2142
+ sage: g = x^3 + 9*x^2 + 7
2143
+
2144
+ sage: # needs sage.libs.flint
2145
+ sage: A.<a> = R.ext(g)
2146
+ sage: b = A.teichmuller(1 + 2*a - a^2); b
2147
+ (10*a^2 + 2*a + 1) + (4*a^2 + 7)*11 + (5*a^2 + a + 3)*11^2 + (a^2 + 9*a + 6)*11^3 + (7*a^2 + 2*a + 3)*11^4 + O(11^5)
2148
+ sage: b^1331 == b
2149
+ True
2150
+
2151
+ TESTS:
2152
+
2153
+ Check that :issue:`22083` has been resolved::
2154
+
2155
+ sage: R.<a> = ZpCA(2).extension(x^2 - 2)
2156
+ sage: R.teichmuller(a)
2157
+ O(a^40)
2158
+ """
2159
+ if self.absprec == 0:
2160
+ raise ValueError("not enough precision known")
2161
+ elif self.valuation_c() > 0:
2162
+ self._set_inexact_zero(self.prime_pow.ram_prec_cap)
2163
+ else:
2164
+ self.prime_pow.teichmuller_set_c(&self.value, &self.value, self.absprec)
2165
+
2166
+ # def padded_list(self, n, lift_mode='simple'):
2167
+ # """
2168
+ # Returns a list of coefficients of pi starting with `pi^0` up to
2169
+ # `pi^n` exclusive (padded with zeros if needed)
2170
+
2171
+ # """
2172
+ # raise NotImplementedError
2173
+
2174
+ def precision_absolute(self):
2175
+ """
2176
+ Return the absolute precision of ``self``, ie the power of the
2177
+ uniformizer modulo which this element is defined.
2178
+
2179
+ EXAMPLES::
2180
+
2181
+ sage: R = ZpCA(5,5)
2182
+ sage: S.<x> = ZZ[]
2183
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2184
+ sage: W.<w> = R.ext(f)
2185
+ sage: a = W(75, 19); a
2186
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
2187
+ sage: a.valuation()
2188
+ 10
2189
+ sage: a.precision_absolute()
2190
+ 19
2191
+ sage: a.precision_relative()
2192
+ 9
2193
+ sage: a.unit_part()
2194
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
2195
+ """
2196
+ cdef Integer ans = PY_NEW(Integer)
2197
+ mpz_set_si(ans.value, self.absprec)
2198
+ return ans
2199
+
2200
+ def precision_relative(self):
2201
+ """
2202
+ Return the relative precision of ``self``, ie the power of
2203
+ the uniformizer modulo which the unit part of ``self`` is
2204
+ defined.
2205
+
2206
+ EXAMPLES::
2207
+
2208
+ sage: R = ZpCA(5,5)
2209
+ sage: S.<x> = ZZ[]
2210
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2211
+ sage: W.<w> = R.ext(f)
2212
+ sage: a = W(75, 19); a
2213
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
2214
+ sage: a.valuation()
2215
+ 10
2216
+ sage: a.precision_absolute()
2217
+ 19
2218
+ sage: a.precision_relative()
2219
+ 9
2220
+ sage: a.unit_part()
2221
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
2222
+ """
2223
+ cdef Integer ans = PY_NEW(Integer)
2224
+ mpz_set_ui(ans.value, self.absprec - self.valuation_c())
2225
+ return ans
2226
+
2227
+ # def residue(self, n):
2228
+ # """
2229
+ # Reduces this element modulo pi^n.
2230
+ # """
2231
+ # raise NotImplementedError
2232
+
2233
+ cdef long valuation_c(self) noexcept:
2234
+ """
2235
+ Return the valuation of ``self``.
2236
+
2237
+ EXAMPLES::
2238
+
2239
+ sage: R = ZpCA(5,5)
2240
+ sage: S.<x> = ZZ[]
2241
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2242
+ sage: W.<w> = R.ext(f)
2243
+ sage: a = W(75, 19); a
2244
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
2245
+ sage: a.valuation() # indirect doctest
2246
+ 10
2247
+ sage: a.precision_absolute()
2248
+ 19
2249
+ sage: a.precision_relative()
2250
+ 9
2251
+ sage: a.unit_part()
2252
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
2253
+ """
2254
+ if ZZ_pX_IsZero(self.value):
2255
+ return self.absprec
2256
+ cdef long minval = 0, mini = 0, val
2257
+ ZZ_pX_min_val_coeff(minval, mini, self.value, self.prime_pow.pow_ZZ_tmp(1)[0])
2258
+ if self.prime_pow.e == 1:
2259
+ if minval <= self.absprec:
2260
+ return minval
2261
+ else:
2262
+ return self.absprec
2263
+ else:
2264
+ val = minval * self.prime_pow.e + mini
2265
+ if val <= self.absprec:
2266
+ return val
2267
+ else:
2268
+ return self.absprec
2269
+
2270
+ cpdef pAdicZZpXCAElement unit_part(self):
2271
+ """
2272
+ Return the unit part of ``self``, ie ``self / uniformizer^(self.valuation())``.
2273
+
2274
+ EXAMPLES::
2275
+
2276
+ sage: R = ZpCA(5,5)
2277
+ sage: S.<x> = ZZ[]
2278
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2279
+ sage: W.<w> = R.ext(f)
2280
+ sage: a = W(75, 19); a
2281
+ 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19)
2282
+ sage: a.valuation()
2283
+ 10
2284
+ sage: a.precision_absolute()
2285
+ 19
2286
+ sage: a.precision_relative()
2287
+ 9
2288
+ sage: a.unit_part()
2289
+ 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
2290
+ """
2291
+ return self._rshift_c(self.valuation_c())
2292
+
2293
+ cdef ext_p_list(self, bint pos):
2294
+ """
2295
+ Return a list of integers (in the Eisenstein case) or a list
2296
+ of lists of integers (in the unramified case). ``self`` can
2297
+ be reconstructed as a sum of elements of the list times powers
2298
+ of the uniformizer (in the Eisenstein case), or as a sum of
2299
+ powers of `p` times polynomials in the generator (in the
2300
+ unramified case).
2301
+
2302
+ If ``pos`` is ``True``, all integers will be in the interval
2303
+ `[0,p-1]`, otherwise they will be in the range
2304
+ `[(1-p)/2,p/2]`.
2305
+
2306
+ Note that zeros are truncated from the returned list, so you
2307
+ must use the ``valuation()`` function to completely recover
2308
+ ``self``.
2309
+
2310
+ EXAMPLES::
2311
+
2312
+ sage: R = ZpCA(5,5)
2313
+ sage: S.<x> = ZZ[]
2314
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2315
+ sage: W.<w> = R.ext(f)
2316
+ sage: y = W(775, 19); y
2317
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
2318
+ sage: y._ext_p_list(True)
2319
+ [1, 0, 4, 0, 2, 1, 2, 4, 1]
2320
+ sage: y._ext_p_list(False)
2321
+ [1, 0, -1, 0, 2, 1, 2, 0, 1]
2322
+ sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19)
2323
+ w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19)
2324
+ sage: g = x^3 + 3*x + 3
2325
+
2326
+ sage: # needs sage.libs.flint
2327
+ sage: A.<a> = R.ext(g)
2328
+ sage: y = 75 + 45*a + 1200*a^2; y
2329
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
2330
+ sage: y._ext_p_list(True)
2331
+ [[0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]]
2332
+ sage: y._ext_p_list(False)
2333
+ [[0, -1], [-2, 2, -2], [1], [0, 0, 2]]
2334
+ sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2)
2335
+ 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5)
2336
+ """
2337
+ return self.ext_p_list_precs(pos, self.absprec)
2338
+
2339
+
2340
+ def make_ZZpXCAElement(parent, value, absprec, version):
2341
+ """
2342
+ For pickling. Makes a ``pAdicZZpXCAElement`` with given ``parent``, ``value``, ``absprec``.
2343
+
2344
+ EXAMPLES::
2345
+
2346
+ sage: from sage.rings.padics.padic_ZZ_pX_CA_element import make_ZZpXCAElement
2347
+ sage: R = ZpCA(5,5)
2348
+ sage: S.<x> = ZZ[]
2349
+ sage: f = x^5 + 75*x^3 - 15*x^2 + 125*x - 5
2350
+ sage: W.<w> = R.ext(f)
2351
+ sage: make_ZZpXCAElement(W, ntl.ZZ_pX([3,2,4],5^3),13,0)
2352
+ 3 + 2*w + 4*w^2 + O(w^13)
2353
+ """
2354
+ cdef pAdicZZpXCAElement ans
2355
+ cdef ZZ_pX_c poly
2356
+ if version == 0:
2357
+ ans = pAdicZZpXCAElement(parent, [], empty = True)
2358
+ if mpz_sgn((<Integer>absprec).value) == 0:
2359
+ ans._set_inexact_zero(0)
2360
+ else:
2361
+ ans.prime_pow.restore_context_capdiv(mpz_get_si((<Integer>absprec).value))
2362
+ poly = (<ntl_ZZ_pX>value).x
2363
+ ans._set(&poly, mpz_get_si((<Integer>absprec).value))
2364
+ return ans
2365
+ else:
2366
+ raise ValueError("unknown unpickling version")