passagemath-ntl 10.6.38__cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-ntl might be problematic. Click here for more details.
- passagemath_ntl/__init__.py +3 -0
- passagemath_ntl-10.6.38.dist-info/METADATA +122 -0
- passagemath_ntl-10.6.38.dist-info/RECORD +162 -0
- passagemath_ntl-10.6.38.dist-info/WHEEL +6 -0
- passagemath_ntl-10.6.38.dist-info/top_level.txt +3 -0
- passagemath_ntl.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_ntl.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_ntl.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
- passagemath_ntl.libs/libmpfr-9d41ebf1.so.6.2.1 +0 -0
- passagemath_ntl.libs/libntl-1bc30f7e.so.45.0.0 +0 -0
- sage/all__sagemath_ntl.py +7 -0
- sage/libs/all__sagemath_ntl.py +3 -0
- sage/libs/mpfi/__init__.pxd +287 -0
- sage/libs/mpfi/types.pxd +10 -0
- sage/libs/ntl/GF2.pxd +18 -0
- sage/libs/ntl/GF2E.pxd +28 -0
- sage/libs/ntl/GF2EX.pxd +12 -0
- sage/libs/ntl/GF2X.pxd +81 -0
- sage/libs/ntl/ZZ.pxd +93 -0
- sage/libs/ntl/ZZX.pxd +85 -0
- sage/libs/ntl/ZZ_p.pxd +28 -0
- sage/libs/ntl/ZZ_pE.pxd +37 -0
- sage/libs/ntl/ZZ_pEX.pxd +106 -0
- sage/libs/ntl/ZZ_pX.pxd +122 -0
- sage/libs/ntl/__init__.py +4 -0
- sage/libs/ntl/all.py +72 -0
- sage/libs/ntl/conversion.pxd +106 -0
- sage/libs/ntl/convert.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/convert.pxd +7 -0
- sage/libs/ntl/convert.pyx +38 -0
- sage/libs/ntl/decl.pxi +18 -0
- sage/libs/ntl/error.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/error.pyx +63 -0
- sage/libs/ntl/lzz_p.pxd +20 -0
- sage/libs/ntl/lzz_pX.pxd +59 -0
- sage/libs/ntl/mat_GF2.pxd +30 -0
- sage/libs/ntl/mat_GF2E.pxd +30 -0
- sage/libs/ntl/mat_ZZ.pxd +59 -0
- sage/libs/ntl/misc.pxi +33 -0
- sage/libs/ntl/ntl_GF2.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2.pxd +5 -0
- sage/libs/ntl/ntl_GF2.pyx +281 -0
- sage/libs/ntl/ntl_GF2E.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2E.pxd +8 -0
- sage/libs/ntl/ntl_GF2E.pyx +488 -0
- sage/libs/ntl/ntl_GF2EContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2EContext.pxd +9 -0
- sage/libs/ntl/ntl_GF2EContext.pyx +134 -0
- sage/libs/ntl/ntl_GF2EX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2EX.pxd +10 -0
- sage/libs/ntl/ntl_GF2EX.pyx +251 -0
- sage/libs/ntl/ntl_GF2X.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_GF2X.pxd +5 -0
- sage/libs/ntl/ntl_GF2X.pyx +771 -0
- sage/libs/ntl/ntl_GF2X_linkage.pxi +404 -0
- sage/libs/ntl/ntl_ZZ.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ.pxd +7 -0
- sage/libs/ntl/ntl_ZZ.pyx +541 -0
- sage/libs/ntl/ntl_ZZX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZX.pxd +7 -0
- sage/libs/ntl/ntl_ZZX.pyx +1206 -0
- sage/libs/ntl/ntl_ZZ_p.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_p.pxd +10 -0
- sage/libs/ntl/ntl_ZZ_p.pyx +509 -0
- sage/libs/ntl/ntl_ZZ_pContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pContext.pxd +22 -0
- sage/libs/ntl/ntl_ZZ_pContext.pyx +201 -0
- sage/libs/ntl/ntl_ZZ_pE.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pE.pxd +11 -0
- sage/libs/ntl/ntl_ZZ_pE.pyx +349 -0
- sage/libs/ntl/ntl_ZZ_pEContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pEContext.pxd +23 -0
- sage/libs/ntl/ntl_ZZ_pEContext.pyx +226 -0
- sage/libs/ntl/ntl_ZZ_pEX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pEX.pxd +10 -0
- sage/libs/ntl/ntl_ZZ_pEX.pyx +1255 -0
- sage/libs/ntl/ntl_ZZ_pEX_linkage.pxi +420 -0
- sage/libs/ntl/ntl_ZZ_pX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_ZZ_pX.pxd +17 -0
- sage/libs/ntl/ntl_ZZ_pX.pyx +1532 -0
- sage/libs/ntl/ntl_lzz_p.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_p.pxd +8 -0
- sage/libs/ntl/ntl_lzz_p.pyx +440 -0
- sage/libs/ntl/ntl_lzz_pContext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_pContext.pxd +7 -0
- sage/libs/ntl/ntl_lzz_pContext.pyx +137 -0
- sage/libs/ntl/ntl_lzz_pX.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_lzz_pX.pxd +10 -0
- sage/libs/ntl/ntl_lzz_pX.pyx +902 -0
- sage/libs/ntl/ntl_mat_GF2.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_GF2.pxd +8 -0
- sage/libs/ntl/ntl_mat_GF2.pyx +612 -0
- sage/libs/ntl/ntl_mat_GF2E.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_GF2E.pxd +10 -0
- sage/libs/ntl/ntl_mat_GF2E.pyx +752 -0
- sage/libs/ntl/ntl_mat_ZZ.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/libs/ntl/ntl_mat_ZZ.pxd +6 -0
- sage/libs/ntl/ntl_mat_ZZ.pyx +1523 -0
- sage/libs/ntl/ntl_tools.pxd +3 -0
- sage/libs/ntl/ntlwrap.h +53 -0
- sage/libs/ntl/ntlwrap_impl.h +743 -0
- sage/libs/ntl/types.pxd +157 -0
- sage/libs/ntl/vec_GF2.pxd +26 -0
- sage/libs/ntl/vec_GF2E.pxd +2 -0
- sage/matrix/all__sagemath_ntl.py +1 -0
- sage/matrix/matrix_modn_dense_double.pxd +10 -0
- sage/matrix/matrix_modn_dense_float.pxd +9 -0
- sage/matrix/matrix_modn_dense_template.pxi +3257 -0
- sage/matrix/matrix_modn_dense_template_header.pxi +15 -0
- sage/matrix/matrix_modn_sparse.pxd +8 -0
- sage/misc/all__sagemath_ntl.py +1 -0
- sage/rings/all__sagemath_ntl.py +7 -0
- sage/rings/bernmm.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/bernmm.pyx +161 -0
- sage/rings/bernoulli_mod_p.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/bernoulli_mod_p.pyx +313 -0
- sage/rings/finite_rings/all__sagemath_ntl.py +1 -0
- sage/rings/finite_rings/finite_field_ntl_gf2e.py +305 -0
- sage/rings/finite_rings/residue_field_ntl_gf2e.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/finite_rings/residue_field_ntl_gf2e.pyx +140 -0
- sage/rings/padics/all__sagemath_ntl.py +5 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.pxd +25 -0
- sage/rings/padics/padic_ZZ_pX_CA_element.pyx +2368 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.pxd +33 -0
- sage/rings/padics/padic_ZZ_pX_CR_element.pyx +3277 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.pxd +12 -0
- sage/rings/padics/padic_ZZ_pX_FM_element.pyx +1739 -0
- sage/rings/padics/padic_ZZ_pX_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ZZ_pX_element.pxd +6 -0
- sage/rings/padics/padic_ZZ_pX_element.pyx +919 -0
- sage/rings/padics/padic_ext_element.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/padic_ext_element.pxd +38 -0
- sage/rings/padics/padic_ext_element.pyx +512 -0
- sage/rings/padics/pow_computer_ext.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/padics/pow_computer_ext.pxd +107 -0
- sage/rings/padics/pow_computer_ext.pyx +2401 -0
- sage/rings/polynomial/all__sagemath_ntl.py +1 -0
- sage/rings/polynomial/evaluation_ntl.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_ntl.pxd +7 -0
- sage/rings/polynomial/evaluation_ntl.pyx +70 -0
- sage/rings/polynomial/polynomial_gf2x.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_gf2x.pxd +10 -0
- sage/rings/polynomial/polynomial_gf2x.pyx +364 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.pxd +8 -0
- sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +1128 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.pxd +36 -0
- sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +2049 -0
- sage/rings/polynomial/polynomial_template.pxi +842 -0
- sage/rings/polynomial/polynomial_template_header.pxi +11 -0
- sage/rings/polynomial/polynomial_zz_pex.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zz_pex.pxd +12 -0
- sage/rings/polynomial/polynomial_zz_pex.pyx +778 -0
- sage/rings/real_mpfi.pxd +50 -0
- sage/schemes/all__sagemath_ntl.py +1 -0
- sage/schemes/hyperelliptic_curves/all__sagemath_ntl.py +1 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.pyx +252 -0
|
@@ -0,0 +1,1206 @@
|
|
|
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
|
+
# ****************************************************************************
|
|
10
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
11
|
+
#
|
|
12
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
13
|
+
#
|
|
14
|
+
# This code is distributed in the hope that it will be useful,
|
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
17
|
+
# General Public License for more details.
|
|
18
|
+
#
|
|
19
|
+
# The full text of the GPL is available at:
|
|
20
|
+
#
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# ****************************************************************************
|
|
23
|
+
|
|
24
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
25
|
+
|
|
26
|
+
from sage.cpython.string cimport char_to_str
|
|
27
|
+
from sage.ext.cplusplus cimport ccreadstr
|
|
28
|
+
|
|
29
|
+
include "decl.pxi"
|
|
30
|
+
include 'misc.pxi'
|
|
31
|
+
|
|
32
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
33
|
+
from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ
|
|
34
|
+
from sage.libs.ntl.ntl_ZZ import unpickle_class_value
|
|
35
|
+
|
|
36
|
+
from sage.rings.integer_ring import IntegerRing
|
|
37
|
+
from sage.arith.power cimport generic_power_pos
|
|
38
|
+
|
|
39
|
+
ZZ = IntegerRing()
|
|
40
|
+
|
|
41
|
+
cdef inline ntl_ZZ make_ZZ(ZZ_c* x):
|
|
42
|
+
""" These make_XXXX functions are deprecated and should be phased out."""
|
|
43
|
+
cdef ntl_ZZ y
|
|
44
|
+
y = ntl_ZZ()
|
|
45
|
+
y.x = x[0]
|
|
46
|
+
del x
|
|
47
|
+
return y
|
|
48
|
+
|
|
49
|
+
# You must do sig_on() before calling this function
|
|
50
|
+
cdef inline ntl_ZZ make_ZZ_sig_off(ZZ_c* x):
|
|
51
|
+
cdef ntl_ZZ y = make_ZZ(x)
|
|
52
|
+
sig_off()
|
|
53
|
+
return y
|
|
54
|
+
|
|
55
|
+
cdef inline ntl_ZZX make_ZZX(ZZX_c* x):
|
|
56
|
+
""" These make_XXXX functions are deprecated and should be phased out."""
|
|
57
|
+
cdef ntl_ZZX y
|
|
58
|
+
y = ntl_ZZX()
|
|
59
|
+
y.x = x[0]
|
|
60
|
+
del x
|
|
61
|
+
return y
|
|
62
|
+
|
|
63
|
+
# You must do sig_on() before calling this function
|
|
64
|
+
cdef inline ntl_ZZX make_ZZX_sig_off(ZZX_c* x):
|
|
65
|
+
cdef ntl_ZZX y = make_ZZX(x)
|
|
66
|
+
sig_off()
|
|
67
|
+
return y
|
|
68
|
+
|
|
69
|
+
from sage.structure.proof.proof import get_flag
|
|
70
|
+
cdef proof_flag(t):
|
|
71
|
+
return get_flag(t, "polynomial")
|
|
72
|
+
|
|
73
|
+
##############################################################################
|
|
74
|
+
#
|
|
75
|
+
# ZZX: polynomials over the integers
|
|
76
|
+
#
|
|
77
|
+
##############################################################################
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
cdef class ntl_ZZX():
|
|
81
|
+
r"""
|
|
82
|
+
The class \class{ZZX} implements polynomials in `\Z[X]`, i.e.,
|
|
83
|
+
univariate polynomials with integer coefficients.
|
|
84
|
+
|
|
85
|
+
Polynomial multiplication is very fast, and is implemented using
|
|
86
|
+
one of 4 different algorithms:
|
|
87
|
+
\begin{enumerate}
|
|
88
|
+
\item\hspace{1em} Classical
|
|
89
|
+
\item\hspace{1em} Karatsuba
|
|
90
|
+
\item\hspace{1em} Schoenhage and Strassen --- performs an FFT by working
|
|
91
|
+
modulo a "Fermat number" of appropriate size...
|
|
92
|
+
good for polynomials with huge coefficients
|
|
93
|
+
and moderate degree
|
|
94
|
+
\item\hspace{1em} CRT/FFT --- performs an FFT by working modulo several
|
|
95
|
+
small primes. This is good for polynomials with moderate
|
|
96
|
+
coefficients and huge degree.
|
|
97
|
+
\end{enumerate}
|
|
98
|
+
|
|
99
|
+
The choice of algorithm is somewhat heuristic, and may not always be
|
|
100
|
+
perfect.
|
|
101
|
+
|
|
102
|
+
Many thanks to Juergen Gerhard {\tt
|
|
103
|
+
<jngerhar@plato.uni-paderborn.de>} for pointing out the deficiency
|
|
104
|
+
in the NTL-1.0 ZZX arithmetic, and for contributing the
|
|
105
|
+
Schoenhage/Strassen code.
|
|
106
|
+
|
|
107
|
+
Extensive use is made of modular algorithms to enhance performance
|
|
108
|
+
(e.g., the GCD algorithm and many others).
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
# See ntl_ZZX.pxd for definition of data members
|
|
112
|
+
def __init__(self, v=None):
|
|
113
|
+
"""
|
|
114
|
+
EXAMPLES::
|
|
115
|
+
|
|
116
|
+
sage: f = ntl.ZZX([1,2,5,-9])
|
|
117
|
+
sage: f
|
|
118
|
+
[1 2 5 -9]
|
|
119
|
+
sage: g = ntl.ZZX([0,0,0]); g
|
|
120
|
+
[]
|
|
121
|
+
sage: g[10]=5
|
|
122
|
+
sage: g
|
|
123
|
+
[0 0 0 0 0 0 0 0 0 0 5]
|
|
124
|
+
sage: g[10]
|
|
125
|
+
5
|
|
126
|
+
"""
|
|
127
|
+
cdef ntl_ZZ cc
|
|
128
|
+
cdef Py_ssize_t i
|
|
129
|
+
|
|
130
|
+
if v is None:
|
|
131
|
+
return
|
|
132
|
+
elif isinstance(v, (list, tuple)):
|
|
133
|
+
for i from 0 <= i < len(v):
|
|
134
|
+
x = v[i]
|
|
135
|
+
if not isinstance(x, ntl_ZZ):
|
|
136
|
+
cc = ntl_ZZ(x)
|
|
137
|
+
else:
|
|
138
|
+
cc = x
|
|
139
|
+
ZZX_SetCoeff(self.x, i, cc.x)
|
|
140
|
+
else:
|
|
141
|
+
ccreadstr(self.x, str(v))
|
|
142
|
+
|
|
143
|
+
def __reduce__(self):
|
|
144
|
+
"""
|
|
145
|
+
EXAMPLES::
|
|
146
|
+
|
|
147
|
+
sage: from sage.libs.ntl.ntl_ZZX import ntl_ZZX
|
|
148
|
+
sage: f = ntl_ZZX([1,2,0,4])
|
|
149
|
+
sage: loads(dumps(f)) == f
|
|
150
|
+
True
|
|
151
|
+
"""
|
|
152
|
+
return unpickle_class_value, (ntl_ZZX, self.list())
|
|
153
|
+
|
|
154
|
+
def __repr__(self):
|
|
155
|
+
"""
|
|
156
|
+
Return the string representation of ``self``.
|
|
157
|
+
|
|
158
|
+
EXAMPLES::
|
|
159
|
+
|
|
160
|
+
sage: ntl.ZZX([1,3,0,5]).__repr__()
|
|
161
|
+
'[1 3 0 5]'
|
|
162
|
+
"""
|
|
163
|
+
cdef char * val
|
|
164
|
+
val = ZZX_repr(&self.x)
|
|
165
|
+
result = char_to_str(val)
|
|
166
|
+
cpp_delete_array(val)
|
|
167
|
+
return result
|
|
168
|
+
|
|
169
|
+
def __copy__(self):
|
|
170
|
+
"""
|
|
171
|
+
Return a copy of ``self``.
|
|
172
|
+
|
|
173
|
+
EXAMPLES::
|
|
174
|
+
|
|
175
|
+
sage: x = ntl.ZZX([1,32])
|
|
176
|
+
sage: y = copy(x)
|
|
177
|
+
sage: y == x
|
|
178
|
+
True
|
|
179
|
+
sage: y is x
|
|
180
|
+
False
|
|
181
|
+
"""
|
|
182
|
+
return make_ZZX(ZZX_copy(&self.x))
|
|
183
|
+
|
|
184
|
+
def __setitem__(self, long i, a):
|
|
185
|
+
"""
|
|
186
|
+
EXAMPLES::
|
|
187
|
+
|
|
188
|
+
sage: n=ntl.ZZX([1,2,3])
|
|
189
|
+
sage: n
|
|
190
|
+
[1 2 3]
|
|
191
|
+
sage: n[1] = 4
|
|
192
|
+
sage: n
|
|
193
|
+
[1 4 3]
|
|
194
|
+
"""
|
|
195
|
+
if i < 0:
|
|
196
|
+
raise IndexError("index (i=%s) must be >= 0" % i)
|
|
197
|
+
cdef ntl_ZZ cc
|
|
198
|
+
if isinstance(a, ntl_ZZ):
|
|
199
|
+
cc = a
|
|
200
|
+
else:
|
|
201
|
+
cc = ntl_ZZ(a)
|
|
202
|
+
ZZX_SetCoeff(self.x, i, cc.x)
|
|
203
|
+
|
|
204
|
+
cdef void setitem_from_int(ntl_ZZX self, long i, int value) noexcept:
|
|
205
|
+
r"""
|
|
206
|
+
Set `i`-th coefficient to value.
|
|
207
|
+
|
|
208
|
+
AUTHOR: David Harvey (2006-08-05)
|
|
209
|
+
"""
|
|
210
|
+
ZZX_setitem_from_int(&self.x, i, value)
|
|
211
|
+
|
|
212
|
+
def setitem_from_int_doctest(self, i, value):
|
|
213
|
+
r"""
|
|
214
|
+
This method exists solely for automated testing of setitem_from_int().
|
|
215
|
+
|
|
216
|
+
sage: x = ntl.ZZX([2, 3, 4])
|
|
217
|
+
sage: x.setitem_from_int_doctest(5, 42)
|
|
218
|
+
sage: x
|
|
219
|
+
[2 3 4 0 0 42]
|
|
220
|
+
"""
|
|
221
|
+
self.setitem_from_int(int(i), int(value))
|
|
222
|
+
|
|
223
|
+
def __getitem__(self, long i):
|
|
224
|
+
r"""
|
|
225
|
+
Retrieves coefficient number i as an NTL ZZ.
|
|
226
|
+
|
|
227
|
+
sage: x = ntl.ZZX([129381729371289371237128318293718237, 2, -3, 0, 4])
|
|
228
|
+
sage: x[0]
|
|
229
|
+
129381729371289371237128318293718237
|
|
230
|
+
sage: type(x[0])
|
|
231
|
+
<class 'sage.libs.ntl.ntl_ZZ.ntl_ZZ'>
|
|
232
|
+
sage: x[1]
|
|
233
|
+
2
|
|
234
|
+
sage: x[2]
|
|
235
|
+
-3
|
|
236
|
+
sage: x[3]
|
|
237
|
+
0
|
|
238
|
+
sage: x[4]
|
|
239
|
+
4
|
|
240
|
+
sage: x[5]
|
|
241
|
+
0
|
|
242
|
+
"""
|
|
243
|
+
cdef ntl_ZZ r = ntl_ZZ()
|
|
244
|
+
sig_on()
|
|
245
|
+
r.x = ZZX_coeff(self.x, <long>i)
|
|
246
|
+
sig_off()
|
|
247
|
+
return r
|
|
248
|
+
|
|
249
|
+
cdef int getitem_as_int(ntl_ZZX self, long i) noexcept:
|
|
250
|
+
r"""
|
|
251
|
+
Return `i`-th coefficient as C int.
|
|
252
|
+
Return value is only valid if the result fits into an int.
|
|
253
|
+
|
|
254
|
+
AUTHOR: David Harvey (2006-08-05)
|
|
255
|
+
"""
|
|
256
|
+
return ZZX_getitem_as_int(&self.x, i)
|
|
257
|
+
|
|
258
|
+
def getitem_as_int_doctest(self, i):
|
|
259
|
+
r"""
|
|
260
|
+
This method exists solely for automated testing of getitem_as_int().
|
|
261
|
+
|
|
262
|
+
sage: x = ntl.ZZX([2, 3, 5, -7, 11])
|
|
263
|
+
sage: i = x.getitem_as_int_doctest(3)
|
|
264
|
+
sage: i
|
|
265
|
+
-7
|
|
266
|
+
sage: type(i)
|
|
267
|
+
<... 'int'>
|
|
268
|
+
sage: x.getitem_as_int_doctest(15)
|
|
269
|
+
0
|
|
270
|
+
"""
|
|
271
|
+
return self.getitem_as_int(i)
|
|
272
|
+
|
|
273
|
+
def list(self):
|
|
274
|
+
r"""
|
|
275
|
+
Retrieves coefficients as a list of ntl.ZZ Integers.
|
|
276
|
+
|
|
277
|
+
EXAMPLES::
|
|
278
|
+
|
|
279
|
+
sage: x = ntl.ZZX([129381729371289371237128318293718237, 2, -3, 0, 4])
|
|
280
|
+
sage: L = x.list(); L
|
|
281
|
+
[129381729371289371237128318293718237, 2, -3, 0, 4]
|
|
282
|
+
sage: type(L[0])
|
|
283
|
+
<class 'sage.libs.ntl.ntl_ZZ.ntl_ZZ'>
|
|
284
|
+
sage: x = ntl.ZZX()
|
|
285
|
+
sage: L = x.list(); L
|
|
286
|
+
[]
|
|
287
|
+
"""
|
|
288
|
+
cdef int i
|
|
289
|
+
return [self[i] for i from 0 <= i <= ZZX_deg(self.x)]
|
|
290
|
+
|
|
291
|
+
def __add__(ntl_ZZX self, ntl_ZZX other):
|
|
292
|
+
"""
|
|
293
|
+
EXAMPLES::
|
|
294
|
+
|
|
295
|
+
sage: ntl.ZZX(list(range(5))) + ntl.ZZX(list(range(6)))
|
|
296
|
+
[0 2 4 6 8 5]
|
|
297
|
+
"""
|
|
298
|
+
cdef ntl_ZZX r = ntl_ZZX.__new__(ntl_ZZX)
|
|
299
|
+
if not isinstance(self, ntl_ZZX):
|
|
300
|
+
self = ntl_ZZX(self)
|
|
301
|
+
if not isinstance(other, ntl_ZZX):
|
|
302
|
+
other = ntl_ZZX(other)
|
|
303
|
+
ZZX_add(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
|
|
304
|
+
return r
|
|
305
|
+
|
|
306
|
+
def __sub__(ntl_ZZX self, ntl_ZZX other):
|
|
307
|
+
"""
|
|
308
|
+
EXAMPLES::
|
|
309
|
+
|
|
310
|
+
sage: ntl.ZZX(list(range(5))) - ntl.ZZX(list(range(6)))
|
|
311
|
+
[0 0 0 0 0 -5]
|
|
312
|
+
"""
|
|
313
|
+
cdef ntl_ZZX r = ntl_ZZX.__new__(ntl_ZZX)
|
|
314
|
+
if not isinstance(self, ntl_ZZX):
|
|
315
|
+
self = ntl_ZZX(self)
|
|
316
|
+
if not isinstance(other, ntl_ZZX):
|
|
317
|
+
other = ntl_ZZX(other)
|
|
318
|
+
ZZX_sub(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
|
|
319
|
+
return r
|
|
320
|
+
|
|
321
|
+
def __mul__(ntl_ZZX self, ntl_ZZX other):
|
|
322
|
+
"""
|
|
323
|
+
EXAMPLES::
|
|
324
|
+
|
|
325
|
+
sage: ntl.ZZX(list(range(5))) * ntl.ZZX(list(range(6)))
|
|
326
|
+
[0 0 1 4 10 20 30 34 31 20]
|
|
327
|
+
"""
|
|
328
|
+
cdef ntl_ZZX r = ntl_ZZX.__new__(ntl_ZZX)
|
|
329
|
+
if not isinstance(self, ntl_ZZX):
|
|
330
|
+
self = ntl_ZZX(self)
|
|
331
|
+
if not isinstance(other, ntl_ZZX):
|
|
332
|
+
other = ntl_ZZX(other)
|
|
333
|
+
sig_on()
|
|
334
|
+
ZZX_mul(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
|
|
335
|
+
sig_off()
|
|
336
|
+
return r
|
|
337
|
+
|
|
338
|
+
def __truediv__(ntl_ZZX self, ntl_ZZX other):
|
|
339
|
+
"""
|
|
340
|
+
Compute quotient ``self / other``, if the quotient is a polynomial.
|
|
341
|
+
Otherwise an Exception is raised.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
|
|
346
|
+
sage: g = ntl.ZZX([4,5])
|
|
347
|
+
sage: f/g
|
|
348
|
+
[4 13 22 15]
|
|
349
|
+
sage: ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])
|
|
350
|
+
[4 13 22 15]
|
|
351
|
+
|
|
352
|
+
sage: f = ntl.ZZX(list(range(10))); g = ntl.ZZX([-1,0,1])
|
|
353
|
+
sage: f/g
|
|
354
|
+
Traceback (most recent call last):
|
|
355
|
+
...
|
|
356
|
+
ArithmeticError: self (=[0 1 2 3 4 5 6 7 8 9]) is not divisible by other (=[-1 0 1])
|
|
357
|
+
"""
|
|
358
|
+
sig_on()
|
|
359
|
+
cdef int divisible
|
|
360
|
+
cdef ZZX_c* q
|
|
361
|
+
q = ZZX_div(&self.x, &other.x, &divisible)
|
|
362
|
+
if not divisible:
|
|
363
|
+
del q
|
|
364
|
+
sig_off()
|
|
365
|
+
raise ArithmeticError("self (=%s) is not divisible by other (=%s)" % (self, other))
|
|
366
|
+
result = make_ZZX_sig_off(q)
|
|
367
|
+
return result
|
|
368
|
+
|
|
369
|
+
def __mod__(ntl_ZZX self, ntl_ZZX other):
|
|
370
|
+
"""
|
|
371
|
+
Given polynomials a, b in ZZ[X], there exist polynomials q, r
|
|
372
|
+
in QQ[X] such that a = b*q + r, deg(r) < deg(b). This
|
|
373
|
+
function returns q if q lies in ZZ[X], and otherwise raises an
|
|
374
|
+
Exception.
|
|
375
|
+
|
|
376
|
+
EXAMPLES::
|
|
377
|
+
|
|
378
|
+
sage: f = ntl.ZZX([2,4,6]); g = ntl.ZZX([2])
|
|
379
|
+
sage: f % g # 0
|
|
380
|
+
[]
|
|
381
|
+
|
|
382
|
+
sage: f = ntl.ZZX(list(range(10))); g = ntl.ZZX([-1,0,1])
|
|
383
|
+
sage: f % g
|
|
384
|
+
[20 25]
|
|
385
|
+
"""
|
|
386
|
+
cdef ntl_ZZX r = ntl_ZZX.__new__(ntl_ZZX)
|
|
387
|
+
if not isinstance(self, ntl_ZZX):
|
|
388
|
+
self = ntl_ZZX(self)
|
|
389
|
+
if not isinstance(other, ntl_ZZX):
|
|
390
|
+
other = ntl_ZZX(other)
|
|
391
|
+
sig_on()
|
|
392
|
+
ZZX_rem(r.x, (<ntl_ZZX>self).x, (<ntl_ZZX>other).x)
|
|
393
|
+
sig_off()
|
|
394
|
+
return r
|
|
395
|
+
|
|
396
|
+
def quo_rem(self, ntl_ZZX other):
|
|
397
|
+
"""
|
|
398
|
+
Return the unique integral q and r such that ``self = q*other +
|
|
399
|
+
r``, if they exist. Otherwise raises an Exception.
|
|
400
|
+
|
|
401
|
+
EXAMPLES::
|
|
402
|
+
|
|
403
|
+
sage: f = ntl.ZZX(list(range(10))); g = ntl.ZZX([-1,0,1])
|
|
404
|
+
sage: q, r = f.quo_rem(g)
|
|
405
|
+
sage: q, r
|
|
406
|
+
([20 24 18 21 14 16 8 9], [20 25])
|
|
407
|
+
sage: q*g + r == f
|
|
408
|
+
True
|
|
409
|
+
"""
|
|
410
|
+
cdef ZZX_c *r
|
|
411
|
+
cdef ZZX_c *q
|
|
412
|
+
sig_on()
|
|
413
|
+
try:
|
|
414
|
+
ZZX_quo_rem(&self.x, &other.x, &r, &q)
|
|
415
|
+
return (make_ZZX(q), make_ZZX(r))
|
|
416
|
+
finally:
|
|
417
|
+
sig_off()
|
|
418
|
+
|
|
419
|
+
def square(self):
|
|
420
|
+
"""
|
|
421
|
+
Return f*f.
|
|
422
|
+
|
|
423
|
+
EXAMPLES::
|
|
424
|
+
|
|
425
|
+
sage: f = ntl.ZZX([-1,0,1])
|
|
426
|
+
sage: f*f
|
|
427
|
+
[1 0 -2 0 1]
|
|
428
|
+
"""
|
|
429
|
+
sig_on()
|
|
430
|
+
return make_ZZX_sig_off(ZZX_square(&self.x))
|
|
431
|
+
|
|
432
|
+
def __pow__(ntl_ZZX self, long n, ignored):
|
|
433
|
+
"""
|
|
434
|
+
Return the `n`-th nonnegative power of ``self``.
|
|
435
|
+
|
|
436
|
+
EXAMPLES::
|
|
437
|
+
|
|
438
|
+
sage: g = ntl.ZZX([-1,0,1])
|
|
439
|
+
sage: g ^ 10
|
|
440
|
+
[1 0 -10 0 45 0 -120 0 210 0 -252 0 210 0 -120 0 45 0 -10 0 1]
|
|
441
|
+
sage: g ^ 0
|
|
442
|
+
[1]
|
|
443
|
+
sage: g ^ 1
|
|
444
|
+
[-1 0 1]
|
|
445
|
+
sage: g ^ (-1)
|
|
446
|
+
Traceback (most recent call last):
|
|
447
|
+
...
|
|
448
|
+
ArithmeticError
|
|
449
|
+
"""
|
|
450
|
+
if n == 0:
|
|
451
|
+
from copy import copy
|
|
452
|
+
return copy(one_ZZX)
|
|
453
|
+
if n < 0:
|
|
454
|
+
raise ArithmeticError
|
|
455
|
+
return generic_power_pos(self, <unsigned long>n)
|
|
456
|
+
|
|
457
|
+
def __richcmp__(ntl_ZZX self, other, int op):
|
|
458
|
+
"""
|
|
459
|
+
Compare ``self`` to ``other``.
|
|
460
|
+
|
|
461
|
+
EXAMPLES::
|
|
462
|
+
|
|
463
|
+
sage: f = ntl.ZZX([1,2,3])
|
|
464
|
+
sage: g = ntl.ZZX([1,2,3,0])
|
|
465
|
+
sage: f == g
|
|
466
|
+
True
|
|
467
|
+
sage: g = ntl.ZZX([0,1,2,3])
|
|
468
|
+
sage: f == g
|
|
469
|
+
False
|
|
470
|
+
sage: f == ntl.ZZ(0)
|
|
471
|
+
False
|
|
472
|
+
"""
|
|
473
|
+
if op != Py_EQ and op != Py_NE:
|
|
474
|
+
raise TypeError("polynomials are not ordered")
|
|
475
|
+
|
|
476
|
+
cdef ntl_ZZX b
|
|
477
|
+
try:
|
|
478
|
+
b = <ntl_ZZX?>other
|
|
479
|
+
except TypeError:
|
|
480
|
+
b = ntl_ZZX(other)
|
|
481
|
+
|
|
482
|
+
return (op == Py_EQ) == (self.x == b.x)
|
|
483
|
+
|
|
484
|
+
def is_zero(self):
|
|
485
|
+
"""
|
|
486
|
+
Return ``True`` exactly if this polynomial is 0.
|
|
487
|
+
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: f = ntl.ZZX([0,0,0,0])
|
|
491
|
+
sage: f.is_zero()
|
|
492
|
+
True
|
|
493
|
+
sage: f = ntl.ZZX([0,0,1])
|
|
494
|
+
sage: f
|
|
495
|
+
[0 0 1]
|
|
496
|
+
sage: f.is_zero()
|
|
497
|
+
False
|
|
498
|
+
"""
|
|
499
|
+
return bool(ZZX_IsZero(self.x))
|
|
500
|
+
|
|
501
|
+
def is_one(self):
|
|
502
|
+
"""
|
|
503
|
+
Return ``True`` exactly if this polynomial is 1.
|
|
504
|
+
|
|
505
|
+
EXAMPLES::
|
|
506
|
+
|
|
507
|
+
sage: f = ntl.ZZX([1,1])
|
|
508
|
+
sage: f.is_one()
|
|
509
|
+
False
|
|
510
|
+
sage: f = ntl.ZZX([1])
|
|
511
|
+
sage: f.is_one()
|
|
512
|
+
True
|
|
513
|
+
"""
|
|
514
|
+
return bool(ZZX_IsOne(self.x))
|
|
515
|
+
|
|
516
|
+
def is_monic(self):
|
|
517
|
+
"""
|
|
518
|
+
Return ``True`` exactly if this polynomial is monic.
|
|
519
|
+
|
|
520
|
+
EXAMPLES::
|
|
521
|
+
|
|
522
|
+
sage: f = ntl.ZZX([2,0,0,1])
|
|
523
|
+
sage: f.is_monic()
|
|
524
|
+
True
|
|
525
|
+
sage: g = f.reverse()
|
|
526
|
+
sage: g.is_monic()
|
|
527
|
+
False
|
|
528
|
+
sage: g
|
|
529
|
+
[1 0 0 2]
|
|
530
|
+
"""
|
|
531
|
+
if ZZX_IsZero(self.x):
|
|
532
|
+
return False
|
|
533
|
+
cdef ZZ_c lc
|
|
534
|
+
lc = ZZX_LeadCoeff(self.x)
|
|
535
|
+
return <bint>ZZ_IsOne(lc)
|
|
536
|
+
|
|
537
|
+
# return bool(ZZX_is_monic(&self.x))
|
|
538
|
+
|
|
539
|
+
def __neg__(self):
|
|
540
|
+
"""
|
|
541
|
+
Return the negative of ``self``.
|
|
542
|
+
|
|
543
|
+
EXAMPLES::
|
|
544
|
+
|
|
545
|
+
sage: f = ntl.ZZX([2,0,0,1])
|
|
546
|
+
sage: -f
|
|
547
|
+
[-2 0 0 -1]
|
|
548
|
+
"""
|
|
549
|
+
return make_ZZX(ZZX_neg(&self.x))
|
|
550
|
+
|
|
551
|
+
def left_shift(self, long n):
|
|
552
|
+
"""
|
|
553
|
+
Return the polynomial obtained by shifting all coefficients of
|
|
554
|
+
this polynomial to the left n positions.
|
|
555
|
+
|
|
556
|
+
EXAMPLES::
|
|
557
|
+
|
|
558
|
+
sage: f = ntl.ZZX([2,0,0,1])
|
|
559
|
+
sage: f
|
|
560
|
+
[2 0 0 1]
|
|
561
|
+
sage: f.left_shift(2)
|
|
562
|
+
[0 0 2 0 0 1]
|
|
563
|
+
sage: f.left_shift(5)
|
|
564
|
+
[0 0 0 0 0 2 0 0 1]
|
|
565
|
+
|
|
566
|
+
A negative left shift is a right shift.
|
|
567
|
+
sage: f.left_shift(-2)
|
|
568
|
+
[0 1]
|
|
569
|
+
"""
|
|
570
|
+
return make_ZZX(ZZX_left_shift(&self.x, n))
|
|
571
|
+
|
|
572
|
+
def right_shift(self, long n):
|
|
573
|
+
"""
|
|
574
|
+
Return the polynomial obtained by shifting all coefficients of
|
|
575
|
+
this polynomial to the right n positions.
|
|
576
|
+
|
|
577
|
+
EXAMPLES::
|
|
578
|
+
|
|
579
|
+
sage: f = ntl.ZZX([2,0,0,1])
|
|
580
|
+
sage: f
|
|
581
|
+
[2 0 0 1]
|
|
582
|
+
sage: f.right_shift(2)
|
|
583
|
+
[0 1]
|
|
584
|
+
sage: f.right_shift(5)
|
|
585
|
+
[]
|
|
586
|
+
sage: f.right_shift(-2)
|
|
587
|
+
[0 0 2 0 0 1]
|
|
588
|
+
"""
|
|
589
|
+
return make_ZZX(ZZX_right_shift(&self.x, n))
|
|
590
|
+
|
|
591
|
+
def content(self):
|
|
592
|
+
"""
|
|
593
|
+
Return the content of f, which has sign the same as the
|
|
594
|
+
leading coefficient of f. Also, our convention is that the
|
|
595
|
+
content of 0 is 0.
|
|
596
|
+
|
|
597
|
+
EXAMPLES::
|
|
598
|
+
|
|
599
|
+
sage: f = ntl.ZZX([2,0,0,2])
|
|
600
|
+
sage: f.content()
|
|
601
|
+
2
|
|
602
|
+
sage: f = ntl.ZZX([2,0,0,-2])
|
|
603
|
+
sage: f.content()
|
|
604
|
+
-2
|
|
605
|
+
sage: f = ntl.ZZX([6,12,3,9])
|
|
606
|
+
sage: f.content()
|
|
607
|
+
3
|
|
608
|
+
sage: f = ntl.ZZX([])
|
|
609
|
+
sage: f.content()
|
|
610
|
+
0
|
|
611
|
+
"""
|
|
612
|
+
cdef ntl_ZZ r = ntl_ZZ.__new__(ntl_ZZ)
|
|
613
|
+
ZZX_content(r.x, self.x)
|
|
614
|
+
return r
|
|
615
|
+
|
|
616
|
+
def primitive_part(self):
|
|
617
|
+
"""
|
|
618
|
+
Return the primitive part of f. Our convention is that the leading
|
|
619
|
+
coefficient of the primitive part is nonnegative, and the primitive
|
|
620
|
+
part of 0 is 0.
|
|
621
|
+
|
|
622
|
+
EXAMPLES::
|
|
623
|
+
|
|
624
|
+
sage: f = ntl.ZZX([6,12,3,9])
|
|
625
|
+
sage: f.primitive_part()
|
|
626
|
+
[2 4 1 3]
|
|
627
|
+
sage: f
|
|
628
|
+
[6 12 3 9]
|
|
629
|
+
sage: f = ntl.ZZX([6,12,3,-9])
|
|
630
|
+
sage: f
|
|
631
|
+
[6 12 3 -9]
|
|
632
|
+
sage: f.primitive_part()
|
|
633
|
+
[-2 -4 -1 3]
|
|
634
|
+
sage: f = ntl.ZZX()
|
|
635
|
+
sage: f.primitive_part()
|
|
636
|
+
[]
|
|
637
|
+
"""
|
|
638
|
+
return make_ZZX(ZZX_primitive_part(&self.x))
|
|
639
|
+
|
|
640
|
+
def pseudo_quo_rem(self, ntl_ZZX other):
|
|
641
|
+
r"""
|
|
642
|
+
Perform pseudo-division: computes q and r with deg(r) <
|
|
643
|
+
deg(b), and \code{LeadCoeff(b)\^(deg(a)-deg(b)+1) a = b q + r}.
|
|
644
|
+
Only the classical algorithm is used.
|
|
645
|
+
|
|
646
|
+
EXAMPLES::
|
|
647
|
+
|
|
648
|
+
sage: f = ntl.ZZX([0,1])
|
|
649
|
+
sage: g = ntl.ZZX([1,2,3])
|
|
650
|
+
sage: g.pseudo_quo_rem(f)
|
|
651
|
+
([2 3], [1])
|
|
652
|
+
sage: f = ntl.ZZX([1,1])
|
|
653
|
+
sage: g.pseudo_quo_rem(f)
|
|
654
|
+
([-1 3], [2])
|
|
655
|
+
"""
|
|
656
|
+
cdef ZZX_c *r
|
|
657
|
+
cdef ZZX_c *q
|
|
658
|
+
sig_on()
|
|
659
|
+
try:
|
|
660
|
+
ZZX_pseudo_quo_rem(&self.x, &other.x, &r, &q)
|
|
661
|
+
return (make_ZZX(q), make_ZZX(r))
|
|
662
|
+
finally:
|
|
663
|
+
sig_off()
|
|
664
|
+
|
|
665
|
+
def gcd(self, ntl_ZZX other):
|
|
666
|
+
"""
|
|
667
|
+
Return the gcd d = gcd(a, b), where by convention the leading coefficient
|
|
668
|
+
of d is >= 0. We use a multi-modular algorithm.
|
|
669
|
+
|
|
670
|
+
EXAMPLES::
|
|
671
|
+
|
|
672
|
+
sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
|
|
673
|
+
sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3])
|
|
674
|
+
sage: f.gcd(g)
|
|
675
|
+
[1 2 3]
|
|
676
|
+
sage: g.gcd(f)
|
|
677
|
+
[1 2 3]
|
|
678
|
+
"""
|
|
679
|
+
sig_on()
|
|
680
|
+
return make_ZZX_sig_off(ZZX_gcd(&self.x, &other.x))
|
|
681
|
+
|
|
682
|
+
def lcm(self, ntl_ZZX other):
|
|
683
|
+
"""
|
|
684
|
+
Return the least common multiple of ``self`` and ``other``.
|
|
685
|
+
|
|
686
|
+
EXAMPLES::
|
|
687
|
+
|
|
688
|
+
sage: x1 = ntl.ZZX([-1,0,0,1])
|
|
689
|
+
sage: x2 = ntl.ZZX([-1,0,0,0,0,0,1])
|
|
690
|
+
sage: x1.lcm(x2)
|
|
691
|
+
[-1 0 0 0 0 0 1]
|
|
692
|
+
"""
|
|
693
|
+
g = self.gcd(other)
|
|
694
|
+
return (self*other).quo_rem(g)[0]
|
|
695
|
+
|
|
696
|
+
def xgcd(self, ntl_ZZX other, proof=None):
|
|
697
|
+
r"""
|
|
698
|
+
If ``self`` and ``other`` are coprime over the rationals,
|
|
699
|
+
return ``r, s, t`` such that ``r = s*self + t*other``.
|
|
700
|
+
Otherwise return 0.
|
|
701
|
+
|
|
702
|
+
This is \emph{not} the same as the \sage function on
|
|
703
|
+
polynomials over the integers, since here the return value r
|
|
704
|
+
is always an integer.
|
|
705
|
+
|
|
706
|
+
Here r is the resultant of a and b; if r != 0, then this
|
|
707
|
+
function computes s and t such that: a*s + b*t = r; otherwise
|
|
708
|
+
s and t are both 0. If proof = False (*not* the default),
|
|
709
|
+
then resultant computation may use a randomized strategy that
|
|
710
|
+
errors with probability no more than `2^{-80}`. The default is
|
|
711
|
+
default is proof=None, see proof.polynomial or sage.structure.proof,
|
|
712
|
+
but the global default is True), then this function may use a
|
|
713
|
+
randomized strategy that errors with probability no more than
|
|
714
|
+
`2^{-80}`.
|
|
715
|
+
|
|
716
|
+
EXAMPLES::
|
|
717
|
+
|
|
718
|
+
sage: f = ntl.ZZX([1,2,3]) * ntl.ZZX([4,5])**2
|
|
719
|
+
sage: g = ntl.ZZX([1,1,1])**3 * ntl.ZZX([1,2,3])
|
|
720
|
+
sage: f.xgcd(g) # nothing since they are not coprime
|
|
721
|
+
(0, [], [])
|
|
722
|
+
|
|
723
|
+
In this example the input quadratic polynomials have a common root modulo 13::
|
|
724
|
+
|
|
725
|
+
sage: f = ntl.ZZX([5,0,1])
|
|
726
|
+
sage: g = ntl.ZZX([18,0,1])
|
|
727
|
+
sage: f.xgcd(g)
|
|
728
|
+
(169, [-13], [13])
|
|
729
|
+
"""
|
|
730
|
+
proof = proof_flag(proof)
|
|
731
|
+
|
|
732
|
+
cdef ZZX_c *s
|
|
733
|
+
cdef ZZX_c *t
|
|
734
|
+
cdef ZZ_c *r
|
|
735
|
+
sig_on()
|
|
736
|
+
try:
|
|
737
|
+
ZZX_xgcd(&self.x, &other.x, &r, &s, &t, proof)
|
|
738
|
+
return (make_ZZ(r), make_ZZX(s), make_ZZX(t))
|
|
739
|
+
finally:
|
|
740
|
+
sig_off()
|
|
741
|
+
|
|
742
|
+
def degree(self):
|
|
743
|
+
"""
|
|
744
|
+
Return the degree of this polynomial. The degree of the 0
|
|
745
|
+
polynomial is -1.
|
|
746
|
+
|
|
747
|
+
EXAMPLES::
|
|
748
|
+
|
|
749
|
+
sage: f = ntl.ZZX([5,0,1])
|
|
750
|
+
sage: f.degree()
|
|
751
|
+
2
|
|
752
|
+
sage: f = ntl.ZZX(list(range(100)))
|
|
753
|
+
sage: f.degree()
|
|
754
|
+
99
|
|
755
|
+
sage: f = ntl.ZZX()
|
|
756
|
+
sage: f.degree()
|
|
757
|
+
-1
|
|
758
|
+
sage: f = ntl.ZZX([1])
|
|
759
|
+
sage: f.degree()
|
|
760
|
+
0
|
|
761
|
+
"""
|
|
762
|
+
return ZZX_deg(self.x)
|
|
763
|
+
|
|
764
|
+
def leading_coefficient(self):
|
|
765
|
+
"""
|
|
766
|
+
Return the leading coefficient of this polynomial.
|
|
767
|
+
|
|
768
|
+
EXAMPLES::
|
|
769
|
+
|
|
770
|
+
sage: f = ntl.ZZX([3,6,9])
|
|
771
|
+
sage: f.leading_coefficient()
|
|
772
|
+
9
|
|
773
|
+
sage: f = ntl.ZZX()
|
|
774
|
+
sage: f.leading_coefficient()
|
|
775
|
+
0
|
|
776
|
+
"""
|
|
777
|
+
cdef ntl_ZZ r = ntl_ZZ.__new__(ntl_ZZ)
|
|
778
|
+
r.x = ZZX_LeadCoeff(self.x)
|
|
779
|
+
return r
|
|
780
|
+
|
|
781
|
+
def constant_term(self):
|
|
782
|
+
"""
|
|
783
|
+
Return the constant coefficient of this polynomial.
|
|
784
|
+
|
|
785
|
+
EXAMPLES::
|
|
786
|
+
|
|
787
|
+
sage: f = ntl.ZZX([3,6,9])
|
|
788
|
+
sage: f.constant_term()
|
|
789
|
+
3
|
|
790
|
+
sage: f = ntl.ZZX()
|
|
791
|
+
sage: f.constant_term()
|
|
792
|
+
0
|
|
793
|
+
"""
|
|
794
|
+
cdef ntl_ZZ r = ntl_ZZ.__new__(ntl_ZZ)
|
|
795
|
+
r.x = ZZX_ConstTerm(self.x)
|
|
796
|
+
return r
|
|
797
|
+
|
|
798
|
+
def set_x(self):
|
|
799
|
+
"""
|
|
800
|
+
Set this polynomial to the monomial "x".
|
|
801
|
+
|
|
802
|
+
EXAMPLES::
|
|
803
|
+
|
|
804
|
+
sage: f = ntl.ZZX()
|
|
805
|
+
sage: f.set_x()
|
|
806
|
+
sage: f
|
|
807
|
+
[0 1]
|
|
808
|
+
sage: g = ntl.ZZX([0,1])
|
|
809
|
+
sage: f == g
|
|
810
|
+
True
|
|
811
|
+
|
|
812
|
+
Though f and g are equal, they are not the same objects in memory::
|
|
813
|
+
|
|
814
|
+
sage: f is g
|
|
815
|
+
False
|
|
816
|
+
"""
|
|
817
|
+
ZZX_set_x(&self.x)
|
|
818
|
+
|
|
819
|
+
def is_x(self):
|
|
820
|
+
"""
|
|
821
|
+
``True`` if this is the polynomial "x".
|
|
822
|
+
|
|
823
|
+
EXAMPLES::
|
|
824
|
+
|
|
825
|
+
sage: f = ntl.ZZX()
|
|
826
|
+
sage: f.set_x()
|
|
827
|
+
sage: f.is_x()
|
|
828
|
+
True
|
|
829
|
+
sage: f = ntl.ZZX([0,1])
|
|
830
|
+
sage: f.is_x()
|
|
831
|
+
True
|
|
832
|
+
sage: f = ntl.ZZX([1])
|
|
833
|
+
sage: f.is_x()
|
|
834
|
+
False
|
|
835
|
+
"""
|
|
836
|
+
return bool(ZZX_is_x(&self.x))
|
|
837
|
+
|
|
838
|
+
def derivative(self):
|
|
839
|
+
"""
|
|
840
|
+
Return the derivative of this polynomial.
|
|
841
|
+
|
|
842
|
+
EXAMPLES::
|
|
843
|
+
|
|
844
|
+
sage: f = ntl.ZZX([1,7,0,13])
|
|
845
|
+
sage: f.derivative()
|
|
846
|
+
[7 0 39]
|
|
847
|
+
"""
|
|
848
|
+
return make_ZZX(ZZX_derivative(&self.x))
|
|
849
|
+
|
|
850
|
+
def reverse(self, hi=None):
|
|
851
|
+
"""
|
|
852
|
+
Return the polynomial obtained by reversing the coefficients
|
|
853
|
+
of this polynomial. If hi is set then this function behaves
|
|
854
|
+
as if this polynomial has degree hi.
|
|
855
|
+
|
|
856
|
+
EXAMPLES::
|
|
857
|
+
|
|
858
|
+
sage: f = ntl.ZZX([1,2,3,4,5])
|
|
859
|
+
sage: f.reverse()
|
|
860
|
+
[5 4 3 2 1]
|
|
861
|
+
sage: f.reverse(hi=10)
|
|
862
|
+
[0 0 0 0 0 0 5 4 3 2 1]
|
|
863
|
+
sage: f.reverse(hi=2)
|
|
864
|
+
[3 2 1]
|
|
865
|
+
sage: f.reverse(hi=-2)
|
|
866
|
+
[]
|
|
867
|
+
"""
|
|
868
|
+
if not (hi is None):
|
|
869
|
+
return make_ZZX(ZZX_reverse_hi(&self.x, int(hi)))
|
|
870
|
+
else:
|
|
871
|
+
return make_ZZX(ZZX_reverse(&self.x))
|
|
872
|
+
|
|
873
|
+
def truncate(self, long m):
|
|
874
|
+
"""
|
|
875
|
+
Return the truncation of this polynomial obtained by
|
|
876
|
+
removing all terms of degree >= m.
|
|
877
|
+
|
|
878
|
+
EXAMPLES::
|
|
879
|
+
|
|
880
|
+
sage: f = ntl.ZZX([1,2,3,4,5])
|
|
881
|
+
sage: f.truncate(3)
|
|
882
|
+
[1 2 3]
|
|
883
|
+
sage: f.truncate(8)
|
|
884
|
+
[1 2 3 4 5]
|
|
885
|
+
sage: f.truncate(1)
|
|
886
|
+
[1]
|
|
887
|
+
sage: f.truncate(0)
|
|
888
|
+
[]
|
|
889
|
+
sage: f.truncate(-1)
|
|
890
|
+
[]
|
|
891
|
+
sage: f.truncate(-5)
|
|
892
|
+
[]
|
|
893
|
+
"""
|
|
894
|
+
if m <= 0:
|
|
895
|
+
from copy import copy
|
|
896
|
+
return copy(zero_ZZX)
|
|
897
|
+
sig_on()
|
|
898
|
+
return make_ZZX_sig_off(ZZX_truncate(&self.x, m))
|
|
899
|
+
|
|
900
|
+
def multiply_and_truncate(self, ntl_ZZX other, long m):
|
|
901
|
+
"""
|
|
902
|
+
Return self*other but with terms of degree >= m removed.
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: f = ntl.ZZX([1,2,3,4,5])
|
|
907
|
+
sage: g = ntl.ZZX([10])
|
|
908
|
+
sage: f.multiply_and_truncate(g, 2)
|
|
909
|
+
[10 20]
|
|
910
|
+
sage: g.multiply_and_truncate(f, 2)
|
|
911
|
+
[10 20]
|
|
912
|
+
"""
|
|
913
|
+
if m <= 0:
|
|
914
|
+
from copy import copy
|
|
915
|
+
return copy(zero_ZZX)
|
|
916
|
+
return make_ZZX(ZZX_multiply_and_truncate(&self.x, &other.x, m))
|
|
917
|
+
|
|
918
|
+
def square_and_truncate(self, long m):
|
|
919
|
+
"""
|
|
920
|
+
Return self*self but with terms of degree >= m removed.
|
|
921
|
+
|
|
922
|
+
EXAMPLES::
|
|
923
|
+
|
|
924
|
+
sage: f = ntl.ZZX([1,2,3,4,5])
|
|
925
|
+
sage: f.square_and_truncate(4)
|
|
926
|
+
[1 4 10 20]
|
|
927
|
+
sage: (f*f).truncate(4)
|
|
928
|
+
[1 4 10 20]
|
|
929
|
+
"""
|
|
930
|
+
if m < 0:
|
|
931
|
+
from copy import copy
|
|
932
|
+
return copy(zero_ZZX)
|
|
933
|
+
return make_ZZX(ZZX_square_and_truncate(&self.x, m))
|
|
934
|
+
|
|
935
|
+
def invert_and_truncate(self, long m):
|
|
936
|
+
"""
|
|
937
|
+
Compute and return the inverse of ``self`` modulo `x^m`.
|
|
938
|
+
The constant term of ``self`` must be 1 or -1.
|
|
939
|
+
|
|
940
|
+
EXAMPLES::
|
|
941
|
+
|
|
942
|
+
sage: f = ntl.ZZX([1,2,3,4,5,6,7])
|
|
943
|
+
sage: f.invert_and_truncate(20)
|
|
944
|
+
[1 -2 1 0 0 0 0 8 -23 22 -7 0 0 0 64 -240 337 -210 49]
|
|
945
|
+
sage: g = f.invert_and_truncate(20)
|
|
946
|
+
sage: g * f
|
|
947
|
+
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -512 1344 -1176 343]
|
|
948
|
+
"""
|
|
949
|
+
if m < 0:
|
|
950
|
+
raise ArithmeticError("m (=%s) must be positive" % m)
|
|
951
|
+
n = self.constant_term()
|
|
952
|
+
if n != ntl_ZZ(1) and n != ntl_ZZ(-1):
|
|
953
|
+
raise ArithmeticError("The constant term of self must be 1 or -1.")
|
|
954
|
+
sig_on()
|
|
955
|
+
return make_ZZX_sig_off(ZZX_invert_and_truncate(&self.x, m))
|
|
956
|
+
|
|
957
|
+
def multiply_mod(self, ntl_ZZX other, ntl_ZZX modulus):
|
|
958
|
+
"""
|
|
959
|
+
Return ``self*other % modulus``. The modulus must be monic with
|
|
960
|
+
deg(modulus) > 0, and ``self`` and ``other`` must have smaller degree.
|
|
961
|
+
|
|
962
|
+
EXAMPLES::
|
|
963
|
+
|
|
964
|
+
sage: modulus = ntl.ZZX([1,2,0,1]) # must be monic
|
|
965
|
+
sage: g = ntl.ZZX([-1,0,1])
|
|
966
|
+
sage: h = ntl.ZZX([3,7,13])
|
|
967
|
+
sage: h.multiply_mod(g, modulus)
|
|
968
|
+
[-10 -34 -36]
|
|
969
|
+
"""
|
|
970
|
+
sig_on()
|
|
971
|
+
return make_ZZX_sig_off(ZZX_multiply_mod(&self.x, &other.x, &modulus.x))
|
|
972
|
+
|
|
973
|
+
def trace_mod(self, ntl_ZZX modulus):
|
|
974
|
+
"""
|
|
975
|
+
Return the trace of this polynomial modulus the modulus.
|
|
976
|
+
The modulus must be monic, and of positive degree bigger
|
|
977
|
+
than the degree of ``self``.
|
|
978
|
+
|
|
979
|
+
EXAMPLES::
|
|
980
|
+
|
|
981
|
+
sage: f = ntl.ZZX([1,2,0,3])
|
|
982
|
+
sage: mod = ntl.ZZX([5,3,-1,1,1])
|
|
983
|
+
sage: f.trace_mod(mod)
|
|
984
|
+
-37
|
|
985
|
+
"""
|
|
986
|
+
sig_on()
|
|
987
|
+
return make_ZZ_sig_off(ZZX_trace_mod(&self.x, &modulus.x))
|
|
988
|
+
|
|
989
|
+
def trace_list(self):
|
|
990
|
+
"""
|
|
991
|
+
Return the list of traces of the powers `x^i` of the
|
|
992
|
+
monomial x modulo this polynomial for i = 0, ..., deg(f)-1.
|
|
993
|
+
This polynomial must be monic.
|
|
994
|
+
|
|
995
|
+
EXAMPLES::
|
|
996
|
+
|
|
997
|
+
sage: f = ntl.ZZX([1,2,0,3,0,1])
|
|
998
|
+
sage: f.trace_list()
|
|
999
|
+
[5, 0, -6, 0, 10]
|
|
1000
|
+
|
|
1001
|
+
The input polynomial must be monic or a :exc:`ValueError` is raised::
|
|
1002
|
+
|
|
1003
|
+
sage: f = ntl.ZZX([1,2,0,3,0,2])
|
|
1004
|
+
sage: f.trace_list()
|
|
1005
|
+
Traceback (most recent call last):
|
|
1006
|
+
...
|
|
1007
|
+
ValueError: polynomial must be monic.
|
|
1008
|
+
"""
|
|
1009
|
+
if not self.is_monic():
|
|
1010
|
+
raise ValueError("polynomial must be monic.")
|
|
1011
|
+
sig_on()
|
|
1012
|
+
cdef char* t
|
|
1013
|
+
t = ZZX_trace_list(&self.x)
|
|
1014
|
+
r = eval(char_to_str(t).replace(' ', ','))
|
|
1015
|
+
string_delete(t)
|
|
1016
|
+
return r
|
|
1017
|
+
|
|
1018
|
+
def resultant(self, ntl_ZZX other, proof=None):
|
|
1019
|
+
"""
|
|
1020
|
+
Return the resultant of ``self`` and ``other``. If proof = False (the
|
|
1021
|
+
default is proof=None, see proof.polynomial or sage.structure.proof,
|
|
1022
|
+
but the global default is True), then this function may use a
|
|
1023
|
+
randomized strategy that errors with probability no more than
|
|
1024
|
+
`2^{-80}`.
|
|
1025
|
+
|
|
1026
|
+
EXAMPLES::
|
|
1027
|
+
|
|
1028
|
+
sage: f = ntl.ZZX([17,0,1,1])
|
|
1029
|
+
sage: g = ntl.ZZX([34,-17,18,2])
|
|
1030
|
+
sage: f.resultant(g)
|
|
1031
|
+
1345873
|
|
1032
|
+
sage: f.resultant(g, proof=False)
|
|
1033
|
+
1345873
|
|
1034
|
+
"""
|
|
1035
|
+
proof = proof_flag(proof)
|
|
1036
|
+
# NOTE: Within a factor of 2 in speed compared to MAGMA.
|
|
1037
|
+
sig_on()
|
|
1038
|
+
return make_ZZ_sig_off(ZZX_resultant(&self.x, &other.x, proof))
|
|
1039
|
+
|
|
1040
|
+
def norm_mod(self, ntl_ZZX modulus, proof=None):
|
|
1041
|
+
"""
|
|
1042
|
+
Return the norm of this polynomial modulo the modulus.
|
|
1043
|
+
|
|
1044
|
+
The modulus must be monic, and of positive degree strictly
|
|
1045
|
+
greater than the degree of ``self``. If proof=False (the default
|
|
1046
|
+
is proof=None, see proof.polynomial or sage.structure.proof,
|
|
1047
|
+
but the global default is proof=True) then it may use a
|
|
1048
|
+
randomized strategy that errors with probability no more than
|
|
1049
|
+
`2^{-80}`.
|
|
1050
|
+
|
|
1051
|
+
EXAMPLES::
|
|
1052
|
+
|
|
1053
|
+
sage: f = ntl.ZZX([1,2,0,3])
|
|
1054
|
+
sage: mod = ntl.ZZX([-5,2,0,0,1])
|
|
1055
|
+
sage: f.norm_mod(mod)
|
|
1056
|
+
-8846
|
|
1057
|
+
|
|
1058
|
+
The norm is the constant term of the characteristic polynomial::
|
|
1059
|
+
|
|
1060
|
+
sage: f.charpoly_mod(mod)
|
|
1061
|
+
[-8846 -594 -60 14 1]
|
|
1062
|
+
"""
|
|
1063
|
+
proof = proof_flag(proof)
|
|
1064
|
+
sig_on()
|
|
1065
|
+
return make_ZZ_sig_off(ZZX_norm_mod(&self.x, &modulus.x, proof))
|
|
1066
|
+
|
|
1067
|
+
def discriminant(self, proof=None):
|
|
1068
|
+
r"""
|
|
1069
|
+
Return the discriminant of self, which is by definition
|
|
1070
|
+
$$
|
|
1071
|
+
(-1)^{m(m-1)/2} {\mbox{\tt resultant}}(a, a')/lc(a),
|
|
1072
|
+
$$
|
|
1073
|
+
where m = deg(a), and lc(a) is the leading coefficient of a.
|
|
1074
|
+
If proof is False (the default is proof=None, see
|
|
1075
|
+
proof.polynomial or sage.structure.proof, but the global
|
|
1076
|
+
default is proof=True), then this function may use a
|
|
1077
|
+
randomized strategy that errors with probability no more than
|
|
1078
|
+
`2^{-80}`.
|
|
1079
|
+
|
|
1080
|
+
EXAMPLES::
|
|
1081
|
+
|
|
1082
|
+
sage: f = ntl.ZZX([1,2,0,3])
|
|
1083
|
+
sage: f.discriminant()
|
|
1084
|
+
-339
|
|
1085
|
+
sage: f.discriminant(proof=False)
|
|
1086
|
+
-339
|
|
1087
|
+
"""
|
|
1088
|
+
proof = proof_flag(proof)
|
|
1089
|
+
sig_on()
|
|
1090
|
+
return make_ZZ_sig_off(ZZX_discriminant(&self.x, proof))
|
|
1091
|
+
|
|
1092
|
+
#def __call__(self, ntl_ZZ a):
|
|
1093
|
+
# sig_on()
|
|
1094
|
+
# return make_ZZ_sig_off(ZZX_polyeval(&self.x, a.x))
|
|
1095
|
+
|
|
1096
|
+
def charpoly_mod(self, ntl_ZZX modulus, proof=None):
|
|
1097
|
+
"""
|
|
1098
|
+
Return the characteristic polynomial of this polynomial modulo
|
|
1099
|
+
the modulus. The modulus must be monic of degree bigger than
|
|
1100
|
+
``self``. If proof=False (the default is proof=None, see
|
|
1101
|
+
proof.polynomial or sage.structure.proof, but the global
|
|
1102
|
+
default is proof=True), then this function may use a
|
|
1103
|
+
randomized strategy that errors with probability no more than
|
|
1104
|
+
`2^{-80}`.
|
|
1105
|
+
|
|
1106
|
+
EXAMPLES::
|
|
1107
|
+
|
|
1108
|
+
sage: f = ntl.ZZX([1,2,0,3])
|
|
1109
|
+
sage: mod = ntl.ZZX([-5,2,0,0,1])
|
|
1110
|
+
sage: f.charpoly_mod(mod)
|
|
1111
|
+
[-8846 -594 -60 14 1]
|
|
1112
|
+
"""
|
|
1113
|
+
proof = proof_flag(proof)
|
|
1114
|
+
sig_on()
|
|
1115
|
+
return make_ZZX_sig_off(ZZX_charpoly_mod(&self.x, &modulus.x, proof))
|
|
1116
|
+
|
|
1117
|
+
def minpoly_mod_noproof(self, ntl_ZZX modulus):
|
|
1118
|
+
"""
|
|
1119
|
+
Return the minimal polynomial of this polynomial modulo the
|
|
1120
|
+
modulus. The modulus must be monic of degree bigger than
|
|
1121
|
+
``self``. In all cases, this function may use a randomized
|
|
1122
|
+
strategy that errors with probability no more than `2^{-80}`.
|
|
1123
|
+
|
|
1124
|
+
EXAMPLES::
|
|
1125
|
+
|
|
1126
|
+
sage: f = ntl.ZZX([0,0,1])
|
|
1127
|
+
sage: g = f*f
|
|
1128
|
+
sage: f.charpoly_mod(g)
|
|
1129
|
+
[0 0 0 0 1]
|
|
1130
|
+
|
|
1131
|
+
However, since `f^2 = 0` modulo `g`, its minimal polynomial
|
|
1132
|
+
is of degree `2`::
|
|
1133
|
+
|
|
1134
|
+
sage: f.minpoly_mod_noproof(g)
|
|
1135
|
+
[0 0 1]
|
|
1136
|
+
"""
|
|
1137
|
+
sig_on()
|
|
1138
|
+
return make_ZZX_sig_off(ZZX_minpoly_mod(&self.x, &modulus.x))
|
|
1139
|
+
|
|
1140
|
+
def clear(self):
|
|
1141
|
+
"""
|
|
1142
|
+
Reset this polynomial to 0. Changes this polynomial in place.
|
|
1143
|
+
|
|
1144
|
+
EXAMPLES::
|
|
1145
|
+
|
|
1146
|
+
sage: f = ntl.ZZX([1,2,3])
|
|
1147
|
+
sage: f
|
|
1148
|
+
[1 2 3]
|
|
1149
|
+
sage: f.clear()
|
|
1150
|
+
sage: f
|
|
1151
|
+
[]
|
|
1152
|
+
"""
|
|
1153
|
+
ZZX_clear(&self.x)
|
|
1154
|
+
|
|
1155
|
+
def preallocate_space(self, long n):
|
|
1156
|
+
"""
|
|
1157
|
+
Pre-allocate spaces for n coefficients. The polynomial that f
|
|
1158
|
+
represents is unchanged. This is useful if you know you'll be
|
|
1159
|
+
setting coefficients up to n, so memory isn't re-allocated as
|
|
1160
|
+
the polynomial grows. (You might save a millisecond with this
|
|
1161
|
+
function.)
|
|
1162
|
+
|
|
1163
|
+
EXAMPLES::
|
|
1164
|
+
|
|
1165
|
+
sage: f = ntl.ZZX([1,2,3])
|
|
1166
|
+
sage: f.preallocate_space(20)
|
|
1167
|
+
sage: f
|
|
1168
|
+
[1 2 3]
|
|
1169
|
+
sage: f[10]=5 # no new memory is allocated
|
|
1170
|
+
sage: f
|
|
1171
|
+
[1 2 3 0 0 0 0 0 0 0 5]
|
|
1172
|
+
"""
|
|
1173
|
+
sig_on()
|
|
1174
|
+
ZZX_preallocate_space(&self.x, n)
|
|
1175
|
+
sig_off()
|
|
1176
|
+
|
|
1177
|
+
def squarefree_decomposition(self):
|
|
1178
|
+
"""
|
|
1179
|
+
Return the square-free decomposition of ``self`` (a partial
|
|
1180
|
+
factorization into square-free, relatively prime polynomials)
|
|
1181
|
+
as a list of 2-tuples, where the first element in each tuple
|
|
1182
|
+
is a factor, and the second is its exponent.
|
|
1183
|
+
Assumes that ``self`` is primitive.
|
|
1184
|
+
|
|
1185
|
+
EXAMPLES::
|
|
1186
|
+
|
|
1187
|
+
sage: f = ntl.ZZX([0, 1, 2, 1])
|
|
1188
|
+
sage: f.squarefree_decomposition()
|
|
1189
|
+
[([0 1], 1), ([1 1], 2)]
|
|
1190
|
+
"""
|
|
1191
|
+
cdef ZZX_c** v
|
|
1192
|
+
cdef long* e
|
|
1193
|
+
cdef long i, n
|
|
1194
|
+
sig_on()
|
|
1195
|
+
ZZX_squarefree_decomposition(&v, &e, &n, &self.x)
|
|
1196
|
+
sig_off()
|
|
1197
|
+
F = []
|
|
1198
|
+
for i from 0 <= i < n:
|
|
1199
|
+
F.append((make_ZZX(v[i]), e[i]))
|
|
1200
|
+
sig_free(v)
|
|
1201
|
+
sig_free(e)
|
|
1202
|
+
return F
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
one_ZZX = ntl_ZZX([1])
|
|
1206
|
+
zero_ZZX = ntl_ZZX()
|