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,1128 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-ntl
|
|
2
|
+
# distutils: libraries = NTL_LIBRARIES gmp
|
|
3
|
+
# distutils: extra_compile_args = NTL_CFLAGS
|
|
4
|
+
# distutils: include_dirs = NTL_INCDIR
|
|
5
|
+
# distutils: library_dirs = NTL_LIBDIR
|
|
6
|
+
# distutils: extra_link_args = NTL_LIBEXTRA
|
|
7
|
+
# distutils: language = c++
|
|
8
|
+
r"""
|
|
9
|
+
Dense univariate polynomials over `\ZZ`, implemented using NTL.
|
|
10
|
+
|
|
11
|
+
AUTHORS:
|
|
12
|
+
|
|
13
|
+
- David Harvey: split off from polynomial_element_generic.py (2007-09)
|
|
14
|
+
- David Harvey: rewrote to talk to NTL directly, instead of via ntl.pyx
|
|
15
|
+
(2007-09); a lot of this was based on Joel Mohler's recent rewrite of the NTL
|
|
16
|
+
wrapper
|
|
17
|
+
|
|
18
|
+
Sage includes two implementations of dense univariate polynomials over `\ZZ`;
|
|
19
|
+
this file contains the implementation based on NTL, but there is also an
|
|
20
|
+
implementation based on FLINT in
|
|
21
|
+
:mod:`sage.rings.polynomial.polynomial_integer_dense_flint`.
|
|
22
|
+
|
|
23
|
+
The FLINT implementation is preferred (FLINT's arithmetic operations are
|
|
24
|
+
generally faster), so it is the default; to use the NTL implementation, you can
|
|
25
|
+
do::
|
|
26
|
+
|
|
27
|
+
sage: K.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
28
|
+
sage: K
|
|
29
|
+
Univariate Polynomial Ring in x over Integer Ring (using NTL)
|
|
30
|
+
"""
|
|
31
|
+
#*****************************************************************************
|
|
32
|
+
# Copyright (C) 2007 William Stein <wstein@gmail.com>
|
|
33
|
+
#
|
|
34
|
+
# This program is free software: you can redistribute it and/or modify
|
|
35
|
+
# it under the terms of the GNU General Public License as published by
|
|
36
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
37
|
+
# (at your option) any later version.
|
|
38
|
+
# https://www.gnu.org/licenses/
|
|
39
|
+
#*****************************************************************************
|
|
40
|
+
|
|
41
|
+
from cysignals.memory cimport sig_free
|
|
42
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
43
|
+
from sage.ext.cplusplus cimport ccrepr
|
|
44
|
+
|
|
45
|
+
include "sage/libs/ntl/decl.pxi"
|
|
46
|
+
|
|
47
|
+
from sage.rings.polynomial.polynomial_element cimport Polynomial
|
|
48
|
+
from sage.structure.element cimport Element
|
|
49
|
+
|
|
50
|
+
from sage.rings.integer_ring import IntegerRing
|
|
51
|
+
ZZ_sage = IntegerRing()
|
|
52
|
+
|
|
53
|
+
from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX
|
|
54
|
+
|
|
55
|
+
from sage.rings.integer_ring import ZZ
|
|
56
|
+
from sage.rings.rational_field import QQ
|
|
57
|
+
from sage.rings.integer import Integer
|
|
58
|
+
from sage.rings.integer cimport Integer
|
|
59
|
+
from sage.rings.real_mpfr cimport RealNumber
|
|
60
|
+
from sage.rings.real_mpfi cimport RealIntervalFieldElement
|
|
61
|
+
|
|
62
|
+
from sage.structure.factorization import Factorization
|
|
63
|
+
from sage.structure.element import coerce_binop
|
|
64
|
+
|
|
65
|
+
from sage.rings.fraction_field_element import FractionFieldElement
|
|
66
|
+
from sage.arith.functions import lcm
|
|
67
|
+
|
|
68
|
+
from sage.libs.ntl.ZZX cimport *
|
|
69
|
+
|
|
70
|
+
from sage.rings.polynomial.evaluation_ntl cimport ZZX_evaluation_mpfr, ZZX_evaluation_mpfi
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
from sage.libs.pari import pari
|
|
74
|
+
from cypari2.gen import Gen as pari_gen
|
|
75
|
+
except ImportError:
|
|
76
|
+
pari_gen = ()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
cdef class Polynomial_integer_dense_ntl(Polynomial):
|
|
80
|
+
r"""
|
|
81
|
+
A dense polynomial over the integers, implemented via NTL.
|
|
82
|
+
"""
|
|
83
|
+
cdef Polynomial_integer_dense_ntl _new(self):
|
|
84
|
+
r"""
|
|
85
|
+
Quickly create a new initialized ``Polynomial_integer_dense_ntl``
|
|
86
|
+
with the correct parent and ``_is_gen == 0``.
|
|
87
|
+
"""
|
|
88
|
+
cdef Polynomial_integer_dense_ntl x = Polynomial_integer_dense_ntl.__new__(Polynomial_integer_dense_ntl)
|
|
89
|
+
x._parent = self._parent
|
|
90
|
+
x._is_gen = 0
|
|
91
|
+
return x
|
|
92
|
+
|
|
93
|
+
def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
|
|
94
|
+
r"""
|
|
95
|
+
EXAMPLES::
|
|
96
|
+
|
|
97
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
98
|
+
sage: x
|
|
99
|
+
x
|
|
100
|
+
|
|
101
|
+
Construct from list and tuple::
|
|
102
|
+
|
|
103
|
+
sage: R([])
|
|
104
|
+
0
|
|
105
|
+
sage: R([1, -2, 3])
|
|
106
|
+
3*x^2 - 2*x + 1
|
|
107
|
+
sage: R(())
|
|
108
|
+
0
|
|
109
|
+
sage: R((1, -2, 3))
|
|
110
|
+
3*x^2 - 2*x + 1
|
|
111
|
+
|
|
112
|
+
Coercions from other rings are attempted automatically::
|
|
113
|
+
|
|
114
|
+
sage: R([1, -6/3, 3])
|
|
115
|
+
3*x^2 - 2*x + 1
|
|
116
|
+
sage: R([1, 5/2, 2])
|
|
117
|
+
Traceback (most recent call last):
|
|
118
|
+
...
|
|
119
|
+
TypeError: no conversion of this rational to integer
|
|
120
|
+
|
|
121
|
+
Construct from constant::
|
|
122
|
+
|
|
123
|
+
sage: R(3)
|
|
124
|
+
3
|
|
125
|
+
|
|
126
|
+
Coercion from PARI polynomial::
|
|
127
|
+
|
|
128
|
+
sage: # needs sage.libs.pari
|
|
129
|
+
sage: f = R([-1, 2, 5]); f
|
|
130
|
+
5*x^2 + 2*x - 1
|
|
131
|
+
sage: type(f)
|
|
132
|
+
<class 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
|
|
133
|
+
sage: type(pari(f))
|
|
134
|
+
<class 'cypari2.gen.Gen'>
|
|
135
|
+
sage: type(R(pari(f)))
|
|
136
|
+
<class 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
|
|
137
|
+
sage: R(pari(f))
|
|
138
|
+
5*x^2 + 2*x - 1
|
|
139
|
+
|
|
140
|
+
Coercion from NTL polynomial::
|
|
141
|
+
|
|
142
|
+
sage: f = ntl.ZZX([1, 2, 3])
|
|
143
|
+
sage: print(R(f))
|
|
144
|
+
3*x^2 + 2*x + 1
|
|
145
|
+
|
|
146
|
+
Coercion from dictionary::
|
|
147
|
+
|
|
148
|
+
sage: f = R({2: -4, 3: 47}); f
|
|
149
|
+
47*x^3 - 4*x^2
|
|
150
|
+
|
|
151
|
+
Coercion from fraction field element with trivial denominator::
|
|
152
|
+
|
|
153
|
+
sage: f = (x^3 - 1) / (x - 1)
|
|
154
|
+
sage: type(f)
|
|
155
|
+
<class 'sage.rings.fraction_field_element.FractionFieldElement'>
|
|
156
|
+
sage: g = R(f); g
|
|
157
|
+
x^2 + x + 1
|
|
158
|
+
|
|
159
|
+
NTL polynomials are limited in size to slightly under the word length::
|
|
160
|
+
|
|
161
|
+
sage: PolynomialRing(ZZ, 'x', implementation='NTL')({2^3: 1})
|
|
162
|
+
x^8
|
|
163
|
+
sage: import sys
|
|
164
|
+
sage: PolynomialRing(ZZ, 'x', implementation='NTL')({sys.maxsize>>1: 1})
|
|
165
|
+
Traceback (most recent call last):
|
|
166
|
+
...
|
|
167
|
+
OverflowError: Dense NTL integer polynomials have a maximum degree of 268435455 # 32-bit
|
|
168
|
+
OverflowError: Dense NTL integer polynomials have a maximum degree of 1152921504606846975 # 64-bit
|
|
169
|
+
"""
|
|
170
|
+
Polynomial.__init__(self, parent, is_gen=is_gen)
|
|
171
|
+
|
|
172
|
+
cdef Py_ssize_t degree
|
|
173
|
+
cdef Py_ssize_t i
|
|
174
|
+
cdef ZZ_c y
|
|
175
|
+
|
|
176
|
+
if x is None:
|
|
177
|
+
return # leave initialized to 0 polynomial.
|
|
178
|
+
|
|
179
|
+
if isinstance(x, Polynomial):
|
|
180
|
+
if x.parent() is self.parent():
|
|
181
|
+
# copy with NTL assignment operator
|
|
182
|
+
self._poly = (<Polynomial_integer_dense_ntl>x)._poly
|
|
183
|
+
return
|
|
184
|
+
else:
|
|
185
|
+
# coerce coefficients into Sage integers
|
|
186
|
+
x = [Integer(a) for a in x.list()]
|
|
187
|
+
check = False
|
|
188
|
+
|
|
189
|
+
elif isinstance(x, dict):
|
|
190
|
+
x = x.items()
|
|
191
|
+
degree = 0
|
|
192
|
+
# find max degree to allocate only once
|
|
193
|
+
for ii, a in x:
|
|
194
|
+
i = ii[0] if type(ii) is tuple else ii # mpoly dict style has tuple keys
|
|
195
|
+
if i < 0:
|
|
196
|
+
raise ValueError("Negative monomial degrees not allowed: %s" % i)
|
|
197
|
+
elif i > degree:
|
|
198
|
+
degree = i
|
|
199
|
+
if degree >= NTL_OVFBND:
|
|
200
|
+
raise OverflowError("Dense NTL integer polynomials have a maximum degree of %s" % (NTL_OVFBND-1))
|
|
201
|
+
ZZX_SetCoeff_long(self._poly, degree, 1)
|
|
202
|
+
# now fill them in
|
|
203
|
+
for ii, a in x:
|
|
204
|
+
i = ii[0] if type(ii) is tuple else ii
|
|
205
|
+
if type(a) is int:
|
|
206
|
+
ZZX_SetCoeff_long(self._poly, i, a)
|
|
207
|
+
else:
|
|
208
|
+
if not isinstance(a, Integer):
|
|
209
|
+
a = ZZ(a)
|
|
210
|
+
mpz_to_ZZ(&y, (<Integer>a).value)
|
|
211
|
+
ZZX_SetCoeff(self._poly, i, y)
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
elif isinstance(x, pari_gen):
|
|
215
|
+
x = [Integer(w) for w in x.Vecrev()]
|
|
216
|
+
check = False
|
|
217
|
+
|
|
218
|
+
elif isinstance(x, ntl_ZZX): # coercion from ntl.pyx object
|
|
219
|
+
# copy with NTL assignment operator
|
|
220
|
+
self._poly = (<ntl_ZZX>x).x
|
|
221
|
+
return
|
|
222
|
+
|
|
223
|
+
elif isinstance(x, FractionFieldElement) and \
|
|
224
|
+
isinstance(x.numerator(), Polynomial_integer_dense_ntl):
|
|
225
|
+
if x.denominator() == 1:
|
|
226
|
+
# fraction of the form f(x)/1
|
|
227
|
+
self._poly = (<Polynomial_integer_dense_ntl>x.numerator())._poly
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
elif not isinstance(x, (list, tuple)):
|
|
231
|
+
x = [x] # constant polynomials
|
|
232
|
+
|
|
233
|
+
if len(x) >= NTL_OVFBND:
|
|
234
|
+
raise OverflowError("Dense NTL integer polynomials have a maximum degree of %s" % (NTL_OVFBND-1))
|
|
235
|
+
|
|
236
|
+
for i from 0 <= i < len(x):
|
|
237
|
+
a = x[i]
|
|
238
|
+
if type(a) is int:
|
|
239
|
+
ZZX_SetCoeff_long(self._poly, i, a)
|
|
240
|
+
else:
|
|
241
|
+
if not isinstance(a, Integer):
|
|
242
|
+
a = ZZ(a)
|
|
243
|
+
mpz_to_ZZ(&y, (<Integer>a).value)
|
|
244
|
+
ZZX_SetCoeff(self._poly, i, y)
|
|
245
|
+
|
|
246
|
+
def content(self):
|
|
247
|
+
r"""
|
|
248
|
+
Return the greatest common divisor of the coefficients of this
|
|
249
|
+
polynomial. The sign is the sign of the leading coefficient.
|
|
250
|
+
The content of the zero polynomial is zero.
|
|
251
|
+
|
|
252
|
+
EXAMPLES::
|
|
253
|
+
|
|
254
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
255
|
+
sage: (2*x^2 - 4*x^4 + 14*x^7).content()
|
|
256
|
+
2
|
|
257
|
+
sage: (2*x^2 - 4*x^4 - 14*x^7).content()
|
|
258
|
+
-2
|
|
259
|
+
sage: x.content()
|
|
260
|
+
1
|
|
261
|
+
sage: R(1).content()
|
|
262
|
+
1
|
|
263
|
+
sage: R(0).content()
|
|
264
|
+
0
|
|
265
|
+
"""
|
|
266
|
+
cdef ZZ_c y
|
|
267
|
+
cdef Integer z = Integer.__new__(Integer)
|
|
268
|
+
ZZX_content(y, self._poly)
|
|
269
|
+
ZZ_to_mpz(z.value, &y)
|
|
270
|
+
return z
|
|
271
|
+
|
|
272
|
+
def _eval_mpfr_(self, RealNumber a):
|
|
273
|
+
r"""
|
|
274
|
+
Evaluate this polynomial on the real number element ``a``.
|
|
275
|
+
|
|
276
|
+
This method uses Horner's rule and might not be appropriate for
|
|
277
|
+
polynomials of large degree.
|
|
278
|
+
|
|
279
|
+
TESTS::
|
|
280
|
+
|
|
281
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
282
|
+
sage: (x+1)._eval_mpfr_(RR(1.2))
|
|
283
|
+
2.20000000000000
|
|
284
|
+
sage: (x^2)._eval_mpfr_(RR(2.2))
|
|
285
|
+
4.84000000000000
|
|
286
|
+
sage: R.zero()._eval_mpfr_(RR(2.1))
|
|
287
|
+
0.000000000000000
|
|
288
|
+
sage: R.one()._eval_mpfr_(RR(2.1))
|
|
289
|
+
1.00000000000000
|
|
290
|
+
|
|
291
|
+
sage: p = x^3 - 2*x^2 + x -1
|
|
292
|
+
sage: p._eval_mpfr_(RR(1.3))
|
|
293
|
+
-0.883000000000000
|
|
294
|
+
"""
|
|
295
|
+
cdef RealNumber res = a._new()
|
|
296
|
+
sig_on()
|
|
297
|
+
ZZX_evaluation_mpfr(res.value, self._poly, a.value)
|
|
298
|
+
sig_off()
|
|
299
|
+
return res
|
|
300
|
+
|
|
301
|
+
def _eval_mpfi_(self, RealIntervalFieldElement a):
|
|
302
|
+
r"""
|
|
303
|
+
Evaluate this polynomial on the real interval ``a``.
|
|
304
|
+
|
|
305
|
+
This method uses Horner's rule and might not be appropriate for
|
|
306
|
+
polynomials of large degree.
|
|
307
|
+
|
|
308
|
+
TESTS::
|
|
309
|
+
|
|
310
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
311
|
+
sage: (x+1)._eval_mpfi_(RIF(1.5))
|
|
312
|
+
2.5000000000000000?
|
|
313
|
+
sage: (x^2)._eval_mpfi_(RIF(1.333,1.334))
|
|
314
|
+
1.78?
|
|
315
|
+
sage: R.zero()._eval_mpfi_(RIF(2.1))
|
|
316
|
+
0
|
|
317
|
+
sage: R.one()._eval_mpfi_(RIF(2.1))
|
|
318
|
+
1
|
|
319
|
+
|
|
320
|
+
sage: p = x^3 - x^2 - x - 1
|
|
321
|
+
sage: r = p.roots(RIF, multiplicities=False)[0] # needs sage.libs.linbox
|
|
322
|
+
sage: p._eval_mpfi_(r) # needs sage.libs.linbox
|
|
323
|
+
0.?e-27
|
|
324
|
+
"""
|
|
325
|
+
cdef RealIntervalFieldElement res = a._new()
|
|
326
|
+
sig_on()
|
|
327
|
+
ZZX_evaluation_mpfi(res.value, self._poly, a.value)
|
|
328
|
+
sig_off()
|
|
329
|
+
return res
|
|
330
|
+
|
|
331
|
+
def __reduce__(self):
|
|
332
|
+
r"""
|
|
333
|
+
Used for pickling.
|
|
334
|
+
|
|
335
|
+
EXAMPLES::
|
|
336
|
+
|
|
337
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
338
|
+
sage: loads(dumps(x)) == x
|
|
339
|
+
True
|
|
340
|
+
sage: f = 2*x + 3
|
|
341
|
+
sage: loads(dumps(f)) == f
|
|
342
|
+
True
|
|
343
|
+
"""
|
|
344
|
+
return Polynomial_integer_dense_ntl, \
|
|
345
|
+
(self.parent(), self.list(), False, self.is_gen())
|
|
346
|
+
|
|
347
|
+
cdef get_unsafe(self, Py_ssize_t n):
|
|
348
|
+
"""
|
|
349
|
+
Return the `n`-th coefficient of ``self``.
|
|
350
|
+
|
|
351
|
+
EXAMPLES::
|
|
352
|
+
|
|
353
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
354
|
+
sage: f = 2*x^2 - 3
|
|
355
|
+
sage: f[0]
|
|
356
|
+
-3
|
|
357
|
+
sage: f[1]
|
|
358
|
+
0
|
|
359
|
+
sage: f[2]
|
|
360
|
+
2
|
|
361
|
+
sage: f[3]
|
|
362
|
+
0
|
|
363
|
+
sage: f[-1]
|
|
364
|
+
0
|
|
365
|
+
sage: f = 1 + x + 2*x^2 + 3*x^3 + 4*x^4 + 5*x^5
|
|
366
|
+
sage: f[:4]
|
|
367
|
+
3*x^3 + 2*x^2 + x + 1
|
|
368
|
+
sage: f[:100]
|
|
369
|
+
5*x^5 + 4*x^4 + 3*x^3 + 2*x^2 + x + 1
|
|
370
|
+
"""
|
|
371
|
+
cdef Integer z = Integer.__new__(Integer)
|
|
372
|
+
ZZ_to_mpz(z.value, &self._poly.rep.elts()[n])
|
|
373
|
+
return z
|
|
374
|
+
|
|
375
|
+
def _repr(self, name=None, bint latex=False):
|
|
376
|
+
"""
|
|
377
|
+
Return string representation of this polynomial.
|
|
378
|
+
|
|
379
|
+
EXAMPLES::
|
|
380
|
+
|
|
381
|
+
sage: R.<x> = PolynomialRing(ZZ, 'x', implementation='NTL')
|
|
382
|
+
sage: (-x+1)^5
|
|
383
|
+
-x^5 + 5*x^4 - 10*x^3 + 10*x^2 - 5*x + 1
|
|
384
|
+
"""
|
|
385
|
+
if name is None:
|
|
386
|
+
name = self.parent().variable_name()
|
|
387
|
+
cdef long i
|
|
388
|
+
cdef list all = []
|
|
389
|
+
for i from ZZX_deg(self._poly) >= i >= 0:
|
|
390
|
+
sign = ZZ_sign(ZZX_coeff(self._poly, i))
|
|
391
|
+
if sign:
|
|
392
|
+
if sign > 0:
|
|
393
|
+
sign_str = '+'
|
|
394
|
+
coeff_str = ccrepr(self._poly.rep.elts()[i])
|
|
395
|
+
else:
|
|
396
|
+
sign_str = '-'
|
|
397
|
+
coeff_str = ccrepr(self._poly.rep.elts()[i])[1:]
|
|
398
|
+
if i > 0:
|
|
399
|
+
if coeff_str == '1':
|
|
400
|
+
coeff_str = ''
|
|
401
|
+
elif not latex:
|
|
402
|
+
coeff_str = coeff_str + '*'
|
|
403
|
+
if i > 1:
|
|
404
|
+
if latex:
|
|
405
|
+
all.append(" %s %s%s^{%s}" % (sign_str, coeff_str, name, i))
|
|
406
|
+
else:
|
|
407
|
+
all.append(" %s %s%s^%s" % (sign_str, coeff_str, name, i))
|
|
408
|
+
elif i == 1:
|
|
409
|
+
all.append(" %s %s%s" % (sign_str, coeff_str, name))
|
|
410
|
+
else:
|
|
411
|
+
all.append(" %s %s" % (sign_str, coeff_str))
|
|
412
|
+
if len(all) == 0:
|
|
413
|
+
return '0'
|
|
414
|
+
leading = all[0]
|
|
415
|
+
if leading[1] == '+':
|
|
416
|
+
all[0] = leading[3:]
|
|
417
|
+
else:
|
|
418
|
+
all[0] = '-' + leading[3:]
|
|
419
|
+
return ''.join(all)
|
|
420
|
+
|
|
421
|
+
def _latex_(self, name=None):
|
|
422
|
+
"""
|
|
423
|
+
Return the latex representation of this polynomial.
|
|
424
|
+
|
|
425
|
+
EXAMPLES::
|
|
426
|
+
|
|
427
|
+
sage: R.<t> = ZZ['t']
|
|
428
|
+
sage: latex(t^10-t^2-5*t+1)
|
|
429
|
+
t^{10} - t^{2} - 5t + 1
|
|
430
|
+
sage: latex(cyclotomic_polynomial(10^5))
|
|
431
|
+
x^{40000} - x^{30000} + x^{20000} - x^{10000} + 1
|
|
432
|
+
"""
|
|
433
|
+
if name is None:
|
|
434
|
+
name = self.parent().latex_variable_names()[0]
|
|
435
|
+
return self._repr(name, latex=True)
|
|
436
|
+
|
|
437
|
+
cpdef _add_(self, right):
|
|
438
|
+
r"""
|
|
439
|
+
Return ``self`` plus ``right``.
|
|
440
|
+
|
|
441
|
+
EXAMPLES::
|
|
442
|
+
|
|
443
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
444
|
+
sage: f = 2*x + 1
|
|
445
|
+
sage: g = -3*x^2 + 6
|
|
446
|
+
sage: f + g
|
|
447
|
+
-3*x^2 + 2*x + 7
|
|
448
|
+
"""
|
|
449
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
450
|
+
ZZX_add(x._poly, self._poly,
|
|
451
|
+
(<Polynomial_integer_dense_ntl>right)._poly)
|
|
452
|
+
return x
|
|
453
|
+
|
|
454
|
+
cpdef _sub_(self, right):
|
|
455
|
+
r"""
|
|
456
|
+
Return ``self`` minus ``right``.
|
|
457
|
+
|
|
458
|
+
EXAMPLES::
|
|
459
|
+
|
|
460
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
461
|
+
sage: f = 2*x + 1
|
|
462
|
+
sage: g = -3*x^2 + 6
|
|
463
|
+
sage: f - g
|
|
464
|
+
3*x^2 + 2*x - 5
|
|
465
|
+
"""
|
|
466
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
467
|
+
ZZX_sub(x._poly, self._poly,
|
|
468
|
+
(<Polynomial_integer_dense_ntl>right)._poly)
|
|
469
|
+
return x
|
|
470
|
+
|
|
471
|
+
cpdef _neg_(self):
|
|
472
|
+
r"""
|
|
473
|
+
Return negative of ``self``.
|
|
474
|
+
|
|
475
|
+
EXAMPLES::
|
|
476
|
+
|
|
477
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
478
|
+
sage: f = 2*x - 1
|
|
479
|
+
sage: -f
|
|
480
|
+
-2*x + 1
|
|
481
|
+
"""
|
|
482
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
483
|
+
ZZX_negate(x._poly, self._poly)
|
|
484
|
+
return x
|
|
485
|
+
|
|
486
|
+
@coerce_binop
|
|
487
|
+
def quo_rem(self, right):
|
|
488
|
+
r"""
|
|
489
|
+
Attempt to divide ``self`` by ``right``, and return a quotient and remainder.
|
|
490
|
+
|
|
491
|
+
If right is monic, then it returns ``(q, r)`` where ``self = q * right + r``
|
|
492
|
+
and ``deg(r) < deg(right)``.
|
|
493
|
+
|
|
494
|
+
If right is not monic, then it returns `(q, 0)` where ``q = self/right`` if
|
|
495
|
+
``right`` exactly divides ``self``, otherwise it raises an exception.
|
|
496
|
+
|
|
497
|
+
EXAMPLES::
|
|
498
|
+
|
|
499
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
500
|
+
sage: f = R(range(10)); g = R([-1, 0, 1])
|
|
501
|
+
sage: q, r = f.quo_rem(g)
|
|
502
|
+
sage: q, r
|
|
503
|
+
(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)
|
|
504
|
+
sage: q*g + r == f
|
|
505
|
+
True
|
|
506
|
+
|
|
507
|
+
sage: 0//(2*x)
|
|
508
|
+
0
|
|
509
|
+
|
|
510
|
+
sage: f = x^2
|
|
511
|
+
sage: f.quo_rem(0)
|
|
512
|
+
Traceback (most recent call last):
|
|
513
|
+
...
|
|
514
|
+
ArithmeticError: division by zero polynomial
|
|
515
|
+
|
|
516
|
+
sage: f = (x^2 + 3) * (2*x - 1)
|
|
517
|
+
sage: f.quo_rem(2*x - 1)
|
|
518
|
+
(x^2 + 3, 0)
|
|
519
|
+
|
|
520
|
+
sage: f = x^2
|
|
521
|
+
sage: f.quo_rem(2*x - 1)
|
|
522
|
+
Traceback (most recent call last):
|
|
523
|
+
...
|
|
524
|
+
ArithmeticError: division not exact in Z[x] (consider coercing to Q[x] first)
|
|
525
|
+
|
|
526
|
+
TESTS::
|
|
527
|
+
|
|
528
|
+
sage: z = R(0)
|
|
529
|
+
sage: z.quo_rem(1)
|
|
530
|
+
(0, 0)
|
|
531
|
+
sage: z.quo_rem(x)
|
|
532
|
+
(0, 0)
|
|
533
|
+
sage: z.quo_rem(2*x)
|
|
534
|
+
(0, 0)
|
|
535
|
+
"""
|
|
536
|
+
cdef Polynomial_integer_dense_ntl _right = <Polynomial_integer_dense_ntl> right
|
|
537
|
+
|
|
538
|
+
if ZZX_IsZero(_right._poly):
|
|
539
|
+
raise ArithmeticError("division by zero polynomial")
|
|
540
|
+
|
|
541
|
+
if ZZX_IsZero(self._poly):
|
|
542
|
+
return self, self
|
|
543
|
+
|
|
544
|
+
cdef ZZX_c *q
|
|
545
|
+
cdef ZZX_c *r
|
|
546
|
+
cdef Polynomial_integer_dense_ntl qq = self._new()
|
|
547
|
+
cdef Polynomial_integer_dense_ntl rr = self._new()
|
|
548
|
+
cdef int divisible
|
|
549
|
+
|
|
550
|
+
if ZZ_IsOne(ZZX_LeadCoeff(_right._poly)):
|
|
551
|
+
# divisor is monic. Just do the division and remainder
|
|
552
|
+
ZZX_quo_rem(&self._poly, &_right._poly, &r, &q)
|
|
553
|
+
ZZX_swap(qq._poly, q[0])
|
|
554
|
+
ZZX_swap(rr._poly, r[0])
|
|
555
|
+
del q
|
|
556
|
+
del r
|
|
557
|
+
else:
|
|
558
|
+
# Non-monic divisor. Check whether it divides exactly.
|
|
559
|
+
q = ZZX_div(&self._poly, &_right._poly, &divisible)
|
|
560
|
+
if divisible:
|
|
561
|
+
# exactly divisible
|
|
562
|
+
ZZX_swap(q[0], qq._poly)
|
|
563
|
+
del q
|
|
564
|
+
else:
|
|
565
|
+
# division failed: clean up and raise exception
|
|
566
|
+
del q
|
|
567
|
+
raise ArithmeticError("division not exact in Z[x] (consider coercing to Q[x] first)")
|
|
568
|
+
|
|
569
|
+
return qq, rr
|
|
570
|
+
|
|
571
|
+
@coerce_binop
|
|
572
|
+
def gcd(self, right):
|
|
573
|
+
r"""
|
|
574
|
+
Return the GCD of ``self`` and ``right``. The leading
|
|
575
|
+
coefficient need not be 1.
|
|
576
|
+
|
|
577
|
+
EXAMPLES::
|
|
578
|
+
|
|
579
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
580
|
+
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
|
|
581
|
+
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
|
|
582
|
+
sage: f.gcd(g)
|
|
583
|
+
6*x + 47
|
|
584
|
+
"""
|
|
585
|
+
# todo: we're doing an unnecessary copy here
|
|
586
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
587
|
+
cdef ZZX_c* temp = ZZX_gcd(&self._poly, &(<Polynomial_integer_dense_ntl>right)._poly)
|
|
588
|
+
x._poly = temp[0]
|
|
589
|
+
del temp
|
|
590
|
+
return x
|
|
591
|
+
|
|
592
|
+
@coerce_binop
|
|
593
|
+
def lcm(self, right):
|
|
594
|
+
"""
|
|
595
|
+
Return the LCM of ``self`` and ``right``.
|
|
596
|
+
|
|
597
|
+
EXAMPLES::
|
|
598
|
+
|
|
599
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
600
|
+
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
|
|
601
|
+
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
|
|
602
|
+
sage: h = f.lcm(g); h
|
|
603
|
+
126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786
|
|
604
|
+
sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1)
|
|
605
|
+
True
|
|
606
|
+
|
|
607
|
+
TESTS:
|
|
608
|
+
|
|
609
|
+
Check that :issue:`32033` has been fixed::
|
|
610
|
+
|
|
611
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
612
|
+
sage: R(0).lcm(R(0))
|
|
613
|
+
0
|
|
614
|
+
"""
|
|
615
|
+
if self.is_zero() or right.is_zero():
|
|
616
|
+
P = self.parent()
|
|
617
|
+
return P.zero()
|
|
618
|
+
g = self.gcd(right)
|
|
619
|
+
return (self * right).quo_rem(g)[0]
|
|
620
|
+
|
|
621
|
+
@coerce_binop
|
|
622
|
+
def xgcd(self, right):
|
|
623
|
+
"""
|
|
624
|
+
This function can't in general return `(g,s,t)` as above,
|
|
625
|
+
since they need not exist. Instead, over the integers, we
|
|
626
|
+
first multiply `g` by a divisor of the resultant of `a/g` and
|
|
627
|
+
`b/g`, up to sign, and return ``g, u, v`` such that
|
|
628
|
+
``g = u*self + v*right``. But note that this `g` may be a
|
|
629
|
+
multiple of the gcd.
|
|
630
|
+
|
|
631
|
+
If ``self`` and ``right`` are coprime as polynomials over the
|
|
632
|
+
rationals, then ``g`` is guaranteed to be the resultant of
|
|
633
|
+
``self`` and ``right``, as a constant polynomial.
|
|
634
|
+
|
|
635
|
+
EXAMPLES::
|
|
636
|
+
|
|
637
|
+
sage: P.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
638
|
+
sage: F = (x^2 + 2)*x^3; G = (x^2+2)*(x-3)
|
|
639
|
+
sage: g, u, v = F.xgcd(G)
|
|
640
|
+
sage: g, u, v
|
|
641
|
+
(27*x^2 + 54, 1, -x^2 - 3*x - 9)
|
|
642
|
+
sage: u*F + v*G
|
|
643
|
+
27*x^2 + 54
|
|
644
|
+
sage: x.xgcd(P(0))
|
|
645
|
+
(x, 1, 0)
|
|
646
|
+
sage: f = P(0)
|
|
647
|
+
sage: f.xgcd(x)
|
|
648
|
+
(x, 0, 1)
|
|
649
|
+
sage: F = (x-3)^3; G = (x-15)^2
|
|
650
|
+
sage: g, u, v = F.xgcd(G)
|
|
651
|
+
sage: g, u, v
|
|
652
|
+
(2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)
|
|
653
|
+
sage: u*F + v*G
|
|
654
|
+
2985984
|
|
655
|
+
"""
|
|
656
|
+
cdef ZZX_c *s
|
|
657
|
+
cdef ZZX_c *t
|
|
658
|
+
cdef ZZ_c *r
|
|
659
|
+
|
|
660
|
+
ZZX_xgcd(&self._poly, &(<Polynomial_integer_dense_ntl>right)._poly, &r, &s, &t, 1) # proof = 1
|
|
661
|
+
cdef Integer rr = Integer.__new__(Integer)
|
|
662
|
+
ZZ_to_mpz(rr.value, r)
|
|
663
|
+
cdef Polynomial_integer_dense_ntl ss = self._new()
|
|
664
|
+
cdef Polynomial_integer_dense_ntl tt = self._new()
|
|
665
|
+
ss._poly = s[0]
|
|
666
|
+
tt._poly = t[0]
|
|
667
|
+
del r
|
|
668
|
+
del s
|
|
669
|
+
del t
|
|
670
|
+
|
|
671
|
+
if rr == 0:
|
|
672
|
+
f = self.base_extend(QQ)
|
|
673
|
+
g, u, v = f.xgcd(right.base_extend(QQ))
|
|
674
|
+
d = lcm([g.denominator(), u.denominator(), v.denominator()])
|
|
675
|
+
R = self.parent()
|
|
676
|
+
return R(d*g), R(d*u), R(d*v)
|
|
677
|
+
else:
|
|
678
|
+
S = self.parent()
|
|
679
|
+
return S(rr), ss, tt
|
|
680
|
+
|
|
681
|
+
cpdef _mul_(self, right):
|
|
682
|
+
r"""
|
|
683
|
+
Return ``self`` multiplied by ``right``.
|
|
684
|
+
|
|
685
|
+
EXAMPLES::
|
|
686
|
+
|
|
687
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
688
|
+
sage: (x - 2)*(x^2 - 8*x + 16)
|
|
689
|
+
x^3 - 10*x^2 + 32*x - 32
|
|
690
|
+
"""
|
|
691
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
692
|
+
ZZX_mul(x._poly, self._poly,
|
|
693
|
+
(<Polynomial_integer_dense_ntl>right)._poly)
|
|
694
|
+
return x
|
|
695
|
+
|
|
696
|
+
cpdef _lmul_(self, Element right):
|
|
697
|
+
r"""
|
|
698
|
+
Return ``self`` multiplied by ``right``, where ``right`` is a scalar
|
|
699
|
+
(integer).
|
|
700
|
+
|
|
701
|
+
EXAMPLES::
|
|
702
|
+
|
|
703
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
704
|
+
sage: x*3
|
|
705
|
+
3*x
|
|
706
|
+
sage: (2*x^2 + 4)*3
|
|
707
|
+
6*x^2 + 12
|
|
708
|
+
"""
|
|
709
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
710
|
+
cdef ZZ_c _right
|
|
711
|
+
|
|
712
|
+
mpz_to_ZZ(&_right, (<Integer>right).value)
|
|
713
|
+
ZZX_mul_ZZ(x._poly, self._poly, _right)
|
|
714
|
+
return x
|
|
715
|
+
|
|
716
|
+
cpdef _rmul_(self, Element right):
|
|
717
|
+
r"""
|
|
718
|
+
Return ``self`` multiplied by ``right``, where ``right`` is a scalar
|
|
719
|
+
(integer).
|
|
720
|
+
|
|
721
|
+
EXAMPLES::
|
|
722
|
+
|
|
723
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
724
|
+
sage: 3*x
|
|
725
|
+
3*x
|
|
726
|
+
sage: 3*(2*x^2 + 4)
|
|
727
|
+
6*x^2 + 12
|
|
728
|
+
"""
|
|
729
|
+
cdef Polynomial_integer_dense_ntl x = self._new()
|
|
730
|
+
cdef ZZ_c _right
|
|
731
|
+
|
|
732
|
+
mpz_to_ZZ(&_right, (<Integer>right).value)
|
|
733
|
+
ZZX_mul_ZZ(x._poly, self._poly, _right)
|
|
734
|
+
return x
|
|
735
|
+
|
|
736
|
+
def __floordiv__(self, right):
|
|
737
|
+
"""
|
|
738
|
+
EXAMPLES::
|
|
739
|
+
|
|
740
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
741
|
+
sage: f = R([9,6,1]) ; f
|
|
742
|
+
x^2 + 6*x + 9
|
|
743
|
+
sage: f // x
|
|
744
|
+
x + 6
|
|
745
|
+
sage: f // 3
|
|
746
|
+
2*x + 3
|
|
747
|
+
sage: g = x^3 ; g
|
|
748
|
+
x^3
|
|
749
|
+
sage: f // g
|
|
750
|
+
0
|
|
751
|
+
sage: g // f
|
|
752
|
+
x - 6
|
|
753
|
+
"""
|
|
754
|
+
if isinstance(right, Polynomial) and right.is_constant() and right[0] in ZZ:
|
|
755
|
+
d = ZZ(right[0])
|
|
756
|
+
return self.parent()([c // d for c in self.list()], construct=True)
|
|
757
|
+
elif (right in self.parent().base_ring()):
|
|
758
|
+
d = ZZ(right)
|
|
759
|
+
return self.parent()([c // d for c in self.list()], construct=True)
|
|
760
|
+
else:
|
|
761
|
+
q, _ = self.quo_rem(right)
|
|
762
|
+
return q
|
|
763
|
+
|
|
764
|
+
def _unsafe_mutate(self, long n, value):
|
|
765
|
+
r"""
|
|
766
|
+
Set coefficient of `x^n` to ``value``.
|
|
767
|
+
|
|
768
|
+
This is very unsafe, because Sage polynomials are supposed
|
|
769
|
+
to be immutable.
|
|
770
|
+
|
|
771
|
+
EXAMPLES::
|
|
772
|
+
|
|
773
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
774
|
+
sage: f = 2*x^2 + 3; f
|
|
775
|
+
2*x^2 + 3
|
|
776
|
+
sage: f._unsafe_mutate(1, 42); f
|
|
777
|
+
2*x^2 + 42*x + 3
|
|
778
|
+
"""
|
|
779
|
+
n = int(n)
|
|
780
|
+
if n < 0:
|
|
781
|
+
raise IndexError("n must be >= 0")
|
|
782
|
+
value = Integer(value)
|
|
783
|
+
cdef ZZ_c y
|
|
784
|
+
mpz_to_ZZ(&y, (<Integer>value).value)
|
|
785
|
+
ZZX_SetCoeff(self._poly, n, y)
|
|
786
|
+
|
|
787
|
+
def real_root_intervals(self):
|
|
788
|
+
"""
|
|
789
|
+
Return isolating intervals for the real roots of this polynomial.
|
|
790
|
+
|
|
791
|
+
EXAMPLES:
|
|
792
|
+
We compute the roots of the characteristic polynomial of some Salem numbers::
|
|
793
|
+
|
|
794
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
795
|
+
sage: f = 1 - x^2 - x^3 - x^4 + x^6
|
|
796
|
+
sage: f.real_root_intervals() # needs sage.libs.linbox
|
|
797
|
+
[((1/2, 3/4), 1), ((1, 3/2), 1)]
|
|
798
|
+
"""
|
|
799
|
+
|
|
800
|
+
from sage.rings.polynomial.real_roots import real_roots
|
|
801
|
+
|
|
802
|
+
return real_roots(self)
|
|
803
|
+
|
|
804
|
+
# def __copy__(self):
|
|
805
|
+
# f = Polynomial_integer_dense(self.parent())
|
|
806
|
+
# f._poly = self._poly.copy()
|
|
807
|
+
# return f
|
|
808
|
+
|
|
809
|
+
def degree(self, gen=None):
|
|
810
|
+
"""
|
|
811
|
+
Return the degree of this polynomial. The zero polynomial has
|
|
812
|
+
degree `-1`.
|
|
813
|
+
|
|
814
|
+
EXAMPLES::
|
|
815
|
+
|
|
816
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
817
|
+
sage: x.degree()
|
|
818
|
+
1
|
|
819
|
+
sage: (x^2).degree()
|
|
820
|
+
2
|
|
821
|
+
sage: R(1).degree()
|
|
822
|
+
0
|
|
823
|
+
sage: R(0).degree()
|
|
824
|
+
-1
|
|
825
|
+
"""
|
|
826
|
+
return ZZX_deg(self._poly)
|
|
827
|
+
|
|
828
|
+
def discriminant(self, proof=True):
|
|
829
|
+
r"""
|
|
830
|
+
Return the discriminant of ``self``, which is by definition
|
|
831
|
+
|
|
832
|
+
.. MATH::
|
|
833
|
+
|
|
834
|
+
(-1)^{m(m-1)/2} \text{resultant}(a, a')/lc(a),
|
|
835
|
+
|
|
836
|
+
where `m = deg(a)`, and `lc(a)` is the leading coefficient of a.
|
|
837
|
+
If ``proof`` is False (the default is True), then this function
|
|
838
|
+
may use a randomized strategy that errors with probability no
|
|
839
|
+
more than `2^{-80}`.
|
|
840
|
+
|
|
841
|
+
EXAMPLES::
|
|
842
|
+
|
|
843
|
+
sage: f = ntl.ZZX([1,2,0,3])
|
|
844
|
+
sage: f.discriminant()
|
|
845
|
+
-339
|
|
846
|
+
sage: f.discriminant(proof=False)
|
|
847
|
+
-339
|
|
848
|
+
"""
|
|
849
|
+
cdef ZZ_c* temp = ZZX_discriminant(&self._poly, proof)
|
|
850
|
+
cdef Integer x = Integer.__new__(Integer)
|
|
851
|
+
ZZ_to_mpz(x.value, temp)
|
|
852
|
+
del temp
|
|
853
|
+
return x
|
|
854
|
+
|
|
855
|
+
def __pari__(self, variable=None):
|
|
856
|
+
"""
|
|
857
|
+
EXAMPLES::
|
|
858
|
+
|
|
859
|
+
sage: t = PolynomialRing(ZZ, "t", implementation='NTL').gen()
|
|
860
|
+
sage: f = t^3 + 3*t - 17
|
|
861
|
+
sage: pari(f) # needs sage.libs.pari
|
|
862
|
+
t^3 + 3*t - 17
|
|
863
|
+
"""
|
|
864
|
+
if variable is None:
|
|
865
|
+
variable = self.parent().variable_name()
|
|
866
|
+
return pari(self.list()).Polrev(variable)
|
|
867
|
+
|
|
868
|
+
def squarefree_decomposition(self):
|
|
869
|
+
"""
|
|
870
|
+
Return the square-free decomposition of ``self``. This is
|
|
871
|
+
a partial factorization of ``self`` into square-free, relatively
|
|
872
|
+
prime polynomials.
|
|
873
|
+
|
|
874
|
+
This is a wrapper for the NTL function ``SquareFreeDecomp``.
|
|
875
|
+
|
|
876
|
+
EXAMPLES::
|
|
877
|
+
|
|
878
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
879
|
+
sage: p = 37 * (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
|
|
880
|
+
sage: p.squarefree_decomposition()
|
|
881
|
+
(37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
|
|
882
|
+
|
|
883
|
+
TESTS:
|
|
884
|
+
|
|
885
|
+
Verify that :issue:`13053` has been resolved::
|
|
886
|
+
|
|
887
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
888
|
+
sage: f = -x^2
|
|
889
|
+
sage: f.squarefree_decomposition()
|
|
890
|
+
(-1) * x^2
|
|
891
|
+
"""
|
|
892
|
+
cdef Polynomial_integer_dense_ntl p = self
|
|
893
|
+
c = p.content()
|
|
894
|
+
if c != 1:
|
|
895
|
+
p = self.parent()(p / c)
|
|
896
|
+
|
|
897
|
+
cdef ZZX_c** v
|
|
898
|
+
cdef long* e
|
|
899
|
+
cdef long i, n
|
|
900
|
+
cdef Polynomial_integer_dense_ntl z
|
|
901
|
+
ZZX_squarefree_decomposition(&v, &e, &n, &p._poly)
|
|
902
|
+
F = []
|
|
903
|
+
for i from 0 <= i < n:
|
|
904
|
+
z = self._new()
|
|
905
|
+
z._poly = v[i][0]
|
|
906
|
+
F.append((z, e[i]))
|
|
907
|
+
del v[i]
|
|
908
|
+
sig_free(v)
|
|
909
|
+
sig_free(e)
|
|
910
|
+
return Factorization(F, unit=c, sort=False)
|
|
911
|
+
|
|
912
|
+
def _factor_pari(self):
|
|
913
|
+
"""
|
|
914
|
+
Use pari to factor ``self``.
|
|
915
|
+
|
|
916
|
+
EXAMPLES::
|
|
917
|
+
|
|
918
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
919
|
+
sage: f = R([9,6,1]) ; f
|
|
920
|
+
x^2 + 6*x + 9
|
|
921
|
+
sage: f.factor()
|
|
922
|
+
(x + 3)^2
|
|
923
|
+
sage: f._factor_pari() # needs sage.libs.pari
|
|
924
|
+
(x + 3)^2
|
|
925
|
+
"""
|
|
926
|
+
return Polynomial.factor(self) # uses pari for integers over ZZ
|
|
927
|
+
|
|
928
|
+
def _factor_ntl(self):
|
|
929
|
+
"""
|
|
930
|
+
Use NTL to factor ``self``.
|
|
931
|
+
|
|
932
|
+
AUTHOR:
|
|
933
|
+
|
|
934
|
+
- Joel B. Mohler
|
|
935
|
+
|
|
936
|
+
EXAMPLES::
|
|
937
|
+
|
|
938
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
939
|
+
sage: f = R([9,6,1])
|
|
940
|
+
sage: f._factor_ntl()
|
|
941
|
+
(x + 3)^2
|
|
942
|
+
"""
|
|
943
|
+
cdef Polynomial_integer_dense_ntl fac_py
|
|
944
|
+
cdef ZZ_c content
|
|
945
|
+
cdef vec_pair_ZZX_long_c factors
|
|
946
|
+
cdef long i
|
|
947
|
+
cdef int sig_me = ZZX_deg(self._poly)
|
|
948
|
+
if sig_me > 10:
|
|
949
|
+
sig_on()
|
|
950
|
+
ZZX_factor(content, factors, self._poly, 0, 0)
|
|
951
|
+
if sig_me > 10:
|
|
952
|
+
sig_off()
|
|
953
|
+
results = []
|
|
954
|
+
unit = None
|
|
955
|
+
if not ZZ_IsOne(content):
|
|
956
|
+
fac_py = self._new()
|
|
957
|
+
ZZX_SetCoeff(fac_py._poly, 0, content)
|
|
958
|
+
if ZZX_deg(fac_py._poly) == 0 and ZZ_to_int(fac_py._poly.rep.elts())==-1:
|
|
959
|
+
unit = fac_py
|
|
960
|
+
else:
|
|
961
|
+
results.append( (fac_py,1) )
|
|
962
|
+
for i from 0 <= i < factors.length():
|
|
963
|
+
fac_py = self._new()
|
|
964
|
+
fac_py._poly = factors.RawGet(i).a
|
|
965
|
+
results.append( (fac_py,factors.RawGet(i).b) )
|
|
966
|
+
return Factorization(results, unit = unit)
|
|
967
|
+
|
|
968
|
+
def factor(self):
|
|
969
|
+
"""
|
|
970
|
+
This function overrides the generic polynomial factorization to
|
|
971
|
+
make a somewhat intelligent decision to use PARI or NTL based on
|
|
972
|
+
some benchmarking.
|
|
973
|
+
|
|
974
|
+
Note: This function factors the content of the polynomial,
|
|
975
|
+
which can take very long if it's a really big integer. If you
|
|
976
|
+
do not need the content factored, divide it out of your
|
|
977
|
+
polynomial before calling this function.
|
|
978
|
+
|
|
979
|
+
EXAMPLES::
|
|
980
|
+
|
|
981
|
+
sage: R.<x> = ZZ[]
|
|
982
|
+
sage: f = x^4 - 1
|
|
983
|
+
sage: f.factor()
|
|
984
|
+
(x - 1) * (x + 1) * (x^2 + 1)
|
|
985
|
+
sage: f = 1 - x
|
|
986
|
+
sage: f.factor()
|
|
987
|
+
(-1) * (x - 1)
|
|
988
|
+
sage: f.factor().unit()
|
|
989
|
+
-1
|
|
990
|
+
sage: f = -30*x; f.factor()
|
|
991
|
+
(-1) * 2 * 3 * 5 * x
|
|
992
|
+
"""
|
|
993
|
+
cdef int deg = ZZX_deg(self._poly)
|
|
994
|
+
# it appears that pari has a window from about degrees 30 and 300
|
|
995
|
+
# in which it beats NTL.
|
|
996
|
+
c = self.content()
|
|
997
|
+
g = self // c
|
|
998
|
+
if deg < 30 or deg > 300:
|
|
999
|
+
return c.factor() * g._factor_ntl()
|
|
1000
|
+
return c.factor() * g._factor_pari()
|
|
1001
|
+
|
|
1002
|
+
def factor_mod(self, p):
|
|
1003
|
+
"""
|
|
1004
|
+
Return the factorization of ``self`` modulo the prime `p`.
|
|
1005
|
+
|
|
1006
|
+
INPUT:
|
|
1007
|
+
|
|
1008
|
+
- ``p`` -- prime
|
|
1009
|
+
|
|
1010
|
+
OUTPUT: factorization of ``self`` reduced modulo `p`
|
|
1011
|
+
|
|
1012
|
+
EXAMPLES::
|
|
1013
|
+
|
|
1014
|
+
sage: # needs sage.libs.pari
|
|
1015
|
+
sage: R.<x> = PolynomialRing(ZZ, 'x', implementation='NTL')
|
|
1016
|
+
sage: f = -3*x*(x-2)*(x-9) + x
|
|
1017
|
+
sage: f.factor_mod(3)
|
|
1018
|
+
x
|
|
1019
|
+
sage: f = -3*x*(x-2)*(x-9)
|
|
1020
|
+
sage: f.factor_mod(3)
|
|
1021
|
+
Traceback (most recent call last):
|
|
1022
|
+
...
|
|
1023
|
+
ArithmeticError: factorization of 0 is not defined
|
|
1024
|
+
sage: f = 2*x*(x-2)*(x-9)
|
|
1025
|
+
sage: f.factor_mod(7)
|
|
1026
|
+
(2) * x * (x + 5)^2
|
|
1027
|
+
"""
|
|
1028
|
+
from sage.rings.finite_rings.finite_field_constructor import FiniteField
|
|
1029
|
+
p = Integer(p)
|
|
1030
|
+
if not p.is_prime():
|
|
1031
|
+
raise ValueError("p must be prime")
|
|
1032
|
+
if not any(c % p for c in self.coefficients()):
|
|
1033
|
+
raise ArithmeticError("factorization of 0 is not defined")
|
|
1034
|
+
f = self.__pari__()
|
|
1035
|
+
G = f.factormod(p)
|
|
1036
|
+
k = FiniteField(p)
|
|
1037
|
+
R = k[self.parent().variable_name()]
|
|
1038
|
+
return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient())
|
|
1039
|
+
|
|
1040
|
+
def factor_padic(self, p, prec=10):
|
|
1041
|
+
"""
|
|
1042
|
+
Return `p`-adic factorization of ``self`` to given precision.
|
|
1043
|
+
|
|
1044
|
+
INPUT:
|
|
1045
|
+
|
|
1046
|
+
- ``p`` -- prime
|
|
1047
|
+
|
|
1048
|
+
- ``prec`` -- integer; the precision
|
|
1049
|
+
|
|
1050
|
+
OUTPUT: factorization of ``self`` over the completion at `p`
|
|
1051
|
+
|
|
1052
|
+
EXAMPLES::
|
|
1053
|
+
|
|
1054
|
+
sage: R.<x> = PolynomialRing(ZZ, implementation='NTL')
|
|
1055
|
+
sage: f = x^2 + 1
|
|
1056
|
+
sage: f.factor_padic(5, 4) # needs sage.rings.padics
|
|
1057
|
+
((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))
|
|
1058
|
+
* ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))
|
|
1059
|
+
|
|
1060
|
+
A more difficult example::
|
|
1061
|
+
|
|
1062
|
+
sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
|
|
1063
|
+
sage: f.factor_padic(5, 10) # needs sage.rings.padics
|
|
1064
|
+
(4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2
|
|
1065
|
+
* ((5 + O(5^10))*x + 1 + O(5^10))^2
|
|
1066
|
+
"""
|
|
1067
|
+
from sage.rings.padics.factory import Zp
|
|
1068
|
+
|
|
1069
|
+
p = Integer(p)
|
|
1070
|
+
prec = Integer(prec)
|
|
1071
|
+
|
|
1072
|
+
# Parent field for coefficients and polynomial
|
|
1073
|
+
K = Zp(p, prec, type='capped-rel')
|
|
1074
|
+
R = K[self.parent().variable_name()]
|
|
1075
|
+
|
|
1076
|
+
# Factor the *exact* polynomial using factorpadic()
|
|
1077
|
+
G = self._pari_with_name().factorpadic(p, prec)
|
|
1078
|
+
|
|
1079
|
+
from sage.rings.polynomial.padics.polynomial_padic import _pari_padic_factorization_to_sage
|
|
1080
|
+
return _pari_padic_factorization_to_sage(G, R, self.leading_coefficient())
|
|
1081
|
+
|
|
1082
|
+
cpdef list list(self, bint copy=True):
|
|
1083
|
+
"""
|
|
1084
|
+
Return a new copy of the list of the underlying
|
|
1085
|
+
elements of ``self``.
|
|
1086
|
+
|
|
1087
|
+
EXAMPLES::
|
|
1088
|
+
|
|
1089
|
+
sage: x = PolynomialRing(ZZ, 'x', implementation='NTL').0
|
|
1090
|
+
sage: f = x^3 + 3*x - 17
|
|
1091
|
+
sage: f.list()
|
|
1092
|
+
[-17, 3, 0, 1]
|
|
1093
|
+
sage: f = PolynomialRing(ZZ, 'x', implementation='NTL')(0)
|
|
1094
|
+
sage: f.list()
|
|
1095
|
+
[]
|
|
1096
|
+
"""
|
|
1097
|
+
return [self.get_unsafe(i) for i in range(self.degree()+1)]
|
|
1098
|
+
|
|
1099
|
+
@coerce_binop
|
|
1100
|
+
def resultant(self, other, proof=True):
|
|
1101
|
+
"""
|
|
1102
|
+
Return the resultant of ``self`` and ``other``, which must lie in the same
|
|
1103
|
+
polynomial ring.
|
|
1104
|
+
|
|
1105
|
+
If ``proof=False`` (the default is ``proof=True``), then this function may use a
|
|
1106
|
+
randomized strategy that errors with probability no more than `2^{-80}`.
|
|
1107
|
+
|
|
1108
|
+
INPUT:
|
|
1109
|
+
|
|
1110
|
+
- ``other`` -- a polynomial
|
|
1111
|
+
|
|
1112
|
+
OUTPUT: an element of the base ring of the polynomial ring
|
|
1113
|
+
|
|
1114
|
+
EXAMPLES::
|
|
1115
|
+
|
|
1116
|
+
sage: x = PolynomialRing(ZZ, 'x', implementation='NTL').0
|
|
1117
|
+
sage: f = x^3 + x + 1; g = x^3 - x - 1
|
|
1118
|
+
sage: r = f.resultant(g); r
|
|
1119
|
+
-8
|
|
1120
|
+
sage: r.parent() is ZZ
|
|
1121
|
+
True
|
|
1122
|
+
"""
|
|
1123
|
+
cdef Polynomial_integer_dense_ntl _other = <Polynomial_integer_dense_ntl>(self.parent().coerce(other))
|
|
1124
|
+
cdef ZZ_c* temp = ZZX_resultant(&self._poly, &_other._poly, proof)
|
|
1125
|
+
cdef Integer x = Integer.__new__(Integer)
|
|
1126
|
+
ZZ_to_mpz(x.value, temp)
|
|
1127
|
+
del temp
|
|
1128
|
+
return x
|