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