passagemath-ntl 10.6.33__cp313-cp313-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-ntl might be problematic. Click here for more details.
- passagemath_ntl-10.6.33.dist-info/METADATA +122 -0
- passagemath_ntl-10.6.33.dist-info/RECORD +163 -0
- passagemath_ntl-10.6.33.dist-info/WHEEL +5 -0
- passagemath_ntl-10.6.33.dist-info/top_level.txt +2 -0
- passagemath_ntl.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_ntl.libs/libgf2x-9e30c3e3.so.3.0.0 +0 -0
- passagemath_ntl.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_ntl.libs/libmpfi-2153e8c2.so.0.0.0 +0 -0
- passagemath_ntl.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
- passagemath_ntl.libs/libntl-26885ca2.so.44.0.1 +0 -0
- passagemath_ntl.libs/libstdc++-5d72f927.so.6.0.33 +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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
- sage/rings/bernmm.pyx +161 -0
- sage/rings/bernoulli_mod_p.cpython-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.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-313-x86_64-linux-musl.so +0 -0
- sage/schemes/hyperelliptic_curves/hypellfrob.pyx +252 -0
|
@@ -0,0 +1,902 @@
|
|
|
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
|
+
ntl_lzz_pX.pyx
|
|
10
|
+
|
|
11
|
+
Wraps NTL's zz_pX type for SAGE
|
|
12
|
+
|
|
13
|
+
AUTHORS:
|
|
14
|
+
- Craig Citro
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
#*****************************************************************************
|
|
18
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
19
|
+
#
|
|
20
|
+
# This program is free software: you can redistribute it and/or modify
|
|
21
|
+
# it under the terms of the GNU General Public License as published by
|
|
22
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
23
|
+
# (at your option) any later version.
|
|
24
|
+
# http://www.gnu.org/licenses/
|
|
25
|
+
#*****************************************************************************
|
|
26
|
+
|
|
27
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
28
|
+
|
|
29
|
+
include 'misc.pxi'
|
|
30
|
+
include 'decl.pxi'
|
|
31
|
+
from sage.libs.gmp.mpz cimport *
|
|
32
|
+
|
|
33
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
34
|
+
from sage.rings.integer import Integer
|
|
35
|
+
from sage.rings.integer_ring import IntegerRing
|
|
36
|
+
from sage.rings.integer cimport Integer
|
|
37
|
+
|
|
38
|
+
from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp, IntegerMod_int, IntegerMod_int64
|
|
39
|
+
|
|
40
|
+
from sage.libs.ntl.ntl_lzz_pContext import ntl_zz_pContext
|
|
41
|
+
from sage.libs.ntl.ntl_lzz_pContext cimport ntl_zz_pContext_class
|
|
42
|
+
|
|
43
|
+
from sage.libs.ntl.ntl_lzz_p import ntl_zz_p
|
|
44
|
+
from sage.libs.ntl.ntl_lzz_p cimport ntl_zz_p
|
|
45
|
+
|
|
46
|
+
ZZ_sage = IntegerRing()
|
|
47
|
+
|
|
48
|
+
##############################################################################
|
|
49
|
+
#
|
|
50
|
+
# zz_pX -- polynomials over the integers modulo p, p small
|
|
51
|
+
#
|
|
52
|
+
##############################################################################
|
|
53
|
+
|
|
54
|
+
cdef class ntl_zz_pX():
|
|
55
|
+
r"""
|
|
56
|
+
The class \class{zz_pX} implements polynomial arithmetic modulo `p`,
|
|
57
|
+
for p smaller than a machine word.
|
|
58
|
+
|
|
59
|
+
Polynomial arithmetic is implemented using the FFT, combined with
|
|
60
|
+
the Chinese Remainder Theorem. A more detailed description of the
|
|
61
|
+
techniques used here can be found in [Shoup, J. Symbolic
|
|
62
|
+
Comp. 20:363-397, 1995].
|
|
63
|
+
|
|
64
|
+
Small degree polynomials are multiplied either with classical
|
|
65
|
+
or Karatsuba algorithms.
|
|
66
|
+
"""
|
|
67
|
+
# See ntl_zz_pX.pxd for definition of data members
|
|
68
|
+
def __init__(self, ls=[], modulus=None):
|
|
69
|
+
"""
|
|
70
|
+
EXAMPLES::
|
|
71
|
+
|
|
72
|
+
sage: f = ntl.zz_pX([1,2,5,-9],20)
|
|
73
|
+
sage: f
|
|
74
|
+
[1, 2, 5, 11]
|
|
75
|
+
sage: g = ntl.zz_pX([0,0,0],20); g
|
|
76
|
+
[]
|
|
77
|
+
sage: g[10]=5
|
|
78
|
+
sage: g
|
|
79
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]
|
|
80
|
+
sage: g[10]
|
|
81
|
+
5
|
|
82
|
+
sage: f = ntl.zz_pX([10^30+1, 10^50+1], 100); f
|
|
83
|
+
[1, 1]
|
|
84
|
+
"""
|
|
85
|
+
if modulus is None:
|
|
86
|
+
raise ValueError("You must specify a modulus.")
|
|
87
|
+
|
|
88
|
+
cdef long n
|
|
89
|
+
cdef Py_ssize_t i
|
|
90
|
+
cdef long temp
|
|
91
|
+
|
|
92
|
+
if isinstance(modulus, Integer):
|
|
93
|
+
p_sage = modulus
|
|
94
|
+
else:
|
|
95
|
+
p_sage = Integer(self.c.p)
|
|
96
|
+
|
|
97
|
+
#self.c.restore_c() ## We did this in __new__
|
|
98
|
+
|
|
99
|
+
n = len(ls)
|
|
100
|
+
if (n == 0):
|
|
101
|
+
## the 0 polynomial is just the empty list;
|
|
102
|
+
## so in this case, we're done.
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
self.x.SetMaxLength(n+1)
|
|
106
|
+
|
|
107
|
+
for i from 0 <= i < n:
|
|
108
|
+
a = ls[i]
|
|
109
|
+
|
|
110
|
+
if isinstance(a, IntegerMod_int):
|
|
111
|
+
if (self.c.p == (<IntegerMod_int>a)._modulus.int32): ## this is slow
|
|
112
|
+
zz_pX_SetCoeff_long(self.x, i, (<IntegerMod_int>a).ivalue)
|
|
113
|
+
else:
|
|
114
|
+
raise ValueError("Mismatched modulus for converting to zz_pX.")
|
|
115
|
+
elif isinstance(a, IntegerMod_int64):
|
|
116
|
+
if (self.c.p == (<IntegerMod_int64>a)._modulus.int64): ## this is slow
|
|
117
|
+
zz_pX_SetCoeff_long(self.x, i, (<IntegerMod_int64>a).ivalue)
|
|
118
|
+
else:
|
|
119
|
+
raise ValueError("Mismatched modulus for converting to zz_pX.")
|
|
120
|
+
elif isinstance(a, IntegerMod_gmp):
|
|
121
|
+
if (p_sage == (<IntegerMod_gmp>a)._modulus.sageInteger): ## this is slow
|
|
122
|
+
zz_pX_SetCoeff_long(self.x, i, mpz_get_si((<IntegerMod_gmp>a).value))
|
|
123
|
+
else:
|
|
124
|
+
raise ValueError("Mismatched modulus for converting to zz_pX.")
|
|
125
|
+
elif isinstance(a, Integer):
|
|
126
|
+
zz_pX_SetCoeff_long(self.x, i, mpz_fdiv_ui((<Integer>a).value, self.c.p))
|
|
127
|
+
elif isinstance(a, int):
|
|
128
|
+
# we're lucky that python int is no larger than long
|
|
129
|
+
temp = a
|
|
130
|
+
zz_pX_SetCoeff_long(self.x, i, temp % self.c.p)
|
|
131
|
+
else:
|
|
132
|
+
a = Integer(a)
|
|
133
|
+
zz_pX_SetCoeff_long(self.x, i, mpz_fdiv_ui((<Integer>a).value, self.c.p))
|
|
134
|
+
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
def __cinit__(self, v=None, modulus=None):
|
|
138
|
+
#################### WARNING ###################
|
|
139
|
+
## Before creating a zz_pX, you must create a ##
|
|
140
|
+
## zz_pContext, and restore it. In Python, ##
|
|
141
|
+
## the error checking in __init__ will prevent##
|
|
142
|
+
## you from constructing a zz_pX ##
|
|
143
|
+
## inappropriately. However, from Cython, you##
|
|
144
|
+
## could do r = ntl_zz_pX.__new__(ntl_zz_pX) without
|
|
145
|
+
## first restoring a zz_pContext, which could ##
|
|
146
|
+
## have unfortunate consequences. See _new ##
|
|
147
|
+
## defined below for an example of the right ##
|
|
148
|
+
## way to short-circuit __init__ (or just call##
|
|
149
|
+
## _new in your own code). ##
|
|
150
|
+
################################################
|
|
151
|
+
if modulus is None:
|
|
152
|
+
return
|
|
153
|
+
if isinstance(modulus, ntl_zz_pContext_class):
|
|
154
|
+
self.c = <ntl_zz_pContext_class>modulus
|
|
155
|
+
elif isinstance(modulus, Integer):
|
|
156
|
+
self.c = <ntl_zz_pContext_class>ntl_zz_pContext(modulus)
|
|
157
|
+
elif isinstance(modulus, int):
|
|
158
|
+
self.c = <ntl_zz_pContext_class>ntl_zz_pContext(modulus)
|
|
159
|
+
else:
|
|
160
|
+
try:
|
|
161
|
+
modulus = int(modulus)
|
|
162
|
+
except Exception:
|
|
163
|
+
raise ValueError("%s is not a valid modulus." % modulus)
|
|
164
|
+
self.c = <ntl_zz_pContext_class>ntl_zz_pContext(modulus)
|
|
165
|
+
|
|
166
|
+
## now that we've determined the modulus, set that modulus.
|
|
167
|
+
self.c.restore_c()
|
|
168
|
+
|
|
169
|
+
def __reduce__(self):
|
|
170
|
+
"""
|
|
171
|
+
TESTS::
|
|
172
|
+
|
|
173
|
+
sage: f = ntl.zz_pX([10,10^30+1], 20)
|
|
174
|
+
sage: f == loads(dumps(f))
|
|
175
|
+
True
|
|
176
|
+
"""
|
|
177
|
+
return make_zz_pX, (self.list(), self.c)
|
|
178
|
+
|
|
179
|
+
def __repr__(self):
|
|
180
|
+
"""
|
|
181
|
+
Return the string representation of ``self``.
|
|
182
|
+
|
|
183
|
+
EXAMPLES::
|
|
184
|
+
|
|
185
|
+
sage: f = ntl.zz_pX([3,5], 17)
|
|
186
|
+
sage: f.__repr__()
|
|
187
|
+
'[3, 5]'
|
|
188
|
+
"""
|
|
189
|
+
return str(self.list())
|
|
190
|
+
|
|
191
|
+
def __getitem__(self, long i):
|
|
192
|
+
"""
|
|
193
|
+
Return the i-th coefficient of f.
|
|
194
|
+
|
|
195
|
+
EXAMPLES::
|
|
196
|
+
|
|
197
|
+
sage: f = ntl.zz_pX(range(7), 71)
|
|
198
|
+
sage: f[3] ## indirect doctest
|
|
199
|
+
3
|
|
200
|
+
|
|
201
|
+
sage: f[-5]
|
|
202
|
+
0
|
|
203
|
+
|
|
204
|
+
sage: f[27]
|
|
205
|
+
0
|
|
206
|
+
"""
|
|
207
|
+
cdef ntl_zz_p y
|
|
208
|
+
y = ntl_zz_p.__new__(ntl_zz_p)
|
|
209
|
+
y.c = self.c
|
|
210
|
+
self.c.restore_c()
|
|
211
|
+
y.x = zz_pX_GetCoeff(self.x, i)
|
|
212
|
+
return y
|
|
213
|
+
|
|
214
|
+
def __setitem__(self, long i, val):
|
|
215
|
+
"""
|
|
216
|
+
Set the i-th coefficient of ``self`` to val. If
|
|
217
|
+
i is out of range, raise an exception.
|
|
218
|
+
|
|
219
|
+
EXAMPLES::
|
|
220
|
+
|
|
221
|
+
sage: f = ntl.zz_pX([], 7)
|
|
222
|
+
sage: f[3] = 2 ; f
|
|
223
|
+
[0, 0, 0, 2]
|
|
224
|
+
sage: f[-1] = 5
|
|
225
|
+
Traceback (most recent call last):
|
|
226
|
+
...
|
|
227
|
+
ValueError: index (=-1) is out of range
|
|
228
|
+
"""
|
|
229
|
+
if (i < 0):
|
|
230
|
+
raise ValueError("index (=%s) is out of range" % i)
|
|
231
|
+
self.c.restore_c()
|
|
232
|
+
zz_pX_SetCoeff_long(self.x, i, val)
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
cdef ntl_zz_pX _new(self):
|
|
236
|
+
"""
|
|
237
|
+
Quick and dirty method for creating a new object with the
|
|
238
|
+
same zz_pContext as ``self``.
|
|
239
|
+
|
|
240
|
+
EXAMPLES::
|
|
241
|
+
|
|
242
|
+
sage: f = ntl.zz_pX([1], 20)
|
|
243
|
+
sage: f.square() ## indirect doctest
|
|
244
|
+
[1]
|
|
245
|
+
"""
|
|
246
|
+
cdef ntl_zz_pX y
|
|
247
|
+
y = ntl_zz_pX.__new__(ntl_zz_pX)
|
|
248
|
+
y.c = self.c
|
|
249
|
+
return y
|
|
250
|
+
|
|
251
|
+
def __add__(ntl_zz_pX self, other):
|
|
252
|
+
"""
|
|
253
|
+
Return ``self + other``.
|
|
254
|
+
|
|
255
|
+
EXAMPLES::
|
|
256
|
+
|
|
257
|
+
sage: ntl.zz_pX(range(5),20) + ntl.zz_pX(range(6),20) ## indirect doctest
|
|
258
|
+
[0, 2, 4, 6, 8, 5]
|
|
259
|
+
sage: ntl.zz_pX(range(5),20) + ntl.zz_pX(range(6),50)
|
|
260
|
+
Traceback (most recent call last):
|
|
261
|
+
...
|
|
262
|
+
ValueError: arithmetic operands must have the same modulus.
|
|
263
|
+
"""
|
|
264
|
+
cdef ntl_zz_pX y
|
|
265
|
+
if not isinstance(other, ntl_zz_pX):
|
|
266
|
+
other = ntl_zz_pX(other, modulus=self.c)
|
|
267
|
+
elif self.c is not (<ntl_zz_pX>other).c:
|
|
268
|
+
raise ValueError("arithmetic operands must have the same modulus.")
|
|
269
|
+
y = self._new()
|
|
270
|
+
self.c.restore_c()
|
|
271
|
+
zz_pX_add(y.x, self.x, (<ntl_zz_pX>other).x)
|
|
272
|
+
return y
|
|
273
|
+
|
|
274
|
+
def __sub__(ntl_zz_pX self, other):
|
|
275
|
+
"""
|
|
276
|
+
Return ``self - other``.
|
|
277
|
+
|
|
278
|
+
EXAMPLES::
|
|
279
|
+
|
|
280
|
+
sage: ntl.zz_pX(range(5),32) - ntl.zz_pX(range(6),32)
|
|
281
|
+
[0, 0, 0, 0, 0, 27]
|
|
282
|
+
sage: ntl.zz_pX(range(5),20) - ntl.zz_pX(range(6),50) ## indirect doctest
|
|
283
|
+
Traceback (most recent call last):
|
|
284
|
+
...
|
|
285
|
+
ValueError: arithmetic operands must have the same modulus.
|
|
286
|
+
"""
|
|
287
|
+
cdef ntl_zz_pX y
|
|
288
|
+
if not isinstance(other, ntl_zz_pX):
|
|
289
|
+
other = ntl_zz_pX(other, modulus=self.c)
|
|
290
|
+
elif self.c is not (<ntl_zz_pX>other).c:
|
|
291
|
+
raise ValueError("arithmetic operands must have the same modulus.")
|
|
292
|
+
self.c.restore_c()
|
|
293
|
+
y = self._new()
|
|
294
|
+
zz_pX_sub(y.x, self.x, (<ntl_zz_pX>other).x)
|
|
295
|
+
return y
|
|
296
|
+
|
|
297
|
+
def __mul__(ntl_zz_pX self, other):
|
|
298
|
+
"""
|
|
299
|
+
EXAMPLES::
|
|
300
|
+
|
|
301
|
+
sage: ntl.zz_pX(range(5),20) * ntl.zz_pX(range(6),20) ## indirect doctest
|
|
302
|
+
[0, 0, 1, 4, 10, 0, 10, 14, 11]
|
|
303
|
+
sage: ntl.zz_pX(range(5),20) * ntl.zz_pX(range(6),50)
|
|
304
|
+
Traceback (most recent call last):
|
|
305
|
+
...
|
|
306
|
+
ValueError: arithmetic operands must have the same modulus.
|
|
307
|
+
"""
|
|
308
|
+
cdef ntl_zz_pX y
|
|
309
|
+
if not isinstance(other, ntl_zz_pX):
|
|
310
|
+
other = ntl_zz_pX(other, modulus=self.c)
|
|
311
|
+
elif self.c is not (<ntl_zz_pX>other).c:
|
|
312
|
+
raise ValueError("arithmetic operands must have the same modulus.")
|
|
313
|
+
self.c.restore_c()
|
|
314
|
+
y = self._new()
|
|
315
|
+
sig_on()
|
|
316
|
+
zz_pX_mul(y.x, self.x, (<ntl_zz_pX>other).x)
|
|
317
|
+
sig_off()
|
|
318
|
+
return y
|
|
319
|
+
|
|
320
|
+
def __truediv__(ntl_zz_pX self, other):
|
|
321
|
+
"""
|
|
322
|
+
Compute quotient ``self / other``, if the quotient is a polynomial.
|
|
323
|
+
Otherwise an Exception is raised.
|
|
324
|
+
|
|
325
|
+
EXAMPLES::
|
|
326
|
+
|
|
327
|
+
sage: f = ntl.zz_pX([1,2,3],17) * ntl.zz_pX([4,5],17)**2
|
|
328
|
+
sage: g = ntl.zz_pX([4,5],17)
|
|
329
|
+
sage: f/g ## indirect doctest
|
|
330
|
+
[4, 13, 5, 15]
|
|
331
|
+
sage: ntl.zz_pX([1,2,3],17) * ntl.zz_pX([4,5],17)
|
|
332
|
+
[4, 13, 5, 15]
|
|
333
|
+
|
|
334
|
+
sage: f = ntl.zz_pX(range(10),17); g = ntl.zz_pX([-1,0,1],17)
|
|
335
|
+
sage: f/g
|
|
336
|
+
Traceback (most recent call last):
|
|
337
|
+
...
|
|
338
|
+
ArithmeticError: self (=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) is not divisible by other (=[16, 0, 1])
|
|
339
|
+
sage: ntl.zz_pX(range(5),20) / ntl.zz_pX(range(6),50)
|
|
340
|
+
Traceback (most recent call last):
|
|
341
|
+
...
|
|
342
|
+
ValueError: arithmetic operands must have the same modulus.
|
|
343
|
+
"""
|
|
344
|
+
cdef long divisible
|
|
345
|
+
cdef ntl_zz_pX q
|
|
346
|
+
if not isinstance(other, ntl_zz_pX):
|
|
347
|
+
other = ntl_zz_pX(other, modulus=self.c)
|
|
348
|
+
elif self.c is not (<ntl_zz_pX>other).c:
|
|
349
|
+
raise ValueError("arithmetic operands must have the same modulus.")
|
|
350
|
+
self.c.restore_c()
|
|
351
|
+
q = self._new()
|
|
352
|
+
sig_on()
|
|
353
|
+
divisible = zz_pX_divide(q.x, self.x, (<ntl_zz_pX>other).x)
|
|
354
|
+
sig_off()
|
|
355
|
+
if not divisible:
|
|
356
|
+
raise ArithmeticError("self (=%s) is not divisible by other (=%s)" % (self, other))
|
|
357
|
+
return q
|
|
358
|
+
|
|
359
|
+
def __mod__(ntl_zz_pX self, other):
|
|
360
|
+
"""
|
|
361
|
+
Given polynomials a, b in ZZ[X], there exist polynomials q, r
|
|
362
|
+
in QQ[X] such that a = b*q + r, deg(r) < deg(b). This
|
|
363
|
+
function returns q if q lies in ZZ[X], and otherwise raises an
|
|
364
|
+
Exception.
|
|
365
|
+
|
|
366
|
+
EXAMPLES::
|
|
367
|
+
|
|
368
|
+
sage: f = ntl.zz_pX([2,4,6],17); g = ntl.zz_pX([2],17)
|
|
369
|
+
sage: f % g ## indirect doctest
|
|
370
|
+
[]
|
|
371
|
+
|
|
372
|
+
sage: f = ntl.zz_pX(range(10),17); g = ntl.zz_pX([-1,0,1],17)
|
|
373
|
+
sage: f % g
|
|
374
|
+
[3, 8]
|
|
375
|
+
"""
|
|
376
|
+
cdef ntl_zz_pX y
|
|
377
|
+
if not isinstance(other, ntl_zz_pX):
|
|
378
|
+
other = ntl_zz_pX(other, modulus=self.c)
|
|
379
|
+
elif self.c is not (<ntl_zz_pX>other).c:
|
|
380
|
+
raise ValueError("arithmetic operands must have the same modulus.")
|
|
381
|
+
self.c.restore_c()
|
|
382
|
+
y = self._new()
|
|
383
|
+
sig_on()
|
|
384
|
+
zz_pX_mod(y.x, self.x, (<ntl_zz_pX>other).x)
|
|
385
|
+
sig_off()
|
|
386
|
+
return y
|
|
387
|
+
|
|
388
|
+
def __pow__(ntl_zz_pX self, long n, ignored):
|
|
389
|
+
"""
|
|
390
|
+
Return the `n`-th nonnegative power of ``self``.
|
|
391
|
+
|
|
392
|
+
EXAMPLES::
|
|
393
|
+
|
|
394
|
+
sage: g = ntl.zz_pX([-1,0,1],20)
|
|
395
|
+
sage: g**10 ## indirect doctest
|
|
396
|
+
[1, 0, 10, 0, 5, 0, 0, 0, 10, 0, 8, 0, 10, 0, 0, 0, 5, 0, 10, 0, 1]
|
|
397
|
+
"""
|
|
398
|
+
if n < 0:
|
|
399
|
+
raise ValueError("Only positive exponents allowed.")
|
|
400
|
+
cdef ntl_zz_pX y = self._new()
|
|
401
|
+
self.c.restore_c()
|
|
402
|
+
sig_on()
|
|
403
|
+
zz_pX_power(y.x, self.x, n)
|
|
404
|
+
sig_off()
|
|
405
|
+
return y
|
|
406
|
+
|
|
407
|
+
def quo_rem(ntl_zz_pX self, ntl_zz_pX right):
|
|
408
|
+
"""
|
|
409
|
+
Return the quotient and remainder when ``self`` is divided by ``right``.
|
|
410
|
+
|
|
411
|
+
Specifically, this returns `r`, `q` such that ``self = q * right + r``.
|
|
412
|
+
|
|
413
|
+
EXAMPLES::
|
|
414
|
+
|
|
415
|
+
sage: f = ntl.zz_pX(range(7), 19)
|
|
416
|
+
sage: g = ntl.zz_pX([2,4,6], 19)
|
|
417
|
+
sage: f // g
|
|
418
|
+
[1, 1, 15, 16, 1]
|
|
419
|
+
sage: f % g
|
|
420
|
+
[17, 14]
|
|
421
|
+
sage: f.quo_rem(g)
|
|
422
|
+
([1, 1, 15, 16, 1], [17, 14])
|
|
423
|
+
sage: (f // g) * g + f % g
|
|
424
|
+
[0, 1, 2, 3, 4, 5, 6]
|
|
425
|
+
"""
|
|
426
|
+
cdef ntl_zz_pX q = self._new()
|
|
427
|
+
cdef ntl_zz_pX r = self._new()
|
|
428
|
+
self.c.restore_c()
|
|
429
|
+
sig_on()
|
|
430
|
+
zz_pX_divrem(q.x, r.x, self.x, right.x)
|
|
431
|
+
sig_off()
|
|
432
|
+
return q, r
|
|
433
|
+
|
|
434
|
+
def __floordiv__(ntl_zz_pX self, ntl_zz_pX right):
|
|
435
|
+
"""
|
|
436
|
+
Return the whole part of ``self / right``.
|
|
437
|
+
|
|
438
|
+
EXAMPLES::
|
|
439
|
+
|
|
440
|
+
sage: f = ntl.zz_pX(range(10), 19); g = ntl.zz_pX([1]*5, 19)
|
|
441
|
+
sage: f // g ## indirect doctest
|
|
442
|
+
[8, 18, 18, 18, 18, 9]
|
|
443
|
+
"""
|
|
444
|
+
cdef ntl_zz_pX q = self._new()
|
|
445
|
+
self.c.restore_c()
|
|
446
|
+
sig_on()
|
|
447
|
+
zz_pX_div(q.x, self.x, right.x)
|
|
448
|
+
sig_off()
|
|
449
|
+
return q
|
|
450
|
+
|
|
451
|
+
def __lshift__(ntl_zz_pX self, long n):
|
|
452
|
+
"""
|
|
453
|
+
Shift this polynomial to the left, which is multiplication by `x^n`.
|
|
454
|
+
|
|
455
|
+
EXAMPLES::
|
|
456
|
+
|
|
457
|
+
sage: f = ntl.zz_pX([2,4,6], 17)
|
|
458
|
+
sage: f << 2 ## indirect doctest
|
|
459
|
+
[0, 0, 2, 4, 6]
|
|
460
|
+
"""
|
|
461
|
+
cdef ntl_zz_pX r = self._new()
|
|
462
|
+
self.c.restore_c()
|
|
463
|
+
zz_pX_LeftShift(r.x, self.x, n)
|
|
464
|
+
return r
|
|
465
|
+
|
|
466
|
+
def __rshift__(ntl_zz_pX self, long n):
|
|
467
|
+
"""
|
|
468
|
+
Shift this polynomial to the right, which is division by `x^n` (and truncation).
|
|
469
|
+
|
|
470
|
+
EXAMPLES::
|
|
471
|
+
|
|
472
|
+
sage: f = ntl.zz_pX([1,2,3], 17)
|
|
473
|
+
sage: f >> 2 ## indirect doctest
|
|
474
|
+
[3]
|
|
475
|
+
"""
|
|
476
|
+
cdef ntl_zz_pX r = self._new()
|
|
477
|
+
self.c.restore_c()
|
|
478
|
+
zz_pX_RightShift(r.x, self.x, n)
|
|
479
|
+
return r
|
|
480
|
+
|
|
481
|
+
def diff(self):
|
|
482
|
+
"""
|
|
483
|
+
The formal derivative of ``self``.
|
|
484
|
+
|
|
485
|
+
EXAMPLES::
|
|
486
|
+
|
|
487
|
+
sage: f = ntl.zz_pX(range(10), 17)
|
|
488
|
+
sage: f.diff()
|
|
489
|
+
[1, 4, 9, 16, 8, 2, 15, 13, 13]
|
|
490
|
+
"""
|
|
491
|
+
cdef ntl_zz_pX r = self._new()
|
|
492
|
+
self.c.restore_c()
|
|
493
|
+
zz_pX_diff(r.x, self.x)
|
|
494
|
+
return r
|
|
495
|
+
|
|
496
|
+
def reverse(self):
|
|
497
|
+
"""
|
|
498
|
+
Return ``self`` with coefficients reversed, i.e. ``x^n self(x^{-n})``.
|
|
499
|
+
|
|
500
|
+
EXAMPLES::
|
|
501
|
+
|
|
502
|
+
sage: f = ntl.zz_pX([2,4,6], 17)
|
|
503
|
+
sage: f.reverse()
|
|
504
|
+
[6, 4, 2]
|
|
505
|
+
"""
|
|
506
|
+
cdef ntl_zz_pX r = self._new()
|
|
507
|
+
self.c.restore_c()
|
|
508
|
+
zz_pX_reverse(r.x, self.x)
|
|
509
|
+
return r
|
|
510
|
+
|
|
511
|
+
def __neg__(self):
|
|
512
|
+
"""
|
|
513
|
+
Return the negative of ``self``.
|
|
514
|
+
|
|
515
|
+
EXAMPLES::
|
|
516
|
+
|
|
517
|
+
sage: f = ntl.zz_pX([2,0,0,1],20)
|
|
518
|
+
sage: -f
|
|
519
|
+
[18, 0, 0, 19]
|
|
520
|
+
"""
|
|
521
|
+
cdef ntl_zz_pX y
|
|
522
|
+
y = self._new()
|
|
523
|
+
self.c.restore_c()
|
|
524
|
+
sig_on()
|
|
525
|
+
zz_pX_negate(y.x, self.x)
|
|
526
|
+
sig_off()
|
|
527
|
+
return y
|
|
528
|
+
|
|
529
|
+
def __richcmp__(ntl_zz_pX self, other, int op):
|
|
530
|
+
"""
|
|
531
|
+
Compare ``self`` to ``other``.
|
|
532
|
+
|
|
533
|
+
EXAMPLES::
|
|
534
|
+
|
|
535
|
+
sage: f = ntl.zz_pX([1,2,3],20)
|
|
536
|
+
sage: g = ntl.zz_pX([1,2,3,0],20)
|
|
537
|
+
sage: f == g
|
|
538
|
+
True
|
|
539
|
+
sage: g = ntl.zz_pX([0,1,2,3],20)
|
|
540
|
+
sage: f == g
|
|
541
|
+
False
|
|
542
|
+
sage: f != [0]
|
|
543
|
+
True
|
|
544
|
+
"""
|
|
545
|
+
self.c.restore_c()
|
|
546
|
+
|
|
547
|
+
if op != Py_EQ and op != Py_NE:
|
|
548
|
+
raise TypeError("polynomials are not ordered")
|
|
549
|
+
|
|
550
|
+
cdef ntl_zz_pX b
|
|
551
|
+
try:
|
|
552
|
+
b = <ntl_zz_pX?>other
|
|
553
|
+
except TypeError:
|
|
554
|
+
b = ntl_zz_pX(other, self.c)
|
|
555
|
+
|
|
556
|
+
return (op == Py_EQ) == (self.x == b.x)
|
|
557
|
+
|
|
558
|
+
def list(self):
|
|
559
|
+
"""
|
|
560
|
+
Return list of entries as a list of python ints.
|
|
561
|
+
|
|
562
|
+
EXAMPLES::
|
|
563
|
+
|
|
564
|
+
sage: f = ntl.zz_pX([23, 5,0,1], 10)
|
|
565
|
+
sage: f.list()
|
|
566
|
+
[3, 5, 0, 1]
|
|
567
|
+
sage: type(f.list()[0])
|
|
568
|
+
<... 'int'>
|
|
569
|
+
"""
|
|
570
|
+
cdef long i
|
|
571
|
+
self.c.restore_c()
|
|
572
|
+
return [ zz_p_rep(zz_pX_GetCoeff(self.x, i)) for i from 0 <= i <= zz_pX_deg(self.x) ]
|
|
573
|
+
|
|
574
|
+
def degree(self):
|
|
575
|
+
"""
|
|
576
|
+
Return the degree of this polynomial. The degree of the 0
|
|
577
|
+
polynomial is -1.
|
|
578
|
+
|
|
579
|
+
EXAMPLES::
|
|
580
|
+
|
|
581
|
+
sage: f = ntl.zz_pX([5,0,1],50)
|
|
582
|
+
sage: f.degree()
|
|
583
|
+
2
|
|
584
|
+
sage: f = ntl.zz_pX(range(100),50)
|
|
585
|
+
sage: f.degree()
|
|
586
|
+
99
|
|
587
|
+
sage: f = ntl.zz_pX([],10)
|
|
588
|
+
sage: f.degree()
|
|
589
|
+
-1
|
|
590
|
+
sage: f = ntl.zz_pX([1],77)
|
|
591
|
+
sage: f.degree()
|
|
592
|
+
0
|
|
593
|
+
"""
|
|
594
|
+
self.c.restore_c()
|
|
595
|
+
return zz_pX_deg(self.x)
|
|
596
|
+
|
|
597
|
+
def leading_coefficient(self):
|
|
598
|
+
"""
|
|
599
|
+
Return the leading coefficient of this polynomial.
|
|
600
|
+
|
|
601
|
+
EXAMPLES::
|
|
602
|
+
|
|
603
|
+
sage: f = ntl.zz_pX([3,6,9],19)
|
|
604
|
+
sage: f.leading_coefficient()
|
|
605
|
+
9
|
|
606
|
+
sage: f = ntl.zz_pX([],21)
|
|
607
|
+
sage: f.leading_coefficient()
|
|
608
|
+
0
|
|
609
|
+
"""
|
|
610
|
+
self.c.restore_c()
|
|
611
|
+
return zz_p_rep(zz_pX_LeadCoeff(self.x))
|
|
612
|
+
|
|
613
|
+
def constant_term(self):
|
|
614
|
+
"""
|
|
615
|
+
Return the constant coefficient of this polynomial.
|
|
616
|
+
|
|
617
|
+
EXAMPLES::
|
|
618
|
+
|
|
619
|
+
sage: f = ntl.zz_pX([3,6,9],127)
|
|
620
|
+
sage: f.constant_term()
|
|
621
|
+
3
|
|
622
|
+
sage: f = ntl.zz_pX([], 12223)
|
|
623
|
+
sage: f.constant_term()
|
|
624
|
+
0
|
|
625
|
+
"""
|
|
626
|
+
self.c.restore_c()
|
|
627
|
+
return zz_p_rep(zz_pX_ConstTerm(self.x))
|
|
628
|
+
|
|
629
|
+
def square(self):
|
|
630
|
+
"""
|
|
631
|
+
Return f*f.
|
|
632
|
+
|
|
633
|
+
EXAMPLES::
|
|
634
|
+
|
|
635
|
+
sage: f = ntl.zz_pX([-1,0,1],17)
|
|
636
|
+
sage: f*f
|
|
637
|
+
[1, 0, 15, 0, 1]
|
|
638
|
+
"""
|
|
639
|
+
cdef ntl_zz_pX y = self._new()
|
|
640
|
+
self.c.restore_c()
|
|
641
|
+
sig_on()
|
|
642
|
+
zz_pX_sqr(y.x, self.x)
|
|
643
|
+
sig_off()
|
|
644
|
+
return y
|
|
645
|
+
|
|
646
|
+
def truncate(self, long m):
|
|
647
|
+
"""
|
|
648
|
+
Return the truncation of this polynomial obtained by
|
|
649
|
+
removing all terms of degree >= m.
|
|
650
|
+
|
|
651
|
+
EXAMPLES::
|
|
652
|
+
|
|
653
|
+
sage: f = ntl.zz_pX([1,2,3,4,5],70)
|
|
654
|
+
sage: f.truncate(3)
|
|
655
|
+
[1, 2, 3]
|
|
656
|
+
sage: f.truncate(8)
|
|
657
|
+
[1, 2, 3, 4, 5]
|
|
658
|
+
sage: f.truncate(1)
|
|
659
|
+
[1]
|
|
660
|
+
sage: f.truncate(0)
|
|
661
|
+
[]
|
|
662
|
+
sage: f.truncate(-1)
|
|
663
|
+
[]
|
|
664
|
+
sage: f.truncate(-5)
|
|
665
|
+
[]
|
|
666
|
+
"""
|
|
667
|
+
cdef ntl_zz_pX y = self._new()
|
|
668
|
+
self.c.restore_c()
|
|
669
|
+
if m <= 0:
|
|
670
|
+
y.x = zz_pX_zero()
|
|
671
|
+
else:
|
|
672
|
+
sig_on()
|
|
673
|
+
zz_pX_trunc(y.x, self.x, m)
|
|
674
|
+
sig_off()
|
|
675
|
+
return y
|
|
676
|
+
|
|
677
|
+
def multiply_and_truncate(self, ntl_zz_pX other, long m):
|
|
678
|
+
"""
|
|
679
|
+
Return self*other but with terms of degree >= m removed.
|
|
680
|
+
|
|
681
|
+
EXAMPLES::
|
|
682
|
+
|
|
683
|
+
sage: f = ntl.zz_pX([1,2,3,4,5],20)
|
|
684
|
+
sage: g = ntl.zz_pX([10],20)
|
|
685
|
+
sage: f.multiply_and_truncate(g, 2)
|
|
686
|
+
[10]
|
|
687
|
+
sage: g.multiply_and_truncate(f, 2)
|
|
688
|
+
[10]
|
|
689
|
+
"""
|
|
690
|
+
cdef ntl_zz_pX y = self._new()
|
|
691
|
+
self.c.restore_c()
|
|
692
|
+
if m <= 0:
|
|
693
|
+
y.x = zz_pX_zero()
|
|
694
|
+
else:
|
|
695
|
+
sig_on()
|
|
696
|
+
zz_pX_MulTrunc(y.x, self.x, other.x, m)
|
|
697
|
+
sig_off()
|
|
698
|
+
return y
|
|
699
|
+
|
|
700
|
+
def square_and_truncate(self, long m):
|
|
701
|
+
"""
|
|
702
|
+
Return self*self but with terms of degree >= m removed.
|
|
703
|
+
|
|
704
|
+
EXAMPLES::
|
|
705
|
+
|
|
706
|
+
sage: f = ntl.zz_pX([1,2,3,4,5],20)
|
|
707
|
+
sage: f.square_and_truncate(4)
|
|
708
|
+
[1, 4, 10]
|
|
709
|
+
sage: (f*f).truncate(4)
|
|
710
|
+
[1, 4, 10]
|
|
711
|
+
"""
|
|
712
|
+
cdef ntl_zz_pX y = self._new()
|
|
713
|
+
self.c.restore_c()
|
|
714
|
+
if m <= 0:
|
|
715
|
+
y.x = zz_pX_zero()
|
|
716
|
+
else:
|
|
717
|
+
sig_on()
|
|
718
|
+
zz_pX_SqrTrunc(y.x, self.x, m)
|
|
719
|
+
sig_off()
|
|
720
|
+
return y
|
|
721
|
+
|
|
722
|
+
def invert_and_truncate(self, long m):
|
|
723
|
+
"""
|
|
724
|
+
Compute and return the inverse of ``self`` modulo `x^m`.
|
|
725
|
+
The constant term of ``self`` must be 1 or -1.
|
|
726
|
+
|
|
727
|
+
EXAMPLES::
|
|
728
|
+
|
|
729
|
+
sage: f = ntl.zz_pX([1,2,3,4,5,6,7],20)
|
|
730
|
+
sage: f.invert_and_truncate(20)
|
|
731
|
+
[1, 18, 1, 0, 0, 0, 0, 8, 17, 2, 13, 0, 0, 0, 4, 0, 17, 10, 9]
|
|
732
|
+
sage: g = f.invert_and_truncate(20)
|
|
733
|
+
sage: g * f
|
|
734
|
+
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 4, 4, 3]
|
|
735
|
+
"""
|
|
736
|
+
if m < 0:
|
|
737
|
+
raise ArithmeticError("m (=%s) must be positive" % m)
|
|
738
|
+
n = self.constant_term()
|
|
739
|
+
if n != 1 and n != -1:
|
|
740
|
+
raise ArithmeticError("The constant term of self must be 1 or -1.")
|
|
741
|
+
|
|
742
|
+
cdef ntl_zz_pX y = self._new()
|
|
743
|
+
|
|
744
|
+
self.c.restore_c()
|
|
745
|
+
if m <= 0:
|
|
746
|
+
y.x = zz_pX_zero()
|
|
747
|
+
else:
|
|
748
|
+
sig_on()
|
|
749
|
+
zz_pX_InvTrunc(y.x, self.x, m)
|
|
750
|
+
sig_off()
|
|
751
|
+
return y
|
|
752
|
+
|
|
753
|
+
def is_zero(self):
|
|
754
|
+
"""
|
|
755
|
+
Return ``True`` exactly if this polynomial is 0.
|
|
756
|
+
|
|
757
|
+
EXAMPLES::
|
|
758
|
+
|
|
759
|
+
sage: f = ntl.zz_pX([0,0,0,20],5)
|
|
760
|
+
sage: f.is_zero()
|
|
761
|
+
True
|
|
762
|
+
sage: f = ntl.zz_pX([0,0,1],30)
|
|
763
|
+
sage: f
|
|
764
|
+
[0, 0, 1]
|
|
765
|
+
sage: f.is_zero()
|
|
766
|
+
False
|
|
767
|
+
"""
|
|
768
|
+
self.c.restore_c()
|
|
769
|
+
return zz_pX_IsZero(self.x)
|
|
770
|
+
|
|
771
|
+
def is_one(self):
|
|
772
|
+
"""
|
|
773
|
+
Return ``True`` exactly if this polynomial is 1.
|
|
774
|
+
|
|
775
|
+
EXAMPLES::
|
|
776
|
+
|
|
777
|
+
sage: f = ntl.zz_pX([1,1],101)
|
|
778
|
+
sage: f.is_one()
|
|
779
|
+
False
|
|
780
|
+
sage: f = ntl.zz_pX([1],2)
|
|
781
|
+
sage: f.is_one()
|
|
782
|
+
True
|
|
783
|
+
"""
|
|
784
|
+
self.c.restore_c()
|
|
785
|
+
return zz_pX_IsOne(self.x)
|
|
786
|
+
|
|
787
|
+
def is_monic(self):
|
|
788
|
+
"""
|
|
789
|
+
Return ``True`` exactly if this polynomial is monic.
|
|
790
|
+
|
|
791
|
+
EXAMPLES::
|
|
792
|
+
|
|
793
|
+
sage: f = ntl.zz_pX([2,0,0,1],17)
|
|
794
|
+
sage: f.is_monic()
|
|
795
|
+
True
|
|
796
|
+
sage: g = f.reverse()
|
|
797
|
+
sage: g.is_monic()
|
|
798
|
+
False
|
|
799
|
+
sage: g
|
|
800
|
+
[1, 0, 0, 2]
|
|
801
|
+
sage: f = ntl.zz_pX([1,2,0,3,0,2],717)
|
|
802
|
+
sage: f.is_monic()
|
|
803
|
+
False
|
|
804
|
+
"""
|
|
805
|
+
self.c.restore_c()
|
|
806
|
+
if zz_pX_IsZero(self.x):
|
|
807
|
+
return False
|
|
808
|
+
return zz_p_rep(zz_pX_LeadCoeff(self.x)) == 1
|
|
809
|
+
|
|
810
|
+
def set_x(self):
|
|
811
|
+
"""
|
|
812
|
+
Set this polynomial to the monomial "x".
|
|
813
|
+
|
|
814
|
+
EXAMPLES::
|
|
815
|
+
|
|
816
|
+
sage: f = ntl.zz_pX([],177)
|
|
817
|
+
sage: f.set_x()
|
|
818
|
+
sage: f
|
|
819
|
+
[0, 1]
|
|
820
|
+
sage: g = ntl.zz_pX([0,1],177)
|
|
821
|
+
sage: f == g
|
|
822
|
+
True
|
|
823
|
+
|
|
824
|
+
Though f and g are equal, they are not the same objects in memory:
|
|
825
|
+
sage: f is g
|
|
826
|
+
False
|
|
827
|
+
"""
|
|
828
|
+
self.c.restore_c()
|
|
829
|
+
zz_pX_SetX(self.x)
|
|
830
|
+
|
|
831
|
+
def is_x(self):
|
|
832
|
+
"""
|
|
833
|
+
``True`` if this is the polynomial "x".
|
|
834
|
+
|
|
835
|
+
EXAMPLES::
|
|
836
|
+
|
|
837
|
+
sage: f = ntl.zz_pX([],100)
|
|
838
|
+
sage: f.set_x()
|
|
839
|
+
sage: f.is_x()
|
|
840
|
+
True
|
|
841
|
+
sage: f = ntl.zz_pX([0,1],383)
|
|
842
|
+
sage: f.is_x()
|
|
843
|
+
True
|
|
844
|
+
sage: f = ntl.zz_pX([1],38)
|
|
845
|
+
sage: f.is_x()
|
|
846
|
+
False
|
|
847
|
+
"""
|
|
848
|
+
self.c.restore_c()
|
|
849
|
+
return zz_pX_IsX(self.x)
|
|
850
|
+
|
|
851
|
+
def clear(self):
|
|
852
|
+
"""
|
|
853
|
+
Reset this polynomial to 0. Changes this polynomial in place.
|
|
854
|
+
|
|
855
|
+
EXAMPLES::
|
|
856
|
+
|
|
857
|
+
sage: f = ntl.zz_pX([1,2,3],17)
|
|
858
|
+
sage: f
|
|
859
|
+
[1, 2, 3]
|
|
860
|
+
sage: f.clear()
|
|
861
|
+
sage: f
|
|
862
|
+
[]
|
|
863
|
+
"""
|
|
864
|
+
self.c.restore_c()
|
|
865
|
+
zz_pX_clear(self.x)
|
|
866
|
+
|
|
867
|
+
def preallocate_space(self, long n):
|
|
868
|
+
"""
|
|
869
|
+
Pre-allocate spaces for n coefficients. The polynomial that f
|
|
870
|
+
represents is unchanged. This is useful if you know you'll be
|
|
871
|
+
setting coefficients up to n, so memory isn't re-allocated as
|
|
872
|
+
the polynomial grows. (You might save a millisecond with this
|
|
873
|
+
function.)
|
|
874
|
+
|
|
875
|
+
EXAMPLES::
|
|
876
|
+
|
|
877
|
+
sage: f = ntl.zz_pX([1,2,3],17)
|
|
878
|
+
sage: f.preallocate_space(20)
|
|
879
|
+
sage: f
|
|
880
|
+
[1, 2, 3]
|
|
881
|
+
sage: f[10]=5 # no new memory is allocated
|
|
882
|
+
sage: f
|
|
883
|
+
[1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 5]
|
|
884
|
+
"""
|
|
885
|
+
self.c.restore_c()
|
|
886
|
+
sig_on()
|
|
887
|
+
self.x.SetMaxLength(n)
|
|
888
|
+
sig_off()
|
|
889
|
+
return
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
def make_zz_pX(L, context):
|
|
893
|
+
"""
|
|
894
|
+
For unpickling.
|
|
895
|
+
|
|
896
|
+
TESTS::
|
|
897
|
+
|
|
898
|
+
sage: f = ntl.zz_pX(range(16), 12)
|
|
899
|
+
sage: loads(dumps(f)) == f
|
|
900
|
+
True
|
|
901
|
+
"""
|
|
902
|
+
return ntl_zz_pX(L, context)
|