passagemath-ntl 10.6.33__cp313-cp313-musllinux_1_2_x86_64.whl

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

Potentially problematic release.


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

Files changed (163) hide show
  1. passagemath_ntl-10.6.33.dist-info/METADATA +122 -0
  2. passagemath_ntl-10.6.33.dist-info/RECORD +163 -0
  3. passagemath_ntl-10.6.33.dist-info/WHEEL +5 -0
  4. passagemath_ntl-10.6.33.dist-info/top_level.txt +2 -0
  5. passagemath_ntl.libs/libgcc_s-0cd532bd.so.1 +0 -0
  6. passagemath_ntl.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
  7. passagemath_ntl.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
  8. passagemath_ntl.libs/libmpfi-2153e8c2.so.0.0.0 +0 -0
  9. passagemath_ntl.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
  10. passagemath_ntl.libs/libntl-26885ca2.so.44.0.1 +0 -0
  11. passagemath_ntl.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
  12. sage/all__sagemath_ntl.py +7 -0
  13. sage/libs/all__sagemath_ntl.py +3 -0
  14. sage/libs/mpfi/__init__.pxd +287 -0
  15. sage/libs/mpfi/types.pxd +10 -0
  16. sage/libs/ntl/GF2.pxd +18 -0
  17. sage/libs/ntl/GF2E.pxd +28 -0
  18. sage/libs/ntl/GF2EX.pxd +12 -0
  19. sage/libs/ntl/GF2X.pxd +81 -0
  20. sage/libs/ntl/ZZ.pxd +93 -0
  21. sage/libs/ntl/ZZX.pxd +85 -0
  22. sage/libs/ntl/ZZ_p.pxd +28 -0
  23. sage/libs/ntl/ZZ_pE.pxd +37 -0
  24. sage/libs/ntl/ZZ_pEX.pxd +106 -0
  25. sage/libs/ntl/ZZ_pX.pxd +122 -0
  26. sage/libs/ntl/__init__.py +4 -0
  27. sage/libs/ntl/all.py +72 -0
  28. sage/libs/ntl/conversion.pxd +106 -0
  29. sage/libs/ntl/convert.cpython-313-x86_64-linux-musl.so +0 -0
  30. sage/libs/ntl/convert.pxd +7 -0
  31. sage/libs/ntl/convert.pyx +38 -0
  32. sage/libs/ntl/decl.pxi +18 -0
  33. sage/libs/ntl/error.cpython-313-x86_64-linux-musl.so +0 -0
  34. sage/libs/ntl/error.pyx +63 -0
  35. sage/libs/ntl/lzz_p.pxd +20 -0
  36. sage/libs/ntl/lzz_pX.pxd +59 -0
  37. sage/libs/ntl/mat_GF2.pxd +30 -0
  38. sage/libs/ntl/mat_GF2E.pxd +30 -0
  39. sage/libs/ntl/mat_ZZ.pxd +59 -0
  40. sage/libs/ntl/misc.pxi +33 -0
  41. sage/libs/ntl/ntl_GF2.cpython-313-x86_64-linux-musl.so +0 -0
  42. sage/libs/ntl/ntl_GF2.pxd +5 -0
  43. sage/libs/ntl/ntl_GF2.pyx +281 -0
  44. sage/libs/ntl/ntl_GF2E.cpython-313-x86_64-linux-musl.so +0 -0
  45. sage/libs/ntl/ntl_GF2E.pxd +8 -0
  46. sage/libs/ntl/ntl_GF2E.pyx +488 -0
  47. sage/libs/ntl/ntl_GF2EContext.cpython-313-x86_64-linux-musl.so +0 -0
  48. sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
  49. sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
  50. sage/libs/ntl/ntl_GF2EX.cpython-313-x86_64-linux-musl.so +0 -0
  51. sage/libs/ntl/ntl_GF2EX.pxd +10 -0
  52. sage/libs/ntl/ntl_GF2EX.pyx +251 -0
  53. sage/libs/ntl/ntl_GF2X.cpython-313-x86_64-linux-musl.so +0 -0
  54. sage/libs/ntl/ntl_GF2X.pxd +5 -0
  55. sage/libs/ntl/ntl_GF2X.pyx +771 -0
  56. sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
  57. sage/libs/ntl/ntl_ZZ.cpython-313-x86_64-linux-musl.so +0 -0
  58. sage/libs/ntl/ntl_ZZ.pxd +7 -0
  59. sage/libs/ntl/ntl_ZZ.pyx +541 -0
  60. sage/libs/ntl/ntl_ZZX.cpython-313-x86_64-linux-musl.so +0 -0
  61. sage/libs/ntl/ntl_ZZX.pxd +7 -0
  62. sage/libs/ntl/ntl_ZZX.pyx +1206 -0
  63. sage/libs/ntl/ntl_ZZ_p.cpython-313-x86_64-linux-musl.so +0 -0
  64. sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
  65. sage/libs/ntl/ntl_ZZ_p.pyx +509 -0
  66. sage/libs/ntl/ntl_ZZ_pContext.cpython-313-x86_64-linux-musl.so +0 -0
  67. sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
  68. sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
  69. sage/libs/ntl/ntl_ZZ_pE.cpython-313-x86_64-linux-musl.so +0 -0
  70. sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
  71. sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
  72. sage/libs/ntl/ntl_ZZ_pEContext.cpython-313-x86_64-linux-musl.so +0 -0
  73. sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
  74. sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
  75. sage/libs/ntl/ntl_ZZ_pEX.cpython-313-x86_64-linux-musl.so +0 -0
  76. sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
  77. sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
  78. sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
  79. sage/libs/ntl/ntl_ZZ_pX.cpython-313-x86_64-linux-musl.so +0 -0
  80. sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
  81. sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
  82. sage/libs/ntl/ntl_lzz_p.cpython-313-x86_64-linux-musl.so +0 -0
  83. sage/libs/ntl/ntl_lzz_p.pxd +8 -0
  84. sage/libs/ntl/ntl_lzz_p.pyx +440 -0
  85. sage/libs/ntl/ntl_lzz_pContext.cpython-313-x86_64-linux-musl.so +0 -0
  86. sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
  87. sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
  88. sage/libs/ntl/ntl_lzz_pX.cpython-313-x86_64-linux-musl.so +0 -0
  89. sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
  90. sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
  91. sage/libs/ntl/ntl_mat_GF2.cpython-313-x86_64-linux-musl.so +0 -0
  92. sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
  93. sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
  94. sage/libs/ntl/ntl_mat_GF2E.cpython-313-x86_64-linux-musl.so +0 -0
  95. sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
  96. sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
  97. sage/libs/ntl/ntl_mat_ZZ.cpython-313-x86_64-linux-musl.so +0 -0
  98. sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
  99. sage/libs/ntl/ntl_mat_ZZ.pyx +1523 -0
  100. sage/libs/ntl/ntl_tools.pxd +3 -0
  101. sage/libs/ntl/ntlwrap.h +53 -0
  102. sage/libs/ntl/ntlwrap_impl.h +743 -0
  103. sage/libs/ntl/types.pxd +157 -0
  104. sage/libs/ntl/vec_GF2.pxd +26 -0
  105. sage/libs/ntl/vec_GF2E.pxd +2 -0
  106. sage/matrix/all__sagemath_ntl.py +1 -0
  107. sage/matrix/matrix_modn_dense_double.pxd +10 -0
  108. sage/matrix/matrix_modn_dense_float.pxd +9 -0
  109. sage/matrix/matrix_modn_dense_template.pxi +3257 -0
  110. sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
  111. sage/matrix/matrix_modn_sparse.pxd +8 -0
  112. sage/misc/all__sagemath_ntl.py +1 -0
  113. sage/rings/all__sagemath_ntl.py +7 -0
  114. sage/rings/bernmm.cpython-313-x86_64-linux-musl.so +0 -0
  115. sage/rings/bernmm.pyx +161 -0
  116. sage/rings/bernoulli_mod_p.cpython-313-x86_64-linux-musl.so +0 -0
  117. sage/rings/bernoulli_mod_p.pyx +313 -0
  118. sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
  119. sage/rings/finite_rings/finite_field_ntl_gf2e.py +305 -0
  120. sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-313-x86_64-linux-musl.so +0 -0
  121. sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
  122. sage/rings/padics/all__sagemath_ntl.py +5 -0
  123. sage/rings/padics/padic_ZZ_pX_CA_element.cpython-313-x86_64-linux-musl.so +0 -0
  124. sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
  125. sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2368 -0
  126. sage/rings/padics/padic_ZZ_pX_CR_element.cpython-313-x86_64-linux-musl.so +0 -0
  127. sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
  128. sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3277 -0
  129. sage/rings/padics/padic_ZZ_pX_FM_element.cpython-313-x86_64-linux-musl.so +0 -0
  130. sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
  131. sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1739 -0
  132. sage/rings/padics/padic_ZZ_pX_element.cpython-313-x86_64-linux-musl.so +0 -0
  133. sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
  134. sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
  135. sage/rings/padics/padic_ext_element.cpython-313-x86_64-linux-musl.so +0 -0
  136. sage/rings/padics/padic_ext_element.pxd +38 -0
  137. sage/rings/padics/padic_ext_element.pyx +512 -0
  138. sage/rings/padics/pow_computer_ext.cpython-313-x86_64-linux-musl.so +0 -0
  139. sage/rings/padics/pow_computer_ext.pxd +107 -0
  140. sage/rings/padics/pow_computer_ext.pyx +2401 -0
  141. sage/rings/polynomial/all__sagemath_ntl.py +1 -0
  142. sage/rings/polynomial/evaluation_ntl.cpython-313-x86_64-linux-musl.so +0 -0
  143. sage/rings/polynomial/evaluation_ntl.pxd +7 -0
  144. sage/rings/polynomial/evaluation_ntl.pyx +70 -0
  145. sage/rings/polynomial/polynomial_gf2x.cpython-313-x86_64-linux-musl.so +0 -0
  146. sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
  147. sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
  148. sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-313-x86_64-linux-musl.so +0 -0
  149. sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
  150. sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
  151. sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-313-x86_64-linux-musl.so +0 -0
  152. sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
  153. sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2049 -0
  154. sage/rings/polynomial/polynomial_template.pxi +842 -0
  155. sage/rings/polynomial/polynomial_template_header.pxi +11 -0
  156. sage/rings/polynomial/polynomial_zz_pex.cpython-313-x86_64-linux-musl.so +0 -0
  157. sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
  158. sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
  159. sage/rings/real_mpfi.pxd +50 -0
  160. sage/schemes/all__sagemath_ntl.py +1 -0
  161. sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
  162. sage/schemes/hyperelliptic_curves/hypellfrob.cpython-313-x86_64-linux-musl.so +0 -0
  163. sage/schemes/hyperelliptic_curves/hypellfrob.pyx +252 -0
@@ -0,0 +1,778 @@
1
+ # sage_setup: distribution = sagemath-ntl
2
+ # sage.doctest: needs sage.libs.ntl sage.rings.finite_rings
3
+ # distutils: libraries = NTL_LIBRARIES gmp
4
+ # distutils: extra_compile_args = NTL_CFLAGS
5
+ # distutils: include_dirs = NTL_INCDIR
6
+ # distutils: library_dirs = NTL_LIBDIR
7
+ # distutils: extra_link_args = NTL_LIBEXTRA
8
+ # distutils: language = c++
9
+ """
10
+ Univariate Polynomials over GF(p^e) via NTL's ZZ_pEX
11
+
12
+ AUTHOR:
13
+
14
+ - Yann Laigle-Chapuy (2010-01) initial implementation
15
+ - Lorenz Panny (2023-01): :meth:`minpoly_mod`
16
+ - Giacomo Pope (2023-08): :meth:`reverse`, :meth:`inverse_series_trunc`
17
+ """
18
+ from cysignals.signals cimport sig_on, sig_off
19
+
20
+ from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class
21
+ from sage.libs.ntl.ZZ_pE cimport ZZ_pE_to_ZZ_pX
22
+ from sage.libs.ntl.ZZ_pX cimport ZZ_pX_deg, ZZ_pX_coeff
23
+ from sage.libs.ntl.ZZ_p cimport ZZ_p_rep
24
+ from sage.libs.ntl.convert cimport ZZ_to_mpz, mpz_to_ZZ
25
+
26
+ from sage.structure.element import have_same_parent, canonical_coercion
27
+
28
+ # We need to define this stuff before including the templating stuff
29
+ # to make sure the function get_cparent is found since it is used in
30
+ # 'polynomial_template.pxi'.
31
+
32
+ cdef cparent get_cparent(parent) except? NULL:
33
+ if parent is None:
34
+ return NULL
35
+ cdef ntl_ZZ_pEContext_class pec
36
+ try:
37
+ pec = parent._modulus
38
+ except AttributeError:
39
+ return NULL
40
+ return &(pec.ptrs)
41
+
42
+ # first we include the definitions
43
+ include "sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi"
44
+
45
+ # and then the interface
46
+ include "polynomial_template.pxi"
47
+
48
+ from sage.libs.ntl.ntl_ZZ_pE cimport ntl_ZZ_pE
49
+
50
+ cdef inline ZZ_pE_c_to_list(ZZ_pE_c x):
51
+ cdef list L = []
52
+ cdef ZZ_pX_c c_pX
53
+ cdef ZZ_p_c c_p
54
+ cdef ZZ_c c_c
55
+ cdef Integer ans
56
+
57
+ c_pX = ZZ_pE_to_ZZ_pX(x)
58
+ d = ZZ_pX_deg(c_pX)
59
+ if d>=0:
60
+ for 0 <= j <= d:
61
+ c_p = ZZ_pX_coeff(c_pX, j)
62
+ c_c = ZZ_p_rep(c_p)
63
+ ans = Integer.__new__(Integer)
64
+ ZZ_to_mpz(ans.value, &c_c)
65
+ L.append(ans)
66
+ return L
67
+
68
+
69
+ cdef class Polynomial_ZZ_pEX(Polynomial_template):
70
+ r"""
71
+ Univariate Polynomials over `\GF{p^n}` via NTL's ``ZZ_pEX``.
72
+
73
+ EXAMPLES::
74
+
75
+ sage: K.<a> = GF(next_prime(2**60)**3)
76
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
77
+ sage: (x^3 + a*x^2 + 1) * (x + a)
78
+ x^4 + 2*a*x^3 + a^2*x^2 + x + a
79
+ """
80
+ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
81
+ r"""
82
+ Create a new univariate polynomials over `\GF{p^n}`.
83
+
84
+ EXAMPLES::
85
+
86
+ sage: K.<a> = GF(next_prime(2**60)**3)
87
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
88
+ sage: x^2+a
89
+ x^2 + a
90
+
91
+ TESTS:
92
+
93
+ The following tests against a bug that was fixed in :issue:`9944`.
94
+ With the ring definition above, we now have::
95
+
96
+ sage: R([3,'1234'])
97
+ 1234*x + 3
98
+ sage: R([3,'12e34'])
99
+ Traceback (most recent call last):
100
+ ...
101
+ TypeError: unable to convert '12e34' to an integer
102
+ sage: R([3,x])
103
+ Traceback (most recent call last):
104
+ ...
105
+ TypeError: x is not a constant polynomial
106
+
107
+ Check that NTL contexts are correctly restored and that
108
+ :issue:`9524` has been fixed::
109
+
110
+ sage: x = polygen(GF(9, 'a'))
111
+ sage: x = polygen(GF(49, 'a'))
112
+ sage: -x
113
+ 6*x
114
+ sage: 5*x
115
+ 5*x
116
+
117
+ Check that :issue:`11239` is fixed::
118
+
119
+ sage: Fq.<a> = GF(2^4); Fqq.<b> = GF(3^7)
120
+ sage: PFq.<x> = Fq[]; PFqq.<y> = Fqq[]
121
+ sage: f = x^3 + (a^3 + 1)*x
122
+ sage: sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX(PFqq, f)
123
+ Traceback (most recent call last):
124
+ ...
125
+ TypeError: unable to coerce from a finite field other than the prime subfield
126
+ """
127
+ cdef ntl_ZZ_pE d
128
+ try:
129
+ if (x.parent() is parent.base_ring()) or (x.parent() == parent.base_ring()):
130
+ Polynomial.__init__(self, parent, is_gen=is_gen)
131
+ (<Polynomial_template>self)._cparent = get_cparent(parent)
132
+ celement_construct(&self.x, (<Polynomial_template>self)._cparent)
133
+ d = parent._modulus.ZZ_pE(list(x.polynomial()))
134
+ ZZ_pEX_SetCoeff(self.x, 0, d.x)
135
+ return
136
+ except AttributeError:
137
+ pass
138
+
139
+ if isinstance(x, Polynomial):
140
+ x = x.list()
141
+
142
+ if isinstance(x, (list, tuple)):
143
+ Polynomial.__init__(self, parent, is_gen=is_gen)
144
+ (<Polynomial_template>self)._cparent = get_cparent(parent)
145
+ celement_construct(&self.x, (<Polynomial_template>self)._cparent)
146
+ K = parent.base_ring()
147
+ for i,e in enumerate(x):
148
+ # self(x) is supposed to be a conversion,
149
+ # not necessarily a coercion. So, we must
150
+ # not do K.coerce(e) but K(e).
151
+ e = K(e)
152
+ d = parent._modulus.ZZ_pE(list(e.polynomial()))
153
+ ZZ_pEX_SetCoeff(self.x, i, d.x)
154
+ return
155
+
156
+ Polynomial_template.__init__(self, parent, x, check, is_gen, construct)
157
+
158
+ cdef get_unsafe(self, Py_ssize_t i):
159
+ r"""
160
+ Return the `i`-th coefficient of ``self``.
161
+
162
+ EXAMPLES::
163
+
164
+ sage: K.<a> = GF(next_prime(2**60)**3)
165
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
166
+ sage: f = x^3 + (2*a+1)*x + a
167
+ sage: f[0]
168
+ a
169
+ sage: f[1]
170
+ 2*a + 1
171
+ sage: f[2]
172
+ 0
173
+ sage: f[:2]
174
+ (2*a + 1)*x + a
175
+ sage: f[:50] == f
176
+ True
177
+ """
178
+ self._parent._modulus.restore()
179
+ cdef ZZ_pE_c c_pE = ZZ_pEX_coeff(self.x, i)
180
+ return self._parent._base(ZZ_pE_c_to_list(c_pE))
181
+
182
+ cpdef list list(self, bint copy=True):
183
+ r"""
184
+ Return the list of coefficients.
185
+
186
+ EXAMPLES::
187
+
188
+ sage: K.<a> = GF(5^3)
189
+ sage: P = PolynomialRing(K, 'x')
190
+ sage: f = P.random_element(100)
191
+ sage: f.list() == [f[i] for i in range(f.degree()+1)]
192
+ True
193
+ sage: P.0.list()
194
+ [0, 1]
195
+ """
196
+ cdef Py_ssize_t i
197
+
198
+ self._parent._modulus.restore()
199
+
200
+ K = self._parent.base_ring()
201
+ return [K(ZZ_pE_c_to_list(ZZ_pEX_coeff(self.x, i)))
202
+ for i in range(celement_len(&self.x, (<Polynomial_template>self)._cparent))]
203
+
204
+ cpdef _lmul_(self, Element left):
205
+ r"""
206
+ EXAMPLES::
207
+
208
+ sage: K.<a> = GF(next_prime(2**60)**3)
209
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
210
+ sage: (2*a+1)*x # indirect doctest
211
+ (2*a + 1)*x
212
+ sage: x*(2*a+1) # indirect doctest
213
+ (2*a + 1)*x
214
+ """
215
+ cdef ntl_ZZ_pE d
216
+ cdef Polynomial_ZZ_pEX r
217
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
218
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
219
+ r._parent = (<Polynomial_template>self)._parent
220
+ r._cparent = (<Polynomial_template>self)._cparent
221
+ d = self._parent._modulus.ZZ_pE(list(left.polynomial()))
222
+ ZZ_pEX_mul_ZZ_pE(r.x, self.x, d.x)
223
+ return r
224
+
225
+ def __call__(self, *x, **kwds):
226
+ r"""
227
+ Evaluate polynomial at `a`.
228
+
229
+ EXAMPLES::
230
+
231
+ sage: K.<u> = GF(next_prime(2**60)**3)
232
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
233
+ sage: P = (x-u)*(x+u+1)
234
+ sage: P(u)
235
+ 0
236
+ sage: P(u+1)
237
+ 2*u + 2
238
+
239
+ TESTS:
240
+
241
+ The work around provided in :issue:`10475` is superseded by :issue:`24072`::
242
+
243
+ sage: F.<x> = GF(4)
244
+ sage: P.<y> = F[]
245
+ sage: p = y^4 + x*y^3 + y^2 + (x + 1)*y + x + 1
246
+ sage: SR(p) # needs sage.symbolic
247
+ Traceback (most recent call last):
248
+ ...
249
+ TypeError: positive characteristic not allowed in symbolic computations
250
+
251
+ Check that polynomial evaluation works when using logarithmic
252
+ representation of finite field elements (:issue:`16383`)::
253
+
254
+ sage: for i in range(10):
255
+ ....: F = FiniteField(random_prime(15) ** ZZ.random_element(2, 5), 'a', repr='log')
256
+ ....: b = F.random_element()
257
+ ....: P = PolynomialRing(F, 'x')
258
+ ....: f = P.random_element(8)
259
+ ....: assert f(b) == sum(c * b^i for i, c in enumerate(f))
260
+ """
261
+ cdef ntl_ZZ_pE _a
262
+ cdef ZZ_pE_c c_b
263
+
264
+ K = self._parent.base_ring()
265
+
266
+ if kwds:
267
+ if x:
268
+ raise TypeError("%s__call__() takes exactly 1 argument" % type(self))
269
+ try:
270
+ x = [kwds.pop(self.variable_name())]
271
+ except KeyError:
272
+ pass
273
+ if kwds:
274
+ raise TypeError("%s__call__() accepts no named argument except '%s'" % (type(self), self.variable_name()))
275
+ if len(x)!=1:
276
+ raise TypeError("%s__call__() takes exactly 1 positional argument" % type(self))
277
+
278
+ a = x[0]
279
+ try:
280
+ if a.parent() is not K:
281
+ a = K.coerce(a)
282
+ except (TypeError, AttributeError, NotImplementedError):
283
+ return Polynomial.__call__(self, a)
284
+
285
+ _a = self._parent._modulus.ZZ_pE(list(a.polynomial()))
286
+ ZZ_pEX_eval(c_b, self.x, _a.x)
287
+ return K(ZZ_pE_c_to_list(c_b))
288
+
289
+ def resultant(self, other):
290
+ r"""
291
+ Return the resultant of ``self`` and ``other``, which must lie in the same
292
+ polynomial ring.
293
+
294
+ INPUT:
295
+
296
+ - ``other`` -- a polynomial
297
+
298
+ OUTPUT: an element of the base ring of the polynomial ring
299
+
300
+ EXAMPLES::
301
+
302
+ sage: K.<a> = GF(next_prime(2**60)**3)
303
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
304
+ sage: f = (x-a)*(x-a**2)*(x+1)
305
+ sage: g = (x-a**3)*(x-a**4)*(x+a)
306
+ sage: r = f.resultant(g)
307
+ sage: r == prod(u - v for (u,eu) in f.roots() for (v,ev) in g.roots())
308
+ True
309
+ """
310
+ cdef ZZ_pE_c r
311
+ self._parent._modulus.restore()
312
+
313
+ if other.parent() is not self._parent:
314
+ other = self._parent.coerce(other)
315
+
316
+ ZZ_pEX_resultant(r, self.x, (<Polynomial_ZZ_pEX>other).x)
317
+
318
+ K = self._parent.base_ring()
319
+ return K(K.polynomial_ring()(ZZ_pE_c_to_list(r)))
320
+
321
+ def is_irreducible(self, algorithm='fast_when_false', iter=1):
322
+ r"""
323
+ Return ``True`` precisely when ``self`` is irreducible over its base ring.
324
+
325
+ INPUT:
326
+
327
+ - ``algorithm`` -- string (default: ``'fast_when_false'``);
328
+ there are 3 available algorithms:
329
+ ``'fast_when_true'``, ``'fast_when_false'``, and ``'probabilistic'``
330
+
331
+ - ``iter`` -- (default: 1) if the algorithm is ``'probabilistic'``,
332
+ defines the number of iterations. The error probability is bounded
333
+ by `q^{\text{-iter}}` for polynomials in `\GF{q}[x]`.
334
+
335
+ EXAMPLES::
336
+
337
+ sage: K.<a> = GF(next_prime(2**60)**3)
338
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
339
+ sage: P = x^3 + (2-a)*x + 1
340
+ sage: P.is_irreducible(algorithm='fast_when_false')
341
+ True
342
+ sage: P.is_irreducible(algorithm='fast_when_true')
343
+ True
344
+ sage: P.is_irreducible(algorithm='probabilistic')
345
+ True
346
+ sage: Q = (x^2+a)*(x+a^3)
347
+ sage: Q.is_irreducible(algorithm='fast_when_false')
348
+ False
349
+ sage: Q.is_irreducible(algorithm='fast_when_true')
350
+ False
351
+ sage: Q.is_irreducible(algorithm='probabilistic')
352
+ False
353
+ """
354
+ self._parent._modulus.restore()
355
+ if algorithm=="fast_when_false":
356
+ sig_on()
357
+ res = ZZ_pEX_IterIrredTest(self.x)
358
+ sig_off()
359
+ elif algorithm=="fast_when_true":
360
+ sig_on()
361
+ res = ZZ_pEX_DetIrredTest(self.x)
362
+ sig_off()
363
+ elif algorithm=="probabilistic":
364
+ sig_on()
365
+ res = ZZ_pEX_ProbIrredTest(self.x, iter)
366
+ sig_off()
367
+ else:
368
+ raise ValueError("unknown algorithm")
369
+ return res != 0
370
+
371
+ def minpoly_mod(self, other):
372
+ r"""
373
+ Compute the minimal polynomial of this polynomial modulo another
374
+ polynomial in the same ring.
375
+
376
+ ALGORITHM:
377
+
378
+ NTL's ``MinPolyMod()``, which uses Shoup's algorithm [Sho1999]_.
379
+
380
+ EXAMPLES::
381
+
382
+ sage: R.<x> = GF(101^2)[]
383
+ sage: f = x^17 + x^2 - 1
384
+ sage: (x^2).minpoly_mod(f)
385
+ x^17 + 100*x^2 + 2*x + 100
386
+
387
+ TESTS:
388
+
389
+ Random testing::
390
+
391
+ sage: p = random_prime(50)
392
+ sage: e = randrange(2,10)
393
+ sage: R.<x> = GF((p,e),'a')[]
394
+ sage: d = randrange(1,50)
395
+ sage: f = R.random_element(d)
396
+ sage: g = R.random_element((-1,5*d))
397
+ sage: poly = g.minpoly_mod(f)
398
+ sage: poly(R.quotient(f)(g))
399
+ 0
400
+ """
401
+ self._parent._modulus.restore()
402
+
403
+ if other.parent() is not self._parent:
404
+ other = self._parent.coerce(other)
405
+
406
+ cdef Polynomial_ZZ_pEX r
407
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
408
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
409
+ r._parent = (<Polynomial_template>self)._parent
410
+ r._cparent = (<Polynomial_template>self)._cparent
411
+
412
+ ZZ_pEX_MinPolyMod(r.x, (<Polynomial_ZZ_pEX>(self % other)).x, (<Polynomial_ZZ_pEX>other).x)
413
+ return r
414
+
415
+ cpdef _richcmp_(self, other, int op):
416
+ r"""
417
+ EXAMPLES::
418
+
419
+ sage: K.<a> = GF(next_prime(2**60)**3)
420
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
421
+ sage: P1 = (a**2+a+1)*x^2 + a*x + 1
422
+ sage: P2 = ( a+1)*x^2 + a*x + 1
423
+ sage: P1 < P2 # indirect doctests
424
+ False
425
+
426
+ TESTS::
427
+
428
+ sage: P3 = (a**2+a+1)*x^2 + x + 1
429
+ sage: P4 = x + 1
430
+ sage: P1 < P3
431
+ False
432
+ sage: P1 < P4
433
+ False
434
+ sage: P1 > P2
435
+ True
436
+ sage: P1 > P3
437
+ True
438
+ sage: P1 > P4
439
+ True
440
+ """
441
+ return Polynomial._richcmp_(self, other, op)
442
+
443
+ def shift(self, int n):
444
+ r"""
445
+ EXAMPLES::
446
+
447
+ sage: K.<a> = GF(next_prime(2**60)**3)
448
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
449
+ sage: f = x^3 + x^2 + 1
450
+ sage: f.shift(1)
451
+ x^4 + x^3 + x
452
+ sage: f.shift(-1)
453
+ x^2 + x
454
+ """
455
+ self._parent._modulus.restore()
456
+ cdef Polynomial_ZZ_pEX r
457
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
458
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
459
+ r._parent = (<Polynomial_template>self)._parent
460
+ r._cparent = (<Polynomial_template>self)._cparent
461
+ ZZ_pEX_LeftShift(r.x, self.x, n)
462
+ return r
463
+
464
+ def __lshift__(self, int n):
465
+ r"""
466
+ EXAMPLES::
467
+
468
+ sage: K.<a> = GF(next_prime(2**60)**3)
469
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
470
+ sage: f = x^3 + x^2 + 1
471
+ sage: f << 1
472
+ x^4 + x^3 + x
473
+ sage: f << -1
474
+ x^2 + x
475
+ """
476
+ return self.shift(n)
477
+
478
+ def __rshift__(self, int n):
479
+ r"""
480
+ EXAMPLES::
481
+
482
+ sage: K.<a> = GF(next_prime(2**60)**3)
483
+ sage: R.<x> = PolynomialRing(K, implementation='NTL')
484
+ sage: f = x^3 + x^2 + 1
485
+ sage: f >> 1
486
+ x^2 + x
487
+ sage: f >> -1
488
+ x^4 + x^3 + x
489
+ """
490
+ return self.shift(-n)
491
+
492
+ def reverse(self, degree=None):
493
+ r"""
494
+ Return the polynomial obtained by reversing the coefficients
495
+ of this polynomial. If degree is set then this function behaves
496
+ as if this polynomial has degree ``degree``.
497
+
498
+ EXAMPLES::
499
+
500
+ sage: R.<x> = GF(101^2)[]
501
+ sage: f = x^13 + 11*x^10 + 32*x^6 + 4
502
+ sage: f.reverse()
503
+ 4*x^13 + 32*x^7 + 11*x^3 + 1
504
+ sage: f.reverse(degree=15)
505
+ 4*x^15 + 32*x^9 + 11*x^5 + x^2
506
+ sage: f.reverse(degree=2)
507
+ 4*x^2
508
+
509
+ TESTS::
510
+
511
+ sage: R.<x> = GF(163^2)[]
512
+ sage: f = R([p for p in primes(20)])
513
+ sage: f.reverse()
514
+ 2*x^7 + 3*x^6 + 5*x^5 + 7*x^4 + 11*x^3 + 13*x^2 + 17*x + 19
515
+ sage: f.reverse(degree=200)
516
+ 2*x^200 + 3*x^199 + 5*x^198 + 7*x^197 + 11*x^196 + 13*x^195 + 17*x^194 + 19*x^193
517
+ sage: f.reverse(degree=0)
518
+ 2
519
+ sage: f.reverse(degree=-5)
520
+ Traceback (most recent call last):
521
+ ...
522
+ ValueError: degree argument must be a nonnegative integer, got -5
523
+
524
+ Check that this implementation is compatible with the generic one::
525
+
526
+ sage: p = R([0,1,0,2])
527
+ sage: all(p.reverse(d) == Polynomial.reverse(p, d)
528
+ ....: for d in [None, 0, 1, 2, 3, 4])
529
+ True
530
+ """
531
+ self._parent._modulus.restore()
532
+
533
+ # Construct output polynomial
534
+ cdef Polynomial_ZZ_pEX r
535
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
536
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
537
+ r._parent = (<Polynomial_template>self)._parent
538
+ r._cparent = (<Polynomial_template>self)._cparent
539
+
540
+ # When a degree has been supplied, ensure it is a valid input
541
+ cdef unsigned long d
542
+ if degree is not None:
543
+ if degree < 0:
544
+ raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree))
545
+ d = degree
546
+ if d != degree:
547
+ raise ValueError("degree argument must be a nonnegative integer, got %s" % (degree))
548
+ ZZ_pEX_reverse_hi(r.x, (<Polynomial_ZZ_pEX> self).x, d)
549
+ else:
550
+ ZZ_pEX_reverse(r.x, (<Polynomial_ZZ_pEX> self).x)
551
+ return r
552
+
553
+ def inverse_series_trunc(self, prec):
554
+ r"""
555
+ Compute and return the inverse of ``self`` modulo `x^{prec}`.
556
+
557
+ The constant term of ``self`` must be invertible.
558
+
559
+ EXAMPLES::
560
+
561
+ sage: R.<x> = GF(101^2)[]
562
+ sage: z2 = R.base_ring().gen()
563
+ sage: f = (3*z2 + 57)*x^3 + (13*z2 + 94)*x^2 + (7*z2 + 2)*x + 66*z2 + 15
564
+ sage: f.inverse_series_trunc(1)
565
+ 51*z2 + 92
566
+ sage: f.inverse_series_trunc(2)
567
+ (30*z2 + 30)*x + 51*z2 + 92
568
+ sage: f.inverse_series_trunc(3)
569
+ (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92
570
+ sage: f.inverse_series_trunc(4)
571
+ (99*z2 + 96)*x^3 + (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92
572
+
573
+ TESTS::
574
+
575
+ sage: R.<x> = GF(163^2)[]
576
+ sage: f = R([p for p in primes(20)])
577
+ sage: f.inverse_series_trunc(1)
578
+ 82
579
+ sage: f.inverse_series_trunc(2)
580
+ 40*x + 82
581
+ sage: f.inverse_series_trunc(3)
582
+ 61*x^2 + 40*x + 82
583
+ sage: f.inverse_series_trunc(0)
584
+ Traceback (most recent call last):
585
+ ...
586
+ ValueError: the precision must be positive, got 0
587
+ sage: f.inverse_series_trunc(-1)
588
+ Traceback (most recent call last):
589
+ ...
590
+ ValueError: the precision must be positive, got -1
591
+ sage: f = x + x^2 + x^3
592
+ sage: f.inverse_series_trunc(5)
593
+ Traceback (most recent call last):
594
+ ...
595
+ ValueError: constant term 0 is not a unit
596
+ """
597
+ self._parent._modulus.restore()
598
+
599
+ # Ensure precision is nonnegative
600
+ if prec <= 0:
601
+ raise ValueError("the precision must be positive, got {}".format(prec))
602
+
603
+ # Ensure we can invert the constant term
604
+ const_term = self.get_coeff_c(0)
605
+ if not const_term.is_unit():
606
+ raise ValueError("constant term {} is not a unit".format(const_term))
607
+
608
+ # Construct output polynomial
609
+ cdef Polynomial_ZZ_pEX r
610
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
611
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
612
+ r._parent = (<Polynomial_template>self)._parent
613
+ r._cparent = (<Polynomial_template>self)._cparent
614
+
615
+ # Call to NTL for the inverse truncation
616
+ if prec > 0:
617
+ sig_on()
618
+ ZZ_pEX_InvTrunc(r.x, self.x, prec)
619
+ sig_off()
620
+ return r
621
+
622
+ def __pow__(self, exp, modulus):
623
+ r"""
624
+ Exponentiation of ``self``.
625
+
626
+ If ``modulus`` is not ``None``, the exponentiation is performed
627
+ modulo the polynomial ``modulus``.
628
+
629
+ EXAMPLES::
630
+
631
+ sage: K.<a> = GF(101^2, 'a', modulus=[1,1,1])
632
+ sage: R.<x> = PolynomialRing(K, implementation="NTL")
633
+ sage: pow(x, 100)
634
+ x^100
635
+ sage: pow(x + 3, 5)
636
+ x^5 + 15*x^4 + 90*x^3 + 68*x^2 + x + 41
637
+
638
+ If modulus is not ``None``, performs modular exponentiation::
639
+
640
+ sage: K.<a> = GF(101^2, 'a', modulus=[1,1,1])
641
+ sage: R.<x> = PolynomialRing(K, implementation="NTL")
642
+ sage: pow(x, 100, x^2 + x + a)
643
+ (19*a + 64)*x + 30*a + 2
644
+ sage: pow(x, 100 * 101**200, x^2 + x + a)
645
+ (19*a + 64)*x + 30*a + 2
646
+
647
+ The modulus can have smaller degree than ``self``::
648
+
649
+ sage: K.<a> = GF(101^2, 'a', modulus=[1,1,1])
650
+ sage: R.<x> = PolynomialRing(K, implementation="NTL")
651
+ sage: pow(x^4, 25, x^2 + x + a)
652
+ (19*a + 64)*x + 30*a + 2
653
+
654
+ TESTS:
655
+
656
+ Canonical coercion should apply::
657
+
658
+ sage: xx = GF(101)["x"].gen()
659
+ sage: pow(x+1, 25, 2)
660
+ 0
661
+ sage: pow(x + a, 101**2, xx^3 + xx + 1)
662
+ 4*x^2 + 44*x + a + 70
663
+ sage: pow(x + a, int(101**2), xx^3 + xx + 1)
664
+ 4*x^2 + 44*x + a + 70
665
+ sage: xx = polygen(GF(97))
666
+ sage: _ = pow(x + a, 101**2, xx^3 + xx + 1)
667
+ Traceback (most recent call last):
668
+ ...
669
+ TypeError: no common canonical parent for objects with parents: ...
670
+ """
671
+ exp = Integer(exp)
672
+ if modulus is not None:
673
+ # Handle when modulus is zero
674
+ if modulus.is_zero():
675
+ raise ZeroDivisionError("modulus must be nonzero")
676
+
677
+ # Similar to coerce_binop
678
+ if not have_same_parent(self, modulus):
679
+ a, m = canonical_coercion(self, modulus)
680
+ if a is not self:
681
+ return pow(a, exp, m)
682
+ modulus = m
683
+ self = self % modulus
684
+ if exp > 0 and exp.bit_length() >= 32:
685
+ return (<Polynomial_ZZ_pEX>self)._powmod_bigexp(Integer(exp), modulus)
686
+ return Polynomial_template.__pow__(self, exp, modulus)
687
+
688
+ cdef _powmod_bigexp(Polynomial_ZZ_pEX self, Integer exp, Polynomial_ZZ_pEX modulus):
689
+ """
690
+ Modular exponentiation for large exponents.
691
+ """
692
+ self._parent._modulus.restore()
693
+ cdef Polynomial_ZZ_pEX r
694
+ cdef ZZ_c e_ZZ
695
+ cdef ZZ_pEX_c y
696
+ cdef ZZ_pEX_Modulus_c mod
697
+
698
+ mpz_to_ZZ(&e_ZZ, exp.value)
699
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
700
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
701
+ r._parent = (<Polynomial_template>self)._parent
702
+ r._cparent = (<Polynomial_template>self)._cparent
703
+ ZZ_pEX_Modulus_build(mod, modulus.x)
704
+
705
+ sig_on()
706
+ if ZZ_pEX_IsX(self.x):
707
+ ZZ_pEX_PowerXMod_ZZ_pre(r.x, e_ZZ, mod)
708
+ elif ZZ_pEX_deg(self.x) < ZZ_pEX_deg(modulus.x):
709
+ ZZ_pEX_PowerMod_ZZ_pre(r.x, self.x, e_ZZ, mod)
710
+ else:
711
+ ZZ_pEX_rem_pre(y, self.x, mod)
712
+ ZZ_pEX_PowerMod_ZZ_pre(r.x, y, e_ZZ, mod)
713
+ sig_off()
714
+ return r
715
+
716
+ def compose_mod(self, other, modulus):
717
+ r"""
718
+ Compute `f(g) \bmod h`.
719
+
720
+ To be precise about the order fo compostion, given ``self``, ``other``
721
+ and ``modulus`` as `f(x)`, `g(x)` and `h(x)` compute `f(g(x)) \bmod h(x)`.
722
+
723
+ INPUT:
724
+
725
+ - ``other`` -- a polynomial `g(x)`
726
+ - ``modulus`` -- a polynomial `h(x)`
727
+
728
+ EXAMPLES::
729
+
730
+ sage: R.<x> = GF(3**6)[]
731
+ sage: f = R.random_element()
732
+ sage: g = R.random_element()
733
+ sage: g.compose_mod(g, f) == g(g) % f
734
+ True
735
+
736
+ sage: F.<z3> = GF(3**6)
737
+ sage: R.<x> = F[]
738
+ sage: f = 2*z3^2*x^2 + (z3 + 1)*x + z3^2 + 2
739
+ sage: g = (z3^2 + 2*z3)*x^2 + (2*z3 + 2)*x + 2*z3^2 + z3 + 2
740
+ sage: h = (2*z3 + 2)*x^2 + (2*z3^2 + 1)*x + 2*z3^2 + z3 + 2
741
+ sage: f.compose_mod(g, h)
742
+ (z3^5 + z3^4 + z3^3 + z3^2 + z3)*x + z3^5 + z3^3 + 2*z3 + 2
743
+ sage: f.compose_mod(g, h) == f(g) % h
744
+ True
745
+
746
+ AUTHORS:
747
+
748
+ - Giacomo Pope (2024-08) initial implementation
749
+ """
750
+ self._parent._modulus.restore()
751
+
752
+ # Ensure all the parents match
753
+ if other.parent() is not self._parent:
754
+ other = self._parent.coerce(other)
755
+ if modulus.parent() is not self._parent:
756
+ modulus = self._parent.coerce(modulus)
757
+
758
+ # Create the output polynomial
759
+ cdef Polynomial_ZZ_pEX r
760
+ r = Polynomial_ZZ_pEX.__new__(Polynomial_ZZ_pEX)
761
+ celement_construct(&r.x, (<Polynomial_template>self)._cparent)
762
+ r._parent = (<Polynomial_template>self)._parent
763
+ r._cparent = (<Polynomial_template>self)._cparent
764
+
765
+ # Create ZZ_pEX_Modulus type from modulus input
766
+ cdef ZZ_pEX_Modulus_c mod
767
+ ZZ_pEX_Modulus_build(mod, (<Polynomial_ZZ_pEX>modulus).x)
768
+
769
+ # Compute f(g) mod h
770
+ sig_on()
771
+ ZZ_pEX_CompMod(r.x, (<Polynomial_ZZ_pEX>self).x, (<Polynomial_ZZ_pEX>(other % modulus)).x, mod)
772
+ sig_off()
773
+
774
+ return r
775
+
776
+ # compose_mod is the natural name from the NTL bindings, but polynomial_gf2x
777
+ # has modular_composition as the method name so here we allow both
778
+ modular_composition = compose_mod