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,1255 @@
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
+
9
+ r"""
10
+ Wrapper for NTL's polynomials over finite ring extensions of `\Z / p\Z.`
11
+
12
+ AUTHORS:
13
+
14
+ - David Roe (2007-10-10)
15
+ """
16
+
17
+ # ****************************************************************************
18
+ # Copyright (C) 2007 William Stein <wstein@gmail.com>
19
+ # David Roe <roed@math.harvard.edu>
20
+ #
21
+ # Distributed under the terms of the GNU General Public License (GPL)
22
+ #
23
+ # This code is distributed in the hope that it will be useful,
24
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
25
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26
+ # General Public License for more details.
27
+ #
28
+ # The full text of the GPL is available at:
29
+ #
30
+ # https://www.gnu.org/licenses/
31
+ # ****************************************************************************
32
+
33
+ from cysignals.signals cimport sig_on, sig_off
34
+ from sage.ext.cplusplus cimport ccrepr
35
+
36
+ include 'misc.pxi'
37
+ include 'decl.pxi'
38
+
39
+ from cpython.object cimport Py_EQ, Py_NE
40
+ from sage.libs.ntl.ntl_ZZ_pE cimport ntl_ZZ_pE
41
+ from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class
42
+ from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext
43
+ from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class
44
+ from sage.arith.power cimport generic_power_pos
45
+
46
+ ##############################################################################
47
+ #
48
+ # ZZ_pEX -- polynomials over an extension of the integers modulo p
49
+ #
50
+ ##############################################################################
51
+
52
+ cdef class ntl_ZZ_pEX():
53
+ r"""
54
+ The class \class{ZZ_pEX} implements polynomials over finite ring extensions of `\Z / p\Z`.
55
+
56
+ It can be used, for example, for arithmetic in `GF(p^n)[X]`.
57
+ However, except where mathematically necessary (e.g., GCD computations),
58
+ ZZ_pE need not be a field.
59
+ """
60
+ # See ntl_ZZ_pEX.pxd for definition of data members
61
+ def __init__(self, v=None, modulus=None):
62
+ """
63
+ EXAMPLES::
64
+
65
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
66
+ sage: a = ntl.ZZ_pE([3,2], c)
67
+ sage: b = ntl.ZZ_pE([1,2], c)
68
+ sage: f = ntl.ZZ_pEX([a, b, b])
69
+ sage: f
70
+ [[3 2] [1 2] [1 2]]
71
+ sage: g = ntl.ZZ_pEX([0,0,0], c); g
72
+ []
73
+ sage: g[10]=5
74
+ sage: g
75
+ [[] [] [] [] [] [] [] [] [] [] [5]]
76
+ sage: g[10]
77
+ [5]
78
+ """
79
+ if modulus is None and v is None:
80
+ raise ValueError("You must specify a modulus when creating a ZZ_pEX.")
81
+
82
+ # self.c._assert_is_current_modulus() ## Restoring the context is taken care of in __new__
83
+ cdef ntl_ZZ_pE cc
84
+ cdef Py_ssize_t i
85
+
86
+ if v is None:
87
+ return
88
+ elif isinstance(v, (list, tuple)):
89
+ for i from 0 <= i < len(v):
90
+ x = v[i]
91
+ if not isinstance(x, ntl_ZZ_pE):
92
+ cc = ntl_ZZ_pE(x,self.c)
93
+ self.c.restore_c()
94
+ else:
95
+ if self.c is not (<ntl_ZZ_pE>x).c:
96
+ raise ValueError("inconsistent moduli")
97
+ cc = x
98
+ ZZ_pEX_SetCoeff(self.x, i, cc.x)
99
+ else:
100
+ raise NotImplementedError
101
+
102
+ def __cinit__(self, v=None, modulus=None):
103
+ #################### WARNING ###################
104
+ ## Before creating a ZZ_pEX, you must create a##
105
+ ## ZZ_pEContext, and restore it. In Python, ##
106
+ ## the error checking in __init__ will prevent##
107
+ ## you from constructing an ntl_ZZ_pEX ##
108
+ ## inappropriately. However, from Cython, you##
109
+ ## could do r = ntl_ZZ_pEX.__new__(ntl_ZZ_pEX) without
110
+ ## first restoring a ZZ_pEContext, which could##
111
+ ## have unfortunate consequences. See _new ##
112
+ ## defined below for an example of the right ##
113
+ ## way to short-circuit __init__ (or just call##
114
+ ## _new in your own code). ##
115
+ ################################################
116
+ if modulus is None and v is None: # we also check for v is None so that a user can specify the modulus by v.
117
+ return
118
+ if isinstance(modulus, ntl_ZZ_pEContext_class):
119
+ self.c = <ntl_ZZ_pEContext_class>modulus
120
+ elif isinstance(v, ntl_ZZ_pEX):
121
+ self.c = (<ntl_ZZ_pEX>v).c
122
+ elif isinstance(v, ntl_ZZ_pE):
123
+ self.c = (<ntl_ZZ_pE>v).c
124
+ elif isinstance(v, (list, tuple)) and v:
125
+ if isinstance(v[0], ntl_ZZ_pEX):
126
+ self.c = (<ntl_ZZ_pEX>v[0]).c
127
+ elif isinstance(v[0], ntl_ZZ_pE):
128
+ self.c = (<ntl_ZZ_pEX>v[0]).c
129
+ else:
130
+ self.c = <ntl_ZZ_pEContext_class>ntl_ZZ_pEContext(modulus)
131
+ elif modulus is not None:
132
+ self.c = <ntl_ZZ_pEContext_class>ntl_ZZ_pEContext(modulus)
133
+ else:
134
+ raise ValueError("modulus must not be None")
135
+ self.c.restore_c()
136
+
137
+ cdef ntl_ZZ_pEX _new(self):
138
+ cdef ntl_ZZ_pEX r
139
+ self.c.restore_c()
140
+ r = ntl_ZZ_pEX.__new__(ntl_ZZ_pEX)
141
+ r.c = self.c
142
+ return r
143
+
144
+ def __reduce__(self):
145
+ """
146
+ TESTS::
147
+
148
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
149
+ sage: a = ntl.ZZ_pE([3,2], c)
150
+ sage: b = ntl.ZZ_pE([1,2], c)
151
+ sage: f = ntl.ZZ_pEX([a, b, b])
152
+ sage: loads(dumps(f)) == f
153
+ True
154
+ """
155
+ return make_ZZ_pEX, (self.list(), self.get_modulus_context())
156
+
157
+ def __repr__(self):
158
+ """
159
+ Return a string representation of ``self``.
160
+
161
+ TESTS::
162
+
163
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
164
+ sage: a = ntl.ZZ_pE([3,2], c)
165
+ sage: b = ntl.ZZ_pE([1,2], c)
166
+ sage: f = ntl.ZZ_pEX([a, b, b])
167
+ sage: f
168
+ [[3 2] [1 2] [1 2]]
169
+ """
170
+ self.c.restore_c()
171
+ return ccrepr(self.x)
172
+
173
+ def __copy__(self):
174
+ """
175
+ Return a copy of ``self``.
176
+
177
+ TESTS::
178
+
179
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
180
+ sage: a = ntl.ZZ_pE([3,2], c)
181
+ sage: b = ntl.ZZ_pE([1,2], c)
182
+ sage: f = ntl.ZZ_pEX([a, b, b])
183
+ sage: f
184
+ [[3 2] [1 2] [1 2]]
185
+ sage: y = copy(f)
186
+ sage: y == f
187
+ True
188
+ sage: y is f
189
+ False
190
+ sage: f[0] = 0; y
191
+ [[3 2] [1 2] [1 2]]
192
+ """
193
+ cdef ntl_ZZ_pEX r = self._new()
194
+ #self.c.restore_c() ## _new() restores
195
+ r.x = self.x
196
+ return r
197
+
198
+ def get_modulus_context(self):
199
+ """
200
+ Return the structure that holds the underlying NTL modulus.
201
+
202
+ EXAMPLES::
203
+
204
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
205
+ sage: a = ntl.ZZ_pE([3,2], c)
206
+ sage: b = ntl.ZZ_pE([1,2], c)
207
+ sage: f = ntl.ZZ_pEX([a, b, b])
208
+ sage: f.get_modulus_context()
209
+ NTL modulus [1 1 1] (mod 7)
210
+ """
211
+ return self.c
212
+
213
+ def __setitem__(self, long i, a):
214
+ r"""
215
+ Set the i-th coefficient of ``self`` to be a.
216
+
217
+ EXAMPLES::
218
+
219
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
220
+ sage: a = ntl.ZZ_pE([3,2], c)
221
+ sage: b = ntl.ZZ_pE([1,2], c)
222
+ sage: f = ntl.ZZ_pEX([a, b, b])
223
+ sage: f[1] = 4; f
224
+ [[3 2] [4] [1 2]]
225
+ """
226
+ if i < 0:
227
+ raise IndexError("index (i=%s) must be >= 0" % i)
228
+ cdef ntl_ZZ_pE _a
229
+ if isinstance(a, ntl_ZZ_pE):
230
+ _a = <ntl_ZZ_pE> a
231
+ else:
232
+ _a = ntl_ZZ_pE(a,self.c)
233
+ self.c.restore_c()
234
+ ZZ_pEX_SetCoeff(self.x, i, _a.x)
235
+
236
+ def __getitem__(self, long i):
237
+ r"""
238
+ Return the i-th coefficient of ``self``.
239
+
240
+ EXAMPLES::
241
+
242
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
243
+ sage: a = ntl.ZZ_pE([3,2], c)
244
+ sage: b = ntl.ZZ_pE([1,2], c)
245
+ sage: f = ntl.ZZ_pEX([a, b, b])
246
+ sage: f[0]
247
+ [3 2]
248
+ sage: f[5]
249
+ []
250
+ """
251
+ if i < 0:
252
+ raise IndexError("index (=%s) must be >= 0" % i)
253
+ cdef ntl_ZZ_pE r
254
+ sig_on()
255
+ self.c.restore_c()
256
+ r = ntl_ZZ_pE.__new__(ntl_ZZ_pE)
257
+ r.c = self.c
258
+ r.x = ZZ_pEX_coeff( self.x, i)
259
+ sig_off()
260
+ return r
261
+
262
+ def list(self):
263
+ """
264
+ Return list of entries as a list of ntl_ZZ_pEs.
265
+
266
+ EXAMPLES::
267
+
268
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
269
+ sage: a = ntl.ZZ_pE([3,2], c)
270
+ sage: b = ntl.ZZ_pE([1,2], c)
271
+ sage: f = ntl.ZZ_pEX([a, b, b])
272
+ sage: f.list()
273
+ [[3 2], [1 2], [1 2]]
274
+ """
275
+ # This function could be sped up by using the list API and not restoring the context each time.
276
+ # Or by using self.x.rep directly.
277
+ self.c.restore_c()
278
+ cdef Py_ssize_t i
279
+ return [self[i] for i from 0 <= i <= self.degree()]
280
+
281
+ def __add__(ntl_ZZ_pEX self, ntl_ZZ_pEX other):
282
+ """
283
+ Add ``self`` and ``other``.
284
+
285
+ EXAMPLES::
286
+
287
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
288
+ sage: a = ntl.ZZ_pE([3,2], c)
289
+ sage: b = ntl.ZZ_pE([1,2], c)
290
+ sage: f = ntl.ZZ_pEX([a, b, b])
291
+ sage: g = ntl.ZZ_pEX([-b, a])
292
+ sage: f + g
293
+ [[2] [4 4] [1 2]]
294
+ """
295
+ if self.c is not other.c:
296
+ raise ValueError("You cannot perform arithmetic with elements of different moduli.")
297
+ cdef ntl_ZZ_pEX r = self._new()
298
+ sig_on()
299
+ # self.c.restore_c() # _new restores the context
300
+ ZZ_pEX_add(r.x, self.x, other.x)
301
+ sig_off()
302
+ return r
303
+
304
+ def __sub__(ntl_ZZ_pEX self, ntl_ZZ_pEX other):
305
+ """
306
+ Subtracts ``other`` from ``self``.
307
+
308
+ EXAMPLES::
309
+
310
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
311
+ sage: a = ntl.ZZ_pE([3,2], c)
312
+ sage: b = ntl.ZZ_pE([1,2], c)
313
+ sage: f = ntl.ZZ_pEX([a, b, b])
314
+ sage: g = ntl.ZZ_pEX([-b, a])
315
+ sage: f - g
316
+ [[4 4] [5] [1 2]]
317
+ """
318
+ if self.c is not other.c:
319
+ raise ValueError("You cannot perform arithmetic with elements of different moduli.")
320
+ cdef ntl_ZZ_pEX r = self._new()
321
+ sig_on()
322
+ # self.c.restore_c() # _new restores the context
323
+ ZZ_pEX_sub(r.x, self.x, other.x)
324
+ sig_off()
325
+ return r
326
+
327
+ def __mul__(ntl_ZZ_pEX self, ntl_ZZ_pEX other):
328
+ """
329
+ Return the product ``self * other``.
330
+
331
+ EXAMPLES::
332
+
333
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
334
+ sage: a = ntl.ZZ_pE([3,2], c)
335
+ sage: b = ntl.ZZ_pE([1,2], c)
336
+ sage: f = ntl.ZZ_pEX([a, b, b])
337
+ sage: g = ntl.ZZ_pEX([-b, a])
338
+ sage: f * g
339
+ [[1 3] [1 1] [2 4] [6 4]]
340
+ sage: c2 = ntl.ZZ_pEContext(ntl.ZZ_pX([4,1,1], 5)) # we can mix up the moduli
341
+ sage: x = c2.ZZ_pEX([2,4])
342
+ sage: x^2
343
+ [[4] [1] [1]]
344
+ sage: f * g # back to the first one and the ntl modulus gets reset correctly
345
+ [[1 3] [1 1] [2 4] [6 4]]
346
+ """
347
+ if self.c is not other.c:
348
+ raise ValueError("You cannot perform arithmetic with elements of different moduli.")
349
+ cdef ntl_ZZ_pEX r = self._new()
350
+ sig_on()
351
+ # self.c.restore_c() # _new() restores the context
352
+ ZZ_pEX_mul(r.x, self.x, other.x)
353
+ sig_off()
354
+ return r
355
+
356
+ def __truediv__(ntl_ZZ_pEX self, ntl_ZZ_pEX other):
357
+ """
358
+ Compute quotient ``self / other``, if the quotient is a polynomial.
359
+ Otherwise an Exception is raised.
360
+
361
+ EXAMPLES::
362
+
363
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
364
+ sage: a = ntl.ZZ_pE([3,2], c)
365
+ sage: b = ntl.ZZ_pE([1,2], c)
366
+ sage: f = ntl.ZZ_pEX([a^2, -a*b-a*b, b^2])
367
+ sage: g = ntl.ZZ_pEX([-a, b])
368
+ sage: f / g
369
+ [[4 5] [1 2]]
370
+ sage: g / f
371
+ Traceback (most recent call last):
372
+ ...
373
+ ArithmeticError: self (=[[4 5] [1 2]]) is not divisible by other (=[[5 1] [2 6] [4]])
374
+ """
375
+ if self.c is not other.c:
376
+ raise ValueError("You cannot perform arithmetic with elements of different moduli.")
377
+ cdef int divisible
378
+ cdef ntl_ZZ_pEX r = self._new()
379
+ sig_on()
380
+ #self.c.restore_c() # _new restores context
381
+ divisible = ZZ_pEX_divide(r.x, self.x, other.x)
382
+ sig_off()
383
+ if not divisible:
384
+ raise ArithmeticError("self (=%s) is not divisible by other (=%s)" % (self, other))
385
+ return r
386
+
387
+ def __mod__(ntl_ZZ_pEX self, ntl_ZZ_pEX other):
388
+ """
389
+ Given polynomials a, b in ZZ_pE[X], if p is prime and the defining modulus irreducible,
390
+ there exist polynomials q, r in ZZ_pE[X] such that a = b*q + r, deg(r) < deg(b). This
391
+ function returns r.
392
+
393
+ If p is not prime or the modulus is not irreducible, this
394
+ function may raise a :exc:`RuntimeError` due to division by
395
+ a noninvertible element of ZZ_p.
396
+
397
+ EXAMPLES::
398
+
399
+ sage: c = ntl.ZZ_pEContext(ntl.ZZ_pX([-5, 0, 1], 5^10))
400
+ sage: a = c.ZZ_pE([5, 1])
401
+ sage: b = c.ZZ_pE([4, 99])
402
+ sage: f = c.ZZ_pEX([a, b])
403
+ sage: g = c.ZZ_pEX([a^2, -b, a + b])
404
+ sage: g % f
405
+ [[1864280 2123186]]
406
+ sage: f % g
407
+ [[5 1] [4 99]]
408
+ """
409
+ if self.c is not other.c:
410
+ raise ValueError("You cannot perform arithmetic with elements of different moduli.")
411
+ cdef ntl_ZZ_pEX r = self._new()
412
+ sig_on()
413
+ # self.c.restore_c() # _new() restores the context
414
+ ZZ_pEX_rem(r.x, self.x, other.x)
415
+ sig_off()
416
+ return r
417
+
418
+ def quo_rem(self, ntl_ZZ_pEX other):
419
+ """
420
+ Given polynomials a, b in ZZ_pE[X], if p is prime and the defining modulus irreducible,
421
+ there exist polynomials q, r in ZZ_pE[X] such that a = b*q + r, deg(r) < deg(b). This
422
+ function returns (q, r).
423
+
424
+ If p is not prime or the modulus is not irreducible, this function may raise a
425
+ :exc:`RuntimeError` due to division by a noninvertible element of ZZ_p.
426
+
427
+ EXAMPLES::
428
+
429
+ sage: c = ntl.ZZ_pEContext(ntl.ZZ_pX([-5, 0, 1], 5^10))
430
+ sage: a = c.ZZ_pE([5, 1])
431
+ sage: b = c.ZZ_pE([4, 99])
432
+ sage: f = c.ZZ_pEX([a, b])
433
+ sage: g = c.ZZ_pEX([a^2, -b, a + b])
434
+ sage: g.quo_rem(f)
435
+ ([[4947544 2492106] [4469276 6572944]], [[1864280 2123186]])
436
+ sage: f.quo_rem(g)
437
+ ([], [[5 1] [4 99]])
438
+ """
439
+ if self.c is not other.c:
440
+ raise ValueError("You cannot perform arithmetic with elements of different moduli.")
441
+ cdef ntl_ZZ_pEX r = self._new()
442
+ cdef ntl_ZZ_pEX q = self._new()
443
+ sig_on()
444
+ # self.c.restore_c() # _new() restores the context
445
+ ZZ_pEX_DivRem(q.x, r.x, self.x, other.x)
446
+ sig_off()
447
+ return q,r
448
+
449
+ def square(self):
450
+ """
451
+ Return `f^2`.
452
+
453
+ EXAMPLES::
454
+
455
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
456
+ sage: a = ntl.ZZ_pE([3,2], c)
457
+ sage: b = ntl.ZZ_pE([1,2], c)
458
+ sage: f = ntl.ZZ_pEX([a, b, b])
459
+ sage: f.square()
460
+ [[5 1] [5 1] [2 1] [1] [4]]
461
+ """
462
+ # self.c.restore_c() # _new() restores the context
463
+ cdef ntl_ZZ_pEX r = self._new()
464
+ sig_on()
465
+ ZZ_pEX_sqr(r.x, self.x)
466
+ sig_off()
467
+ return r
468
+
469
+ def __pow__(ntl_ZZ_pEX self, long n, ignored):
470
+ """
471
+ Return the `n`-th nonnegative power of ``self``.
472
+
473
+ EXAMPLES::
474
+
475
+ sage: c = ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
476
+ sage: a = ntl.ZZ_pE([3,2], c)
477
+ sage: b = ntl.ZZ_pE([1,2], c)
478
+ sage: f = ntl.ZZ_pEX([a, b, b])
479
+ sage: f ^ 5
480
+ [[5 1] [2 6] [4 5] [5 1] [] [6 2] [2 3] [0 1] [1 4] [3 6] [2 4]]
481
+ sage: f ^ 0
482
+ [[1]]
483
+ sage: f ^ 1
484
+ [[3 2] [1 2] [1 2]]
485
+ sage: f ^ (-1)
486
+ Traceback (most recent call last):
487
+ ...
488
+ ArithmeticError
489
+ """
490
+ self.c.restore_c()
491
+ if n == 0:
492
+ return ntl_ZZ_pEX([[1]], self.c)
493
+ if n < 0:
494
+ raise ArithmeticError
495
+ return generic_power_pos(self, <unsigned long>n)
496
+
497
+ def __richcmp__(ntl_ZZ_pEX self, other, int op):
498
+ """
499
+ Compare ``self`` to ``other``.
500
+
501
+ EXAMPLES::
502
+
503
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
504
+ sage: a = ntl.ZZ_pE([3,2], c)
505
+ sage: b = ntl.ZZ_pE([1,2], c)
506
+ sage: f = ntl.ZZ_pEX([a, b, b])
507
+ sage: g = ntl.ZZ_pEX([a, b, b, 0])
508
+ sage: f == g
509
+ True
510
+ sage: g = ntl.ZZ_pEX([a, b, a])
511
+ sage: f == g
512
+ False
513
+ sage: f == []
514
+ False
515
+ """
516
+ self.c.restore_c()
517
+
518
+ if op != Py_EQ and op != Py_NE:
519
+ raise TypeError("polynomials are not ordered")
520
+
521
+ cdef ntl_ZZ_pEX b
522
+ try:
523
+ b = <ntl_ZZ_pEX?>other
524
+ except TypeError:
525
+ b = ntl_ZZ_pEX(other, self.c)
526
+
527
+ return (op == Py_EQ) == (self.x == b.x)
528
+
529
+ def is_zero(self):
530
+ """
531
+ Return ``True`` exactly if this polynomial is 0.
532
+
533
+ EXAMPLES::
534
+
535
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
536
+ sage: a = ntl.ZZ_pE([3,2], c)
537
+ sage: b = ntl.ZZ_pE([1,2], c)
538
+ sage: f = ntl.ZZ_pEX([a, b, b])
539
+ sage: f.is_zero()
540
+ False
541
+ sage: f = ntl.ZZ_pEX([0,0,7], c)
542
+ sage: f.is_zero()
543
+ True
544
+ """
545
+ self.c.restore_c()
546
+ return bool(ZZ_pEX_IsZero(self.x))
547
+
548
+ def is_one(self):
549
+ """
550
+ Return ``True`` exactly if this polynomial is 1.
551
+
552
+ EXAMPLES::
553
+
554
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
555
+ sage: a = ntl.ZZ_pE([3,2], c)
556
+ sage: b = ntl.ZZ_pE([1,2], c)
557
+ sage: f = ntl.ZZ_pEX([a, b, b])
558
+ sage: f.is_one()
559
+ False
560
+ sage: f = ntl.ZZ_pEX([1, 0, 0], c)
561
+ sage: f.is_one()
562
+ True
563
+ """
564
+ self.c.restore_c()
565
+ return bool(ZZ_pEX_IsOne(self.x))
566
+
567
+ def is_monic(self):
568
+ """
569
+ Return ``True`` exactly if this polynomial is monic.
570
+
571
+ EXAMPLES::
572
+
573
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
574
+ sage: a = ntl.ZZ_pE([3,2], c)
575
+ sage: b = ntl.ZZ_pE([1,2], c)
576
+ sage: f = ntl.ZZ_pEX([a, b, b])
577
+ sage: f.is_monic()
578
+ False
579
+ sage: f = ntl.ZZ_pEX([a, b, 1], c)
580
+ sage: f.is_monic()
581
+ True
582
+ """
583
+ self.c.restore_c()
584
+ # The following line is what we should have. However, strangely this is *broken*
585
+ # on PowerPC Intel in NTL, so we program around
586
+ # the problem. (William Stein)
587
+ #return bool(ZZ_pEX_is_monic(self.x))
588
+
589
+ if ZZ_pEX_IsZero(self.x):
590
+ return False
591
+ cdef ZZ_pE_c x = ZZ_pEX_LeadCoeff(self.x)
592
+ return bool(ZZ_pE_IsOne(x))
593
+
594
+ def __neg__(self):
595
+ """
596
+ Return the negative of ``self``.
597
+
598
+ EXAMPLES::
599
+
600
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
601
+ sage: a = ntl.ZZ_pE([3,2], c)
602
+ sage: b = ntl.ZZ_pE([1,2], c)
603
+ sage: f = ntl.ZZ_pEX([a, b, b])
604
+ sage: -f
605
+ [[4 5] [6 5] [6 5]]
606
+ """
607
+ cdef ntl_ZZ_pEX r = self._new()
608
+ # self.c.restore_c() # _new() calls restore
609
+ ZZ_pEX_negate(r.x, self.x)
610
+ return r
611
+
612
+ def convert_to_modulus(self, ntl_ZZ_pContext_class c):
613
+ """
614
+ Return a new ntl_ZZ_pX which is the same as self, but considered modulo a different p (but the SAME polynomial).
615
+
616
+ In order for this to make mathematical sense, c.p should divide self.c.p
617
+ (in which case ``self`` is reduced modulo c.p) or self.c.p should divide c.p
618
+ (in which case ``self`` is lifted to something modulo c.p congruent to ``self`` modulo self.c.p)
619
+
620
+ EXAMPLES::
621
+
622
+ sage: c = ntl.ZZ_pEContext(ntl.ZZ_pX([-5, 0, 1], 5^20))
623
+ sage: a = ntl.ZZ_pE([192870, 1928189], c)
624
+ sage: b = ntl.ZZ_pE([18275,293872987], c)
625
+ sage: f = ntl.ZZ_pEX([a, b])
626
+ sage: g = f.convert_to_modulus(ntl.ZZ_pContext(ntl.ZZ(5^5)))
627
+ sage: g
628
+ [[2245 64] [2650 1112]]
629
+ sage: g.get_modulus_context()
630
+ NTL modulus [3120 0 1] (mod 3125)
631
+ sage: g^2
632
+ [[1130 2985] [805 830] [2095 2975]]
633
+ sage: (f^2).convert_to_modulus(ntl.ZZ_pContext(ntl.ZZ(5^5)))
634
+ [[1130 2985] [805 830] [2095 2975]]
635
+ """
636
+ cdef ntl_ZZ_pEContext_class cE = ntl_ZZ_pEContext(self.c.f.convert_to_modulus(c))
637
+ cE.restore_c()
638
+ cdef ntl_ZZ_pEX ans = ntl_ZZ_pEX.__new__(ntl_ZZ_pEX)
639
+ sig_on()
640
+ ZZ_pEX_conv_modulus(ans.x, self.x, c.x)
641
+ sig_off()
642
+ ans.c = cE
643
+ return ans
644
+
645
+ def left_shift(self, long n):
646
+ """
647
+ Return the polynomial obtained by shifting all coefficients of
648
+ this polynomial to the left n positions.
649
+
650
+ EXAMPLES::
651
+
652
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
653
+ sage: a = ntl.ZZ_pE([3,2], c)
654
+ sage: b = ntl.ZZ_pE([1,2], c)
655
+ sage: f = ntl.ZZ_pEX([a, b, b]); f
656
+ [[3 2] [1 2] [1 2]]
657
+ sage: f.left_shift(2)
658
+ [[] [] [3 2] [1 2] [1 2]]
659
+ sage: f.left_shift(5)
660
+ [[] [] [] [] [] [3 2] [1 2] [1 2]]
661
+
662
+ A negative left shift is a right shift::
663
+
664
+ sage: f.left_shift(-2)
665
+ [[1 2]]
666
+ """
667
+ # self.c.restore_c() # _new() calls restore
668
+ cdef ntl_ZZ_pEX r = self._new()
669
+ sig_on()
670
+ ZZ_pEX_LeftShift(r.x, self.x, n)
671
+ sig_off()
672
+ return r
673
+
674
+ def right_shift(self, long n):
675
+ """
676
+ Return the polynomial obtained by shifting all coefficients of
677
+ this polynomial to the right n positions.
678
+
679
+ EXAMPLES::
680
+
681
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 7))
682
+ sage: a = ntl.ZZ_pE([3,2], c)
683
+ sage: b = ntl.ZZ_pE([1,2], c)
684
+ sage: f = ntl.ZZ_pEX([a, b, b]); f
685
+ [[3 2] [1 2] [1 2]]
686
+ sage: f.right_shift(2)
687
+ [[1 2]]
688
+ sage: f.right_shift(5)
689
+ []
690
+
691
+ A negative right shift is a left shift::
692
+
693
+ sage: f.right_shift(-5)
694
+ [[] [] [] [] [] [3 2] [1 2] [1 2]]
695
+ """
696
+ # self.c.restore_c() # _new() calls restore
697
+ cdef ntl_ZZ_pEX r = self._new()
698
+ sig_on()
699
+ ZZ_pEX_RightShift(r.x, self.x, n)
700
+ sig_off()
701
+ return r
702
+
703
+ def gcd(self, ntl_ZZ_pEX other, check=True):
704
+ """
705
+ Return ``gcd(self, other)`` if we are working over a field.
706
+
707
+ NOTE: Does not work if p is not prime or if the modulus is not irreducible.
708
+
709
+ EXAMPLES::
710
+
711
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
712
+ sage: a = ntl.ZZ_pE([3,2], c)
713
+ sage: b = ntl.ZZ_pE([1,2], c)
714
+ sage: f = ntl.ZZ_pEX([a, b, b])
715
+ sage: g = f^2
716
+ sage: h = f^3
717
+ sage: g.gcd(h)
718
+ [[2 1] [8 1] [9 1] [2] [1]]
719
+ sage: f^2
720
+ [[5 8] [9 8] [6 8] [5] [8]]
721
+ sage: eight = ntl.ZZ_pEX([[8]], c)
722
+ sage: f^2 / eight
723
+ [[2 1] [8 1] [9 1] [2] [1]]
724
+ """
725
+ #If check = True, need to check that ZZ_pE is a field.
726
+ self.c.restore_c()
727
+ cdef ntl_ZZ_pEX r = self._new()
728
+ sig_on()
729
+ ZZ_pEX_GCD(r.x, self.x, other.x)
730
+ sig_off()
731
+ return r
732
+
733
+ def xgcd(self, ntl_ZZ_pEX other):
734
+ """
735
+ Return `r`, `s`, `t` such that ``r = s*self + t*other``.
736
+
737
+ Here `r` is the gcd of ``self`` and ``other``.
738
+
739
+ EXAMPLES::
740
+
741
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
742
+ sage: a = ntl.ZZ_pE([3,2], c)
743
+ sage: b = ntl.ZZ_pE([1,2], c)
744
+ sage: f = ntl.ZZ_pEX([a, b, b])
745
+ sage: g = ntl.ZZ_pEX([a-b, b^2, a])
746
+ sage: h = ntl.ZZ_pEX([a^2-b, b^4, b,a])
747
+ sage: r,s,t = (g*f).xgcd(h*f)
748
+ sage: r
749
+ [[4 6] [1] [1]]
750
+ sage: f / ntl.ZZ_pEX([b])
751
+ [[4 6] [1] [1]]
752
+ sage: s*f*g+t*f*h
753
+ [[4 6] [1] [1]]
754
+ """
755
+ self.c.restore_c()
756
+ cdef ntl_ZZ_pEX s = self._new()
757
+ cdef ntl_ZZ_pEX t = self._new()
758
+ cdef ntl_ZZ_pEX r = self._new()
759
+ sig_on()
760
+ ZZ_pEX_XGCD(r.x, s.x, t.x, self.x, other.x)
761
+ sig_off()
762
+ return (r,s,t)
763
+
764
+ def degree(self):
765
+ """
766
+ Return the degree of this polynomial. The degree of the 0
767
+ polynomial is -1.
768
+
769
+ EXAMPLES::
770
+
771
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
772
+ sage: a = ntl.ZZ_pE([3,2], c)
773
+ sage: b = ntl.ZZ_pE([1,2], c)
774
+ sage: f = ntl.ZZ_pEX([a, b, b])
775
+ sage: f.degree()
776
+ 2
777
+ sage: ntl.ZZ_pEX([], c).degree()
778
+ -1
779
+ """
780
+ self.c.restore_c()
781
+ return ZZ_pEX_deg(self.x)
782
+
783
+ def leading_coefficient(self):
784
+ """
785
+ Return the leading coefficient of this polynomial.
786
+
787
+ EXAMPLES::
788
+
789
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
790
+ sage: a = ntl.ZZ_pE([3,2], c)
791
+ sage: b = ntl.ZZ_pE([1,2], c)
792
+ sage: f = ntl.ZZ_pEX([a, b, b])
793
+ sage: f.leading_coefficient()
794
+ [1 2]
795
+ """
796
+ self.c.restore_c()
797
+ cdef long i
798
+ i = ZZ_pEX_deg(self.x)
799
+ return self[i]
800
+
801
+ def constant_term(self):
802
+ """
803
+ Return the constant coefficient of this polynomial.
804
+
805
+ EXAMPLES::
806
+
807
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
808
+ sage: a = ntl.ZZ_pE([3,2], c)
809
+ sage: b = ntl.ZZ_pE([1,2], c)
810
+ sage: f = ntl.ZZ_pEX([a, b, b])
811
+ sage: f.constant_term()
812
+ [3 2]
813
+ """
814
+ self.c.restore_c()
815
+ return self[0]
816
+
817
+ def set_x(self):
818
+ """
819
+ Set this polynomial to the monomial "x".
820
+
821
+ EXAMPLES::
822
+
823
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
824
+ sage: a = ntl.ZZ_pE([3,2], c)
825
+ sage: b = ntl.ZZ_pE([1,2], c)
826
+ sage: f = ntl.ZZ_pEX([a, b, b])
827
+ sage: f
828
+ [[3 2] [1 2] [1 2]]
829
+ sage: f.set_x(); f
830
+ [[] [1]]
831
+ """
832
+ self.c.restore_c()
833
+ ZZ_pEX_SetX(self.x)
834
+
835
+ def is_x(self):
836
+ """
837
+ ``True`` if this is the polynomial "x".
838
+
839
+ EXAMPLES::
840
+
841
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
842
+ sage: a = ntl.ZZ_pE([3,2], c)
843
+ sage: b = ntl.ZZ_pE([1,2], c)
844
+ sage: f = ntl.ZZ_pEX([a, b, b])
845
+ sage: f.is_x()
846
+ False
847
+ sage: f.set_x(); f.is_x()
848
+ True
849
+ """
850
+ return bool(ZZ_pEX_IsX(self.x))
851
+
852
+ def derivative(self):
853
+ """
854
+ Return the derivative of this polynomial.
855
+
856
+ EXAMPLES::
857
+
858
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
859
+ sage: a = ntl.ZZ_pE([3,2], c)
860
+ sage: b = ntl.ZZ_pE([1,2], c)
861
+ sage: f = ntl.ZZ_pEX([a, b, b])
862
+ sage: f.derivative()
863
+ [[1 2] [2 4]]
864
+ """
865
+ cdef ntl_ZZ_pEX r = self._new()
866
+ sig_on()
867
+ ZZ_pEX_diff(r.x, self.x)
868
+ sig_off()
869
+ return r
870
+
871
+ #def factor(self, verbose=False):
872
+ # cdef ZZ_pX_c** v
873
+ # cdef long* e
874
+ # cdef long i, n
875
+ # sig_on()
876
+ # ZZ_pX_factor(&v, &e, &n, &self.x, verbose)
877
+ # sig_off()
878
+ # F = []
879
+ # for i from 0 <= i < n:
880
+ # F.append((make_ZZ_pX(v[i], self.c), e[i]))
881
+ # free(v)
882
+ # free(e)
883
+ # return F
884
+
885
+ #def linear_roots(self):
886
+ # """
887
+ # Assumes that input is monic, and has deg(f) distinct roots.
888
+ # Returns the list of roots.
889
+ # """
890
+ # cdef ZZ_p_c** v
891
+ # cdef long i, n
892
+ # sig_on()
893
+ # ZZ_pX_linear_roots(&v, &n, &self.x)
894
+ # sig_off()
895
+ # F = []
896
+ # for i from 0 <= i < n:
897
+ # F.append(make_ZZ_p(v[i], self.c))
898
+ # free(v)
899
+ # return F
900
+
901
+ def reverse(self, hi=None):
902
+ """
903
+ Return the polynomial obtained by reversing the coefficients
904
+ of this polynomial. If hi is set then this function behaves
905
+ as if this polynomial has degree hi.
906
+
907
+ EXAMPLES::
908
+
909
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
910
+ sage: a = ntl.ZZ_pE([3,2], c)
911
+ sage: b = ntl.ZZ_pE([1,2], c)
912
+ sage: f = ntl.ZZ_pEX([a, b, b])
913
+ sage: f.reverse()
914
+ [[1 2] [1 2] [3 2]]
915
+ sage: f.reverse(hi=5)
916
+ [[] [] [] [1 2] [1 2] [3 2]]
917
+ sage: f.reverse(hi=1)
918
+ [[1 2] [3 2]]
919
+ sage: f.reverse(hi=-2)
920
+ []
921
+ """
922
+ cdef ntl_ZZ_pEX r = self._new()
923
+ if not (hi is None):
924
+ ZZ_pEX_reverse_hi(r.x, self.x, int(hi))
925
+ else:
926
+ ZZ_pEX_reverse(r.x, self.x)
927
+ return r
928
+
929
+ def truncate(self, long m):
930
+ """
931
+ Return the truncation of this polynomial obtained by
932
+ removing all terms of degree >= m.
933
+
934
+ EXAMPLES::
935
+
936
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
937
+ sage: a = ntl.ZZ_pE([3,2], c)
938
+ sage: b = ntl.ZZ_pE([1,2], c)
939
+ sage: f = ntl.ZZ_pEX([a, b, b])
940
+ sage: f.truncate(3)
941
+ [[3 2] [1 2] [1 2]]
942
+ sage: f.truncate(1)
943
+ [[3 2]]
944
+ """
945
+ cdef ntl_ZZ_pEX r = self._new()
946
+ if m > 0:
947
+ sig_on()
948
+ ZZ_pEX_trunc(r.x, self.x, m)
949
+ sig_off()
950
+ return r
951
+
952
+ def multiply_and_truncate(self, ntl_ZZ_pEX other, long m):
953
+ """
954
+ Return self*other but with terms of degree >= m removed.
955
+
956
+ EXAMPLES::
957
+
958
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
959
+ sage: a = ntl.ZZ_pE([3,2], c)
960
+ sage: b = ntl.ZZ_pE([1,2], c)
961
+ sage: f = ntl.ZZ_pEX([a, b, b])
962
+ sage: g = ntl.ZZ_pEX([a - b, b^2, a, a*b])
963
+ sage: f*g
964
+ [[6 4] [4 9] [4 6] [7] [1 9] [2 5]]
965
+ sage: f.multiply_and_truncate(g, 3)
966
+ [[6 4] [4 9] [4 6]]
967
+ """
968
+ cdef ntl_ZZ_pEX r = self._new()
969
+ if m > 0:
970
+ sig_on()
971
+ ZZ_pEX_MulTrunc(r.x, self.x, other.x, m)
972
+ sig_off()
973
+ return r
974
+
975
+ def square_and_truncate(self, long m):
976
+ """
977
+ Return self*self but with terms of degree >= m removed.
978
+
979
+ EXAMPLES::
980
+
981
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
982
+ sage: a = ntl.ZZ_pE([3,2], c)
983
+ sage: b = ntl.ZZ_pE([1,2], c)
984
+ sage: f = ntl.ZZ_pEX([a, b, b])
985
+ sage: f^2
986
+ [[5 8] [9 8] [6 8] [5] [8]]
987
+ sage: f.square_and_truncate(3)
988
+ [[5 8] [9 8] [6 8]]
989
+ """
990
+ cdef ntl_ZZ_pEX r = self._new()
991
+ if m > 0:
992
+ sig_on()
993
+ ZZ_pEX_SqrTrunc(r.x, self.x, m)
994
+ sig_off()
995
+ return r
996
+
997
+ def invert_and_truncate(self, long m):
998
+ """
999
+ Compute and return the inverse of ``self`` modulo `x^m`.
1000
+ The constant term of ``self`` must be invertible.
1001
+
1002
+ EXAMPLES::
1003
+
1004
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1005
+ sage: a = ntl.ZZ_pE([3,2], c)
1006
+ sage: b = ntl.ZZ_pE([1,2], c)
1007
+ sage: f = ntl.ZZ_pEX([a, b, b])
1008
+ sage: g = f.invert_and_truncate(5)
1009
+ sage: g
1010
+ [[8 6] [4 4] [5 9] [1 4] [0 1]]
1011
+ sage: f * g
1012
+ [[1] [] [] [] [] [2 8] [9 10]]
1013
+ """
1014
+ if m < 0:
1015
+ raise ArithmeticError("m (=%s) must be positive" % m)
1016
+ #Need to check here if constant term is invertible
1017
+ cdef ntl_ZZ_pEX r = self._new()
1018
+ if m > 0:
1019
+ sig_on()
1020
+ ZZ_pEX_InvTrunc(r.x, self.x, m)
1021
+ sig_off()
1022
+ return r
1023
+
1024
+ def multiply_mod(self, ntl_ZZ_pEX other, ntl_ZZ_pEX modulus):
1025
+ """
1026
+ Return ``self*other % modulus``. The modulus must be monic with
1027
+ ``deg(modulus) > 0``, and ``self`` and ``other`` must have smaller degree.
1028
+
1029
+ EXAMPLES::
1030
+
1031
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1032
+ sage: a = ntl.ZZ_pE([3,2], c)
1033
+ sage: b = ntl.ZZ_pE([1,2], c)
1034
+ sage: f = ntl.ZZ_pEX([a, b, b])
1035
+ sage: g = ntl.ZZ_pEX([b^4, a*b^2, a - b])
1036
+ sage: m = ntl.ZZ_pEX([a - b, b^2, a, a*b])
1037
+ sage: f.multiply_mod(g, m)
1038
+ [[10 10] [4 4] [10 3]]
1039
+ """
1040
+ self.c.restore_c()
1041
+ cdef ntl_ZZ_pEX r = self._new()
1042
+ sig_on()
1043
+ ZZ_pEX_MulMod(r.x, self.x, other.x, modulus.x)
1044
+ sig_off()
1045
+ return r
1046
+
1047
+ def trace_mod(self, ntl_ZZ_pEX modulus):
1048
+ """
1049
+ Return the trace of this polynomial modulo the modulus.
1050
+ The modulus must be monic, and of positive degree bigger
1051
+ than the degree of ``self``.
1052
+
1053
+ EXAMPLES::
1054
+
1055
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1056
+ sage: a = ntl.ZZ_pE([3,2], c)
1057
+ sage: b = ntl.ZZ_pE([1,2], c)
1058
+ sage: f = ntl.ZZ_pEX([a, b, b])
1059
+ sage: m = ntl.ZZ_pEX([a - b, b^2, a, a*b])
1060
+ sage: f.trace_mod(m)
1061
+ [8 1]
1062
+ """
1063
+ self.c.restore_c()
1064
+ cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus=self.c)
1065
+ sig_on()
1066
+ ZZ_pEX_TraceMod(r.x, self.x, modulus.x)
1067
+ sig_off()
1068
+ return r
1069
+
1070
+ #def trace_list(self):
1071
+ # """
1072
+ # Return the list of traces of the powers $x^i$ of the
1073
+ # monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
1074
+ # This polynomial must be monic.
1075
+ #
1076
+ # EXAMPLES::
1077
+ #
1078
+ # sage: c=ntl.ZZ_pContext(ntl.ZZ(20))
1079
+ # sage: f = c.ZZ_pX([1,2,0,3,0,1])
1080
+ # sage: f.trace_list()
1081
+ # [5, 0, 14, 0, 10]
1082
+ #
1083
+ # The input polynomial must be monic or a :exc:`ValueError` is raised::
1084
+ #
1085
+ # sage: c=ntl.ZZ_pContext(ntl.ZZ(20))
1086
+ # sage: f = c.ZZ_pX([1,2,0,3,0,2]
1087
+ # sage: f.trace_list()
1088
+ # Traceback (most recent call last):
1089
+ # ...
1090
+ # ValueError: polynomial must be monic.
1091
+ # """
1092
+ # self.c.restore_c()
1093
+ # if not self.is_monic():
1094
+ # raise ValueError("polynomial must be monic.")
1095
+ # cdef long N = self.degree()
1096
+ # cdef vec_ZZ_pE_c
1097
+ # sig_on()
1098
+ # cdef char* t
1099
+ # t = ZZ_pX_trace_list(&self.x)
1100
+ # return eval(string(t).replace(' ', ','))
1101
+
1102
+ def resultant(self, ntl_ZZ_pEX other):
1103
+ """
1104
+ Return the resultant of ``self`` and ``other``.
1105
+
1106
+ EXAMPLES::
1107
+
1108
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1109
+ sage: a = ntl.ZZ_pE([3,2], c)
1110
+ sage: b = ntl.ZZ_pE([1,2], c)
1111
+ sage: f = ntl.ZZ_pEX([a, b, b])
1112
+ sage: g = ntl.ZZ_pEX([a - b, b^2, a, a*b])
1113
+ sage: f.resultant(g)
1114
+ [1]
1115
+ sage: (f*g).resultant(f^2)
1116
+ []
1117
+ """
1118
+ self.c.restore_c()
1119
+ cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus=self.c)
1120
+ sig_on()
1121
+ ZZ_pEX_resultant(r.x, self.x, other.x)
1122
+ sig_off()
1123
+ return r
1124
+
1125
+ def norm_mod(self, ntl_ZZ_pEX modulus):
1126
+ """
1127
+ Return the norm of this polynomial modulo the modulus. The
1128
+ modulus must be monic, and of positive degree strictly greater
1129
+ than the degree of ``self``.
1130
+
1131
+ EXAMPLES::
1132
+
1133
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1134
+ sage: a = ntl.ZZ_pE([3,2], c)
1135
+ sage: b = ntl.ZZ_pE([1,2], c)
1136
+ sage: f = ntl.ZZ_pEX([a, b, b])
1137
+ sage: m = ntl.ZZ_pEX([a - b, b^2, a, a*b])
1138
+ sage: f.norm_mod(m)
1139
+ [9 2]
1140
+ """
1141
+ self.c.restore_c()
1142
+ cdef ntl_ZZ_pE r = ntl_ZZ_pE(modulus=self.c)
1143
+ sig_on()
1144
+ ZZ_pEX_NormMod(r.x, self.x, modulus.x)
1145
+ sig_off()
1146
+ return r
1147
+
1148
+ def discriminant(self):
1149
+ r"""
1150
+ Return the discriminant of a=self, which is by definition
1151
+ $$
1152
+ (-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
1153
+ $$
1154
+ where m = deg(a), and lc(a) is the leading coefficient of a.
1155
+
1156
+ EXAMPLES::
1157
+
1158
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1159
+ sage: a = ntl.ZZ_pE([3,2], c)
1160
+ sage: b = ntl.ZZ_pE([1,2], c)
1161
+ sage: f = ntl.ZZ_pEX([a, b, b])
1162
+ sage: f.discriminant()
1163
+ [1 6]
1164
+ """
1165
+ self.c.restore_c()
1166
+ cdef long m
1167
+
1168
+ c = ~self.leading_coefficient()
1169
+ m = self.degree()
1170
+ if (m*(m-1) // 2) % 2:
1171
+ c = -c
1172
+ return c*self.resultant(self.derivative())
1173
+
1174
+ def minpoly_mod(self, ntl_ZZ_pEX modulus):
1175
+ """
1176
+ Return the minimal polynomial of this polynomial modulo the
1177
+ modulus. The modulus must be monic of degree bigger than
1178
+ ``self``.
1179
+
1180
+ EXAMPLES::
1181
+
1182
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1183
+ sage: a = ntl.ZZ_pE([3,2], c)
1184
+ sage: b = ntl.ZZ_pE([1,2], c)
1185
+ sage: f = ntl.ZZ_pEX([a, b, b])
1186
+ sage: m = ntl.ZZ_pEX([a - b, b^2, a, a*b])
1187
+ sage: f.minpoly_mod(m)
1188
+ [[2 9] [8 2] [3 10] [1]]
1189
+ """
1190
+ self.c.restore_c()
1191
+ cdef ntl_ZZ_pEX r = self._new()
1192
+ sig_on()
1193
+ ZZ_pEX_MinPolyMod(r.x, self.x, modulus.x)
1194
+ sig_off()
1195
+ return r
1196
+
1197
+ def clear(self):
1198
+ """
1199
+ Reset this polynomial to 0. Changes this polynomial in place.
1200
+
1201
+ EXAMPLES::
1202
+
1203
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1204
+ sage: a = ntl.ZZ_pE([3,2], c)
1205
+ sage: b = ntl.ZZ_pE([1,2], c)
1206
+ sage: f = ntl.ZZ_pEX([a, b, b])
1207
+ sage: f
1208
+ [[3 2] [1 2] [1 2]]
1209
+ sage: f.clear(); f
1210
+ []
1211
+ """
1212
+ self.c.restore_c()
1213
+ sig_on()
1214
+ ZZ_pEX_clear(self.x)
1215
+ sig_off()
1216
+
1217
+ def preallocate_space(self, long n):
1218
+ """
1219
+ Pre-allocate spaces for n coefficients. The polynomial that f
1220
+ represents is unchanged. This is useful if you know you'll be
1221
+ setting coefficients up to n, so memory isn't re-allocated as
1222
+ the polynomial grows. (You might save a millisecond with this
1223
+ function.)
1224
+
1225
+ EXAMPLES::
1226
+
1227
+ sage: c=ntl.ZZ_pEContext(ntl.ZZ_pX([1,1,1], 11))
1228
+ sage: a = ntl.ZZ_pE([3,2], c)
1229
+ sage: b = ntl.ZZ_pE([1,2], c)
1230
+ sage: f = ntl.ZZ_pEX([a, b, b])
1231
+ sage: f[10]=ntl.ZZ_pE([1,8],c) # no new memory is allocated
1232
+ sage: f
1233
+ [[3 2] [1 2] [1 2] [] [] [] [] [] [] [] [1 8]]
1234
+ """
1235
+ self.c.restore_c()
1236
+ sig_on()
1237
+ self.x.SetMaxLength(n)
1238
+ sig_off()
1239
+
1240
+
1241
+ def make_ZZ_pEX(v, modulus):
1242
+ """
1243
+ Here for unpickling.
1244
+
1245
+ EXAMPLES::
1246
+
1247
+ sage: c = ntl.ZZ_pEContext(ntl.ZZ_pX([-5,0,1],25))
1248
+ sage: a = ntl.ZZ_pE([3,2], c)
1249
+ sage: b = ntl.ZZ_pE([1,2], c)
1250
+ sage: sage.libs.ntl.ntl_ZZ_pEX.make_ZZ_pEX([a,b,b], c)
1251
+ [[3 2] [1 2] [1 2]]
1252
+ sage: type(sage.libs.ntl.ntl_ZZ_pEX.make_ZZ_pEX([a,b,b], c))
1253
+ <class 'sage.libs.ntl.ntl_ZZ_pEX.ntl_ZZ_pEX'>
1254
+ """
1255
+ return ntl_ZZ_pEX(v, modulus)