passagemath-ntl 10.6.37__cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-ntl might be problematic. Click here for more details.

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