passagemath-ntl 10.8.1a1__cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. passagemath_ntl/__init__.py +3 -0
  2. passagemath_ntl-10.8.1a1.dist-info/METADATA +121 -0
  3. passagemath_ntl-10.8.1a1.dist-info/RECORD +162 -0
  4. passagemath_ntl-10.8.1a1.dist-info/WHEEL +6 -0
  5. passagemath_ntl-10.8.1a1.dist-info/top_level.txt +3 -0
  6. passagemath_ntl.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  7. passagemath_ntl.libs/libgmp-6e109695.so.10.5.0 +0 -0
  8. passagemath_ntl.libs/libmpfi-bcd96d8d.so.0.0.0 +0 -0
  9. passagemath_ntl.libs/libmpfr-104d25bb.so.6.2.2 +0 -0
  10. passagemath_ntl.libs/libntl-bacfd860.so.45.0.0 +0 -0
  11. sage/all__sagemath_ntl.py +7 -0
  12. sage/libs/all__sagemath_ntl.py +3 -0
  13. sage/libs/mpfi/__init__.pxd +287 -0
  14. sage/libs/mpfi/types.pxd +10 -0
  15. sage/libs/ntl/GF2.pxd +18 -0
  16. sage/libs/ntl/GF2E.pxd +28 -0
  17. sage/libs/ntl/GF2EX.pxd +12 -0
  18. sage/libs/ntl/GF2X.pxd +81 -0
  19. sage/libs/ntl/ZZ.pxd +93 -0
  20. sage/libs/ntl/ZZX.pxd +85 -0
  21. sage/libs/ntl/ZZ_p.pxd +28 -0
  22. sage/libs/ntl/ZZ_pE.pxd +37 -0
  23. sage/libs/ntl/ZZ_pEX.pxd +106 -0
  24. sage/libs/ntl/ZZ_pX.pxd +122 -0
  25. sage/libs/ntl/__init__.py +4 -0
  26. sage/libs/ntl/all.py +72 -0
  27. sage/libs/ntl/conversion.pxd +106 -0
  28. sage/libs/ntl/convert.cpython-314t-x86_64-linux-gnu.so +0 -0
  29. sage/libs/ntl/convert.pxd +7 -0
  30. sage/libs/ntl/convert.pyx +38 -0
  31. sage/libs/ntl/decl.pxi +18 -0
  32. sage/libs/ntl/error.cpython-314t-x86_64-linux-gnu.so +0 -0
  33. sage/libs/ntl/error.pyx +63 -0
  34. sage/libs/ntl/lzz_p.pxd +20 -0
  35. sage/libs/ntl/lzz_pX.pxd +59 -0
  36. sage/libs/ntl/mat_GF2.pxd +30 -0
  37. sage/libs/ntl/mat_GF2E.pxd +30 -0
  38. sage/libs/ntl/mat_ZZ.pxd +59 -0
  39. sage/libs/ntl/misc.pxi +33 -0
  40. sage/libs/ntl/ntl_GF2.cpython-314t-x86_64-linux-gnu.so +0 -0
  41. sage/libs/ntl/ntl_GF2.pxd +5 -0
  42. sage/libs/ntl/ntl_GF2.pyx +281 -0
  43. sage/libs/ntl/ntl_GF2E.cpython-314t-x86_64-linux-gnu.so +0 -0
  44. sage/libs/ntl/ntl_GF2E.pxd +8 -0
  45. sage/libs/ntl/ntl_GF2E.pyx +488 -0
  46. sage/libs/ntl/ntl_GF2EContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  47. sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
  48. sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
  49. sage/libs/ntl/ntl_GF2EX.cpython-314t-x86_64-linux-gnu.so +0 -0
  50. sage/libs/ntl/ntl_GF2EX.pxd +10 -0
  51. sage/libs/ntl/ntl_GF2EX.pyx +251 -0
  52. sage/libs/ntl/ntl_GF2X.cpython-314t-x86_64-linux-gnu.so +0 -0
  53. sage/libs/ntl/ntl_GF2X.pxd +5 -0
  54. sage/libs/ntl/ntl_GF2X.pyx +771 -0
  55. sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
  56. sage/libs/ntl/ntl_ZZ.cpython-314t-x86_64-linux-gnu.so +0 -0
  57. sage/libs/ntl/ntl_ZZ.pxd +7 -0
  58. sage/libs/ntl/ntl_ZZ.pyx +541 -0
  59. sage/libs/ntl/ntl_ZZX.cpython-314t-x86_64-linux-gnu.so +0 -0
  60. sage/libs/ntl/ntl_ZZX.pxd +7 -0
  61. sage/libs/ntl/ntl_ZZX.pyx +1206 -0
  62. sage/libs/ntl/ntl_ZZ_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  63. sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
  64. sage/libs/ntl/ntl_ZZ_p.pyx +508 -0
  65. sage/libs/ntl/ntl_ZZ_pContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  66. sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
  67. sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
  68. sage/libs/ntl/ntl_ZZ_pE.cpython-314t-x86_64-linux-gnu.so +0 -0
  69. sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
  70. sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
  71. sage/libs/ntl/ntl_ZZ_pEContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  72. sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
  73. sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
  74. sage/libs/ntl/ntl_ZZ_pEX.cpython-314t-x86_64-linux-gnu.so +0 -0
  75. sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
  76. sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
  77. sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
  78. sage/libs/ntl/ntl_ZZ_pX.cpython-314t-x86_64-linux-gnu.so +0 -0
  79. sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
  80. sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
  81. sage/libs/ntl/ntl_lzz_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  82. sage/libs/ntl/ntl_lzz_p.pxd +8 -0
  83. sage/libs/ntl/ntl_lzz_p.pyx +440 -0
  84. sage/libs/ntl/ntl_lzz_pContext.cpython-314t-x86_64-linux-gnu.so +0 -0
  85. sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
  86. sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
  87. sage/libs/ntl/ntl_lzz_pX.cpython-314t-x86_64-linux-gnu.so +0 -0
  88. sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
  89. sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
  90. sage/libs/ntl/ntl_mat_GF2.cpython-314t-x86_64-linux-gnu.so +0 -0
  91. sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
  92. sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
  93. sage/libs/ntl/ntl_mat_GF2E.cpython-314t-x86_64-linux-gnu.so +0 -0
  94. sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
  95. sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
  96. sage/libs/ntl/ntl_mat_ZZ.cpython-314t-x86_64-linux-gnu.so +0 -0
  97. sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
  98. sage/libs/ntl/ntl_mat_ZZ.pyx +1522 -0
  99. sage/libs/ntl/ntl_tools.pxd +3 -0
  100. sage/libs/ntl/ntlwrap.h +53 -0
  101. sage/libs/ntl/ntlwrap_impl.h +743 -0
  102. sage/libs/ntl/types.pxd +157 -0
  103. sage/libs/ntl/vec_GF2.pxd +26 -0
  104. sage/libs/ntl/vec_GF2E.pxd +2 -0
  105. sage/matrix/all__sagemath_ntl.py +1 -0
  106. sage/matrix/matrix_modn_dense_double.pxd +10 -0
  107. sage/matrix/matrix_modn_dense_float.pxd +9 -0
  108. sage/matrix/matrix_modn_dense_template.pxi +3475 -0
  109. sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
  110. sage/matrix/matrix_modn_sparse.pxd +8 -0
  111. sage/misc/all__sagemath_ntl.py +1 -0
  112. sage/rings/all__sagemath_ntl.py +7 -0
  113. sage/rings/bernmm.cpython-314t-x86_64-linux-gnu.so +0 -0
  114. sage/rings/bernmm.pyx +161 -0
  115. sage/rings/bernoulli_mod_p.cpython-314t-x86_64-linux-gnu.so +0 -0
  116. sage/rings/bernoulli_mod_p.pyx +312 -0
  117. sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
  118. sage/rings/finite_rings/finite_field_ntl_gf2e.py +309 -0
  119. sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-314t-x86_64-linux-gnu.so +0 -0
  120. sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
  121. sage/rings/padics/all__sagemath_ntl.py +5 -0
  122. sage/rings/padics/padic_ZZ_pX_CA_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  123. sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
  124. sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2366 -0
  125. sage/rings/padics/padic_ZZ_pX_CR_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  126. sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
  127. sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3282 -0
  128. sage/rings/padics/padic_ZZ_pX_FM_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  129. sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
  130. sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1737 -0
  131. sage/rings/padics/padic_ZZ_pX_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  132. sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
  133. sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
  134. sage/rings/padics/padic_ext_element.cpython-314t-x86_64-linux-gnu.so +0 -0
  135. sage/rings/padics/padic_ext_element.pxd +38 -0
  136. sage/rings/padics/padic_ext_element.pyx +513 -0
  137. sage/rings/padics/pow_computer_ext.cpython-314t-x86_64-linux-gnu.so +0 -0
  138. sage/rings/padics/pow_computer_ext.pxd +107 -0
  139. sage/rings/padics/pow_computer_ext.pyx +2402 -0
  140. sage/rings/polynomial/all__sagemath_ntl.py +1 -0
  141. sage/rings/polynomial/evaluation_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  142. sage/rings/polynomial/evaluation_ntl.pxd +7 -0
  143. sage/rings/polynomial/evaluation_ntl.pyx +70 -0
  144. sage/rings/polynomial/polynomial_gf2x.cpython-314t-x86_64-linux-gnu.so +0 -0
  145. sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
  146. sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
  147. sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  148. sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
  149. sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
  150. sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-314t-x86_64-linux-gnu.so +0 -0
  151. sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
  152. sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2050 -0
  153. sage/rings/polynomial/polynomial_template.pxi +839 -0
  154. sage/rings/polynomial/polynomial_template_header.pxi +11 -0
  155. sage/rings/polynomial/polynomial_zz_pex.cpython-314t-x86_64-linux-gnu.so +0 -0
  156. sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
  157. sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
  158. sage/rings/real_mpfi.pxd +50 -0
  159. sage/schemes/all__sagemath_ntl.py +1 -0
  160. sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
  161. sage/schemes/hyperelliptic_curves/hypellfrob.cpython-314t-x86_64-linux-gnu.so +0 -0
  162. sage/schemes/hyperelliptic_curves/hypellfrob.pyx +253 -0
@@ -0,0 +1,2050 @@
1
+ # sage_setup: distribution = sagemath-ntl
2
+ # distutils: libraries = NTL_LIBRARIES gmp
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.libs.pari
9
+ r"""
10
+ Dense univariate polynomials over `\ZZ/n\ZZ`, implemented using NTL
11
+
12
+ This implementation is generally slower than the FLINT implementation in
13
+ :mod:`~sage.rings.polynomial.polynomial_zmod_flint`, so we use FLINT by
14
+ default when the modulus is small enough; but NTL does not require that `n` be
15
+ ``int``-sized, so we use it as default when `n` is too large for FLINT.
16
+
17
+ Note that the classes :class:`Polynomial_dense_modn_ntl_zz` and
18
+ :class:`Polynomial_dense_modn_ntl_ZZ` are different; the former is limited to
19
+ moduli less than a certain bound, while the latter supports arbitrarily large
20
+ moduli.
21
+
22
+ AUTHORS:
23
+
24
+ - Robert Bradshaw: Split off from polynomial_element_generic.py (2007-09)
25
+ - Robert Bradshaw: Major rewrite to use NTL directly (2007-09)
26
+ """
27
+ # ****************************************************************************
28
+ # Copyright (C) 2007 William Stein <wstein@gmail.com>
29
+ #
30
+ # This program is free software: you can redistribute it and/or modify
31
+ # it under the terms of the GNU General Public License as published by
32
+ # the Free Software Foundation, either version 2 of the License, or
33
+ # (at your option) any later version.
34
+ # https://www.gnu.org/licenses/
35
+ # ****************************************************************************
36
+
37
+ from cysignals.signals cimport sig_on, sig_off
38
+
39
+ from sage.rings.polynomial.polynomial_element cimport Polynomial, _dict_to_list
40
+
41
+ from sage.rings.integer cimport smallInteger
42
+
43
+ from sage.libs.ntl.ntl_ZZX import ntl_ZZX as ZZX
44
+ from sage.libs.ntl.ntl_ZZ_pX import ntl_ZZ_pX as ZZ_pX
45
+ from sage.rings.integer_ring import ZZ
46
+
47
+ from sage.rings.fraction_field_element import FractionFieldElement
48
+
49
+ from sage.rings.infinity import infinity
50
+
51
+ from sage.structure.element import canonical_coercion, coerce_binop, have_same_parent
52
+
53
+ from sage.libs.ntl.types cimport NTL_SP_BOUND
54
+ from sage.libs.ntl.ZZ_p cimport *
55
+ from sage.libs.ntl.lzz_p cimport *
56
+ from sage.libs.ntl.lzz_pX cimport *
57
+ from sage.libs.ntl.ZZ_pX cimport *
58
+
59
+ try:
60
+ from sage.libs.pari import pari
61
+ from cypari2.gen import Gen as pari_gen
62
+ except ImportError:
63
+ pari_gen = ()
64
+
65
+
66
+ def make_element(parent, args):
67
+ return parent(*args)
68
+
69
+
70
+ zz_p_max = NTL_SP_BOUND
71
+
72
+ cdef class Polynomial_dense_mod_n(Polynomial):
73
+ """
74
+ A dense polynomial over the integers modulo n, where n is composite, with
75
+ the underlying arithmetic done using NTL.
76
+
77
+ EXAMPLES::
78
+
79
+ sage: R.<x> = PolynomialRing(Integers(16), implementation='NTL')
80
+ sage: f = x^3 - x + 17
81
+ sage: f^2
82
+ x^6 + 14*x^4 + 2*x^3 + x^2 + 14*x + 1
83
+
84
+ sage: loads(f.dumps()) == f
85
+ True
86
+
87
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
88
+ sage: p = 3*x
89
+ sage: q = 7*x
90
+ sage: p + q
91
+ 10*x
92
+ sage: R.<x> = PolynomialRing(Integers(8), implementation='NTL')
93
+ sage: parent(p)
94
+ Univariate Polynomial Ring in x over Ring of integers modulo 100 (using NTL)
95
+ sage: p + q
96
+ 10*x
97
+ sage: R({10:-1})
98
+ 7*x^10
99
+
100
+ TESTS::
101
+
102
+ sage: # needs sage.libs.pari
103
+ sage: f = Integers(5*2^100)['x'].random_element()
104
+ sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_mod_n
105
+ sage: isinstance(f, Polynomial_dense_mod_n)
106
+ True
107
+ """
108
+ def __init__(self, parent, x=None, check=True,
109
+ is_gen=False, construct=False):
110
+ Polynomial.__init__(self, parent, is_gen=is_gen)
111
+ cdef Polynomial_dense_mod_n numer, denom
112
+
113
+ if construct:
114
+ if isinstance(x, ZZ_pX):
115
+ self._poly = x
116
+ return
117
+ self._poly = ZZ_pX(x, parent.modulus())
118
+ return
119
+
120
+ self._poly = ZZ_pX([], parent.modulus())
121
+
122
+ if x is None:
123
+ return # leave initialized to 0 polynomial.
124
+
125
+ if isinstance(x, Polynomial):
126
+ if x.parent() == self.parent():
127
+ self._poly = (<Polynomial_dense_modn_ntl_zz>x)._poly.__copy__()
128
+ return
129
+ else:
130
+ R = parent.base_ring()
131
+ x = [ZZ(R(a)) for a in x.list()]
132
+ check = False
133
+
134
+ elif isinstance(x, dict):
135
+ R = parent.base_ring()
136
+ x = _dict_to_list(x, R(0))
137
+
138
+ elif isinstance(x, ZZX):
139
+ self._poly = x.copy()
140
+ return
141
+
142
+ elif isinstance(x, pari_gen):
143
+ x = [ZZ(w) for w in x.list()]
144
+ check = False
145
+
146
+ elif isinstance(x, FractionFieldElement) and \
147
+ isinstance(x.numerator(), Polynomial_dense_mod_n):
148
+ if x.denominator().is_unit():
149
+ numer = x.numerator()
150
+ denom = x.denominator().inverse_of_unit()
151
+ x = numer._poly * denom._poly
152
+ check = False
153
+ else:
154
+ raise TypeError("Denominator not a unit.")
155
+
156
+ elif not isinstance(x, list) and not isinstance(x, tuple):
157
+ x = [x] # constant polynomials
158
+
159
+ if check:
160
+ R = parent.base_ring()
161
+ x = [ZZ(R(a)) for a in x]
162
+
163
+ self._poly = ZZ_pX(x, parent.modulus())
164
+
165
+ def __reduce__(self):
166
+ return make_element, (self.parent(), (self.list(), False, self.is_gen()))
167
+
168
+ def int_list(self):
169
+ return eval(str(self._poly).replace(' ',','))
170
+
171
+ def __pari__(self, variable=None):
172
+ """
173
+ EXAMPLES::
174
+
175
+ sage: t = PolynomialRing(IntegerModRing(17), "t", implementation='NTL').gen()
176
+ sage: f = t^3 + 3*t - 17
177
+ sage: pari(f) # needs sage.libs.pari
178
+ Mod(1, 17)*t^3 + Mod(3, 17)*t
179
+ """
180
+ if variable is None:
181
+ variable = self.parent().variable_name()
182
+ return pari(self.int_list()).Polrev(variable) * \
183
+ pari(1).Mod(self.parent().base_ring().order())
184
+
185
+ def ntl_ZZ_pX(self):
186
+ r"""
187
+ Return underlying NTL representation of this polynomial. Additional
188
+ ''bonus'' functionality is available through this function.
189
+
190
+ .. warning::
191
+
192
+ You must call ``ntl.set_modulus(ntl.ZZ(n))`` before doing
193
+ arithmetic with this object!
194
+ """
195
+ return self._poly
196
+
197
+ cdef get_unsafe(self, Py_ssize_t n):
198
+ """
199
+ Return the `n`-th coefficient of ``self``.
200
+
201
+ EXAMPLES::
202
+
203
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
204
+ sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_mod_n
205
+ sage: f = Polynomial_dense_mod_n(R, [5,10,13,1,4]); f
206
+ 4*x^4 + x^3 + 13*x^2 + 10*x + 5
207
+ sage: f[2]
208
+ 13
209
+ sage: f[:3]
210
+ 13*x^2 + 10*x + 5
211
+ """
212
+ return self._parent._base((<ntl_ZZ_pX> self._poly)[n]._integer_())
213
+
214
+ def _unsafe_mutate(self, n, value):
215
+ n = int(n)
216
+ if n < 0:
217
+ raise IndexError("n must be >= 0")
218
+ self._poly[n] = int(value)
219
+
220
+ def _pow(self, n):
221
+ n = int(n)
222
+ if self.degree() <= 0:
223
+ return self.parent()(self[0]**n)
224
+ if n < 0:
225
+ return (~self)**(-n)
226
+ return self.parent()(self._poly**n, construct=True)
227
+
228
+ cpdef _add_(self, right):
229
+ return self.parent()(self._poly + (<Polynomial_dense_mod_n>right)._poly, construct=True)
230
+
231
+ cpdef _mul_(self, right):
232
+ """
233
+ EXAMPLES::
234
+
235
+ sage: x = PolynomialRing(Integers(100), 'x', implementation='NTL').0
236
+ sage: (x - 2)*(x^2 - 8*x + 16)
237
+ x^3 + 90*x^2 + 32*x + 68
238
+ """
239
+ return self.parent()(self._poly * (<Polynomial_dense_mod_n>right)._poly, construct=True)
240
+
241
+ cpdef _lmul_(self, Element c):
242
+ try:
243
+ return self.parent()(ZZ_pX([c], self.parent().modulus()) * self._poly, construct=True)
244
+ except RuntimeError as msg: # should this really be a TypeError
245
+ raise TypeError(msg)
246
+
247
+ @coerce_binop
248
+ def quo_rem(self, right):
249
+ """
250
+ Return a tuple ``(quotient, remainder)`` where ``self = quotient*other +
251
+ remainder``.
252
+ """
253
+ v = self._poly.quo_rem((<Polynomial_dense_mod_n>right)._poly)
254
+ P = self.parent()
255
+ return (P(v[0], construct=True), P(v[1], construct=True) )
256
+
257
+ def shift(self, n):
258
+ r"""
259
+ Return this polynomial multiplied by the power `x^n`. If `n` is negative,
260
+ terms below `x^n` will be discarded. Does not change this polynomial.
261
+
262
+ EXAMPLES::
263
+
264
+ sage: R.<x> = PolynomialRing(Integers(12345678901234567890), implementation='NTL')
265
+ sage: p = x^2 + 2*x + 4
266
+ sage: p.shift(0)
267
+ x^2 + 2*x + 4
268
+ sage: p.shift(-1)
269
+ x + 2
270
+ sage: p.shift(-5)
271
+ 0
272
+ sage: p.shift(2)
273
+ x^4 + 2*x^3 + 4*x^2
274
+
275
+ TESTS::
276
+
277
+ sage: p = R(0)
278
+ sage: p.shift(3).is_zero()
279
+ True
280
+ sage: p.shift(-3).is_zero()
281
+ True
282
+
283
+ AUTHOR:
284
+
285
+ - David Harvey (2006-08-06)
286
+ """
287
+ if n == 0 or self.degree() < 0:
288
+ return self
289
+ return self.parent()(self._poly.left_shift(n),
290
+ construct=True)
291
+
292
+ cpdef _sub_(self, right):
293
+ return self.parent()(self._poly - (<Polynomial_dense_mod_n>right)._poly, construct=True)
294
+
295
+ def __floordiv__(self, right):
296
+ q, _ = self.quo_rem(right)
297
+ return q
298
+
299
+ def degree(self, gen=None):
300
+ """
301
+ Return the degree of this polynomial.
302
+
303
+ The zero polynomial has degree -1.
304
+
305
+ EXAMPLES::
306
+
307
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
308
+ sage: (x^3 + 3*x - 17).degree()
309
+ 3
310
+ sage: R.zero().degree()
311
+ -1
312
+
313
+ TESTS:
314
+
315
+ Check output type (see :issue:`25182`)::
316
+
317
+ sage: R.<x> = PolynomialRing(Integers(3), implementation='NTL')
318
+ sage: isinstance(x.degree(), Integer)
319
+ True
320
+ """
321
+ return smallInteger(max(self._poly.degree(), -1))
322
+
323
+ cpdef list list(self, bint copy=True):
324
+ """
325
+ Return a new copy of the list of the underlying
326
+ elements of ``self``.
327
+
328
+ EXAMPLES::
329
+
330
+ sage: _.<x> = PolynomialRing(Integers(100), implementation='NTL')
331
+ sage: f = x^3 + 3*x - 17
332
+ sage: f.list()
333
+ [83, 3, 0, 1]
334
+ """
335
+ return [self.get_unsafe(n) for n from 0 <= n <= self.degree()]
336
+
337
+ def ntl_set_directly(self, v):
338
+ r"""
339
+ Set the value of this polynomial directly from a vector or string.
340
+
341
+ Polynomials over the integers modulo n are stored internally using
342
+ NTL's ``ZZ_pX`` class. Use this function to set the value of this
343
+ polynomial using the NTL constructor, which is potentially *very* fast.
344
+ The input v is either a vector of ints or a string of the form ``[ n1
345
+ n2 n3 ... ]`` where the ni are integers and there are no commas between
346
+ them. The optimal input format is the string format, since that's what
347
+ NTL uses by default.
348
+
349
+ EXAMPLES::
350
+
351
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
352
+ sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_mod_n as poly_modn_dense
353
+ sage: poly_modn_dense(R, ([1,-2,3]))
354
+ 3*x^2 + 98*x + 1
355
+ sage: f = poly_modn_dense(R, 0)
356
+ sage: f.ntl_set_directly([1,-2,3])
357
+ sage: f
358
+ 3*x^2 + 98*x + 1
359
+ sage: f.ntl_set_directly('[1 -2 3 4]')
360
+ sage: f
361
+ 4*x^3 + 3*x^2 + 98*x + 1
362
+ """
363
+ if self.is_gen():
364
+ raise TypeError("Cannot change the value of the generator.")
365
+ self._poly = ZZ_pX(v, self.parent().modulus())
366
+
367
+ # Polynomial_singular_repr stuff, copied due to lack of multiple inheritance
368
+ def _singular_(self, singular=None, force=False):
369
+ self.parent()._singular_(singular, force=force).set_ring() # this is expensive
370
+ if self.__singular is not None:
371
+ try:
372
+ self.__singular._check_valid()
373
+ if self.__singular.parent() is singular:
374
+ return self.__singular
375
+ except (AttributeError, ValueError):
376
+ pass
377
+ return self._singular_init_(singular)
378
+
379
+ def _singular_init_(self, singular=None, force=False):
380
+ self.parent()._singular_(singular, force=force).set_ring() # this is expensive
381
+ self.__singular = singular(str(self))
382
+ return self.__singular
383
+
384
+ @coerce_binop
385
+ def minpoly_mod(self, other):
386
+ r"""
387
+ Compute the minimal polynomial of this polynomial modulo another
388
+ polynomial in the same ring.
389
+
390
+ ALGORITHM:
391
+
392
+ NTL's ``MinPolyMod()``, which uses Shoup's algorithm [Sho1999]_.
393
+
394
+ EXAMPLES::
395
+
396
+ sage: R.<x> = PolynomialRing(GF(101), implementation='NTL')
397
+ sage: f = x^17 + x^2 - 1
398
+ sage: (x^2).minpoly_mod(f)
399
+ x^17 + 100*x^2 + 2*x + 100
400
+
401
+ TESTS:
402
+
403
+ Random testing::
404
+
405
+ sage: # needs sage.libs.pari
406
+ sage: p = random_prime(2^99)
407
+ sage: R.<x> = PolynomialRing(GF(p), implementation='NTL')
408
+ sage: d = randrange(1,50)
409
+ sage: f = R.random_element(d)
410
+ sage: g = R.random_element((-1,5*d))
411
+ sage: poly = g.minpoly_mod(f)
412
+ sage: poly(R.quotient(f)(g))
413
+ 0
414
+ """
415
+ mod = other.ntl_ZZ_pX()
416
+ elt = self.ntl_ZZ_pX() % mod
417
+ res = elt.minpoly_mod(mod)
418
+ return self.parent()(res, construct=True)
419
+
420
+ def small_roots(self, *args, **kwds):
421
+ r"""
422
+ See :func:`sage.rings.polynomial.polynomial_modn_dense_ntl.small_roots`
423
+ for the documentation of this function.
424
+
425
+ EXAMPLES::
426
+
427
+ sage: # needs sage.libs.pari
428
+ sage: N = 10001
429
+ sage: K = Zmod(10001)
430
+ sage: P.<x> = PolynomialRing(K, implementation='NTL')
431
+ sage: f = x^3 + 10*x^2 + 5000*x - 222
432
+ sage: f.small_roots() # needs fpylll
433
+ [4]
434
+ """
435
+ return small_roots(self, *args, **kwds)
436
+
437
+ def compose_mod(self, other, modulus):
438
+ r"""
439
+ Compute `f(g) \pmod h`.
440
+
441
+ To be precise about the order fo compostion, given ``self``, ``other``
442
+ and ``modulus`` as `f(x)`, `g(x)` and `h(x)` compute `f(g(x)) \bmod h(x)`.
443
+
444
+ INPUT:
445
+
446
+ - ``other`` -- a polynomial `g(x)`
447
+ - ``modulus`` -- a polynomial `h(x)`
448
+
449
+ EXAMPLES::
450
+
451
+ sage: # needs sage.rings.finite_rings
452
+ sage: R.<x> = GF(2**127 - 1)[]
453
+ sage: f = R.random_element()
454
+ sage: g = R.random_element()
455
+ sage: g.compose_mod(g, f) == g(g) % f
456
+ True
457
+
458
+ sage: R.<x> = GF(163)[]
459
+ sage: f = R([i for i in range(100)])
460
+ sage: g = R([i**2 for i in range(100)])
461
+ sage: h = 1 + x + x**5
462
+ sage: f.compose_mod(g, h)
463
+ 82*x^4 + 56*x^3 + 45*x^2 + 60*x + 127
464
+ sage: f.compose_mod(g, h) == f(g) % h
465
+ True
466
+
467
+ AUTHORS:
468
+
469
+ - Giacomo Pope (2024-08) initial implementation
470
+ """
471
+ elt = self.ntl_ZZ_pX()
472
+ mod = modulus.ntl_ZZ_pX()
473
+ other = other.ntl_ZZ_pX()
474
+ res = elt.compose_mod(other, mod)
475
+ return self.parent()(res, construct=True)
476
+
477
+ # compose_mod is the natural name from the NTL bindings, but polynomial_gf2x
478
+ # has modular_composition as the method name so here we allow both
479
+ modular_composition = compose_mod
480
+
481
+
482
+ def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds):
483
+ r"""
484
+ Let `N` be the characteristic of the base ring this polynomial
485
+ is defined over: ``N = self.base_ring().characteristic()``.
486
+ This method returns small roots of this polynomial modulo some
487
+ factor `b` of `N` with the constraint that `b >= N^\beta`.
488
+ Small in this context means that if `x` is a root of `f`
489
+ modulo `b` then `|x| < X`. This `X` is either provided by the
490
+ user or the maximum `X` is chosen such that this algorithm
491
+ terminates in polynomial time. If `X` is chosen automatically
492
+ it is `X = ceil(1/2 N^{\beta^2/\delta - \epsilon})`.
493
+ The algorithm may also return some roots which are larger than `X`.
494
+ 'This algorithm' in this context means Coppersmith's algorithm for finding
495
+ small roots using the LLL algorithm. The implementation of this algorithm
496
+ follows Alexander May's PhD thesis referenced below.
497
+
498
+ INPUT:
499
+
500
+ - ``X`` -- an absolute bound for the root (default: see above)
501
+ - ``beta`` -- compute a root mod `b` where `b` is a factor of `N` and `b
502
+ \ge N^\beta` (default: 1.0, so `b = N`.)
503
+ - ``epsilon`` -- the parameter `\epsilon` described above. (default: `\beta/8`)
504
+ - ``**kwds`` -- passed through to method :meth:`Matrix_integer_dense.LLL() <sage.matrix.matrix_integer_dense.Matrix_integer_dense.LLL>`
505
+
506
+ EXAMPLES:
507
+
508
+ First consider a small example::
509
+
510
+ sage: # needs sage.libs.pari
511
+ sage: N = 10001
512
+ sage: K = Zmod(10001)
513
+ sage: P.<x> = PolynomialRing(K, implementation='NTL')
514
+ sage: f = x^3 + 10*x^2 + 5000*x - 222
515
+
516
+ This polynomial has no roots without modular reduction (i.e. over `\ZZ`)::
517
+
518
+ sage: f.change_ring(ZZ).roots() # needs sage.libs.pari
519
+ []
520
+
521
+ To compute its roots we need to factor the modulus `N` and use the Chinese
522
+ remainder theorem::
523
+
524
+ sage: # needs sage.libs.pari
525
+ sage: p, q = N.prime_divisors()
526
+ sage: f.change_ring(GF(p)).roots()
527
+ [(4, 1)]
528
+ sage: f.change_ring(GF(q)).roots()
529
+ [(4, 1)]
530
+ sage: crt(4, 4, p, q)
531
+ 4
532
+
533
+ This root is quite small compared to `N`, so we can attempt to
534
+ recover it without factoring `N` using Coppersmith's small root
535
+ method::
536
+
537
+ sage: f.small_roots() # needs fpylll sage.libs.pari
538
+ [4]
539
+
540
+ An application of this method is to consider RSA. We are using 512-bit RSA
541
+ with public exponent `e=3` to encrypt a 56-bit DES key. Because it would be
542
+ easy to attack this setting if no padding was used we pad the key `K` with
543
+ 1s to get a large number::
544
+
545
+ sage: Nbits, Kbits = 512, 56
546
+ sage: e = 3
547
+
548
+ We choose two primes of size 256-bit each::
549
+
550
+ sage: p = 2^256 + 2^8 + 2^5 + 2^3 + 1
551
+ sage: q = 2^256 + 2^8 + 2^5 + 2^3 + 2^2 + 1
552
+ sage: N = p*q
553
+ sage: ZmodN = Zmod( N )
554
+
555
+ We choose a random key::
556
+
557
+ sage: K = ZZ.random_element(0, 2^Kbits)
558
+
559
+ and pad it with `512-56=456` 1s::
560
+
561
+ sage: Kdigits = K.digits(2)
562
+ sage: M = [0]*Kbits + [1]*(Nbits-Kbits)
563
+ sage: for i in range(len(Kdigits)): M[i] = Kdigits[i]
564
+
565
+ sage: M = ZZ(M, 2)
566
+
567
+ Now we encrypt the resulting message::
568
+
569
+ sage: C = ZmodN(M)^e
570
+
571
+ To recover `K` we consider the following polynomial modulo `N`::
572
+
573
+ sage: P.<x> = PolynomialRing(ZmodN, implementation='NTL') # needs sage.libs.pari
574
+ sage: f = (2^Nbits - 2^Kbits + x)^e - C # needs sage.libs.pari
575
+
576
+ and recover its small roots::
577
+
578
+ sage: Kbar = f.small_roots()[0] # needs fpylll sage.libs.pari
579
+ sage: K == Kbar # needs fpylll sage.libs.pari
580
+ True
581
+
582
+ The same algorithm can be used to factor `N = pq` if partial
583
+ knowledge about `q` is available. This example is from the
584
+ Magma handbook:
585
+
586
+ First, we set up `p`, `q` and `N`::
587
+
588
+ sage: length = 512
589
+ sage: hidden = 110
590
+ sage: p = next_prime(2^int(round(length/2)))
591
+ sage: q = next_prime(round(pi.n()*p)) # needs sage.symbolic
592
+ sage: N = p*q # needs sage.symbolic
593
+
594
+ Now we disturb the low 110 bits of `q`::
595
+
596
+ sage: qbar = q + ZZ.random_element(0, 2^hidden - 1) # needs sage.symbolic
597
+
598
+ And try to recover `q` from it::
599
+
600
+ sage: F.<x> = PolynomialRing(Zmod(N), implementation='NTL') # needs sage.symbolic
601
+ sage: f = x - qbar # needs sage.symbolic
602
+
603
+ We know that the error is `\le 2^{\text{hidden}}-1` and that the modulus
604
+ we are looking for is `\ge \sqrt{N}`::
605
+
606
+ sage: from sage.misc.verbose import set_verbose
607
+ sage: set_verbose(2)
608
+ sage: d = f.small_roots(X=2^hidden-1, beta=0.5)[0] # time random # needs fpylll sage.symbolic
609
+ verbose 2 (<module>) m = 4
610
+ verbose 2 (<module>) t = 4
611
+ verbose 2 (<module>) X = 1298074214633706907132624082305023
612
+ verbose 1 (<module>) LLL of 8x8 matrix (algorithm fpLLL:wrapper)
613
+ verbose 1 (<module>) LLL finished (time = 0.006998)
614
+ sage: q == qbar - d # needs fpylll sage.symbolic
615
+ True
616
+
617
+ REFERENCES:
618
+
619
+ Don Coppersmith. *Finding a small root of a univariate modular equation.*
620
+ In Advances in Cryptology, EuroCrypt 1996, volume 1070 of Lecture
621
+ Notes in Computer Science, p. 155--165. Springer, 1996.
622
+ http://cr.yp.to/bib/2001/coppersmith.pdf
623
+
624
+ Alexander May. *New RSA Vulnerabilities Using Lattice Reduction Methods.*
625
+ PhD thesis, University of Paderborn, 2003.
626
+ http://www.cs.uni-paderborn.de/uploads/tx_sibibtex/bp.pdf
627
+ """
628
+ from sage.misc.verbose import verbose
629
+ from sage.matrix.constructor import Matrix
630
+ from sage.rings.real_mpfr import RR
631
+
632
+ N = self.parent().characteristic()
633
+
634
+ if not self.is_monic():
635
+ raise ArithmeticError("Polynomial must be monic.")
636
+
637
+ beta = RR(beta)
638
+ if beta <= 0.0 or beta > 1.0:
639
+ raise ValueError("0.0 < beta <= 1.0 not satisfied.")
640
+
641
+ f = self.change_ring(ZZ)
642
+
643
+ _, (x,) = f.parent().objgens()
644
+
645
+ delta = f.degree()
646
+
647
+ if epsilon is None:
648
+ epsilon = beta/8
649
+ verbose("epsilon = %f" % epsilon, level=2)
650
+
651
+ m = max(beta**2/(delta * epsilon), 7*beta/delta).ceil()
652
+ verbose("m = %d" % m, level=2)
653
+
654
+ t = int( ( delta*m*(1/beta -1) ).floor() )
655
+ verbose("t = %d" % t, level=2)
656
+
657
+ if X is None:
658
+ X = (0.5 * N**(beta**2/delta - epsilon)).ceil()
659
+ verbose("X = %s" % X, level=2)
660
+
661
+ # we could do this much faster, but this is a cheap step
662
+ # compared to LLL
663
+ g = [x**j * N**(m-i) * f**i for i in range(m) for j in range(delta)]
664
+ g.extend([x**i * f**m for i in range(t)]) # h
665
+
666
+ B = Matrix(ZZ, len(g), delta*m + max(delta,t) )
667
+ for i in range(B.nrows()):
668
+ for j in range( g[i].degree()+1 ):
669
+ B[i, j] = g[i][j]*X**j
670
+
671
+ B = B.LLL(**kwds)
672
+
673
+ f = sum([ZZ(B[0, i]//X**i)*x**i for i in range(B.ncols())])
674
+ R = f.roots()
675
+
676
+ ZmodN = self.base_ring()
677
+ roots = set(ZmodN(r) for r, m in R if abs(r) <= X)
678
+ Nbeta = N**beta
679
+ return [root for root in roots if N.gcd(ZZ(self(root))) >= Nbeta]
680
+
681
+
682
+ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n):
683
+ r"""
684
+ Polynomial on `\ZZ/n\ZZ` implemented via NTL.
685
+
686
+ .. automethod:: _add_
687
+ .. automethod:: _sub_
688
+ .. automethod:: _lmul_
689
+ .. automethod:: _rmul_
690
+ .. automethod:: _mul_
691
+ .. automethod:: _mul_trunc_
692
+ """
693
+ def __init__(self, parent, v=None, check=True, is_gen=False, construct=False):
694
+ r"""
695
+ EXAMPLES::
696
+
697
+ sage: R = Integers(5**21)
698
+ sage: S.<x> = PolynomialRing(R, implementation='NTL') # needs sage.libs.pari
699
+ sage: S(1/4) # needs sage.libs.pari
700
+ 357627868652344
701
+ """
702
+ if isinstance(v, Polynomial):
703
+ if (<Element>v)._parent == parent:
704
+ Polynomial.__init__(self, parent, is_gen=is_gen)
705
+ self.x = (<Polynomial_dense_modn_ntl_zz>v).x
706
+ self.c = (<Polynomial_dense_modn_ntl_zz>v).c
707
+ return
708
+
709
+ Polynomial_dense_mod_n.__init__(self, parent, v, check=check, is_gen=is_gen, construct=construct)
710
+ v = [a for a in self._poly.list()]
711
+ self._poly = None # this will eventually go away
712
+ cdef ntl_zz_pX ntl = ntl_zz_pX(v, parent.modulus()) # let it handle the hard work
713
+ self.x = ntl.x
714
+ self.c = ntl.c
715
+
716
+ def __dealloc__(self):
717
+ if <object>self.c is not None:
718
+ self.c.restore_c()
719
+
720
+ def ntl_set_directly(self, v):
721
+ # TODO: Get rid of this
722
+ Polynomial_dense_mod_n.ntl_set_directly(self, v)
723
+ # verbatim from __init__
724
+ v = [int(a) for a in self._poly.list()]
725
+ self._poly = None # this will eventually go away
726
+ cdef ntl_zz_pX ntl = ntl_zz_pX(v, self._parent.modulus()) # let it handle the hard work
727
+ self.x = ntl.x
728
+ self.c = ntl.c
729
+
730
+ cdef Polynomial_dense_modn_ntl_zz _new(self):
731
+ cdef Polynomial_dense_modn_ntl_zz y = <Polynomial_dense_modn_ntl_zz>Polynomial_dense_modn_ntl_zz.__new__(Polynomial_dense_modn_ntl_zz)
732
+ y.c = self.c
733
+ y._parent = self._parent
734
+ return y
735
+
736
+ def int_list(self):
737
+ """
738
+ Return the coefficients of ``self`` as efficiently as possible as a
739
+ list of python ints.
740
+
741
+ EXAMPLES::
742
+
743
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
744
+ sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_mod_n as poly_modn_dense
745
+ sage: f = poly_modn_dense(R,[5,0,0,1])
746
+ sage: f.int_list()
747
+ [5, 0, 0, 1]
748
+ sage: [type(a) for a in f.int_list()]
749
+ [<... 'int'>, <... 'int'>, <... 'int'>, <... 'int'>]
750
+ """
751
+ cdef long i
752
+ return [ zz_p_rep(zz_pX_GetCoeff(self.x, i)) for i from 0 <= i <= zz_pX_deg(self.x) ]
753
+
754
+ cdef get_unsafe(self, Py_ssize_t n):
755
+ """
756
+ Return the `n`-th coefficient of ``self``.
757
+
758
+ EXAMPLES::
759
+
760
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
761
+ sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_modn_ntl_zz
762
+ sage: f = Polynomial_dense_modn_ntl_zz(R,[2, 1])^7
763
+ sage: f[3]
764
+ 60
765
+ sage: f[:6]
766
+ 84*x^5 + 80*x^4 + 60*x^3 + 72*x^2 + 48*x + 28
767
+ sage: f[:50] == f
768
+ True
769
+ """
770
+ return self._parent._base(zz_p_rep(zz_pX_GetCoeff(self.x, n)))
771
+
772
+ def _unsafe_mutate(self, n, value):
773
+ self.c.restore_c()
774
+ zz_pX_SetCoeff_long(self.x, n, value)
775
+
776
+ cpdef _add_(self, _right):
777
+ """
778
+ TESTS::
779
+
780
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
781
+ sage: (x + 5) + (x^2 - 6)
782
+ x^2 + x + 99
783
+ """
784
+ cdef Polynomial_dense_modn_ntl_zz right = <Polynomial_dense_modn_ntl_zz>_right
785
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
786
+ cdef bint do_sig = zz_pX_deg(self.x) + zz_pX_deg(right.x) > 1000000
787
+ if do_sig: sig_on()
788
+ self.c.restore_c()
789
+ zz_pX_add(r.x, self.x, right.x)
790
+ if do_sig: sig_off()
791
+ return r
792
+
793
+ cpdef _sub_(self, _right):
794
+ """
795
+ TESTS::
796
+
797
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
798
+ sage: (x + 5) - (x^2 - 6)
799
+ 99*x^2 + x + 11
800
+ """
801
+ cdef Polynomial_dense_modn_ntl_zz right = <Polynomial_dense_modn_ntl_zz>_right
802
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
803
+ cdef bint do_sig = zz_pX_deg(self.x) + zz_pX_deg(right.x) > 1000000
804
+ if do_sig: sig_on()
805
+ self.c.restore_c()
806
+ zz_pX_sub(r.x, self.x, right.x)
807
+ if do_sig: sig_off()
808
+ return r
809
+
810
+ cpdef _mul_(self, _right):
811
+ """
812
+ TESTS::
813
+
814
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
815
+ sage: (x + 5) * (x^2 - 1)
816
+ x^3 + 5*x^2 + 99*x + 95
817
+ """
818
+ cdef Polynomial_dense_modn_ntl_zz right = <Polynomial_dense_modn_ntl_zz>_right
819
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
820
+ cdef bint do_sig = zz_pX_deg(self.x) + zz_pX_deg(right.x) > 10000
821
+ if do_sig: sig_on()
822
+ self.c.restore_c()
823
+ if self is right:
824
+ zz_pX_sqr(r.x, self.x)
825
+ else:
826
+ zz_pX_mul(r.x, self.x, right.x)
827
+ if do_sig: sig_off()
828
+ return r
829
+
830
+ cpdef Polynomial _mul_trunc_(self, Polynomial right, long n):
831
+ r"""
832
+ Return the product of ``self`` and ``right`` truncated to the
833
+ given length `n`
834
+
835
+ EXAMPLES::
836
+
837
+ sage: R.<x> = PolynomialRing(Integers(100), implementation="NTL")
838
+ sage: f = x - 2
839
+ sage: g = x^2 - 8*x + 16
840
+ sage: f*g
841
+ x^3 + 90*x^2 + 32*x + 68
842
+ sage: f._mul_trunc_(g, 42)
843
+ x^3 + 90*x^2 + 32*x + 68
844
+ sage: f._mul_trunc_(g, 3)
845
+ 90*x^2 + 32*x + 68
846
+ sage: f._mul_trunc_(g, 2)
847
+ 32*x + 68
848
+ sage: f._mul_trunc_(g, 1)
849
+ 68
850
+ sage: f._mul_trunc_(g, 0)
851
+ 0
852
+ sage: f = x^2 - 8*x + 16
853
+ sage: f._mul_trunc_(f, 2)
854
+ 44*x + 56
855
+ """
856
+ cdef Polynomial_dense_modn_ntl_zz op2 = <Polynomial_dense_modn_ntl_zz> right
857
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
858
+ cdef bint do_sig = zz_pX_deg(self.x) + zz_pX_deg(op2.x) > 10000
859
+ if do_sig: sig_on()
860
+ self.c.restore_c()
861
+ if self is op2:
862
+ zz_pX_SqrTrunc(r.x, self.x, n)
863
+ else:
864
+ zz_pX_MulTrunc(r.x, self.x, op2.x, n)
865
+ if do_sig: sig_off()
866
+ return r
867
+
868
+ cpdef _rmul_(self, Element c):
869
+ """
870
+ TESTS::
871
+
872
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
873
+ sage: (x+5) * 3
874
+ 3*x + 15
875
+ """
876
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
877
+ cdef bint do_sig = zz_pX_deg(self.x) > 100000
878
+ if do_sig: sig_on()
879
+ self.c.restore_c()
880
+ zz_pX_rmul(r.x, self.x, c)
881
+ if do_sig: sig_off()
882
+ return r
883
+
884
+ cpdef _lmul_(self, Element c):
885
+ """
886
+ TESTS::
887
+
888
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
889
+ sage: 3 * (x+5)
890
+ 3*x + 15
891
+ """
892
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
893
+ cdef bint do_sig = zz_pX_deg(self.x) > 100000
894
+ if do_sig: sig_on()
895
+ self.c.restore_c()
896
+ zz_pX_lmul(r.x, c, self.x)
897
+ if do_sig: sig_off()
898
+ return r
899
+
900
+ def __pow__(Polynomial_dense_modn_ntl_zz self, ee, modulus):
901
+ r"""
902
+ TESTS::
903
+
904
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
905
+ sage: (x-1)^5
906
+ x^5 + 95*x^4 + 10*x^3 + 90*x^2 + 5*x + 99
907
+
908
+ We define ``0^0`` to be unity, :issue:`13895`::
909
+
910
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
911
+ sage: R(0)^0
912
+ 1
913
+
914
+ The value returned from ``0^0`` should belong to our ring::
915
+
916
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
917
+ sage: type(R(0)^0) == type(R(0))
918
+ True
919
+
920
+ Negative powers work (over prime fields) but use the generic
921
+ implementation of fraction fields::
922
+
923
+ sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
924
+ sage: f = (x-1)^(-5)
925
+ sage: type(f)
926
+ <class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
927
+ sage: (f + 2).numerator()
928
+ 2*x^5 + 91*x^4 + 20*x^3 + 81*x^2 + 10*x + 100
929
+
930
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
931
+ sage: (x-1)^(-5)
932
+ Traceback (most recent call last):
933
+ ...
934
+ TypeError: ...
935
+ """
936
+ cdef bint recip = 0, do_sig
937
+ cdef long e = ee
938
+ if e != ee:
939
+ raise TypeError("Only integral powers defined.")
940
+ elif e < 0:
941
+ recip = 1
942
+ e = -e
943
+ if self == 0 and e == 0:
944
+ return self.parent(1)
945
+
946
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
947
+ cdef zz_pX_Modulus_c mod
948
+
949
+ self.c.restore_c()
950
+
951
+ if modulus is None:
952
+ if zz_pX_IsX(self.x):
953
+ zz_pX_LeftShift(r.x, self.x, e-1)
954
+ else:
955
+ do_sig = zz_pX_deg(self.x) *e > 1000
956
+ if do_sig: sig_on()
957
+ zz_pX_power(r.x, self.x, e)
958
+ if do_sig: sig_off()
959
+ else:
960
+ if not isinstance(modulus, Polynomial_dense_modn_ntl_zz):
961
+ modulus = self.parent().coerce(modulus)
962
+ zz_pX_Modulus_build(mod, (<Polynomial_dense_modn_ntl_zz>modulus).x)
963
+
964
+ do_sig = zz_pX_deg(self.x) * e * self.c.p_bits > 1e5
965
+ if do_sig: sig_on()
966
+ zz_pX_PowerMod_long_pre(r.x, self.x, e, mod)
967
+ if do_sig: sig_off()
968
+
969
+ if recip:
970
+ return ~r
971
+ else:
972
+ return r
973
+
974
+ @coerce_binop
975
+ def quo_rem(self, right):
976
+ r"""
977
+ Return `q` and `r`, with the degree of `r` less than the degree of ``right``,
978
+ such that `q \cdot` ``right`` `{}+ r =` ``self``.
979
+
980
+ EXAMPLES::
981
+
982
+ sage: R.<x> = PolynomialRing(Integers(125), implementation='NTL')
983
+ sage: f = x^5+1; g = (x+1)^2
984
+ sage: q, r = f.quo_rem(g)
985
+ sage: q
986
+ x^3 + 123*x^2 + 3*x + 121
987
+ sage: r
988
+ 5*x + 5
989
+ sage: q*g + r
990
+ x^5 + 1
991
+ """
992
+ cdef Polynomial_dense_modn_ntl_zz q = self._new()
993
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
994
+ cdef Polynomial_dense_modn_ntl_zz denom = <Polynomial_dense_modn_ntl_zz>right
995
+ sig_on()
996
+ self.c.restore_c()
997
+ zz_pX_divrem(q.x, r.x, self.x, denom.x)
998
+ sig_off()
999
+ return q, r
1000
+
1001
+ cpdef _floordiv_(self, right):
1002
+ """
1003
+ Return the whole part of ``self``/``right``, without remainder.
1004
+
1005
+ For q = n // d, we have deg(n - q*d) < deg(d)
1006
+
1007
+ EXAMPLES::
1008
+
1009
+ sage: R.<x> = PolynomialRing(Integers(25), implementation='NTL')
1010
+ sage: f = x^7 + 1; g = x^2 - 1
1011
+ sage: q = f // g; q
1012
+ x^5 + x^3 + x
1013
+ sage: f - q*g
1014
+ x + 1
1015
+ """
1016
+ cdef Polynomial_dense_modn_ntl_zz numer = <Polynomial_dense_modn_ntl_zz>self
1017
+ cdef Polynomial_dense_modn_ntl_zz denom = <Polynomial_dense_modn_ntl_zz>right
1018
+ cdef Polynomial_dense_modn_ntl_zz q = numer._new()
1019
+ sig_on()
1020
+ numer.c.restore_c()
1021
+ zz_pX_div(q.x, numer.x, denom.x)
1022
+ sig_off()
1023
+ return q
1024
+
1025
+ cpdef _mod_(self, right):
1026
+ """
1027
+ EXAMPLES::
1028
+
1029
+ sage: R.<x> = PolynomialRing(Integers(81), implementation='NTL')
1030
+ sage: f = x^7 + x + 1; g = x^3
1031
+ sage: r = f % g; r
1032
+ x + 1
1033
+ sage: g * x^4 + r
1034
+ x^7 + x + 1
1035
+ """
1036
+ cdef Polynomial_dense_modn_ntl_zz numer = <Polynomial_dense_modn_ntl_zz>self
1037
+ cdef Polynomial_dense_modn_ntl_zz denom = <Polynomial_dense_modn_ntl_zz>right
1038
+ cdef Polynomial_dense_modn_ntl_zz r = numer._new()
1039
+ sig_on()
1040
+ numer.c.restore_c()
1041
+ zz_pX_mod(r.x, numer.x, denom.x)
1042
+ sig_off()
1043
+ return r
1044
+
1045
+ def shift(self, n):
1046
+ """
1047
+ Shift ``self`` to left by `n`, which is multiplication by `x^n`,
1048
+ truncating if `n` is negative.
1049
+
1050
+ EXAMPLES::
1051
+
1052
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1053
+ sage: f = x^7 + x + 1
1054
+ sage: f.shift(1)
1055
+ x^8 + x^2 + x
1056
+ sage: f.shift(-1)
1057
+ x^6 + 1
1058
+ sage: f.shift(10).shift(-10) == f
1059
+ True
1060
+
1061
+ TESTS::
1062
+
1063
+ sage: p = R(0)
1064
+ sage: p.shift(3).is_zero()
1065
+ True
1066
+ sage: p.shift(-3).is_zero()
1067
+ True
1068
+ """
1069
+ return self << n
1070
+
1071
+ def __lshift__(Polynomial_dense_modn_ntl_zz self, long n):
1072
+ """
1073
+ TESTS::
1074
+
1075
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1076
+ sage: f = x^5 + 2*x + 1
1077
+ sage: f << 3
1078
+ x^8 + 2*x^4 + x^3
1079
+ """
1080
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
1081
+ zz_pX_LeftShift(r.x, self.x, n)
1082
+ return r
1083
+
1084
+ def __rshift__(Polynomial_dense_modn_ntl_zz self, long n):
1085
+ """
1086
+ TESTS::
1087
+
1088
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1089
+ sage: f = x^5 + 2*x + 1
1090
+ sage: f >> 3
1091
+ x^2
1092
+ """
1093
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
1094
+ zz_pX_RightShift(r.x, self.x, n)
1095
+ return r
1096
+
1097
+ def _derivative(self, var=None):
1098
+ r"""
1099
+ Return the formal derivative of ``self`` with respect to ``var``.
1100
+
1101
+ ``var`` must be either the generator of the polynomial ring to which
1102
+ this polynomial belongs, or ``None`` (either way the behaviour is the
1103
+ same).
1104
+
1105
+ .. SEEALSO:: :meth:`.derivative`
1106
+
1107
+ EXAMPLES::
1108
+
1109
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1110
+ sage: f = x^4 - x - 1
1111
+ sage: f._derivative()
1112
+ 4*x^3 + 76
1113
+ sage: f._derivative(None)
1114
+ 4*x^3 + 76
1115
+
1116
+ sage: f._derivative(2*x)
1117
+ Traceback (most recent call last):
1118
+ ...
1119
+ ValueError: cannot differentiate with respect to 2*x
1120
+
1121
+ TESTS::
1122
+
1123
+ sage: y = var("y") # needs sage.symbolic
1124
+ sage: f._derivative(y) # needs sage.symbolic
1125
+ Traceback (most recent call last):
1126
+ ...
1127
+ ValueError: cannot differentiate with respect to y
1128
+ """
1129
+ if var is not None and var != self._parent.gen():
1130
+ raise ValueError('cannot differentiate with respect to {}'.format(var))
1131
+
1132
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
1133
+ zz_pX_diff(r.x, self.x)
1134
+ return r
1135
+
1136
+ def reverse(self, degree=None):
1137
+ """
1138
+ Return the reverse of the input polynomial thought as a polynomial of
1139
+ degree ``degree``.
1140
+
1141
+ If `f` is a degree-`d` polynomial, its reverse is `x^d f(1/x)`.
1142
+
1143
+ INPUT:
1144
+
1145
+ - ``degree`` -- ``None`` or integer; if specified, truncate or zero
1146
+ pad the list of coefficients to this degree before reversing it
1147
+
1148
+ EXAMPLES::
1149
+
1150
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1151
+ sage: f = x^4 - x - 1
1152
+ sage: f.reverse()
1153
+ 76*x^4 + 76*x^3 + 1
1154
+ sage: f.reverse(2)
1155
+ 76*x^2 + 76*x
1156
+ sage: f.reverse(5)
1157
+ 76*x^5 + 76*x^4 + x
1158
+ sage: g = x^3 - x
1159
+ sage: g.reverse()
1160
+ 76*x^2 + 1
1161
+
1162
+ TESTS:
1163
+
1164
+ We check that this implementation is compatible with the generic one::
1165
+
1166
+ sage: all(f.reverse(d) == Polynomial.reverse(f, d)
1167
+ ....: for d in [None, 0, 1, 2, 3, 4, 5])
1168
+ True
1169
+ """
1170
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
1171
+
1172
+ if degree is None:
1173
+ zz_pX_reverse(r.x, self.x)
1174
+ else:
1175
+ zz_pX_reverse_hi(r.x, self.x, degree)
1176
+ return r
1177
+
1178
+ def is_gen(self):
1179
+ return zz_pX_IsX(self.x)
1180
+
1181
+ def __bool__(self):
1182
+ """
1183
+ TESTS::
1184
+
1185
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1186
+ sage: f = x^4 - x - 1
1187
+ sage: not f
1188
+ False
1189
+ sage: not (x-x)
1190
+ True
1191
+ """
1192
+ return not zz_pX_IsZero(self.x)
1193
+
1194
+ def valuation(self):
1195
+ """
1196
+ Return the valuation of ``self``, that is, the power of the
1197
+ lowest nonzero monomial of ``self``.
1198
+
1199
+ EXAMPLES::
1200
+
1201
+ sage: R.<x> = PolynomialRing(Integers(10), implementation='NTL')
1202
+ sage: x.valuation()
1203
+ 1
1204
+ sage: f = x-3; f.valuation()
1205
+ 0
1206
+ sage: f = x^99; f.valuation()
1207
+ 99
1208
+ sage: f = x-x; f.valuation()
1209
+ +Infinity
1210
+ """
1211
+ cdef long n
1212
+ for n from 0 <= n <= zz_pX_deg(self.x):
1213
+ if zz_p_rep(zz_pX_GetCoeff(self.x, n)):
1214
+ return n
1215
+ return infinity
1216
+
1217
+ def degree(self):
1218
+ """
1219
+ EXAMPLES::
1220
+
1221
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1222
+ sage: f = x^4 - x - 1
1223
+ sage: f.degree()
1224
+ 4
1225
+ sage: f = 77*x + 1
1226
+ sage: f.degree()
1227
+ 0
1228
+ """
1229
+ return zz_pX_deg(self.x)
1230
+
1231
+ cpdef Polynomial truncate(self, long n):
1232
+ """
1233
+ Return this polynomial mod `x^n`.
1234
+
1235
+ EXAMPLES::
1236
+
1237
+ sage: R.<x> = PolynomialRing(Integers(77), implementation='NTL')
1238
+ sage: f = sum(x^n for n in range(10)); f
1239
+ x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
1240
+ sage: f.truncate(6)
1241
+ x^5 + x^4 + x^3 + x^2 + x + 1
1242
+ """
1243
+ cdef Polynomial_dense_modn_ntl_zz r = self._new()
1244
+ zz_pX_trunc(r.x, self.x, n)
1245
+ return r
1246
+
1247
+ def __call__(self, *args, **kwds):
1248
+ """
1249
+ Evaluate ``self`` at ``x``. If ``x`` is a single argument coercible into
1250
+ the base ring of ``self``, this is done directly in NTL, otherwise
1251
+ the generic Polynomial call code is used.
1252
+
1253
+ EXAMPLES::
1254
+
1255
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
1256
+ sage: f = x^3 + 7
1257
+ sage: f(5)
1258
+ 32
1259
+ sage: f(5r)
1260
+ 32
1261
+ sage: f(mod(5, 1000))
1262
+ 32
1263
+ sage: f(x)
1264
+ x^3 + 7
1265
+ sage: S.<y> = PolynomialRing(Integers(5), implementation='NTL')
1266
+ sage: f(y)
1267
+ y^3 + 2
1268
+
1269
+ TESTS::
1270
+
1271
+ sage: R.<x> = PolynomialRing(Integers(100), implementation='NTL')
1272
+ sage: f = x^3 + 7
1273
+ sage: f(1).parent() == R.base_ring()
1274
+ True
1275
+ sage: f(int(1)).parent() == R.base_ring()
1276
+ True
1277
+ sage: f(x + 1).parent() == f.parent()
1278
+ True
1279
+
1280
+ sage: R.<x> = PolynomialRing(Zmod(12), 'x', implementation='NTL')
1281
+ sage: u = Zmod(4)(3)
1282
+ sage: x(u).parent() == u.parent()
1283
+ True
1284
+ """
1285
+ if len(args) != 1 or len(kwds) != 0:
1286
+ return Polynomial.__call__(self, *args, **kwds)
1287
+ arg = args[0]
1288
+ cdef ntl_zz_p fx = ntl_zz_p(0, self.c), x = None
1289
+ if isinstance(arg, int):
1290
+ x = ntl_zz_p(arg, self.c)
1291
+ elif isinstance(arg, Integer):
1292
+ x = ntl_zz_p(arg, self.c)
1293
+ elif isinstance(arg, Element):
1294
+ if <void *>self._parent._base == <void *>(<Element>arg)._parent: # c++ pointer hack
1295
+ x = ntl_zz_p(arg, self.c)
1296
+ else:
1297
+ map = self._parent._base.coerce_map_from((<Element>arg)._parent)
1298
+ if map is not None:
1299
+ x = ntl_zz_p(map(arg), self.c)
1300
+ if x is None:
1301
+ return Polynomial.__call__(self, *args, **kwds)
1302
+ else:
1303
+ zz_pX_eval(fx.x, self.x, x.x)
1304
+ return self._parent._base(int(fx))
1305
+
1306
+
1307
+ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n):
1308
+
1309
+ def __init__(self, parent, v=None, check=True, is_gen=False, construct=False):
1310
+ if isinstance(v, Polynomial):
1311
+ if (<Element>v)._parent == parent:
1312
+ Polynomial.__init__(self, parent, is_gen=is_gen)
1313
+ self.x = (<Polynomial_dense_modn_ntl_ZZ>v).x
1314
+ self.c = (<Polynomial_dense_modn_ntl_ZZ>v).c
1315
+ return
1316
+
1317
+ Polynomial_dense_mod_n.__init__(self, parent, v, check=check, is_gen=is_gen, construct=construct)
1318
+ cdef ntl_ZZ_pX ntl = self._poly
1319
+ self._poly = None # this will eventually go away
1320
+ self.x = ntl.x
1321
+ self.c = ntl.c
1322
+
1323
+ def __dealloc__(self):
1324
+ if <object>self.c is not None:
1325
+ self.c.restore_c()
1326
+
1327
+ cdef Polynomial_dense_modn_ntl_ZZ _new(self):
1328
+ cdef Polynomial_dense_modn_ntl_ZZ y = <Polynomial_dense_modn_ntl_ZZ>Polynomial_dense_modn_ntl_ZZ.__new__(Polynomial_dense_modn_ntl_ZZ)
1329
+ y.c = self.c
1330
+ y._parent = self._parent
1331
+ return y
1332
+
1333
+ cpdef list list(self, bint copy=True):
1334
+ return [self.get_unsafe(n) for n from 0 <= n <= self.degree()]
1335
+
1336
+ cdef get_unsafe(self, Py_ssize_t n):
1337
+ """
1338
+ Return the `n`-th coefficient of ``self``.
1339
+
1340
+ EXAMPLES::
1341
+
1342
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1343
+ sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_dense_modn_ntl_ZZ
1344
+ sage: f = Polynomial_dense_modn_ntl_ZZ(R,[2,1])^7
1345
+ sage: f[3]
1346
+ 560
1347
+ sage: f[:6]
1348
+ 84*x^5 + 280*x^4 + 560*x^3 + 672*x^2 + 448*x + 128
1349
+ sage: f[:50] == f
1350
+ True
1351
+ """
1352
+ self.c.restore_c()
1353
+ # TODO, make this faster
1354
+ cdef ntl_ZZ_p ntl = ntl_ZZ_p(0, self.c)
1355
+ ntl.x = ZZ_pX_coeff(self.x, n)
1356
+ return self._parent._base(ntl._integer_())
1357
+
1358
+ def _unsafe_mutate(self, n, value):
1359
+ self.c.restore_c()
1360
+ cdef Integer a
1361
+ if isinstance(value, Integer):
1362
+ a = <Integer>value
1363
+ else:
1364
+ a = ZZ(value)
1365
+ cdef ntl_ZZ_p val = ntl_ZZ_p(a, self.c)
1366
+ ZZ_pX_SetCoeff(self.x, n, val.x)
1367
+
1368
+ cpdef _add_(self, _right):
1369
+ """
1370
+ TESTS::
1371
+
1372
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1373
+ sage: (x + 5) + (x^2 - 6)
1374
+ x^2 + x + 999999999999999999999999999999
1375
+ """
1376
+ cdef Polynomial_dense_modn_ntl_ZZ right = <Polynomial_dense_modn_ntl_ZZ>_right
1377
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1378
+ cdef bint do_sig = (ZZ_pX_deg(self.x) + ZZ_pX_deg(right.x)) * self.c.p_bits > 1e7
1379
+ if do_sig: sig_on()
1380
+ self.c.restore_c()
1381
+ ZZ_pX_add(r.x, self.x, right.x)
1382
+ if do_sig: sig_off()
1383
+ return r
1384
+
1385
+ cpdef _sub_(self, _right):
1386
+ """
1387
+ TESTS::
1388
+
1389
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1390
+ sage: (x + 5) - (x^2 - 6)
1391
+ 999999999999999999999999999999*x^2 + x + 11
1392
+ """
1393
+ cdef Polynomial_dense_modn_ntl_ZZ right = <Polynomial_dense_modn_ntl_ZZ>_right
1394
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1395
+ cdef bint do_sig = (ZZ_pX_deg(self.x) + ZZ_pX_deg(right.x)) * self.c.p_bits > 1e7
1396
+ if do_sig: sig_on()
1397
+ self.c.restore_c()
1398
+ ZZ_pX_sub(r.x, self.x, right.x)
1399
+ if do_sig: sig_off()
1400
+ return r
1401
+
1402
+ cpdef _mul_(self, _right):
1403
+ """
1404
+ TESTS::
1405
+
1406
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1407
+ sage: (x+5) * (x^2 - 1)
1408
+ x^3 + 5*x^2 + 999999999999999999999999999999*x + 999999999999999999999999999995
1409
+ """
1410
+ cdef Polynomial_dense_modn_ntl_ZZ right = <Polynomial_dense_modn_ntl_ZZ>_right
1411
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1412
+ cdef bint do_sig = (ZZ_pX_deg(self.x) + ZZ_pX_deg(right.x)) * self.c.p_bits > 1e5
1413
+ if do_sig: sig_on()
1414
+ self.c.restore_c()
1415
+ if self is right:
1416
+ ZZ_pX_sqr(r.x, self.x)
1417
+ else:
1418
+ ZZ_pX_mul(r.x, self.x, right.x)
1419
+ if do_sig: sig_off()
1420
+ return r
1421
+
1422
+ cpdef Polynomial _mul_trunc_(self, Polynomial right, long n):
1423
+ """
1424
+ Return the product of ``self`` and ``right`` truncated to the
1425
+ given length `n`, only return terms of degree less than `n`.
1426
+
1427
+ EXAMPLES::
1428
+
1429
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation="NTL")
1430
+ sage: f = x - 2
1431
+ sage: g = x^2 - 8*x + 16
1432
+ sage: f*g
1433
+ x^3 + 999999999999999999999999999990*x^2 + 32*x + 999999999999999999999999999968
1434
+ sage: f._mul_trunc_(g, 42)
1435
+ x^3 + 999999999999999999999999999990*x^2 + 32*x + 999999999999999999999999999968
1436
+ sage: f._mul_trunc_(g, 3)
1437
+ 999999999999999999999999999990*x^2 + 32*x + 999999999999999999999999999968
1438
+ sage: f._mul_trunc_(g, 2)
1439
+ 32*x + 999999999999999999999999999968
1440
+ sage: f._mul_trunc_(g, 1)
1441
+ 999999999999999999999999999968
1442
+ sage: f._mul_trunc_(g, 0)
1443
+ 0
1444
+ sage: f = x^2 - 8*x + 16
1445
+ sage: f._mul_trunc_(f, 2)
1446
+ 999999999999999999999999999744*x + 256
1447
+ """
1448
+ cdef Polynomial_dense_modn_ntl_ZZ op2 = <Polynomial_dense_modn_ntl_ZZ> right
1449
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1450
+ cdef bint do_sig = (ZZ_pX_deg(self.x) + ZZ_pX_deg(op2.x)) * self.c.p_bits > 1e5
1451
+ if do_sig: sig_on()
1452
+ self.c.restore_c()
1453
+ if self is op2:
1454
+ ZZ_pX_SqrTrunc(r.x, self.x, n)
1455
+ else:
1456
+ ZZ_pX_MulTrunc(r.x, self.x, op2.x, n)
1457
+ if do_sig: sig_off()
1458
+ return r
1459
+
1460
+ cpdef _rmul_(self, Element c):
1461
+ """
1462
+ TESTS::
1463
+
1464
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1465
+ sage: (x+5) * 3
1466
+ 3*x + 15
1467
+ """
1468
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1469
+ cdef bint do_sig = ZZ_pX_deg(self.x) * self.c.p_bits > 1e7
1470
+ if do_sig: sig_on()
1471
+ self.c.restore_c()
1472
+ cdef ntl_ZZ_p value = ntl_ZZ_p(c, self.c)
1473
+ ZZ_pX_rmul(r.x, self.x, value.x)
1474
+ if do_sig: sig_off()
1475
+ return r
1476
+
1477
+ cpdef _lmul_(self, Element c):
1478
+ """
1479
+ TESTS::
1480
+
1481
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1482
+ sage: 3 * (x+5)
1483
+ 3*x + 15
1484
+ """
1485
+ return self._rmul_(c)
1486
+
1487
+ def __pow__(Polynomial_dense_modn_ntl_ZZ self, ee, modulus):
1488
+ """
1489
+ TESTS::
1490
+
1491
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1492
+ sage: (x+1)^5
1493
+ x^5 + 5*x^4 + 10*x^3 + 10*x^2 + 5*x + 1
1494
+
1495
+ We define ``0^0`` to be unity, :issue:`13895`::
1496
+
1497
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1498
+ sage: R(0)^0
1499
+ 1
1500
+
1501
+ The value returned from ``0^0`` should belong to our ring::
1502
+
1503
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1504
+ sage: type(R(0)^0) == type(R(0))
1505
+ True
1506
+ """
1507
+ cdef bint recip = 0, do_sig
1508
+ cdef long e = ee
1509
+ if e != ee:
1510
+ raise TypeError("Only integral powers defined.")
1511
+ elif e < 0:
1512
+ recip = 1 # delay because powering frac field elements is slow
1513
+ e = -e
1514
+ if self == 0 and e == 0:
1515
+ return self.parent(1)
1516
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1517
+ cdef ZZ_pX_Modulus_c mod
1518
+
1519
+ self.c.restore_c()
1520
+
1521
+ if modulus is None:
1522
+ if ZZ_pX_IsX(self.x):
1523
+ ZZ_pX_LeftShift(r.x, self.x, e - 1)
1524
+ else:
1525
+ do_sig = ZZ_pX_deg(self.x) * e * self.c.p_bits > 1e5
1526
+ if do_sig: sig_on()
1527
+ ZZ_pX_power(r.x, self.x, e)
1528
+ if do_sig: sig_off()
1529
+ else:
1530
+ if not isinstance(modulus, Polynomial_dense_modn_ntl_ZZ):
1531
+ modulus = self.parent().coerce(modulus)
1532
+ ZZ_pX_Modulus_build(mod, (<Polynomial_dense_modn_ntl_ZZ>modulus).x)
1533
+
1534
+ do_sig = ZZ_pX_deg(self.x) * e * self.c.p_bits > 1e5
1535
+ if do_sig: sig_on()
1536
+ ZZ_pX_PowerMod_long_pre(r.x, self.x, e, mod)
1537
+ if do_sig: sig_off()
1538
+ if recip:
1539
+ return ~r
1540
+ else:
1541
+ return r
1542
+
1543
+ @coerce_binop
1544
+ def quo_rem(self, right):
1545
+ r"""
1546
+ Return `q` and `r`, with the degree of `r` less than the degree of ``right``,
1547
+ such that `q \cdot` ``right`` `+ r =` ``self``.
1548
+
1549
+ EXAMPLES::
1550
+
1551
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1552
+ sage: f = x^5+1; g = (x+1)^2
1553
+ sage: q, r = f.quo_rem(g)
1554
+ sage: q
1555
+ x^3 + 999999999999999999999999999998*x^2 + 3*x + 999999999999999999999999999996
1556
+ sage: r
1557
+ 5*x + 5
1558
+ sage: q*g + r
1559
+ x^5 + 1
1560
+ """
1561
+ cdef Polynomial_dense_modn_ntl_ZZ q = self._new()
1562
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1563
+ cdef Polynomial_dense_modn_ntl_ZZ denom = <Polynomial_dense_modn_ntl_ZZ>right
1564
+ sig_on()
1565
+ self.c.restore_c()
1566
+ ZZ_pX_DivRem(q.x, r.x, self.x, denom.x)
1567
+ sig_off()
1568
+ return q, r
1569
+
1570
+ cpdef _floordiv_(self, right):
1571
+ """
1572
+ Return the whole part of ``self`` / ``right``, without remainder.
1573
+
1574
+ For q = n // d, we have deg(n - q*d) < deg(d)
1575
+
1576
+ EXAMPLES::
1577
+
1578
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1579
+ sage: f = x^7 + 1; g = x^2 - 1
1580
+ sage: q = f // g; q
1581
+ x^5 + x^3 + x
1582
+ sage: f - q*g
1583
+ x + 1
1584
+ """
1585
+ cdef Polynomial_dense_modn_ntl_ZZ numer = <Polynomial_dense_modn_ntl_ZZ>self
1586
+ cdef Polynomial_dense_modn_ntl_ZZ denom = <Polynomial_dense_modn_ntl_ZZ>right
1587
+ cdef Polynomial_dense_modn_ntl_ZZ q = numer._new()
1588
+ sig_on()
1589
+ numer.c.restore_c()
1590
+ ZZ_pX_div(q.x, numer.x, denom.x)
1591
+ sig_off()
1592
+ return q
1593
+
1594
+ cpdef _mod_(self, right):
1595
+ """
1596
+ EXAMPLES::
1597
+
1598
+ sage: R.<x> = PolynomialRing(Integers(9^30), implementation='NTL')
1599
+ sage: f = x^7 + x + 1; g = x^3 - 1
1600
+ sage: r = f % g; r
1601
+ 2*x + 1
1602
+ sage: g * (x^4 + x) + r
1603
+ x^7 + x + 1
1604
+ """
1605
+ cdef Polynomial_dense_modn_ntl_ZZ numer = <Polynomial_dense_modn_ntl_ZZ>self
1606
+ cdef Polynomial_dense_modn_ntl_ZZ denom = <Polynomial_dense_modn_ntl_ZZ>right
1607
+ cdef Polynomial_dense_modn_ntl_ZZ r = numer._new()
1608
+ sig_on()
1609
+ numer.c.restore_c()
1610
+ ZZ_pX_rem(r.x, numer.x, denom.x)
1611
+ sig_off()
1612
+ return r
1613
+
1614
+ def shift(self, n):
1615
+ """
1616
+ Shift ``self`` to left by `n`, which is multiplication by `x^n`,
1617
+ truncating if `n` is negative.
1618
+
1619
+ EXAMPLES::
1620
+
1621
+ sage: R.<x> = PolynomialRing(Integers(12^30), implementation='NTL')
1622
+ sage: f = x^7 + x + 1
1623
+ sage: f.shift(1)
1624
+ x^8 + x^2 + x
1625
+ sage: f.shift(-1)
1626
+ x^6 + 1
1627
+ sage: f.shift(10).shift(-10) == f
1628
+ True
1629
+
1630
+ TESTS::
1631
+
1632
+ sage: p = R(0)
1633
+ sage: p.shift(3).is_zero()
1634
+ True
1635
+ sage: p.shift(-3).is_zero()
1636
+ True
1637
+ """
1638
+ return self << n
1639
+
1640
+ def __lshift__(Polynomial_dense_modn_ntl_ZZ self, long n):
1641
+ """
1642
+ TESTS::
1643
+
1644
+ sage: R.<x> = PolynomialRing(Integers(14^30), implementation='NTL')
1645
+ sage: f = x^5 + 2*x + 1
1646
+ sage: f << 3
1647
+ x^8 + 2*x^4 + x^3
1648
+ """
1649
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1650
+ ZZ_pX_LeftShift(r.x, self.x, n)
1651
+ return r
1652
+
1653
+ def __rshift__(Polynomial_dense_modn_ntl_ZZ self, long n):
1654
+ """
1655
+ TESTS::
1656
+
1657
+ sage: R.<x> = PolynomialRing(Integers(15^30), implementation='NTL')
1658
+ sage: f = x^5 + 2*x + 1
1659
+ sage: f >> 3
1660
+ x^2
1661
+ """
1662
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1663
+ ZZ_pX_RightShift(r.x, self.x, n)
1664
+ return r
1665
+
1666
+ def _derivative(self, var=None):
1667
+ r"""
1668
+ Return the formal derivative of ``self`` with respect to ``var``.
1669
+
1670
+ ``var`` must be either the generator of the polynomial ring to which
1671
+ this polynomial belongs, or None (either way the behaviour is the
1672
+ same).
1673
+
1674
+ .. SEEALSO:: :meth:`.derivative`
1675
+
1676
+ EXAMPLES::
1677
+
1678
+ sage: R.<x> = PolynomialRing(Integers(12^29), implementation='NTL')
1679
+ sage: f = x^4 + x + 5
1680
+ sage: f._derivative()
1681
+ 4*x^3 + 1
1682
+ sage: f._derivative(None)
1683
+ 4*x^3 + 1
1684
+
1685
+ sage: f._derivative(2*x)
1686
+ Traceback (most recent call last):
1687
+ ...
1688
+ ValueError: cannot differentiate with respect to 2*x
1689
+
1690
+ TESTS::
1691
+
1692
+ sage: y = var("y") # needs sage.symbolic
1693
+ sage: f._derivative(y) # needs sage.symbolic
1694
+ Traceback (most recent call last):
1695
+ ...
1696
+ ValueError: cannot differentiate with respect to y
1697
+ """
1698
+ if var is not None and var != self._parent.gen():
1699
+ raise ValueError("cannot differentiate with respect to {}".format(var))
1700
+
1701
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1702
+ ZZ_pX_diff(r.x, self.x)
1703
+ return r
1704
+
1705
+ def reverse(self, degree=None):
1706
+ """
1707
+ Return the reverse of the input polynomial thought as a polynomial of
1708
+ degree ``degree``.
1709
+
1710
+ If `f` is a degree-`d` polynomial, its reverse is `x^d f(1/x)`.
1711
+
1712
+ INPUT:
1713
+
1714
+ - ``degree`` -- ``None`` or integer; if specified, truncate or zero
1715
+ pad the list of coefficients to this degree before reversing it
1716
+
1717
+ EXAMPLES::
1718
+
1719
+ sage: R.<x> = PolynomialRing(Integers(12^29), implementation='NTL')
1720
+ sage: f = x^4 + 2*x + 5
1721
+ sage: f.reverse()
1722
+ 5*x^4 + 2*x^3 + 1
1723
+ sage: f = x^3 + x
1724
+ sage: f.reverse()
1725
+ x^2 + 1
1726
+ sage: f.reverse(1)
1727
+ 1
1728
+ sage: f.reverse(5)
1729
+ x^4 + x^2
1730
+
1731
+ TESTS:
1732
+
1733
+ We check that this implementation is compatible with the generic one::
1734
+
1735
+ sage: all(f.reverse(d) == Polynomial.reverse(f, d)
1736
+ ....: for d in [None, 0, 1, 2, 3, 4, 5])
1737
+ True
1738
+ """
1739
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1740
+
1741
+ if degree is None:
1742
+ ZZ_pX_reverse(r.x, self.x)
1743
+ else:
1744
+ ZZ_pX_reverse_hi(r.x, self.x, degree)
1745
+ return r
1746
+
1747
+ def is_gen(self):
1748
+ return ZZ_pX_IsX(self.x)
1749
+
1750
+ def valuation(self):
1751
+ """
1752
+ Return the valuation of ``self``, that is, the power of the
1753
+ lowest nonzero monomial of ``self``.
1754
+
1755
+ EXAMPLES::
1756
+
1757
+ sage: R.<x> = PolynomialRing(Integers(10^50), implementation='NTL')
1758
+ sage: x.valuation()
1759
+ 1
1760
+ sage: f = x - 3; f.valuation()
1761
+ 0
1762
+ sage: f = x^99; f.valuation()
1763
+ 99
1764
+ sage: f = x - x; f.valuation()
1765
+ +Infinity
1766
+ """
1767
+ cdef long n
1768
+ cdef ZZ_p_c coeff
1769
+ for n from 0 <= n <= ZZ_pX_deg(self.x):
1770
+ coeff = ZZ_pX_coeff(self.x, n)
1771
+ if not ZZ_p_IsZero(coeff):
1772
+ return n
1773
+ return infinity
1774
+
1775
+ def __bool__(self):
1776
+ """
1777
+ TESTS::
1778
+
1779
+ sage: R.<x> = PolynomialRing(Integers(12^29), implementation='NTL')
1780
+ sage: f = x^4 + 1
1781
+ sage: not f
1782
+ False
1783
+ sage: not (x-x)
1784
+ True
1785
+ """
1786
+ return not ZZ_pX_IsZero(self.x)
1787
+
1788
+ def degree(self):
1789
+ """
1790
+ EXAMPLES::
1791
+
1792
+ sage: R.<x> = PolynomialRing(Integers(14^34), implementation='NTL')
1793
+ sage: f = x^4 - x - 1
1794
+ sage: f.degree()
1795
+ 4
1796
+ sage: f = 14^43*x + 1
1797
+ sage: f.degree()
1798
+ 0
1799
+ """
1800
+ return ZZ_pX_deg(self.x)
1801
+
1802
+ cpdef Polynomial truncate(self, long n):
1803
+ """
1804
+ Return this polynomial mod `x^n`.
1805
+
1806
+ EXAMPLES::
1807
+
1808
+ sage: R.<x> = PolynomialRing(Integers(15^30), implementation='NTL')
1809
+ sage: f = sum(x^n for n in range(10)); f
1810
+ x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
1811
+ sage: f.truncate(6)
1812
+ x^5 + x^4 + x^3 + x^2 + x + 1
1813
+ """
1814
+ cdef Polynomial_dense_modn_ntl_ZZ r = self._new()
1815
+ ZZ_pX_trunc(r.x, self.x, n)
1816
+ return r
1817
+
1818
+ def __call__(self, *args, **kwds):
1819
+ """
1820
+ Evaluate ``self`` at ``x``. If ``x`` is a single argument coercible into
1821
+ the base ring of ``self``, this is done directly in NTL, otherwise
1822
+ the generic Polynomial call code is used.
1823
+
1824
+ EXAMPLES::
1825
+
1826
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1827
+ sage: f = x^3 + 7
1828
+ sage: f(5)
1829
+ 132
1830
+ sage: f(5r)
1831
+ 132
1832
+ sage: f(mod(5, 10^50))
1833
+ 132
1834
+ sage: f(x)
1835
+ x^3 + 7
1836
+ sage: S.<y> = PolynomialRing(Integers(5), implementation='NTL')
1837
+ sage: f(y)
1838
+ y^3 + 2
1839
+
1840
+ TESTS::
1841
+
1842
+ sage: R.<x> = PolynomialRing(Integers(10^30), implementation='NTL')
1843
+ sage: f = x^3 + 7
1844
+ sage: f(1).parent() == R.base_ring()
1845
+ True
1846
+ sage: f(int(1)).parent() == R.base_ring()
1847
+ True
1848
+ sage: f(x + 1).parent() == f.parent()
1849
+ True
1850
+
1851
+ sage: R.<x> = PolynomialRing(Zmod(10^30), 'x', implementation='NTL')
1852
+ sage: u = Zmod(10^29)(3)
1853
+ sage: x(u).parent() == u.parent()
1854
+ True
1855
+ sage: v = Zmod(10)(3)
1856
+ sage: x(v).parent() == v.parent()
1857
+ True
1858
+ """
1859
+ if len(args) != 1 or len(kwds) != 0:
1860
+ return Polynomial.__call__(self, *args, **kwds)
1861
+ arg = args[0]
1862
+ cdef ntl_ZZ_p fx = ntl_ZZ_p(0, self.c), x = None
1863
+ if isinstance(arg, (int, Integer)):
1864
+ x = ntl_ZZ_p(arg, self.c)
1865
+ elif isinstance(arg, Element):
1866
+ if <void *>self._parent._base == <void *>(<Element>arg)._parent: # c++ pointer hack
1867
+ x = ntl_ZZ_p(arg, self.c)
1868
+ else:
1869
+ map = self._parent._base.coerce_map_from((<Element>arg)._parent)
1870
+ if map is not None:
1871
+ x = ntl_ZZ_p(map(arg), self.c)
1872
+ if x is None:
1873
+ return Polynomial.__call__(self, *args, **kwds)
1874
+ else:
1875
+ ZZ_pX_eval(fx.x, self.x, x.x)
1876
+ return self._parent._base(fx._integer_())
1877
+
1878
+
1879
+ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n):
1880
+ """
1881
+ A dense polynomial over the integers modulo `p`, where `p` is prime.
1882
+ """
1883
+
1884
+ def __pow__(self, n, modulus):
1885
+ """
1886
+ Exponentiation of ``self``.
1887
+
1888
+ If ``modulus`` is not ``None``, the exponentiation is performed
1889
+ modulo the polynomial ``modulus``.
1890
+
1891
+ EXAMPLES::
1892
+
1893
+ sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
1894
+ sage: (x-1)^5
1895
+ x^5 + 96*x^4 + 10*x^3 + 91*x^2 + 5*x + 100
1896
+ sage: pow(x-1, 15, x^3+x+1)
1897
+ 55*x^2 + 6*x + 46
1898
+
1899
+ TESTS:
1900
+
1901
+ Negative powers work but use the generic
1902
+ implementation of fraction fields::
1903
+
1904
+ sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
1905
+ sage: f = (x-1)^(-5)
1906
+ sage: type(f)
1907
+ <class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
1908
+ sage: (f + 2).numerator()
1909
+ 2*x^5 + 91*x^4 + 20*x^3 + 81*x^2 + 10*x + 100
1910
+
1911
+ We define ``0^0`` to be unity, :issue:`13895`::
1912
+
1913
+ sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
1914
+ sage: R(0)^0
1915
+ 1
1916
+
1917
+ The value returned from ``0^0`` should belong to our ring::
1918
+
1919
+ sage: R.<x> = PolynomialRing(Integers(101), implementation='NTL')
1920
+ sage: type(R(0)^0) == type(R(0))
1921
+ True
1922
+
1923
+ The modulus can have smaller degree than ``self``::
1924
+
1925
+ sage: R.<x> = PolynomialRing(GF(101), implementation="NTL")
1926
+ sage: pow(x^4 + 1, 100, x^2 + x + 1)
1927
+ 100*x + 100
1928
+
1929
+ Canonical coercion should apply::
1930
+
1931
+ sage: # needs sage.libs.flint
1932
+ sage: R.<x> = PolynomialRing(GF(101), implementation="FLINT")
1933
+ sage: x_ZZ = ZZ["x"].gen()
1934
+ sage: pow(x+1, 100, 2)
1935
+ 0
1936
+ sage: pow(x+1, 100, x_ZZ^2 + x_ZZ + 1)
1937
+ 100*x + 100
1938
+ sage: pow(x+1, int(100), x_ZZ^2 + x_ZZ + 1)
1939
+ 100*x + 100
1940
+ sage: xx = polygen(GF(97))
1941
+ sage: _ = pow(x + 1, 3, xx^3 + xx + 1)
1942
+ Traceback (most recent call last):
1943
+ ...
1944
+ TypeError: no common canonical parent for objects with parents: ...
1945
+ """
1946
+ n = Integer(n)
1947
+ parent = (<Element>self)._parent
1948
+
1949
+ if modulus is not None:
1950
+ # Similar to coerce_binop
1951
+ if not have_same_parent(self, modulus):
1952
+ a, m = canonical_coercion(self, modulus)
1953
+ if a is not self:
1954
+ return pow(a, n, m)
1955
+ modulus = m
1956
+ self = self % modulus
1957
+ return parent(pow(self.ntl_ZZ_pX(), n, modulus.ntl_ZZ_pX()), construct=True)
1958
+ else:
1959
+ if n < 0:
1960
+ return ~(self**(-n))
1961
+ elif self.degree() <= 0:
1962
+ return parent(self[0]**n)
1963
+ else:
1964
+ return parent(self.ntl_ZZ_pX()**n, construct=True)
1965
+
1966
+ @coerce_binop
1967
+ def gcd(self, right):
1968
+ """
1969
+ Return the greatest common divisor of this polynomial and ``other``, as
1970
+ a monic polynomial.
1971
+
1972
+ INPUT:
1973
+
1974
+ - ``other`` -- a polynomial defined over the same ring as ``self``
1975
+
1976
+ EXAMPLES::
1977
+
1978
+ sage: R.<x> = PolynomialRing(GF(3), implementation="NTL")
1979
+ sage: f, g = x + 2, x^2 - 1
1980
+ sage: f.gcd(g)
1981
+ x + 2
1982
+ """
1983
+ g = self.ntl_ZZ_pX().gcd(right.ntl_ZZ_pX())
1984
+ return self.parent()(g, construct=True)
1985
+
1986
+ @coerce_binop
1987
+ def xgcd(self, other):
1988
+ r"""
1989
+ Compute the extended gcd of this element and ``other``.
1990
+
1991
+ INPUT:
1992
+
1993
+ - ``other`` -- an element in the same polynomial ring
1994
+
1995
+ OUTPUT:
1996
+
1997
+ A tuple ``(r,s,t)`` of elements in the polynomial ring such
1998
+ that ``r = s*self + t*other``.
1999
+
2000
+ EXAMPLES::
2001
+
2002
+ sage: R.<x> = PolynomialRing(GF(3), implementation='NTL')
2003
+ sage: x.xgcd(x)
2004
+ (x, 0, 1)
2005
+ sage: (x^2 - 1).xgcd(x - 1)
2006
+ (x + 2, 0, 1)
2007
+ sage: R.zero().xgcd(R.one())
2008
+ (1, 0, 1)
2009
+ sage: (x^3 - 1).xgcd((x - 1)^2)
2010
+ (x^2 + x + 1, 0, 1)
2011
+ sage: ((x - 1)*(x + 1)).xgcd(x*(x - 1))
2012
+ (x + 2, 1, 2)
2013
+ """
2014
+ r, s, t = self.ntl_ZZ_pX().xgcd(other.ntl_ZZ_pX())
2015
+ return self.parent()(r, construct=True), self.parent()(s, construct=True), self.parent()(t, construct=True)
2016
+
2017
+ @coerce_binop
2018
+ def resultant(self, other):
2019
+ """
2020
+ Return the resultant of ``self`` and ``other``, which must lie in the same
2021
+ polynomial ring.
2022
+
2023
+ INPUT:
2024
+
2025
+ - ``other`` -- a polynomial
2026
+
2027
+ OUTPUT: an element of the base ring of the polynomial ring
2028
+
2029
+ EXAMPLES::
2030
+
2031
+ sage: R.<x> = PolynomialRing(GF(19), implementation='NTL')
2032
+ sage: f = x^3 + x + 1; g = x^3 - x - 1
2033
+ sage: r = f.resultant(g); r
2034
+ 11
2035
+ sage: r.parent() is GF(19)
2036
+ True
2037
+ """
2038
+ other = self.parent().coerce(other)
2039
+ return self.base_ring()(str(self.ntl_ZZ_pX().resultant(other.ntl_ZZ_pX())))
2040
+
2041
+ def discriminant(self):
2042
+ """
2043
+ EXAMPLES::
2044
+
2045
+ sage: _.<x> = PolynomialRing(GF(19), implementation='NTL')
2046
+ sage: f = x^3 + 3*x - 17
2047
+ sage: f.discriminant()
2048
+ 12
2049
+ """
2050
+ return self.base_ring()(str(self.ntl_ZZ_pX().discriminant()))