diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index 3657b929c8f..3a891ec1ae8 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -30,32 +30,34 @@ import sys from cysignals.memory cimport sig_malloc, check_calloc, sig_free from cysignals.signals cimport sig_on, sig_off -from sage.structure.element cimport parent - from sage.arith.misc import factor -from sage.rings.integer_ring import ZZ -from sage.misc.misc_c import prod from sage.combinat.subset import subsets -from sage.libs.pari.all import pari +from sage.misc.misc_c import prod +from sage.rings.integer_ring import ZZ +from sage.structure.element cimport parent +try: + from sage.libs.pari.all import pari +except ImportError: + pass def cyclotomic_coeffs(nn, sparse=None): """ - Return the coefficients of the n-th cyclotomic polynomial + Return the coefficients of the `n`-th cyclotomic polynomial by using the formula .. MATH:: \\Phi_n(x) = \\prod_{d|n} (1-x^{n/d})^{\\mu(d)} - where `\\mu(d)` is the Möbius function that is 1 if d has an even - number of distinct prime divisors, -1 if it has an odd number of - distinct prime divisors, and 0 if d is not squarefree. + where `\\mu(d)` is the Möbius function that is 1 if `d` has an even + number of distinct prime divisors, `-1` if it has an odd number of + distinct prime divisors, and `0` if `d` is not squarefree. Multiplications and divisions by polynomials of the form `1-x^n` can be done very quickly in a single pass. - If sparse is ``True``, the result is returned as a dictionary of + If ``sparse`` is ``True``, the result is returned as a dictionary of the non-zero entries, otherwise the result is returned as a list of python ints. @@ -72,17 +74,19 @@ def cyclotomic_coeffs(nn, sparse=None): Check that it has the right degree:: - sage: euler_phi(30) + sage: euler_phi(30) # needs sage.libs.pari 8 - sage: R(cyclotomic_coeffs(14)).factor() + sage: R(cyclotomic_coeffs(14)).factor() # needs sage.libs.pari x^6 - x^5 + x^4 - x^3 + x^2 - x + 1 The coefficients are not always +/-1:: sage: cyclotomic_coeffs(105) - [1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1] + [1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, + 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1, -2, + -1, -1, 0, 0, 1, 1, 1] - In fact the height is not bounded by any polynomial in n (Erdos), + In fact the height is not bounded by any polynomial in `n` (Erdos), although takes a while just to exceed linear:: sage: v = cyclotomic_coeffs(1181895) @@ -200,10 +204,10 @@ def cyclotomic_value(n, x): INPUT: - - `n` -- an Integer, specifying which cyclotomic polynomial is to be + - ``n`` -- an Integer, specifying which cyclotomic polynomial is to be evaluated - - `x` -- an element of a ring + - ``x`` -- an element of a ring OUTPUT: @@ -247,9 +251,12 @@ def cyclotomic_value(n, x): TESTS:: - sage: R. = QQ[] - sage: K. = NumberField(x^2 + 1) - sage: for y in [-1, 0, 1, 2, 1/2, Mod(3, 8), Mod(3,11), GF(9,'a').gen(), Zp(3)(54), i, x^2+2]: + sage: elements = [-1, 0, 1, 2, 1/2, Mod(3, 8), Mod(3,11)] + sage: R. = QQ[]; elements += [x^2 + 2] + sage: K. = NumberField(x^2 + 1); elements += [i] # needs sage.rings.number_fields + sage: elements += [GF(9,'a').gen()] # needs sage.rings.finite_rings + sage: elements += [Zp(3)(54)] # needs sage.rings.padics + sage: for y in elements: ....: for n in [1..60]: ....: val1 = cyclotomic_value(n, y) ....: val2 = cyclotomic_polynomial(n)(y) @@ -258,29 +265,31 @@ def cyclotomic_value(n, x): ....: if val1.parent() is not val2.parent(): ....: print("Wrong parent for cyclotomic_value(%s, %s) in %s"%(n,y,parent(y))) - sage: cyclotomic_value(20, I) + sage: cyclotomic_value(20, I) # needs sage.symbolic 5 sage: a = cyclotomic_value(10, mod(3, 11)); a 6 sage: a.parent() Ring of integers modulo 11 - sage: cyclotomic_value(30, -1.0) + sage: cyclotomic_value(30, -1.0) # needs sage.rings.real_mpfr 1.00000000000000 + + sage: # needs sage.libs.pari sage: S. = R.quotient(R.cyclotomic_polynomial(15)) sage: cyclotomic_value(15, t) 0 sage: cyclotomic_value(30, t) 2*t^7 - 2*t^5 - 2*t^3 + 2*t sage: S. = R.quotient(x^10) - sage: cyclotomic_value(2^128-1, t) + sage: cyclotomic_value(2^128 - 1, t) -t^7 - t^6 - t^5 + t^2 + t + 1 - sage: cyclotomic_value(10,mod(3,4)) + sage: cyclotomic_value(10, mod(3,4)) 1 Check that the issue with symbolic element in :trac:`14982` is fixed:: - sage: a = cyclotomic_value(3, I) - sage: parent(a) + sage: a = cyclotomic_value(3, I) # needs sage.rings.number_fields + sage: parent(a) # needs sage.rings.number_fields Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ n = ZZ(n) @@ -387,7 +396,7 @@ def bateman_bound(nn): EXAMPLES:: sage: from sage.rings.polynomial.cyclotomic import bateman_bound - sage: bateman_bound(2**8*1234567893377) + sage: bateman_bound(2**8 * 1234567893377) # needs sage.libs.pari 66944986927 """ _, n = nn.val_unit(2) diff --git a/src/sage/rings/polynomial/flatten.py b/src/sage/rings/polynomial/flatten.py index eeb20ea35c1..cfc5f96179c 100644 --- a/src/sage/rings/polynomial/flatten.py +++ b/src/sage/rings/polynomial/flatten.py @@ -111,37 +111,41 @@ def __init__(self, domain): :: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: R = K['x','y']['a','b'] # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 2) + sage: R = K['x','y']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field - sage: f(R('v*a*x^2 + b^2 + 1/v*y')) # optional - sage.rings.number_field + sage: f = FlatteningMorphism(R) + sage: f(R('v*a*x^2 + b^2 + 1/v*y')) v*x^2*a + b^2 + (1/2*v^2)*y :: - sage: R = QQbar['x','y']['a','b'] # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R = QQbar['x','y']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field - sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y')) # optional - sage.rings.number_field + sage: f = FlatteningMorphism(R) + sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y')) # needs sage.symbolic 1.414213562373095?*x^2*a + b^2 + I*y :: - sage: R. = PolynomialRing(QQbar, 1) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 1) sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field - sage: f.domain(), f.codomain() # optional - sage.rings.number_field + sage: f = FlatteningMorphism(R) + sage: f.domain(), f.codomain() (Multivariate Polynomial Ring in z over Algebraic Field, Multivariate Polynomial Ring in z over Algebraic Field) :: - sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar) sage: from sage.rings.polynomial.flatten import FlatteningMorphism - sage: f = FlatteningMorphism(R) # optional - sage.rings.number_field - sage: f.domain(), f.codomain() # optional - sage.rings.number_field + sage: f = FlatteningMorphism(R) + sage: f.domain(), f.codomain() (Univariate Polynomial Ring in z over Algebraic Field, Univariate Polynomial Ring in z over Algebraic Field) @@ -376,8 +380,8 @@ def _call_(self, p): sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: rings = [ZZ['x']['y']['a,b,c']] - sage: rings += [GF(4)['x','y']['a','b']] # optional - sage.rings.finite_rings - sage: rings += [AA['x']['a','b']['y'], QQbar['a1','a2']['t']['X','Y']] # optional - sage.rings.number_field + sage: rings += [GF(4)['x','y']['a','b']] # needs sage.rings.finite_rings + sage: rings += [AA['x']['a','b']['y'], QQbar['a1','a2']['t']['X','Y']] # needs sage.rings.number_field sage: for R in rings: ....: f = FlatteningMorphism(R) ....: g = f.section() @@ -490,8 +494,9 @@ def __init__(self, domain, D): sage: P. = AffineSpace(R, 1) sage: H = End(P) sage: f = H([z^2 + c]) - sage: f.specialization({c:1}) - Scheme endomorphism of Affine Space of dimension 1 over Real Field with 53 bits of precision + sage: f.specialization({c:1}) # needs sage.modules + Scheme endomorphism of + Affine Space of dimension 1 over Real Field with 53 bits of precision Defn: Defined on coordinates by sending (z) to (z^2 + 1.00000000000000) """ diff --git a/src/sage/rings/polynomial/groebner_fan.py b/src/sage/rings/polynomial/groebner_fan.py index 5177b2eaf27..7e067a3a087 100644 --- a/src/sage/rings/polynomial/groebner_fan.py +++ b/src/sage/rings/polynomial/groebner_fan.py @@ -1246,27 +1246,27 @@ def render(self, file=None, larger=False, shift=0, rgbcolor=(0, 0, 0), INPUT: - - ``file`` - a filename if you prefer the output + - ``file`` -- a filename if you prefer the output saved to a file. This will be in xfig format. - - ``shift`` - shift the positions of the variables in + - ``shift`` -- shift the positions of the variables in the drawing. For example, with shift=1, the corners will be b (right), c (left), and d (top). The shifting is done modulo the number of variables in the polynomial ring. The default is 0. - - ``larger`` - bool (default: ``False``); if ``True``, make + - ``larger`` -- bool (default: ``False``); if ``True``, make the triangle larger so that the shape of the Groebner region appears. Affects the xfig file but probably not the sage graphics (?) - - ``rgbcolor`` - This will not affect the saved xfig + - ``rgbcolor`` -- This will not affect the saved xfig file, only the sage graphics produced. - - ``polyfill`` - Whether or not to fill the cones with + - ``polyfill`` -- Whether or not to fill the cones with a color determined by the highest degree in each reduced Groebner basis for that cone. - - ``scale_colors`` - if True, this will normalize + - ``scale_colors`` -- if True, this will normalize color values to try to maximize the range @@ -1274,23 +1274,23 @@ def render(self, file=None, larger=False, shift=0, rgbcolor=(0, 0, 0), sage: R. = PolynomialRing(QQ,3) sage: G = R.ideal([y^3 - x^2, y^2 - 13*x,z]).groebner_fan() - sage: test_render = G.render() + sage: test_render = G.render() # needs sage.plot :: sage: R. = PolynomialRing(QQ,3) sage: G = R.ideal([x^2*y - z, y^2*z - x, z^2*x - y]).groebner_fan() - sage: test_render = G.render(larger=True) + sage: test_render = G.render(larger=True) # needs sage.plot TESTS: Testing the case where the number of generators is < 3. Currently, - this should raise a ``NotImplementedError`` error. + this should raise a :class:`NotImplementedError`. :: sage: R. = PolynomialRing(QQ, 2) - sage: R.ideal([y^3 - x^2, y^2 - 13*x]).groebner_fan().render() + sage: R.ideal([y^3 - x^2, y^2 - 13*x]).groebner_fan().render() # needs sage.plot Traceback (most recent call last): ... NotImplementedError @@ -1460,17 +1460,17 @@ def render3d(self, verbose=False): sage: R4. = PolynomialRing(QQ,4) sage: gf = R4.ideal([w^2-x,x^2-y,y^2-z,z^2-x]).groebner_fan() - sage: three_d = gf.render3d() + sage: three_d = gf.render3d() # needs sage.plot TESTS: Now test the case where the number of generators is not 4. Currently, - this should raise a ``NotImplementedError`` error. + this should raise a :class:`NotImplementedError` error. :: sage: P. = PolynomialRing(QQ, 3, order="lex") - sage: sage.rings.ideal.Katsura(P, 3).groebner_fan().render3d() + sage: sage.rings.ideal.Katsura(P, 3).groebner_fan().render3d() # needs sage.plot Traceback (most recent call last): ... NotImplementedError diff --git a/src/sage/rings/polynomial/hilbert.pyx b/src/sage/rings/polynomial/hilbert.pyx index ccf5159dfac..ff191640fc3 100644 --- a/src/sage/rings/polynomial/hilbert.pyx +++ b/src/sage/rings/polynomial/hilbert.pyx @@ -20,9 +20,10 @@ in any example with more than 34 variables. # #***************************************************************************** +import sage.interfaces.abc + from sage.rings.polynomial.polydict cimport ETuple from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint -from sage.interfaces.singular import Singular from cysignals.memory cimport sig_malloc from cpython.list cimport PyList_GET_ITEM @@ -476,7 +477,7 @@ def first_hilbert_series(I, grading=None, return_grading=False): cdef Polynomial_integer_dense_flint fhs = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint) fhs._parent = PR fhs._is_gen = 0 - if isinstance(I.parent(), Singular): + if isinstance(I, sage.interfaces.abc.SingularElement): S = I._check_valid() # First, we need to deal with quotient rings, which also covers the case # of graded commutative rings that arise as cohomology rings in odd characteristic. diff --git a/src/sage/rings/polynomial/ideal.py b/src/sage/rings/polynomial/ideal.py index d84264e9d69..a117c7bd663 100644 --- a/src/sage/rings/polynomial/ideal.py +++ b/src/sage/rings/polynomial/ideal.py @@ -32,9 +32,9 @@ def residue_class_degree(self): EXAMPLES:: - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: P = R.ideal(t^4 + t + 1) # optional - sage.rings.finite_rings - sage: P.residue_class_degree() # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: P = R.ideal(t^4 + t + 1) + sage: P.residue_class_degree() 4 """ return self.gen().degree() @@ -45,8 +45,8 @@ def residue_field(self, names=None, check=True): EXAMPLES:: - sage: R. = GF(17)[]; P = R.ideal(t^3 + 2*t + 9) # optional - sage.rings.finite_rings - sage: k. = P.residue_field(); k # optional - sage.rings.finite_rings + sage: R. = GF(17)[]; P = R.ideal(t^3 + 2*t + 9) + sage: k. = P.residue_field(); k # needs sage.rings.finite_rings Residue field in a of Principal ideal (t^3 + 2*t + 9) of Univariate Polynomial Ring in t over Finite Field of size 17 """ @@ -75,11 +75,11 @@ def groebner_basis(self, algorithm=None): sage: R. = QQ[] sage: I = R.ideal([x^2 - 1, x^3 - 1]) - sage: G = I.groebner_basis(); G # optional - sage.libs.singular + sage: G = I.groebner_basis(); G [x - 1] - sage: type(G) # optional - sage.libs.singular + sage: type(G) - sage: list(G) # optional - sage.libs.singular + sage: list(G) [x - 1] """ gb = self.gens_reduced() diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index cad5877fd0f..fc8449b340e 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -48,8 +48,8 @@ There is a permutation action on Infinite Polynomial Rings by permuting the indices of the variables:: - sage: P = Permutation(((4,5),(2,3))) # optional - sage.combinat - sage: c^P # optional - sage.combinat + sage: P = Permutation(((4,5),(2,3))) + sage: c^P x_2^3 + x_2*y_5 - 2*y_5^4 Note that ``P(0)==0``, and thus variables of index zero are invariant @@ -299,16 +299,16 @@ def polynomial(self): EXAMPLES:: - sage: X. = InfinitePolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: p = x[2]*y[1] + 3*y[0] # optional - sage.rings.finite_rings - sage: p # optional - sage.rings.finite_rings + sage: X. = InfinitePolynomialRing(GF(7)) + sage: p = x[2]*y[1] + 3*y[0] + sage: p x_2*y_1 + 3*y_0 - sage: p.polynomial() # optional - sage.rings.finite_rings + sage: p.polynomial() x_2*y_1 + 3*y_0 - sage: p.polynomial().parent() # optional - sage.rings.finite_rings + sage: p.polynomial().parent() Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0 over Finite Field of size 7 - sage: p.parent() # optional - sage.rings.finite_rings + sage: p.parent() Infinite polynomial ring in x, y over Finite Field of size 7 """ @@ -440,13 +440,14 @@ def subs(self, fixed=None, **kwargs): The substitution can also handle matrices:: - sage: M = matrix([[1,0], [0,2]]) # optional - sage.modules - sage: N = matrix([[0,3], [4,0]]) # optional - sage.modules - sage: g = x[0]^2 + 3*x[1] # optional - sage.modules - sage: g.subs({'x_0': M}) # optional - sage.modules + sage: # needs sage.modules + sage: M = matrix([[1,0], [0,2]]) + sage: N = matrix([[0,3], [4,0]]) + sage: g = x[0]^2 + 3*x[1] + sage: g.subs({'x_0': M}) [3*x_1 + 1 0] [ 0 3*x_1 + 4] - sage: g.subs({x[0]: M, x[1]: N}) # optional - sage.modules + sage: g.subs({x[0]: M, x[1]: N}) [ 1 9] [12 4] @@ -464,7 +465,7 @@ def subs(self, fixed=None, **kwargs): TESTS:: - sage: g.subs(fixed=x[0], x_1=N) + sage: g.subs(fixed=x[0], x_1=N) # needs sage.modules Traceback (most recent call last): ... ValueError: fixed must be a dict @@ -540,10 +541,10 @@ def is_nilpotent(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(QQbar) # optional - sage.rings.number_field - sage: (x[0] + x[1]).is_nilpotent() # optional - sage.rings.number_field + sage: R. = InfinitePolynomialRing(QQbar) # needs sage.rings.number_field + sage: (x[0] + x[1]).is_nilpotent() # needs sage.rings.number_field False - sage: R(0).is_nilpotent() # optional - sage.rings.number_field + sage: R(0).is_nilpotent() # needs sage.rings.number_field True sage: _. = InfinitePolynomialRing(Zmod(4)) sage: (2*x[0]).is_nilpotent() @@ -656,7 +657,7 @@ def _div_(self, x): sage: z = 1/(x[2]*(x[1]+x[2]))+1/(x[1]*(x[1]+x[2])) sage: z.parent() Fraction Field of Infinite polynomial ring in x over Rational Field - sage: factor(z) # optional - sage.libs.singular + sage: factor(z) # needs sage.libs.singular x_1^-1 * x_2^-1 """ if not x.variables(): @@ -896,11 +897,11 @@ def symmetric_cancellation_order(self, other): sage: X. = InfinitePolynomialRing(QQ) sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]^2) (None, 1, 1) - sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) # optional - sage.combinat + sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) (-1, [2, 3, 1], y_1) - sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) # optional - sage.combinat + sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1]) (None, 1, 1) - sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2]) # optional - sage.combinat + sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2]) (-1, [2, 3, 1], 1) """ @@ -1097,7 +1098,7 @@ def reduce(self, I, tailreduce=False, report=None): reduction. However, reduction by ``y[1]*x[2]^2`` works, since one can change variable index 1 into 2 and 2 into 3:: - sage: p.reduce([y[1]*x[2]^2]) + sage: p.reduce([y[1]*x[2]^2]) # needs sage.libs.singular y_3*y_1^2 The next example shows that tail reduction is not done, unless @@ -1107,13 +1108,13 @@ def reduce(self, I, tailreduce=False, report=None): sage: I = (y[3])*X sage: p.reduce(I) x_3^3*y_2 + y_3*y_1^2 - sage: p.reduce(I, tailreduce=True) + sage: p.reduce(I, tailreduce=True) # needs sage.libs.singular x_3^3*y_2 Last, we demonstrate the ``report`` option:: sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4] - sage: p.reduce(I, tailreduce=True, report=True) + sage: p.reduce(I, tailreduce=True, report=True) # needs sage.libs.singular :T[2]:> > x_1^2 + y_2^2 @@ -1258,8 +1259,8 @@ def __call__(self, *args, **kwargs): sage: a(x_1=x[100]) x_100 + x_0 - sage: M = matrix([[1,1], [2,0]]) # optional - sage.modules - sage: a(x_1=M) # optional - sage.modules + sage: M = matrix([[1,1], [2,0]]) # needs sage.modules + sage: a(x_1=M) # needs sage.modules [x_0 + 1 1] [ 2 x_0] """ @@ -1389,8 +1390,8 @@ def __pow__(self, n): sage: X. = InfinitePolynomialRing(QQ, implementation='sparse') sage: p = x[10]*y[2] + 2*x[1]*y[3] - sage: P = Permutation(((1,2),(3,4,5))) # optional - sage.combinat - sage: p^P # indirect doctest # optional - sage.combinat + sage: P = Permutation(((1,2),(3,4,5))) + sage: p^P # indirect doctest x_10*y_1 + 2*x_2*y_4 """ @@ -1480,10 +1481,10 @@ def _richcmp_(self, x, op): An example in which a previous version had failed:: - sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='sparse') # optional - sage.rings.finite_rings - sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') # optional - sage.rings.finite_rings - sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') # optional - sage.rings.finite_rings - sage: p < q # indirect doctest # optional - sage.rings.finite_rings + sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='sparse') + sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') + sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') + sage: p < q False """ @@ -1583,10 +1584,10 @@ def _richcmp_(self, x, op): An example in which a previous version had failed:: - sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='dense') # optional - sage.rings.finite_rings - sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') # optional - sage.rings.finite_rings - sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') # optional - sage.rings.finite_rings - sage: p < q # optional - sage.rings.finite_rings + sage: X. = InfinitePolynomialRing(GF(3), order='degrevlex', implementation='dense') + sage: p = Y('x_3*x_0^2 + x_0*y_3*y_0') + sage: q = Y('x_1*x_0^2 + x_0*y_1*y_0') + sage: p < q False """ @@ -1665,8 +1666,8 @@ def __pow__(self, n): sage: x[10]^3 x_10^3 sage: p = x[10]*y[2] + 2*x[1]*y[3] - sage: P = Permutation(((1,2),(3,4,5))) # optional - sage.combinat - sage: p^P # optional - sage.combinat + sage: P = Permutation(((1,2),(3,4,5))) + sage: p^P x_10*y_1 + 2*x_2*y_4 """ diff --git a/src/sage/rings/polynomial/infinite_polynomial_ring.py b/src/sage/rings/polynomial/infinite_polynomial_ring.py index b9318c36d49..32f62258a7c 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_ring.py +++ b/src/sage/rings/polynomial/infinite_polynomial_ring.py @@ -86,10 +86,10 @@ There is a permutation action on the variables, by permuting positive variable indices:: - sage: P = Permutation(((10,1))) # optional - sage.combinat - sage: p^P # optional - sage.combinat + sage: P = Permutation(((10,1))) + sage: p^P x_5*x_1^2 + 3*x_1^2*y_10 + 2*x_1^2 - sage: p2^P # optional - sage.combinat + sage: p2^P alpha_5*alpha_1^2 + 3*alpha_1^2*beta_10 + 2*alpha_1^2 Note that `x_0^P = x_0`, since the permutations only change *positive* @@ -103,7 +103,7 @@ base ring is a field, one can compute Symmetric Groebner Bases:: sage: J = A * (alpha[1]*beta[2]) - sage: J.groebner_basis() # optional - sage.combinat + sage: J.groebner_basis() # needs sage.combinat sage.libs.singular [alpha_1*beta_2, alpha_2*beta_1] For more details, see :class:`~sage.rings.polynomial.symmetric_ideal.SymmetricIdeal`. @@ -810,8 +810,8 @@ def construction(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(5)) # optional - sage.rings.finite_rings - sage: R.construction() # optional - sage.rings.finite_rings + sage: R. = InfinitePolynomialRing(GF(5)) + sage: R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5] """ @@ -1109,10 +1109,10 @@ def is_noetherian(self): TESTS:: - sage: R = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings - sage: R # optional - sage.rings.finite_rings + sage: R = InfinitePolynomialRing(GF(2)) + sage: R Infinite polynomial ring in x over Finite Field of size 2 - sage: R.is_noetherian() # optional - sage.rings.finite_rings + sage: R.is_noetherian() False sage: R. = InfinitePolynomialRing(QQ) @@ -1136,10 +1136,10 @@ def is_field(self, *args, **kwds): TESTS:: - sage: R = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings - sage: R # optional - sage.rings.finite_rings + sage: R = InfinitePolynomialRing(GF(2)) + sage: R Infinite polynomial ring in x over Finite Field of size 2 - sage: R.is_field() # optional - sage.rings.finite_rings + sage: R.is_field() False :trac:`9443`:: @@ -1230,8 +1230,8 @@ def gen(self, i=None): x_1 sage: X.gen() is X.gen(0) True - sage: XX = InfinitePolynomialRing(GF(5)) # optional - sage.rings.finite_rings - sage: XX.gen(0) is XX.gen() # optional - sage.rings.finite_rings + sage: XX = InfinitePolynomialRing(GF(5)) + sage: XX.gen(0) is XX.gen() True """ if i is not None and i > len(self._names): @@ -1297,10 +1297,10 @@ def characteristic(self): EXAMPLES:: - sage: X. = InfinitePolynomialRing(GF(25,'a')) # optional - sage.rings.finite_rings - sage: X # optional - sage.rings.finite_rings + sage: X. = InfinitePolynomialRing(GF(25,'a')) # needs sage.rings.finite_rings + sage: X # needs sage.rings.finite_rings Infinite polynomial ring in x, y over Finite Field in a of size 5^2 - sage: X.characteristic() # optional - sage.rings.finite_rings + sage: X.characteristic() # needs sage.rings.finite_rings 5 """ @@ -1349,8 +1349,8 @@ def order(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings - sage: R.order() # optional - sage.rings.finite_rings + sage: R. = InfinitePolynomialRing(GF(2)) + sage: R.order() +Infinity """ from sage.rings.infinity import Infinity @@ -1363,13 +1363,14 @@ def key_basis(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(2)) # optional - sage.rings.finite_rings - sage: R.key_basis() # optional - sage.rings.finite_rings + sage: R. = InfinitePolynomialRing(GF(2)) + sage: R.key_basis() # needs sage.combinat Key polynomial basis over Finite Field of size 2 """ from sage.combinat.key_polynomial import KeyPolynomialBasis return KeyPolynomialBasis(self) + class InfinitePolynomialGen(SageObject): """ This class provides the object which is responsible for returning @@ -1572,8 +1573,8 @@ def construction(self): EXAMPLES:: - sage: R. = InfinitePolynomialRing(GF(5)) # optional - sage.rings.finite_rings - sage: R.construction() # optional - sage.rings.finite_rings + sage: R. = InfinitePolynomialRing(GF(5)) + sage: R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5] """ return [InfinitePolynomialFunctor(self._names, self._order, 'dense'), self._base] diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index b9aa5a69f8e..4be246c6688 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -27,8 +27,8 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): EXAMPLES:: - sage: L. = LaurentPolynomialRing(QQ) # indirect doctest # optional - sage.modules - sage: x*y # optional - sage.modules + sage: L. = LaurentPolynomialRing(QQ) # indirect doctest # needs sage.modules + sage: x*y # needs sage.modules x*y """ cdef type t = type(self) @@ -110,18 +110,19 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): :: - sage: L. = LaurentPolynomialRing(QQ) # optional - sage.modules - sage: L(42)._integer_(ZZ) # optional - sage.modules + sage: # needs sage.modules + sage: L. = LaurentPolynomialRing(QQ) + sage: L(42)._integer_(ZZ) 42 - sage: a._integer_(ZZ) # optional - sage.modules + sage: a._integer_(ZZ) Traceback (most recent call last): ... ValueError: a is not constant - sage: L(2/3)._integer_(ZZ) # optional - sage.modules + sage: L(2/3)._integer_(ZZ) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: ZZ(L(42)) # optional - sage.modules + sage: ZZ(L(42)) 42 """ if not self.is_constant(): @@ -152,14 +153,15 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): :: - sage: L. = LaurentPolynomialRing(QQ) # optional - sage.modules - sage: L(42)._rational_() # optional - sage.modules + sage: # needs sage.modules + sage: L. = LaurentPolynomialRing(QQ) + sage: L(42)._rational_() 42 - sage: a._rational_() # optional - sage.modules + sage: a._rational_() Traceback (most recent call last): ... ValueError: a is not constant - sage: QQ(L(2/3)) # optional - sage.modules + sage: QQ(L(2/3)) 2/3 """ if not self.is_constant(): @@ -175,14 +177,14 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): sage: R. = LaurentPolynomialRing(QQ) sage: a = x^2 + 3*x^3 + 5*x^-1 - sage: a.change_ring(GF(3)) # optional - sage.rings.finite_rings + sage: a.change_ring(GF(3)) 2*x^-1 + x^2 Check that :trac:`22277` is fixed:: - sage: R. = LaurentPolynomialRing(QQ) - sage: a = 2*x^2 + 3*x^3 + 4*x^-1 - sage: a.change_ring(GF(3)) # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(QQ) # needs sage.modules + sage: a = 2*x^2 + 3*x^3 + 4*x^-1 # needs sage.modules + sage: a.change_ring(GF(3)) # needs sage.modules -x^2 + x^-1 """ return self._parent.change_ring(R)(self) @@ -251,40 +253,42 @@ cdef class LaurentPolynomial(CommutativeAlgebraElement): EXAMPLES:: - sage: k. = GF(9) # optional - sage.rings.finite_rings - sage: R. = LaurentPolynomialRing(k) # optional - sage.rings.finite_rings - sage: f = x*a + a # optional - sage.rings.finite_rings - sage: f.map_coefficients(lambda a: a + 1) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(9) + sage: R. = LaurentPolynomialRing(k) + sage: f = x*a + a + sage: f.map_coefficients(lambda a: a + 1) (a + 1) + (a + 1)*x - sage: R. = LaurentPolynomialRing(k, 2) # optional - sage.rings.finite_rings - sage: f = x*a + 2*x^3*y*a + a # optional - sage.rings.finite_rings - sage: f.map_coefficients(lambda a: a + 1) # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(k, 2) + sage: f = x*a + 2*x^3*y*a + a + sage: f.map_coefficients(lambda a: a + 1) (2*a + 1)*x^3*y + (a + 1)*x + a + 1 Examples with different base ring:: - sage: R. = GF(9); S. = GF(81) # optional - sage.rings.finite_rings - sage: h = Hom(R, S)[0]; h # optional - sage.rings.finite_rings + sage: # needs sage.modules sage.rings.finite_rings + sage: R. = GF(9); S. = GF(81) + sage: h = Hom(R, S)[0]; h Ring morphism: From: Finite Field in r of size 3^2 To: Finite Field in s of size 3^4 Defn: r |--> 2*s^3 + 2*s^2 + 1 - sage: T. = LaurentPolynomialRing(R, 2) # optional - sage.modules sage.rings.finite_rings - sage: f = r*X + Y # optional - sage.modules sage.rings.finite_rings - sage: g = f.map_coefficients(h); g # optional - sage.modules sage.rings.finite_rings + sage: T. = LaurentPolynomialRing(R, 2) + sage: f = r*X + Y + sage: g = f.map_coefficients(h); g (2*s^3 + 2*s^2 + 1)*X + Y - sage: g.parent() # optional - sage.modules sage.rings.finite_rings + sage: g.parent() Multivariate Laurent Polynomial Ring in X, Y over Finite Field in s of size 3^4 sage: h = lambda x: x.trace() - sage: g = f.map_coefficients(h); g # optional - sage.modules sage.rings.finite_rings + sage: g = f.map_coefficients(h); g X - Y - sage: g.parent() # optional - sage.modules sage.rings.finite_rings + sage: g.parent() Multivariate Laurent Polynomial Ring in X, Y over Finite Field in r of size 3^2 - sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g # optional - sage.modules sage.rings.finite_rings + sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g X - Y - sage: g.parent() # optional - sage.modules sage.rings.finite_rings + sage: g.parent() Multivariate Laurent Polynomial Ring in X, Y over Finite Field of size 3 """ @@ -329,13 +333,14 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): :: - sage: S. = LaurentPolynomialRing(GF(5)) # optional - sage.rings.finite_rings sage.rings.padics - sage: T. = PolynomialRing(pAdicRing(5)) # optional - sage.rings.finite_rings sage.rings.padics - sage: S(t) # optional - sage.rings.finite_rings sage.rings.padics + sage: # needs sage.rings.padics + sage: S. = LaurentPolynomialRing(GF(5)) + sage: T. = PolynomialRing(pAdicRing(5)) + sage: S(t) s - sage: parent(S(t)) # optional - sage.rings.finite_rings sage.rings.padics + sage: parent(S(t)) Univariate Laurent Polynomial Ring in s over Finite Field of size 5 - sage: parent(S(t)[1]) # optional - sage.rings.finite_rings sage.rings.padics + sage: parent(S(t)[1]) Finite Field of size 5 :: @@ -385,7 +390,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: Pxy = PolynomialRing(QQ, "x,y") sage: Paxb = PolynomialRing(QQ, "a,x,b") sage: Qx = PolynomialRing(ZZ, "x") - sage: Rx = PolynomialRing(GF(2), "x") # optional - sage.rings.finite_rings + sage: Rx = PolynomialRing(GF(2), "x") sage: p1 = Lx.gen() sage: p2 = Lx.zero() sage: p3 = Lx.one() @@ -395,7 +400,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: Pxes = [(Px, Px.gen()), (Qx, Qx.gen()), ....: (Pxy, Pxy.gen(0)), (Paxb, Paxb.gen(1))] - sage: Pxes += [(Rx, Rx.gen())] # optional - sage.rings.finite_rings + sage: Pxes += [(Rx, Rx.gen())] sage: for P, x in Pxes: ....: assert P(p1) == x and parent(P(p1)) is P ....: assert P(p2) == P.zero() and parent(P(p2)) is P @@ -510,13 +515,14 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): You can specify a map on the base ring:: + sage: # needs sage.rings.number_field sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: cc = K.hom([-i]) # optional - sage.rings.number_field - sage: R. = LaurentPolynomialRing(K) # optional - sage.rings.number_field - sage: H = Hom(R, R) # optional - sage.rings.number_field - sage: phi = H([t^-2], base_map=cc) # optional - sage.rings.number_field - sage: phi(i*t) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) + sage: cc = K.hom([-i]) + sage: R. = LaurentPolynomialRing(K) + sage: H = Hom(R, R) + sage: phi = H([t^-2], base_map=cc) + sage: phi(i*t) -i*t^-2 """ x = im_gens[0] @@ -811,22 +817,22 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ EXAMPLES:: + sage: # needs sage.symbolic sage: R. = LaurentPolynomialRing(QQ) sage: f = x^3 + 2/x - sage: g = f._symbolic_(SR); g # optional - sage.symbolic + sage: g = f._symbolic_(SR); g (x^4 + 2)/x - sage: g(x=2) # optional - sage.symbolic + sage: g(x=2) 9 - - sage: g = SR(f) # optional - sage.symbolic - sage: g(x=2) # optional - sage.symbolic + sage: g = SR(f) + sage: g(x=2) 9 Since :trac:`24072` the symbolic ring does not accept positive characteristic:: - sage: R. = LaurentPolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: SR(2*w^3 + 1) # optional - sage.rings.finite_rings sage.symbolic + sage: R. = LaurentPolynomialRing(GF(7)) + sage: SR(2*w^3 + 1) # needs sage.symbolic Traceback (most recent call last): ... TypeError: positive characteristic not allowed in symbolic computations @@ -1046,10 +1052,10 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): """ EXAMPLES:: - sage: R. = LaurentPolynomialRing(GF(2)) # optional - sage.rings.finite_rings - sage: f = 1/x^3 + x + x^2 + 3*x^4 # optional - sage.rings.finite_rings - sage: g = 1 - x + x^2 - x^4 # optional - sage.rings.finite_rings - sage: f*g # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(GF(2)) + sage: f = 1/x^3 + x + x^2 + 3*x^4 + sage: g = 1 - x + x^2 - x^4 + sage: f*g x^-3 + x^-2 + x^-1 + x^8 """ cdef LaurentPolynomial_univariate right = right_r @@ -1625,10 +1631,11 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): The answer is dependent of the base ring:: - sage: S. = LaurentPolynomialRing(QQbar) # optional - sage.rings.number_field - sage: (2 + 4*t + 2*t^2).is_square() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: S. = LaurentPolynomialRing(QQbar) + sage: (2 + 4*t + 2*t^2).is_square() False - sage: (2 + 4*u + 2*u^2).is_square() # optional - sage.rings.number_field + sage: (2 + 4*u + 2*u^2).is_square() True TESTS:: @@ -1751,12 +1758,13 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): Check that :trac:`28187` is fixed:: + sage: # needs sage.symbolic sage: R. = LaurentPolynomialRing(ZZ) sage: p = 1/x + 1 + x - sage: x,y = var("x, y") # optional - sage.symbolic - sage: p._derivative(x) # optional - sage.symbolic + sage: x,y = var("x, y") + sage: p._derivative(x) -x^-2 + 1 - sage: p._derivative(y) # optional - sage.symbolic + sage: p._derivative(y) Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -1903,7 +1911,7 @@ cdef class LaurentPolynomial_univariate(LaurentPolynomial): sage: R. = LaurentPolynomialRing(ZZ) sage: f = 4*t^-7 + 3*t^3 + 2*t^4 + t^-6 - sage: f.factor() # optional - sage.libs.pari + sage: f.factor() # needs sage.libs.pari (t^-7) * (4 + t + 3*t^10 + 2*t^11) """ cdef LaurentPolynomial_univariate u, d diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index 2289b69e111..aa18314e523 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: needs sage.libs.singular sage.modules (because all doctests need laurent_polynomial_mpair, Groebner bases) r""" Ideals in Laurent polynomial rings. @@ -57,15 +57,16 @@ def __init__(self, ring, gens, coerce=True, hint=None): sage: R.ideal([x, y]) Ideal (x, y) of Multivariate Laurent Polynomial Ring in x, y over Integer Ring - sage: R. = LaurentPolynomialRing(GF(3), 2) # optional - sage.rings.finite_rings - sage: R.ideal([x0^2, x1^-3]) # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(GF(3), 2) + sage: R.ideal([x0^2, x1^-3]) Ideal (x0^2, x1^-3) of Multivariate Laurent Polynomial Ring in x0, x1 over Finite Field of size 3 sage: P. = LaurentPolynomialRing(QQ, 2) sage: I = P.ideal([~x + ~y - 1]) sage: print(I) - Ideal (-1 + y^-1 + x^-1) of Multivariate Laurent Polynomial Ring in x, y over Rational Field + Ideal (-1 + y^-1 + x^-1) of + Multivariate Laurent Polynomial Ring in x, y over Rational Field sage: I.is_zero() False sage: (x^(-2) + x^(-1)*y^(-1) - x^(-1)) in I @@ -83,9 +84,9 @@ def __init__(self, ring, gens, coerce=True, hint=None): (Ideal (-1/2*z^2 + y - 1/2*z, x + z) of Multivariate Laurent Polynomial Ring in x, y, z over Rational Field,) - sage: K. = CyclotomicField(4) # optional - sage.rings.number_field - sage: J = I1.base_extend(K) # optional - sage.rings.number_field - sage: J.base_ring() # optional - sage.rings.number_field + sage: K. = CyclotomicField(4) # needs sage.rings.number_field + sage: J = I1.base_extend(K) # needs sage.rings.number_field + sage: J.base_ring() # needs sage.rings.number_field Cyclotomic Field of order 4 and degree 2 """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) @@ -228,8 +229,8 @@ def base_extend(self, F): sage: P. = LaurentPolynomialRing(QQ, 2) sage: I = P.ideal([x + y]) - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: I.base_extend(K) # optional - sage.rings.number_field + sage: K. = CyclotomicField(3) # needs sage.rings.number_field + sage: I.base_extend(K) # needs sage.rings.number_field Ideal (x + y) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 3 and degree 2 """ @@ -250,8 +251,8 @@ def apply_map(self, f, new_ring=None, new_base_ring=None, apply_to_hint=None): sage: I.apply_map(lambda z: z + 2) Ideal (x + 3, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Rational Field - sage: K. = CyclotomicField(4) # optional - sage.rings.number_field - sage: I.apply_map(lambda z: z + 2, new_base_ring=K) # optional - sage.rings.number_field + sage: K. = CyclotomicField(4) # needs sage.rings.number_field + sage: I.apply_map(lambda z: z + 2, new_base_ring=K) # needs sage.rings.number_field Ideal (x + 3, y + 1) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 4 and degree 2 """ @@ -276,16 +277,17 @@ def apply_coeff_map(self, f, new_base_ring=None, forward_hint=True): EXAMPLES:: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: P. = LaurentPolynomialRing(K, 2) # optional - sage.rings.number_field - sage: I = P.ideal([x + z, y - z]) # optional - sage.rings.number_field - sage: h = K.hom([z^2]) # optional - sage.rings.number_field - sage: I.apply_coeff_map(h) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: P. = LaurentPolynomialRing(K, 2) + sage: I = P.ideal([x + z, y - z]) + sage: h = K.hom([z^2]) + sage: I.apply_coeff_map(h) Ideal (x - z - 1, y + z + 1) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 3 and degree 2 - sage: K1. = CyclotomicField(12) # optional - sage.rings.number_field - sage: h1 = K.hom([z1^4]) # optional - sage.rings.number_field - sage: I.apply_coeff_map(h1, new_base_ring=K1) # optional - sage.rings.number_field + sage: K1. = CyclotomicField(12) + sage: h1 = K.hom([z1^4]) + sage: I.apply_coeff_map(h1, new_base_ring=K1) Ideal (x + z1^2 - 1, y - z1^2 + 1) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 12 and degree 4 """ @@ -310,11 +312,12 @@ def toric_coordinate_change(self, M, forward_hint=True): EXAMPLES:: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: P. = LaurentPolynomialRing(K, 2) # optional - sage.rings.number_field - sage: I = P.ideal([x + 1, y - 1]) # optional - sage.rings.number_field - sage: M = Matrix([[2,1], [1,-3]]) # optional - sage.rings.number_field - sage: I.toric_coordinate_change(M) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: P. = LaurentPolynomialRing(K, 2) + sage: I = P.ideal([x + 1, y - 1]) + sage: M = Matrix([[2,1], [1,-3]]) + sage: I.toric_coordinate_change(M) Ideal (x^2*y + 1, -1 + x*y^-3) of Multivariate Laurent Polynomial Ring in x, y over Cyclotomic Field of order 3 and degree 2 """ diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 7f99b0635b5..5db2df9dbbd 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -234,12 +234,13 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): check compatibility with :trac:`26105`:: - sage: F. = GF(4) # optional - sage.rings.finite_rings - sage: LF. = LaurentPolynomialRing(F) # optional - sage.rings.finite_rings - sage: rho = LF.hom([b,a], base_map=F.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: s = t*~a + b +~t*(b**-3)*a**2; rs = rho(s); rs # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = GF(4) + sage: LF. = LaurentPolynomialRing(F) + sage: rho = LF.hom([b,a], base_map=F.frobenius_endomorphism()) + sage: s = t*~a + b +~t*(b**-3)*a**2; rs = rho(s); rs a + (t + 1)*b^-1 + t*a^-3*b^2 - sage: s == rho(rs) # optional - sage.rings.finite_rings + sage: s == rho(rs) True """ p = self._poly @@ -984,17 +985,17 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: L. = LaurentPolynomialRing(QQ) sage: f = x^3 + y^-3 sage: g = y + x - sage: f // g + sage: f // g # needs sage.libs.singular x^5*y^-3 - x^4*y^-2 + x^3*y^-1 sage: h = x + y^(-1) - sage: f // h + sage: f // h # needs sage.libs.singular x^2 - x*y^-1 + y^-2 - sage: h * (f // h) == f + sage: h * (f // h) == f # needs sage.libs.singular True sage: f // 1 x^3 + y^-3 - sage: 1 // f + sage: 1 // f # needs sage.libs.singular 0 TESTS: @@ -1006,8 +1007,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): Check that :trac:`21999` is fixed:: - sage: L. = LaurentPolynomialRing(QQbar) - sage: (a+a*b) // a + sage: L. = LaurentPolynomialRing(QQbar) # needs sage.rings.number_field + sage: (a+a*b) // a # needs sage.libs.singular sage.rings.number_field b + 1 """ cdef LaurentPolynomial_mpair ans = self._new_c() @@ -1035,24 +1036,25 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): EXAMPLES:: sage: R. = LaurentPolynomialRing(QQ) - sage: (s^2 - t^2).quo_rem(s - t) + sage: (s^2 - t^2).quo_rem(s - t) # needs sage.libs.singular (s + t, 0) - sage: (s^-2 - t^2).quo_rem(s - t) + sage: (s^-2 - t^2).quo_rem(s - t) # needs sage.libs.singular (s + t, -s^2 + s^-2) - sage: (s^-2 - t^2).quo_rem(s^-1 - t) + sage: (s^-2 - t^2).quo_rem(s^-1 - t) # needs sage.libs.singular (t + s^-1, 0) TESTS: Verify that :trac:`31257` is fixed:: + sage: # needs sage.libs.singular sage: R. = LaurentPolynomialRing(QQ) sage: q, r = (1/x).quo_rem(y) sage: q, r (x^-1*y^-1, 0) sage: q*y + r == 1/x True - sage: q,r = (x^-2 - y^2).quo_rem(x - y) + sage: q, r = (x^-2 - y^2).quo_rem(x - y) sage: q*(x - y) + r == x^-2 - y^2 True """ @@ -1347,15 +1349,15 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): """ EXAMPLES:: + sage: # needs sage.symbolic sage: R. = LaurentPolynomialRing(QQ) sage: f = x^3 + y/x - sage: g = f._symbolic_(SR); g # optional - sage.symbolic + sage: g = f._symbolic_(SR); g (x^4 + y)/x - sage: g(x=2, y=2) # optional - sage.symbolic + sage: g(x=2, y=2) 9 - - sage: g = SR(f) # optional - sage.symbolic - sage: g(x=2, y=2) # optional - sage.symbolic + sage: g = SR(f) + sage: g(x=2, y=2) 9 """ d = {repr(g): R.var(g) for g in self._parent.gens()} @@ -1633,14 +1635,14 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: p = x^-2*y + x*y^-2 sage: p.rescale_vars({0: 2, 1: 3}) 2/9*x*y^-2 + 3/4*x^-2*y - sage: F = GF(2) # optional - sage.rings.finite_rings - sage: p.rescale_vars({0: 3, 1: 7}, new_ring=L.change_ring(F)) # optional - sage.rings.finite_rings + sage: F = GF(2) + sage: p.rescale_vars({0: 3, 1: 7}, new_ring=L.change_ring(F)) x*y^-2 + x^-2*y Test for :trac:`30331`:: - sage: F. = CyclotomicField(3) # optional - sage.rings.number_field - sage: p.rescale_vars({0: 2, 1: z}, new_ring=L.change_ring(F)) # optional - sage.rings.number_field + sage: F. = CyclotomicField(3) # needs sage.rings.number_field + sage: p.rescale_vars({0: 2, 1: z}, new_ring=L.change_ring(F)) # needs sage.rings.number_field 2*z*x*y^-2 + 1/4*z*x^-2*y """ cdef int i @@ -1695,8 +1697,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: p = 2*x^2 + y - x*y sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]])) 2*x^2*y^2 - x^-2*y^2 + x^-3*y - sage: F = GF(2) # optional - sage.rings.finite_rings - sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]]), # optional - sage.rings.finite_rings + sage: F = GF(2) + sage: p.toric_coordinate_change(Matrix([[1,-3], [1,1]]), ....: new_ring=L.change_ring(F)) x^-2*y^2 + x^-3*y @@ -1772,8 +1774,8 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): sage: L. = LaurentPolynomialRing(QQ, 2) sage: p = x + y - sage: F. = CyclotomicField(3) - sage: p.toric_substitute((2,3), (-1,1), z, new_ring=L.change_ring(F)) + sage: F. = CyclotomicField(3) # needs sage.rings.number_field + sage: p.toric_substitute((2,3), (-1,1), z, new_ring=L.change_ring(F)) # needs sage.rings.number_field (-z - 1)*x^3*y^3 + z*x^-2*y^-2 sage: P. = LaurentPolynomialRing(QQ, 1) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index ece3c70c34f..d922a1a57fc 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -20,7 +20,7 @@ sage: A. = QQ[] sage: R. = LaurentPolynomialRing(A) - sage: matrix(R,2,2,[X,0,0,1]) # optional - sage.modules + sage: matrix(R,2,2,[X,0,0,1]) # needs sage.modules [X 0] [0 1] @@ -64,8 +64,8 @@ def is_LaurentPolynomialRing(R): See https://github.com/sagemath/sage/issues/35229 for details. False - sage: R = LaurentPolynomialRing(QQ,3,'x') # optional - sage.modules - sage: is_LaurentPolynomialRing(R) # optional - sage.modules + sage: R = LaurentPolynomialRing(QQ,3,'x') # needs sage.modules + sage: is_LaurentPolynomialRing(R) # needs sage.modules True """ from sage.misc.superseded import deprecation @@ -121,9 +121,9 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: R. = LaurentPolynomialRing(QQ, 2); R # optional - sage.modules + sage: R. = LaurentPolynomialRing(QQ, 2); R # needs sage.modules Multivariate Laurent Polynomial Ring in x, y over Rational Field - sage: f = x^2 - 2*y^-2 # optional - sage.modules + sage: f = x^2 - 2*y^-2 # needs sage.modules You can't just globally change the names of those variables. This is because objects all over Sage could have pointers to @@ -131,7 +131,7 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: R._assign_names(['z','w']) # optional - sage.modules + sage: R._assign_names(['z','w']) # needs sage.modules Traceback (most recent call last): ... ValueError: variable names cannot be changed after object creation. @@ -163,7 +163,7 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): sage: R. = LaurentPolynomialRing(QQ, sparse=True); R Univariate Laurent Polynomial Ring in abc over Rational Field - sage: R. = LaurentPolynomialRing(PolynomialRing(GF(7),'k')); R # optional - sage.rings.finite_rings + sage: R. = LaurentPolynomialRing(PolynomialRing(GF(7),'k')); R Univariate Laurent Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 @@ -176,31 +176,32 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: R = LaurentPolynomialRing(QQ, 'a,b,c'); R # optional - sage.modules + sage: R = LaurentPolynomialRing(QQ, 'a,b,c'); R # needs sage.modules Multivariate Laurent Polynomial Ring in a, b, c over Rational Field - sage: S = LaurentPolynomialRing(QQ, ['a','b','c']); S # optional - sage.modules + sage: S = LaurentPolynomialRing(QQ, ['a','b','c']); S # needs sage.modules Multivariate Laurent Polynomial Ring in a, b, c over Rational Field - sage: T = LaurentPolynomialRing(QQ, ('a','b','c')); T # optional - sage.modules + sage: T = LaurentPolynomialRing(QQ, ('a','b','c')); T # needs sage.modules Multivariate Laurent Polynomial Ring in a, b, c over Rational Field All three rings are identical. :: - sage: (R is S) and (S is T) # optional - sage.modules + sage: (R is S) and (S is T) # needs sage.modules True There is a unique Laurent polynomial ring with each term order:: - sage: R = LaurentPolynomialRing(QQ, 'x,y,z', order='degrevlex'); R # optional - sage.modules + sage: # needs sage.modules + sage: R = LaurentPolynomialRing(QQ, 'x,y,z', order='degrevlex'); R Multivariate Laurent Polynomial Ring in x, y, z over Rational Field - sage: S = LaurentPolynomialRing(QQ, 'x,y,z', order='invlex'); S # optional - sage.modules + sage: S = LaurentPolynomialRing(QQ, 'x,y,z', order='invlex'); S Multivariate Laurent Polynomial Ring in x, y, z over Rational Field - sage: S is LaurentPolynomialRing(QQ, 'x,y,z', order='invlex') # optional - sage.modules + sage: S is LaurentPolynomialRing(QQ, 'x,y,z', order='invlex') True - sage: R == S # optional - sage.modules + sage: R == S False @@ -211,27 +212,27 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): :: - sage: LaurentPolynomialRing(QQ, 'x', 10) # optional - sage.modules + sage: LaurentPolynomialRing(QQ, 'x', 10) # needs sage.modules Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field - sage: LaurentPolynomialRing(GF(7), 'y', 5) # optional - sage.modules sage.rings.finite_rings + sage: LaurentPolynomialRing(GF(7), 'y', 5) # needs sage.modules Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7 - sage: LaurentPolynomialRing(QQ, 'y', 3, sparse=True) # optional - sage.modules + sage: LaurentPolynomialRing(QQ, 'y', 3, sparse=True) # needs sage.modules Multivariate Laurent Polynomial Ring in y0, y1, y2 over Rational Field By calling the :meth:`~sage.structure.category_object.CategoryObject.inject_variables` method, all those variable names are available for interactive use:: - sage: R = LaurentPolynomialRing(GF(7), 15, 'w'); R # optional - sage.modules sage.rings.finite_rings + sage: R = LaurentPolynomialRing(GF(7), 15, 'w'); R # needs sage.modules Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7 - sage: R.inject_variables() # optional - sage.modules sage.rings.finite_rings + sage: R.inject_variables() # needs sage.modules Defining w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 - sage: (w0 + 2*w8 + w13)^2 # optional - sage.modules sage.rings.finite_rings + sage: (w0 + 2*w8 + w13)^2 # needs sage.modules w0^2 + 4*w0*w8 + 4*w8^2 + 2*w0*w13 + 4*w8*w13 + w13^2 """ from sage.rings.polynomial.polynomial_ring import is_PolynomialRing @@ -354,12 +355,13 @@ def _split_laurent_polynomial_dict_(P, M, d): TESTS:: - sage: L. = LaurentPolynomialRing(ZZ) # optional - sage.modules - sage: M = LaurentPolynomialRing(ZZ, 'c, d') # optional - sage.modules - sage: N = LaurentPolynomialRing(M, 'a, b') # optional - sage.modules - sage: M(c/d + 1/c) # indirect doctest # optional - sage.modules + sage: # needs sage.modules + sage: L. = LaurentPolynomialRing(ZZ) + sage: M = LaurentPolynomialRing(ZZ, 'c, d') + sage: N = LaurentPolynomialRing(M, 'a, b') + sage: M(c/d + 1/c) # indirect doctest c*d^-1 + c^-1 - sage: N(a + b/c/d + 1/b) # indirect doctest # optional - sage.modules + sage: N(a + b/c/d + 1/b) # indirect doctest a + (c^-1*d^-1)*b + b^-1 """ vars_P = P.variable_names() @@ -410,11 +412,12 @@ def from_fraction_field(L, x): EXAMPLES:: + sage: # needs sage.modules sage: from sage.rings.polynomial.laurent_polynomial_ring import from_fraction_field - sage: L. = LaurentPolynomialRing(ZZ) # optional - sage.modules - sage: F = L.fraction_field() # optional - sage.modules - sage: xi = F(~x) # optional - sage.modules - sage: from_fraction_field(L, xi) == ~x # optional - sage.modules + sage: L. = LaurentPolynomialRing(ZZ) + sage: F = L.fraction_field() + sage: xi = F(~x) + sage: from_fraction_field(L, xi) == ~x True """ d = L(x.denominator()) @@ -466,37 +469,39 @@ def _element_constructor_(self, x): sage: L(1/2) 1/2 - sage: L(x + 3/x) + sage: L(x + 3/x) # needs sage.symbolic 3*x^-1 + x :: - sage: L(exp(x)) + sage: L(exp(x)) # needs sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert e^x to a rational :: + sage: # needs sage.modules sage: U = LaurentPolynomialRing(QQ, 'a') sage: V = LaurentPolynomialRing(QQ, 'c') sage: L. = LaurentPolynomialRing(QQ) - sage: M = LaurentPolynomialRing(QQ, 'c, d') # optional - sage.modules - sage: Mc, Md = M.gens() # optional - sage.modules - sage: N = LaurentPolynomialRing(M, 'a, b') # optional - sage.modules - sage: Na, Nb = N.gens() # optional - sage.modules - sage: U(Na) # optional - sage.modules + sage: M = LaurentPolynomialRing(QQ, 'c, d') + sage: Mc, Md = M.gens() + sage: N = LaurentPolynomialRing(M, 'a, b') + sage: Na, Nb = N.gens() + sage: U(Na) a - sage: V(Mc) # optional - sage.modules + sage: V(Mc) c - sage: M(L(0)) # optional - sage.modules + sage: # needs sage.modules + sage: M(L(0)) 0 - sage: N(L(0)) # optional - sage.modules + sage: N(L(0)) 0 - sage: L(M(0)) # optional - sage.modules + sage: L(M(0)) 0 - sage: L(N(0)) # optional - sage.modules + sage: L(N(0)) 0 :: @@ -508,8 +513,8 @@ def _element_constructor_(self, x): sage: C. = LaurentPolynomialRing(B) sage: B(C(b)) b - sage: D. = LaurentPolynomialRing(B) # optional - sage.modules - sage: B(D(b)) # optional - sage.modules + sage: D. = LaurentPolynomialRing(B) # needs sage.modules + sage: B(D(b)) # needs sage.modules b TESTS: @@ -578,11 +583,11 @@ def __init__(self, R): """ EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ,2,'x') # optional - sage.modules - sage: type(L) # optional - sage.modules + sage: L = LaurentPolynomialRing(QQ,2,'x') # needs sage.modules + sage: type(L) # needs sage.modules - sage: L == loads(dumps(L)) # optional - sage.modules + sage: L == loads(dumps(L)) # needs sage.modules True """ if R.ngens() <= 0: @@ -597,9 +602,9 @@ def _repr_(self): """ TESTS:: - sage: LaurentPolynomialRing(QQ,2,'x').__repr__() # optional - sage.modules + sage: LaurentPolynomialRing(QQ,2,'x').__repr__() # needs sage.modules 'Multivariate Laurent Polynomial Ring in x0, x1 over Rational Field' - sage: LaurentPolynomialRing(QQ,1,'x').__repr__() # optional - sage.modules + sage: LaurentPolynomialRing(QQ,1,'x').__repr__() # needs sage.modules 'Multivariate Laurent Polynomial Ring in x over Rational Field' """ return "Multivariate Laurent Polynomial Ring in %s over %s"%(", ".join(self._R.variable_names()), self._R.base_ring()) @@ -610,21 +615,22 @@ def monomial(self, *args): EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ, 'x', 2) # optional - sage.modules - sage: L.monomial(-3, 5) # optional - sage.modules + sage: # needs sage.modules + sage: L = LaurentPolynomialRing(QQ, 'x', 2) + sage: L.monomial(-3, 5) x0^-3*x1^5 - sage: L.monomial(1, 1) # optional - sage.modules + sage: L.monomial(1, 1) x0*x1 - sage: L.monomial(0, 0) # optional - sage.modules + sage: L.monomial(0, 0) 1 - sage: L.monomial(-2, -3) # optional - sage.modules + sage: L.monomial(-2, -3) x0^-2*x1^-3 - sage: x0, x1 = L.gens() # optional - sage.modules - sage: L.monomial(-1, 2) == x0^-1 * x1^2 # optional - sage.modules + sage: x0, x1 = L.gens() # needs sage.modules + sage: L.monomial(-1, 2) == x0^-1 * x1^2 # needs sage.modules True - sage: L.monomial(1, 2, 3) # optional - sage.modules + sage: L.monomial(1, 2, 3) # needs sage.modules Traceback (most recent call last): ... TypeError: tuple key must have same length as ngens @@ -640,96 +646,103 @@ def _element_constructor_(self, x, mon=None): """ EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ,2,'x') # optional - sage.modules - sage: L(1/2) # optional - sage.modules + sage: L = LaurentPolynomialRing(QQ,2,'x') # needs sage.modules + sage: L(1/2) # needs sage.modules 1/2 - sage: M = LaurentPolynomialRing(QQ, 'x, y') # optional - sage.modules - sage: var('x, y') # optional - sage.modules + sage: M = LaurentPolynomialRing(QQ, 'x, y') # needs sage.modules + sage: var('x, y') # needs sage.modules sage.symbolic (x, y) - sage: M(x/y + 3/x) # optional - sage.modules + sage: M(x/y + 3/x) # needs sage.modules sage.symbolic x*y^-1 + 3*x^-1 :: - sage: M(exp(x)) # optional - sage.modules + sage: M(exp(x)) # needs sage.modules sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert e^x to a rational :: - sage: L. = LaurentPolynomialRing(QQ) # optional - sage.modules - sage: M = LaurentPolynomialRing(QQ, 'c, d') # optional - sage.modules - sage: Mc, Md = M.gens() # optional - sage.modules - sage: N = LaurentPolynomialRing(M, 'a, b') # optional - sage.modules - sage: Na, Nb = N.gens() # optional - sage.modules - sage: M(c/d) # optional - sage.modules + sage: # needs sage.modules + sage: L. = LaurentPolynomialRing(QQ) + sage: M = LaurentPolynomialRing(QQ, 'c, d') + sage: Mc, Md = M.gens() + sage: N = LaurentPolynomialRing(M, 'a, b') + sage: Na, Nb = N.gens() + sage: M(c/d) c*d^-1 - sage: N(a*b/c/d) # optional - sage.modules + sage: N(a*b/c/d) (c^-1*d^-1)*a*b - sage: N(c/d) # optional - sage.modules + sage: N(c/d) c*d^-1 - sage: L(Mc) # optional - sage.modules + sage: L(Mc) c - sage: L(Nb) # optional - sage.modules + sage: L(Nb) b - sage: M(L(0)) # optional - sage.modules + sage: # needs sage.modules + sage: M(L(0)) 0 - sage: N(L(0)) # optional - sage.modules + sage: N(L(0)) 0 - sage: L(M(0)) # optional - sage.modules + sage: L(M(0)) 0 - sage: L(N(0)) # optional - sage.modules + sage: L(N(0)) 0 + sage: # needs sage.modules sage: U = LaurentPolynomialRing(QQ, 'a') sage: Ua = U.gen() sage: V = LaurentPolynomialRing(QQ, 'c') sage: Vc = V.gen() - sage: L(Ua) # optional - sage.modules + sage: L(Ua) a - sage: L(Vc) # optional - sage.modules + sage: L(Vc) c - sage: N(Ua) # optional - sage.modules + sage: N(Ua) a - sage: M(Vc) # optional - sage.modules + sage: M(Vc) c - sage: P = LaurentPolynomialRing(QQ, 'a, b') # optional - sage.modules - sage: Q = LaurentPolynomialRing(P, 'c, d') # optional - sage.modules - sage: Q(P.0) # optional - sage.modules + sage: # needs sage.modules + sage: P = LaurentPolynomialRing(QQ, 'a, b') + sage: Q = LaurentPolynomialRing(P, 'c, d') + sage: Q(P.0) a :: + sage: # needs sage.modules sage: A. = LaurentPolynomialRing(QQ) sage: B. = LaurentPolynomialRing(A) - sage: C = LaurentPolynomialRing(QQ, 'a, b') # optional - sage.modules - sage: C(B({1: a})) # optional - sage.modules + sage: C = LaurentPolynomialRing(QQ, 'a, b') + sage: C(B({1: a})) a*b - sage: D. = LaurentPolynomialRing(B) # optional - sage.modules - sage: F. = LaurentPolynomialRing(D) # optional - sage.modules - sage: D(F(d*e)) # optional - sage.modules + sage: D. = LaurentPolynomialRing(B) + sage: F. = LaurentPolynomialRing(D) + sage: D(F(d*e)) d*e :: + sage: # needs sage.modules sage: from sage.rings.polynomial.polydict import ETuple - sage: R. = LaurentPolynomialRing(QQ) # optional - sage.modules - sage: mon = ETuple({}, int(3)) # optional - sage.modules - sage: P = R.polynomial_ring() # optional - sage.modules - sage: R(sum(P.gens()), mon) # optional - sage.modules + sage: R. = LaurentPolynomialRing(QQ) + sage: mon = ETuple({}, int(3)) + sage: P = R.polynomial_ring() + sage: R(sum(P.gens()), mon) x + y + z - sage: R(sum(P.gens()), (-1,-1,-1)) # optional - sage.modules + sage: R(sum(P.gens()), (-1,-1,-1)) y^-1*z^-1 + x^-1*z^-1 + x^-1*y^-1 :: - sage: RL = R.localization(x+1) # optional - sage.modules - sage: xi = RL(~x) # optional - sage.modules - sage: R(xi) == ~x # indirect doctests # optional - sage.modules + sage: # needs sage.modules + sage: RL = R.localization(x + 1) + sage: xi = RL(~x) + sage: R(xi) == ~x # indirect doctests True """ from sage.structure.element import Expression @@ -786,8 +799,8 @@ def __reduce__(self): EXAMPLES:: - sage: L = LaurentPolynomialRing(QQ, 2, 'x') # optional - sage.modules - sage: loads(dumps(L)) == L # optional - sage.modules + sage: L = LaurentPolynomialRing(QQ, 2, 'x') # needs sage.modules + sage: loads(dumps(L)) == L # needs sage.modules True """ return LaurentPolynomialRing_mpair, (self._R,) diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 014fa20efaa..0755d74fd99 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs sage.modules r""" Ring of Laurent Polynomials (base class) @@ -212,6 +212,7 @@ def completion(self, p=None, prec=20, extras=None): sage: 1 / g -x^-1 + 1 + O(x^19) + sage: # needs sage.combinat sage: PP = P.completion(x, prec=oo); PP Lazy Laurent Series Ring in x over Rational Field sage: g = 1 / PP(f); g @@ -390,15 +391,16 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): """ EXAMPLES:: + sage: # needs sage.rings.number_field sage: T. = ZZ[] - sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field - sage: L. = LaurentPolynomialRing(K) # optional - sage.rings.number_field - sage: L._is_valid_homomorphism_(K, (K(1/2), K(3/2))) # optional - sage.rings.number_field + sage: K. = NumberField(t^2 + 1) + sage: L. = LaurentPolynomialRing(K) + sage: L._is_valid_homomorphism_(K, (K(1/2), K(3/2))) True - sage: Q5 = Qp(5); i5 = Q5(-1).sqrt() # optional - sage.rings.padics - sage: L._is_valid_homomorphism_(Q5, (Q5(1/2), Q5(3/2))) # no coercion # optional - sage.rings.padics + sage: Q5 = Qp(5); i5 = Q5(-1).sqrt() # needs sage.rings.padics + sage: L._is_valid_homomorphism_(Q5, (Q5(1/2), Q5(3/2))) # no coercion # needs sage.rings.padics False - sage: L._is_valid_homomorphism_(Q5, (Q5(1/2), Q5(3/2)), base_map=K.hom([i5])) # optional - sage.rings.padics + sage: L._is_valid_homomorphism_(Q5, (Q5(1/2), Q5(3/2)), base_map=K.hom([i5])) # needs sage.rings.padics True """ if base_map is None and not codomain.has_coerce_map_from(self.base_ring()): @@ -463,7 +465,7 @@ def characteristic(self): sage: LaurentPolynomialRing(QQ, 2, 'x').characteristic() 0 - sage: LaurentPolynomialRing(GF(3), 2, 'x').characteristic() # optional - sage.libs.pari + sage: LaurentPolynomialRing(GF(3), 2, 'x').characteristic() 3 """ @@ -518,8 +520,8 @@ def change_ring(self, base_ring=None, names=None, sparse=False, order=None): sage: P. = LaurentPolynomialRing(QQ, 1) sage: P Multivariate Laurent Polynomial Ring in x over Rational Field - sage: K. = CyclotomicField(4) # optional - sage.rings.number_field - sage: P.change_ring(K) # optional - sage.rings.number_field + sage: K. = CyclotomicField(4) # needs sage.rings.number_field + sage: P.change_ring(K) # needs sage.rings.number_field Multivariate Laurent Polynomial Ring in x over Cyclotomic Field of order 4 and degree 2 """ diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index cf2382c0148..d0a430bbfd8 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -14,7 +14,6 @@ from sage.rings.integer cimport Integer from sage.rings.integer_ring import ZZ from sage.structure.coerce cimport coercion_model from sage.misc.derivative import multi_derivative -from sage.combinat.integer_lists.invlex import IntegerListsLex from itertools import chain from sage.misc.misc_c import prod @@ -27,10 +26,7 @@ def is_MPolynomial(x): from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.categories.map cimport Map -from sage.modules.free_module_element import vector from sage.rings.rational_field import QQ -from sage.rings.complex_interval_field import ComplexIntervalField -from sage.rings.real_mpfr import RealField from sage.rings.polynomial.polydict cimport ETuple from sage.rings.polynomial.polynomial_element cimport Polynomial @@ -44,7 +40,8 @@ cdef class MPolynomial(CommutativePolynomial): r""" TESTS:: - sage: ZZ(RR['x,y'](0)) # indirect doctest + sage: # needs sage.rings.real_mpfr + sage: ZZ(RR['x,y'](0)) # indirect doctest 0 sage: ZZ(RR['x,y'](0.5)) Traceback (most recent call last): @@ -55,20 +52,23 @@ cdef class MPolynomial(CommutativePolynomial): ... TypeError: unable to convert non-constant polynomial x to Integer Ring - sage: RR(RR['x,y'](0)) # indirect doctest + sage: # needs sage.rings.real_mpfr + sage: RR(RR['x,y'](0)) # indirect doctest 0.000000000000000 sage: RR(ZZ['x,y'].gen(0)) Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to Real Field with 53 bits of precision - sage: CC(RR['x,y'](0)) # indirect doctest + sage: # needs sage.rings.real_mpfr + sage: CC(RR['x,y'](0)) # indirect doctest 0.000000000000000 sage: CC(ZZ['x,y'].gen(0)) Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to Complex Field with 53 bits of precision + sage: # needs sage.rings.real_mpfr sage: RDF(RR['x,y'](0)) 0.0 sage: RDF(ZZ['x,y'].gen(0)) @@ -76,13 +76,15 @@ cdef class MPolynomial(CommutativePolynomial): ... TypeError: unable to convert non-constant polynomial x to Real Double Field - sage: CDF(RR['x,y'](0)) # indirect doctest + sage: # needs sage.rings.real_mpfr + sage: CDF(RR['x,y'](0)) # indirect doctest 0.0 sage: CDF(ZZ['x,y'].gen(0)) Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to Complex Double Field + sage: # needs sage.libs.flint sage.rings.real_mpfr sage: a = RR['x,y'](1) sage: RBF(a) 1.000000000000000 @@ -92,8 +94,7 @@ cdef class MPolynomial(CommutativePolynomial): 1.000000000000000 sage: CIF(a) 1 - - sage: CBF(RR['x,y'](1)) # indirect doctest + sage: CBF(RR['x,y'](1)) # indirect doctest 1.000000000000000 sage: CBF(ZZ['x,y'].gen(0)) Traceback (most recent call last): @@ -101,8 +102,8 @@ cdef class MPolynomial(CommutativePolynomial): TypeError: unable to convert non-constant polynomial x to Complex ball field with 53 bits of precision sage: x = polygen(QQ) - sage: A. = NumberField(x^3 - 2) - sage: A(A['x,y'](u)) + sage: A. = NumberField(x^3 - 2) # needs sage.rings.number_field + sage: A(A['x,y'](u)) # needs sage.rings.number_field u """ if self.degree() <= 0: @@ -130,7 +131,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: type(RR['x, y'](0)) - sage: int(RR['x,y'](0)) # indirect doctest + sage: int(RR['x,y'](0)) # indirect doctest 0 sage: int(RR['x,y'](10)) 10 @@ -139,7 +140,7 @@ cdef class MPolynomial(CommutativePolynomial): ... TypeError: unable to convert non-constant polynomial x to - sage: ZZ(RR['x,y'](0)) # indirect doctest + sage: ZZ(RR['x,y'](0)) # indirect doctest 0 sage: ZZ(RR['x,y'](0.5)) Traceback (most recent call last): @@ -156,7 +157,7 @@ cdef class MPolynomial(CommutativePolynomial): r""" TESTS:: - sage: float(RR['x,y'](0)) # indirect doctest + sage: float(RR['x,y'](0)) # indirect doctest 0.0 sage: float(ZZ['x,y'].gen(0)) Traceback (most recent call last): @@ -169,7 +170,7 @@ cdef class MPolynomial(CommutativePolynomial): r""" TESTS:: - sage: QQ(RR['x,y'](0.5)) # indirect doctest + sage: QQ(RR['x,y'](0.5)) # indirect doctest 1/2 sage: QQ(RR['x,y'].gen(0)) Traceback (most recent call last): @@ -183,15 +184,15 @@ cdef class MPolynomial(CommutativePolynomial): r""" EXAMPLES:: + sage: # needs sage.symbolic sage: R. = QQ[] sage: f = x^3 + y - sage: g = f._symbolic_(SR); g # optional - sage.symbolic + sage: g = f._symbolic_(SR); g x^3 + y - sage: g(x=2, y=2) # optional - sage.symbolic + sage: g(x=2, y=2) 10 - - sage: g = SR(f) # optional - sage.symbolic - sage: g(x=2, y=2) # optional - sage.symbolic + sage: g = SR(f) + sage: g(x=2, y=2) 10 """ d = dict([(repr(g), R.var(g)) for g in self.parent().gens()]) @@ -314,13 +315,14 @@ cdef class MPolynomial(CommutativePolynomial): Polynomials implemented via Singular:: - sage: R. = PolynomialRing(FiniteField(5)) # optional - sage.rings.finite_rings - sage: f = x^3*y^5 + x^7*y # optional - sage.rings.finite_rings - sage: type(f) # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: R. = PolynomialRing(FiniteField(5)) + sage: f = x^3*y^5 + x^7*y + sage: type(f) - sage: f.derivative(x) # optional - sage.rings.finite_rings + sage: f.derivative(x) 2*x^6*y - 2*x^2*y^5 - sage: f.derivative(y) # optional - sage.rings.finite_rings + sage: f.derivative(y) x^7 Generic multivariate polynomials:: @@ -330,29 +332,30 @@ cdef class MPolynomial(CommutativePolynomial): sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 sage: type(f) - sage: f.derivative(x) # with respect to x + sage: f.derivative(x) # with respect to x (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2 - sage: f.derivative(y) # with respect to y + sage: f.derivative(y) # with respect to y (3*t^2 + O(t^3))*x^2*y^2 - sage: f.derivative(t) # with respect to t (recurses into base ring) + sage: f.derivative(t) # with respect to t (recurses into base ring) (2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3 - sage: f.derivative(x, y) # with respect to x and then y + sage: f.derivative(x, y) # with respect to x and then y (6*t^2 + O(t^3))*x*y^2 - sage: f.derivative(y, 3) # with respect to y three times + sage: f.derivative(y, 3) # with respect to y three times (6*t^2 + O(t^3))*x^2 - sage: f.derivative() # can't figure out the variable + sage: f.derivative() # can't figure out the variable Traceback (most recent call last): ... ValueError: must specify which variable to differentiate with respect to Polynomials over the symbolic ring (just for fun....):: - sage: x = var("x") # optional - sage.symbolic - sage: S. = PolynomialRing(SR) # optional - sage.symbolic - sage: f = u*v*x # optional - sage.symbolic - sage: f.derivative(x) == u*v # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x = var("x") + sage: S. = PolynomialRing(SR) + sage: f = u*v*x + sage: f.derivative(x) == u*v True - sage: f.derivative(u) == v*x # optional - sage.symbolic + sage: f.derivative(u) == v*x True """ return multi_derivative(self, args) @@ -388,11 +391,11 @@ cdef class MPolynomial(CommutativePolynomial): z^5 + x*w*k*z + w^5 + 17*x*w^3 + x^3 + 3*x*w + 5 sage: f.polynomial(k) x*w*z*k + w^5 + z^5 + 17*x*w^3 + x^3 + 3*x*w + 5 - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: f = x^2 + x + y # optional - sage.rings.finite_rings - sage: f.polynomial(x) # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: f = x^2 + x + y + sage: f.polynomial(x) x^2 + x + y - sage: f.polynomial(y) # optional - sage.rings.finite_rings + sage: f.polynomial(y) y + x^2 + x """ cdef int ind @@ -445,8 +448,9 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: R = Qp(7)['x,y,z,t,p']; S = ZZ['x,z,t']['p'] # optional - sage.rings.padics - sage: R(S.0) # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R = Qp(7)['x,y,z,t,p']; S = ZZ['x,z,t']['p'] + sage: R(S.0) p sage: R = QQ['x,y,z,t,p']; S = ZZ['x']['y,z,t']['p'] sage: z = S.base_ring().gen(1) @@ -456,8 +460,8 @@ cdef class MPolynomial(CommutativePolynomial): sage: z = S.base_ring().gen(1); p = S.0; x = S.base_ring().base_ring().gen() sage: R(z+p) z + p - sage: R = Qp(7)['x,y,z,p']; S = ZZ['x']['y,z,t']['p'] # shouldn't work, but should throw a better error # optional - sage.rings.padics - sage: R(S.0) # optional - sage.rings.padics + sage: R = Qp(7)['x,y,z,p']; S = ZZ['x']['y,z,t']['p'] # shouldn't work, but should throw a better error + sage: R(S.0) p See :trac:`2601`:: @@ -466,7 +470,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: a._mpoly_dict_recursive(('c', 'b', 'a')) {(0, 0, 1): 1} sage: testR. = PolynomialRing(QQ,3) - sage: id_ringA = ideal([a^2-b,b^2-c,c^2-a]) + sage: id_ringA = ideal([a^2 - b, b^2 - c, c^2 - a]) sage: id_ringB = ideal(id_ringA.gens()).change_ring(PolynomialRing(QQ,'c,b,a')) """ if not self: @@ -560,9 +564,9 @@ cdef class MPolynomial(CommutativePolynomial): Verify that :trac:`16251` has been resolved, i.e., polynomials with unhashable coefficients are unhashable:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: hash(t) # optional - sage.rings.padics + sage: K. = Qq(9) # needs sage.rings.padics + sage: R. = K[] # needs sage.rings.padics + sage: hash(t) # needs sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' @@ -690,9 +694,9 @@ cdef class MPolynomial(CommutativePolynomial): In particular, this can be surprising in positive characteristic:: - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: f = x + 1 # optional - sage.rings.finite_rings - sage: f.homogenize(x) # optional - sage.rings.finite_rings + sage: R. = GF(2)[] + sage: f = x + 1 + sage: f.homogenize(x) 0 TESTS:: @@ -815,15 +819,15 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = (x^2*y + 2*x - 3) sage: g = (x + 1)*f - sage: g % f # optional - sage.libs.singular + sage: g % f # needs sage.libs.singular 0 - sage: (g+1) % f # optional - sage.libs.singular + sage: (g+1) % f # needs sage.libs.singular 1 sage: M = x*y sage: N = x^2*y^3 - sage: M.divides(N) # optional - sage.libs.singular + sage: M.divides(N) # needs sage.libs.singular True """ try: @@ -847,21 +851,22 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + 3/5*y + 1 - sage: f.change_ring(GF(7)) # optional - sage.rings.finite_rings + sage: f.change_ring(GF(7)) x^3 + 2*y + 1 :: - sage: R. = GF(9,'a')[] # optional - sage.rings.finite_rings - sage: (x+2*y).change_ring(GF(3)) # optional - sage.rings.finite_rings + sage: R. = GF(9,'a')[] # needs sage.rings.finite_rings + sage: (x+2*y).change_ring(GF(3)) x - y :: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: f = x^2 + z*y # optional - sage.rings.number_field - sage: f.change_ring(K.embeddings(CC)[1]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: R. = K[] + sage: f = x^2 + z*y + sage: f.change_ring(K.embeddings(CC)[1]) x^2 + (-0.500000000000000 - 0.866025403784438*I)*y TESTS: @@ -869,7 +874,7 @@ cdef class MPolynomial(CommutativePolynomial): Check that :trac:`25022` is fixed:: sage: K. = ZZ[] - sage: (x*y).change_ring(SR).monomials() # optional - sage.rings.number_field sage.symbolic + sage: (x*y).change_ring(SR).monomials() # needs sage.rings.number_field sage.symbolic [x*y] """ if isinstance(R, Map): @@ -891,27 +896,27 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.groups sage: R. = QQ[] sage: p = (x+y+z)**2 - 3 * (x+y)*(x+z)*(y+z) - sage: p.is_symmetric() # optional - sage.groups + sage: p.is_symmetric() True - sage: (x + y - z).is_symmetric() # optional - sage.groups + sage: (x + y - z).is_symmetric() False - sage: R.one().is_symmetric() # optional - sage.groups + sage: R.one().is_symmetric() True - sage: p = (x-y)*(y-z)*(z-x) - sage: p.is_symmetric() # optional - sage.groups + sage: p.is_symmetric() False - sage: p.is_symmetric(AlternatingGroup(3)) # optional - sage.groups + sage: p.is_symmetric(AlternatingGroup(3)) True sage: R. = QQ[] - sage: ((x + y)**2).is_symmetric() # optional - sage.groups + sage: ((x + y)**2).is_symmetric() # needs sage.groups True - sage: R.one().is_symmetric() # optional - sage.groups + sage: R.one().is_symmetric() # needs sage.groups True - sage: (x + 2*y).is_symmetric() # optional - sage.groups + sage: (x + 2*y).is_symmetric() # needs sage.groups False An example with a GAP permutation group (here the quaternions):: @@ -921,23 +926,23 @@ cdef class MPolynomial(CommutativePolynomial): sage: p = sum(prod(x[i] for i in e) ....: for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7), ....: (3,4,5), (3,4,6), (3,5,6), (4,5,6)]) - sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) # optional - sage.groups + sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) # needs sage.groups True sage: p = sum(prod(x[i] for i in e) ....: for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7), ....: (3,4,5), (3,4,6), (3,5,6)]) - sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) # optional - sage.groups + sage: p.is_symmetric(libgap.TransitiveGroup(8, 5)) # needs sage.groups False TESTS:: sage: R = PolynomialRing(QQ, 'x', 3) - sage: R.one().is_symmetric(3) # optional - sage.groups + sage: R.one().is_symmetric(3) # needs sage.groups Traceback (most recent call last): ... ValueError: argument must be a permutation group - sage: R.one().is_symmetric(SymmetricGroup(4)) # optional - sage.groups + sage: R.one().is_symmetric(SymmetricGroup(4)) # needs sage.groups Traceback (most recent call last): ... ValueError: invalid data to initialize a permutation @@ -979,40 +984,43 @@ cdef class MPolynomial(CommutativePolynomial): Multivariate polynomial over integers:: + sage: # needs sage.libs.gap sage: R. = ZZ[] - sage: gap(-x*y + 3*z) # indirect doctest # optional - sage.libs.gap + sage: gap(-x*y + 3*z) # indirect doctest -x*y+3*z - sage: gap(R.zero()) # indirect doctest # optional - sage.libs.gap + sage: gap(R.zero()) # indirect doctest 0 - sage: (x+y+z)._gap_(libgap) # optional - sage.libs.gap + sage: (x+y+z)._gap_(libgap) x+y+z - sage: g = gap(x - y + 3*x*y*z) # optional - sage.libs.gap - sage: R(g) # optional - sage.libs.gap + sage: g = gap(x - y + 3*x*y*z) # needs sage.libs.gap + sage: R(g) # needs sage.libs.gap 3*x*y*z + x - y - sage: g = libgap(5*x - y*z) # optional - sage.libs.gap - sage: R(g) # optional - sage.libs.gap + sage: g = libgap(5*x - y*z) # needs sage.libs.gap + sage: R(g) # needs sage.libs.gap -y*z + 5*x Multivariate polynomial over a cyclotomic field:: - sage: F. = CyclotomicField(8) # optional - sage.rings.number_field - sage: P. = F[] # optional - sage.rings.number_field - sage: p = zeta + zeta^2*x + zeta^3*y + (1+zeta)*x*y # optional - sage.rings.number_field - sage: gap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field + sage: # needs sage.libs.gap sage.rings.number_field + sage: F. = CyclotomicField(8) + sage: P. = F[] + sage: p = zeta + zeta^2*x + zeta^3*y + (1+zeta)*x*y + sage: gap(p) # indirect doctest (1+E(8))*x*y+E(4)*x+E(8)^3*y+E(8) - sage: libgap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field + sage: libgap(p) # indirect doctest (1+E(8))*x*y+E(4)*x+E(8)^3*y+E(8) Multivariate polynomial over a polynomial ring over a cyclotomic field:: - sage: S. = F[] # optional - sage.rings.number_field - sage: P. = S[] # optional - sage.rings.number_field - sage: p = zeta + zeta^2*x*z + zeta^3*y*z^2 + (1+zeta)*x*y*z # optional - sage.rings.number_field - sage: gap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field + sage: # needs sage.libs.gap sage.rings.number_field + sage: S. = F[] + sage: P. = S[] + sage: p = zeta + zeta^2*x*z + zeta^3*y*z^2 + (1+zeta)*x*y*z + sage: gap(p) # indirect doctest ((1+E(8))*z)*x*y+E(4)*z*x+E(8)^3*z^2*y+E(8) - sage: libgap(p) # indirect doctest # optional - sage.libs.gap sage.rings.number_field + sage: libgap(p) # indirect doctest ((1+E(8))*z)*x*y+E(4)*z*x+E(8)^3*z^2*y+E(8) """ R = gap(self.parent()) @@ -1024,9 +1032,9 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: sage: R. = ZZ[] - sage: libgap(-x*y + 3*z) # indirect doctest # optional - sage.libs.gap + sage: libgap(-x*y + 3*z) # indirect doctest # needs sage.libs.gap -x*y+3*z - sage: libgap(R.zero()) # indirect doctest # optional - sage.libs.gap + sage: libgap(R.zero()) # indirect doctest # needs sage.libs.gap 0 """ from sage.libs.gap.libgap import libgap @@ -1039,20 +1047,21 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: k. = GF(25); R. = k[] # optional - sage.rings.finite_rings - sage: f = y*x^2*b + x*(b+1) + 1 # optional - sage.rings.finite_rings - sage: magma = Magma() # so var names same below # optional - sage.rings.finite_rings - sage: magma(f) # optional - magma # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(25); R. = k[] + sage: f = y*x^2*b + x*(b+1) + 1 + sage: magma = Magma() # so var names same below + sage: magma(f) # optional - magma b*x^2*y + b^22*x + 1 - sage: f._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings + sage: f._magma_init_(magma) # optional - magma '_sage_[...]!((_sage_[...]!(_sage_[...]))*_sage_[...]^2*_sage_[...]+(_sage_[...]!(_sage_[...] + 1))*_sage_[...]+(_sage_[...]!(1))*1)' A more complicated nested example:: sage: R. = QQ[]; S. = R[]; f = (2/3)*x^3*z + w^2 + 5 - sage: f._magma_init_(magma) # optional - magma + sage: f._magma_init_(magma) # optional - magma '_sage_[...]!((_sage_[...]!((1/1)*1))*_sage_[...]^2+(_sage_[...]!((2/3)*_sage_[...]^3))*_sage_[...]+(_sage_[...]!((5/1)*1))*1)' - sage: magma(f) # optional - magma + sage: magma(f) # optional - magma w^2 + 2/3*x^3*z + 5 """ R = magma(self.parent()) @@ -1074,13 +1083,14 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: R. = GF(101)['e,i'][] # optional - sage.rings.finite_rings - sage: f = R('e*i') * x + y^2 # optional - sage.rings.finite_rings - sage: f._giac_init_() # optional - sage.rings.finite_rings + sage: # needs sage.libs.giac + sage: R. = GF(101)['e,i'][] + sage: f = R('e*i') * x + y^2 + sage: f._giac_init_() '((1)*1)*sageVARy^2+((1)*sageVARe*sageVARi)*sageVARx' - sage: giac(f) # optional - sage.rings.finite_rings + sage: giac(f) sageVARy^2+sageVARe*sageVARi*sageVARx - sage: giac(R.zero()) # optional - sage.rings.finite_rings + sage: giac(R.zero()) 0 """ g = ['sageVAR' + x for x in self.parent().variable_names()] @@ -1125,20 +1135,19 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = 1 + x*y + x^3 + y^3 - sage: P = f.newton_polytope() # optional - sage.geometry.polyhedron - sage: P # optional - sage.geometry.polyhedron + sage: P = f.newton_polytope(); P # needs sage.geometry.polyhedron A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices - sage: P.is_simple() # optional - sage.geometry.polyhedron + sage: P.is_simple() # needs sage.geometry.polyhedron True TESTS:: sage: R. = QQ[] - sage: R(0).newton_polytope() # optional - sage.geometry.polyhedron + sage: R(0).newton_polytope() # needs sage.geometry.polyhedron The empty polyhedron in ZZ^0 - sage: R(1).newton_polytope() # optional - sage.geometry.polyhedron + sage: R(1).newton_polytope() # needs sage.geometry.polyhedron A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex - sage: R(x^2+y^2).newton_polytope().integral_points() # optional - sage.geometry.polyhedron + sage: R(x^2+y^2).newton_polytope().integral_points() # needs sage.geometry.polyhedron ((0, 2), (1, 1), (2, 0)) """ from sage.geometry.polyhedron.constructor import Polyhedron @@ -1288,32 +1297,33 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: k. = GF(9); R. = k[]; f = x*a + 2*x^3*y*a + a # optional - sage.rings.finite_rings - sage: f.map_coefficients(lambda a: a + 1) # optional - sage.rings.finite_rings + sage: k. = GF(9); R. = k[]; f = x*a + 2*x^3*y*a + a # needs sage.rings.finite_rings + sage: f.map_coefficients(lambda a: a + 1) # needs sage.rings.finite_rings (-a + 1)*x^3*y + (a + 1)*x + (a + 1) Examples with different base ring:: - sage: R. = GF(9); S. = GF(81) # optional - sage.rings.finite_rings - sage: h = Hom(R,S)[0]; h # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(9); S. = GF(81) + sage: h = Hom(R,S)[0]; h Ring morphism: From: Finite Field in r of size 3^2 To: Finite Field in s of size 3^4 Defn: r |--> 2*s^3 + 2*s^2 + 1 - sage: T. = R[] # optional - sage.rings.finite_rings - sage: f = r*X + Y # optional - sage.rings.finite_rings - sage: g = f.map_coefficients(h); g # optional - sage.rings.finite_rings + sage: T. = R[] + sage: f = r*X + Y + sage: g = f.map_coefficients(h); g (-s^3 - s^2 + 1)*X + Y - sage: g.parent() # optional - sage.rings.finite_rings + sage: g.parent() Multivariate Polynomial Ring in X, Y over Finite Field in s of size 3^4 - sage: h = lambda x: x.trace() # optional - sage.rings.finite_rings - sage: g = f.map_coefficients(h); g # optional - sage.rings.finite_rings + sage: h = lambda x: x.trace() + sage: g = f.map_coefficients(h); g X - Y - sage: g.parent() # optional - sage.rings.finite_rings + sage: g.parent() Multivariate Polynomial Ring in X, Y over Finite Field in r of size 3^2 - sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(h, new_base_ring=GF(3)); g X - Y - sage: g.parent() # optional - sage.rings.finite_rings + sage: g.parent() Multivariate Polynomial Ring in X, Y over Finite Field of size 3 """ @@ -1337,10 +1347,11 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: k. = GF(9) # optional - sage.rings.finite_rings - sage: R. = PolynomialRing(k) # optional - sage.rings.finite_rings - sage: f = (x-a) * (y-a) # optional - sage.rings.finite_rings - sage: f._norm_over_nonprime_finite_field() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(9) + sage: R. = PolynomialRing(k) + sage: f = (x-a) * (y-a) + sage: f._norm_over_nonprime_finite_field() x^2*y^2 - x^2*y - x*y^2 - x^2 + x*y - y^2 + x + y + 1 """ P = self.parent() @@ -1376,8 +1387,8 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(ZZ) sage: f = (y + 1)*x + 3*x**2 sage: g = (y + 2)*x + 4*x**2 - sage: M = f.sylvester_matrix(g, x) # optional - sage.modules - sage: M # optional - sage.modules + sage: M = f.sylvester_matrix(g, x) # needs sage.modules + sage: M # needs sage.modules [ 3 y + 1 0 0] [ 0 3 y + 1 0] [ 4 y + 2 0 0] @@ -1386,10 +1397,10 @@ cdef class MPolynomial(CommutativePolynomial): If the polynomials share a non-constant common factor then the determinant of the Sylvester matrix will be zero:: - sage: M.determinant() # optional - sage.modules + sage: M.determinant() # needs sage.modules 0 - sage: f.sylvester_matrix(1 + g, x).determinant() # optional - sage.modules + sage: f.sylvester_matrix(1 + g, x).determinant() # needs sage.modules y^2 - y + 7 If both polynomials are of positive degree with respect to ``variable``, the @@ -1397,7 +1408,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: f = R.random_element(4) or (x^2 * y^2) sage: g = R.random_element(4) or (x^2 * y^2) - sage: f.sylvester_matrix(g, x).determinant() == f.resultant(g, x) # optional - sage.modules + sage: f.sylvester_matrix(g, x).determinant() == f.resultant(g, x) # needs sage.libs.singular sage.modules True TESTS: @@ -1406,25 +1417,26 @@ cdef class MPolynomial(CommutativePolynomial): sage: f = x + y sage: g = x + y - sage: f.sylvester_matrix(g) # optional - sage.modules + sage: f.sylvester_matrix(g) # needs sage.modules [1 y] [1 y] Polynomials must be defined over compatible base rings:: + sage: # needs sage.modules sage: K. = QQ[] sage: f = x + y sage: L. = ZZ[] sage: g = x + y - sage: R. = GF(25, 'a')[] + sage: R. = GF(25, 'a')[] # needs sage.rings.finite_rings sage: h = x + y - sage: f.sylvester_matrix(g, 'x') # optional - sage.modules + sage: f.sylvester_matrix(g, 'x') [1 y] [1 y] - sage: g.sylvester_matrix(h, 'x') # optional - sage.modules + sage: g.sylvester_matrix(h, 'x') # needs sage.rings.finite_rings [1 y] [1 y] - sage: f.sylvester_matrix(h, 'x') # optional - sage.modules + sage: f.sylvester_matrix(h, 'x') # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -1434,31 +1446,32 @@ cdef class MPolynomial(CommutativePolynomial): sage: f = x + y sage: L. = QQ[] sage: g = x + z - sage: f.sylvester_matrix(g) # optional - sage.modules + sage: f.sylvester_matrix(g) [1 y] [1 z] Corner cases:: - sage: K.=QQ[] + sage: # needs sage.modules + sage: K. = QQ[] sage: f = x^2 + 1 sage: g = K(0) - sage: f.sylvester_matrix(g) # optional - sage.modules + sage: f.sylvester_matrix(g) Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(f) # optional - sage.modules + sage: g.sylvester_matrix(f) Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(g) # optional - sage.modules + sage: g.sylvester_matrix(g) Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: K(3).sylvester_matrix(x^2) # optional - sage.modules + sage: K(3).sylvester_matrix(x^2) [3 0] [0 3] - sage: K(3).sylvester_matrix(K(4)) # optional - sage.modules + sage: K(3).sylvester_matrix(K(4)) [] """ @@ -1522,11 +1535,11 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = 4*x*y^2 + 1/4*x*y*z + 3/2*x*z^2 - 1/2*z^2 - sage: f.discriminant(x) # optional - sage.libs.singular + sage: f.discriminant(x) # needs sage.libs.singular 1 - sage: f.discriminant(y) # optional - sage.libs.singular + sage: f.discriminant(y) # needs sage.libs.singular -383/16*x^2*z^2 + 8*x*z^2 - sage: f.discriminant(z) # optional - sage.libs.singular + sage: f.discriminant(z) # needs sage.libs.singular -383/16*x^2*y^2 + 8*x*y^2 Note that, unlike the univariate case, the result lives in @@ -1534,20 +1547,21 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^5*y + 3*x^2*y^2 - 2*x + y - 1 - sage: f.discriminant(y) # optional - sage.libs.singular + sage: f.discriminant(y) # needs sage.libs.singular x^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1 - sage: f.polynomial(y).discriminant() # optional - sage.libs.singular + sage: f.polynomial(y).discriminant() x^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1 - sage: f.discriminant(y).parent() == f.polynomial(y).discriminant().parent() # optional - sage.libs.singular + sage: f.discriminant(y).parent() == f.polynomial(y).discriminant().parent() # needs sage.libs.singular False TESTS: Test polynomials over QQbar (:trac:`25265`):: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = x^5*y + 3*x^2*y^2 - 2*x + y - 1 # optional - sage.rings.number_field - sage: f.discriminant(y) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = x^5*y + 3*x^2*y^2 - 2*x + y - 1 + sage: f.discriminant(y) x^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1 AUTHOR: Miguel Marco @@ -1626,7 +1640,7 @@ cdef class MPolynomial(CommutativePolynomial): The number of polynomials has to match the number of variables:: sage: R. = PolynomialRing(QQ, 3) - sage: y.macaulay_resultant(x + z) # optional - sage.modules + sage: y.macaulay_resultant(x + z) # needs sage.modules Traceback (most recent call last): ... TypeError: number of polynomials(= 2) must equal number of variables (= 3) @@ -1634,7 +1648,7 @@ cdef class MPolynomial(CommutativePolynomial): The polynomials need to be all homogeneous:: sage: R. = PolynomialRing(QQ, 3) - sage: y.macaulay_resultant([x + z, z + x^3]) # optional - sage.modules + sage: y.macaulay_resultant([x + z, z + x^3]) # needs sage.modules Traceback (most recent call last): ... TypeError: resultant for non-homogeneous polynomials is not supported @@ -1643,7 +1657,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ, 3) sage: S. = PolynomialRing(QQ, 2) - sage: y.macaulay_resultant(z + x, z) # optional - sage.modules + sage: y.macaulay_resultant(z + x, z) # needs sage.modules Traceback (most recent call last): ... TypeError: not all inputs are polynomials in the calling ring @@ -1652,7 +1666,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: K. = PolynomialRing(ZZ, 2) sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2]) - sage: flist[0].macaulay_resultant(flist[1:]) # optional - sage.modules + sage: flist[0].macaulay_resultant(flist[1:]) # needs sage.modules u2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 + u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - 2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9 @@ -1663,7 +1677,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: K. = PolynomialRing(ZZ, 2) sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,1]) - sage: flist[0].macaulay_resultant(flist[1:]) # optional - sage.modules + sage: flist[0].macaulay_resultant(flist[1:]) # needs sage.modules -u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8 The following example is by Patrick Ingram (:arxiv:`1310.4114`):: @@ -1673,38 +1687,38 @@ cdef class MPolynomial(CommutativePolynomial): sage: f0 = y0*x2^2 - x0^2 + 2*x1*x2 sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2 sage: f2 = x0*x1 - x2^2 - sage: f0.macaulay_resultant(f1, f2) # optional - sage.modules + sage: f0.macaulay_resultant(f1, f2) # needs sage.modules y0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27 a simple example with constant rational coefficients:: sage: R. = PolynomialRing(QQ, 4) - sage: w.macaulay_resultant([z, y, x]) # optional - sage.modules + sage: w.macaulay_resultant([z, y, x]) # needs sage.modules 1 an example where the resultant vanishes:: sage: R. = PolynomialRing(QQ, 3) - sage: (x + y).macaulay_resultant([y^2, x]) # optional - sage.modules + sage: (x + y).macaulay_resultant([y^2, x]) # needs sage.modules 0 an example of bad reduction at a prime ``p = 5``:: sage: R. = PolynomialRing(QQ, 3) - sage: y.macaulay_resultant([x^3 + 25*y^2*x, 5*z]) # optional - sage.modules + sage: y.macaulay_resultant([x^3 + 25*y^2*x, 5*z]) # needs sage.libs.pari sage.modules 125 The input can given as an unpacked list of polynomials:: sage: R. = PolynomialRing(QQ, 3) - sage: y.macaulay_resultant(x^3 + 25*y^2*x, 5*z) # optional - sage.modules + sage: y.macaulay_resultant(x^3 + 25*y^2*x, 5*z) # needs sage.libs.pari sage.modules 125 an example when the coefficients live in a finite field:: - sage: F = FiniteField(11) # optional - sage.rings.finite_rings - sage: R. = PolynomialRing(F, 4) # optional - sage.rings.finite_rings - sage: z.macaulay_resultant([x^3, 5*y, w]) # optional - sage.rings.finite_rings sage.modules + sage: F = FiniteField(11) + sage: R. = PolynomialRing(F, 4) + sage: z.macaulay_resultant([x^3, 5*y, w]) # needs sage.modules sage.rings.finite_rings 4 example when the denominator in the algorithm vanishes(in this case @@ -1712,7 +1726,7 @@ cdef class MPolynomial(CommutativePolynomial): char polynomials of numerator/denominator):: sage: R. = PolynomialRing(QQ, 3) - sage: y.macaulay_resultant([x + z, z^2]) # optional - sage.modules + sage: y.macaulay_resultant([x + z, z^2]) # needs sage.libs.pari sage.modules -1 When there are only 2 polynomials, the Macaulay resultant degenerates to the traditional resultant:: @@ -1722,7 +1736,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: fh = f.homogenize() sage: gh = g.homogenize() sage: RH = fh.parent() - sage: f.resultant(g) == fh.macaulay_resultant(gh) # optional - sage.modules + sage: f.resultant(g) == fh.macaulay_resultant(gh) # needs sage.modules True """ @@ -1763,10 +1777,11 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: R. = NumberField(symbolic_expression(x^2+3),'a')['x,y'] # optional - sage.rings.number_field sage.symbolic - sage: f = (1/17)*x^19 + (1/6)*y - (2/3)*x + 1/3; f # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: R. = NumberField(symbolic_expression(x^2+3),'a')['x,y'] + sage: f = (1/17)*x^19 + (1/6)*y - (2/3)*x + 1/3; f 1/17*x^19 - 2/3*x + 1/6*y + 1/3 - sage: f.denominator() # optional - sage.rings.number_field sage.symbolic + sage: f.denominator() 102 Finally, we try to compute the denominator of a polynomial with @@ -1775,27 +1790,27 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: R. = RR[] - sage: f = a + b + RR('0.3'); f + sage: R. = RR[] # needs sage.rings.real_mpfr + sage: f = a + b + RR('0.3'); f # needs sage.rings.real_mpfr a + b + 0.300000000000000 - sage: f.denominator() + sage: f.denominator() # needs sage.rings.real_mpfr 1.00000000000000 Check that the denominator is an element over the base whenever the base has no denominator function. This closes :trac:`9063`:: - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: x = R(0) # optional - sage.rings.finite_rings - sage: x.denominator() # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: x = R(0) + sage: x.denominator() 1 - sage: type(x.denominator()) # optional - sage.rings.finite_rings + sage: type(x.denominator()) - sage: type(a.denominator()) # optional - sage.rings.finite_rings + sage: type(a.denominator()) sage: from sage.rings.polynomial.multi_polynomial_element import MPolynomial - sage: isinstance(a / b, MPolynomial) # optional - sage.rings.finite_rings + sage: isinstance(a / b, MPolynomial) False - sage: isinstance(a.numerator() / a.denominator(), MPolynomial) # optional - sage.rings.finite_rings + sage: isinstance(a.numerator() / a.denominator(), MPolynomial) True """ if self.degree() == -1: @@ -1840,12 +1855,13 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: R. = NumberField(symbolic_expression(x^2+3), 'a')['x,y'] # optional - sage.rings.number_field sage.symbolic - sage: f = (1/17)*y^19 - (2/3)*x + 1/3; f # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: R. = NumberField(symbolic_expression(x^2+3), 'a')['x,y'] + sage: f = (1/17)*y^19 - (2/3)*x + 1/3; f 1/17*y^19 - 2/3*x + 1/3 - sage: f.numerator() # optional - sage.rings.number_field sage.symbolic + sage: f.numerator() 3*y^19 - 34*x + 17 - sage: f == f.numerator() # optional - sage.rings.number_field sage.symbolic + sage: f == f.numerator() False We try to compute the numerator of a polynomial with coefficients in @@ -1853,10 +1869,10 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: K. = GF(3)['x, y, z'] # optional - sage.rings.finite_rings - sage: f = 2*x*z + 2*z^2 + 2*y + 1; f # optional - sage.rings.finite_rings + sage: K. = GF(3)['x, y, z'] + sage: f = 2*x*z + 2*z^2 + 2*y + 1; f -x*z - z^2 - y + 1 - sage: f.numerator() # optional - sage.rings.finite_rings + sage: f.numerator() -x*z - z^2 - y + 1 We check that the computation the numerator and denominator @@ -1864,9 +1880,10 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: K = NumberField(symbolic_expression('x^3+2'), 'a')['x']['s,t'] # optional - sage.rings.number_field sage.symbolic - sage: f = K.random_element() # optional - sage.rings.number_field sage.symbolic - sage: f.numerator() / f.denominator() == f # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: K = NumberField(symbolic_expression('x^3+2'), 'a')['x']['s,t'] + sage: f = K.random_element() + sage: f.numerator() / f.denominator() == f True sage: R = RR['x,y,z'] sage: f = R.random_element() @@ -1882,13 +1899,13 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: A. = PolynomialRing(CC, 2, order='degrevlex') sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ]) sage: f = x*y^13 + y^12 - sage: M = f.lift(I) - sage: M + sage: M = f.lift(I); M # needs sage.libs.singular [y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 + y^4] - sage: sum( map( mul , zip( M, I.gens() ) ) ) == f + sage: sum(map(mul, zip(M, I.gens()))) == f # needs sage.libs.singular True """ raise NotImplementedError @@ -1911,9 +1928,9 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1) - sage: f = x1 + 3*x2^2; g = f.inverse_mod(I); g # optional - sage.libs.singular + sage: f = x1 + 3*x2^2; g = f.inverse_mod(I); g # needs sage.libs.singular 1/16*x1 + 3/16 - sage: (f*g).reduce(I) # optional - sage.libs.singular + sage: (f*g).reduce(I) # needs sage.libs.singular 1 Test a non-invertible element:: @@ -1921,7 +1938,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1) sage: f = x1 + x2 - sage: f.inverse_mod(I) # optional - sage.libs.singular + sage: f.inverse_mod(I) # needs sage.libs.singular Traceback (most recent call last): ... ArithmeticError: element is non-invertible @@ -1954,38 +1971,38 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = GF(7)[] # optional - sage.rings.finite_rings - sage: p = x^3 + y + x*z^2 # optional - sage.rings.finite_rings - sage: p.weighted_degree({z:0, x:1, y:2}) # optional - sage.rings.finite_rings + sage: R. = GF(7)[] + sage: p = x^3 + y + x*z^2 + sage: p.weighted_degree({z:0, x:1, y:2}) 3 - sage: p.weighted_degree(1, 2, 0) # optional - sage.rings.finite_rings + sage: p.weighted_degree(1, 2, 0) 3 - sage: p.weighted_degree((1, 4, 2)) # optional - sage.rings.finite_rings + sage: p.weighted_degree((1, 4, 2)) 5 - sage: p.weighted_degree((1, 4, 1)) # optional - sage.rings.finite_rings + sage: p.weighted_degree((1, 4, 1)) 4 - sage: p.weighted_degree(2**64, 2**50, 2**128) # optional - sage.rings.finite_rings + sage: p.weighted_degree(2**64, 2**50, 2**128) 680564733841876926945195958937245974528 - sage: q = R.random_element(100, 20) #random # optional - sage.rings.finite_rings - sage: q.weighted_degree(1, 1, 1) == q.total_degree() # optional - sage.rings.finite_rings + sage: q = R.random_element(100, 20) + sage: q.weighted_degree(1, 1, 1) == q.total_degree() True You may also work with negative weights :: - sage: p.weighted_degree(-1, -2, -1) # optional - sage.rings.finite_rings + sage: p.weighted_degree(-1, -2, -1) -2 Note that only integer weights are allowed :: - sage: p.weighted_degree(x, 1, 1) # optional - sage.rings.finite_rings + sage: p.weighted_degree(x, 1, 1) Traceback (most recent call last): ... TypeError: unable to convert non-constant polynomial x to Integer Ring - sage: p.weighted_degree(2/1, 1, 1) # optional - sage.rings.finite_rings + sage: p.weighted_degree(2/1, 1, 1) 6 The :meth:`weighted_degree` coincides with the :meth:`degree` of a weighted @@ -2000,6 +2017,7 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: + sage: # needs sage.modules sage: R = PolynomialRing(QQ, 'a', 5) sage: f = R.random_element(terms=20) sage: w = random_vector(ZZ,5) @@ -2076,7 +2094,7 @@ cdef class MPolynomial(CommutativePolynomial): Some multivariate polynomial rings have no gcd implementation:: - sage: R. = GaussianIntegers()[] + sage: R. = GaussianIntegers()[] # needs sage.rings.number_field sage: x.gcd(x) Traceback (most recent call last): ... @@ -2315,7 +2333,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = 19*x^8 - 262*x^7*h + 1507*x^6*h^2 - 4784*x^5*h^3 + 9202*x^4*h^4\ -10962*x^3*h^5 + 7844*x^2*h^6 - 3040*x*h^7 + 475*h^8 - sage: f.reduced_form(prec=200, smallest_coeffs=False) # optional - sage.modules + sage: f.reduced_form(prec=200, smallest_coeffs=False) # needs sage.modules sage.rings.complex_interval_field ( -x^8 - 2*x^7*h + 7*x^6*h^2 + 16*x^5*h^3 + 2*x^4*h^4 - 2*x^3*h^5 + 4*x^2*h^6 - 5*h^8, @@ -2328,7 +2346,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = x^3 + 378666*x^2*y - 12444444*x*y^2 + 1234567890*y^3 sage: j = f * (x-545*y)^9 - sage: j.reduced_form(prec=200, smallest_coeffs=False) # optional - sage.modules + sage: j.reduced_form(prec=200, smallest_coeffs=False) # needs sage.modules sage.rings.complex_interval_field Traceback (most recent call last): ... ValueError: cannot have a root with multiplicity >= 12/2 @@ -2337,7 +2355,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = x^6 + 3*x^5*y - 8*x^4*y^2 - 2*x^3*y^3 - 44*x^2*y^4 - 8*x*y^5 - sage: F.reduced_form(smallest_coeffs=False, prec=400) # optional - sage.modules + sage: F.reduced_form(smallest_coeffs=False, prec=400) # needs sage.modules sage.rings.complex_interval_field Traceback (most recent call last): ... ArithmeticError: Newton's method converged to z not in the upper half plane @@ -2346,7 +2364,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = 5*x^2*y - 5*x*y^2 - 30*y^3 - sage: F.reduced_form(smallest_coeffs=False) # optional - sage.modules + sage: F.reduced_form(smallest_coeffs=False) # needs sage.modules sage.rings.complex_interval_field ( [1 1] 5*x^2*y + 5*x*y^2 - 30*y^3, [0 1] @@ -2357,12 +2375,12 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = (-16*x^7 - 114*x^6*y - 345*x^5*y^2 - 599*x^4*y^3 ....: - 666*x^3*y^4 - 481*x^2*y^5 - 207*x*y^6 - 40*y^7) - sage: F.reduced_form(prec=50, smallest_coeffs=False) # optional - sage.modules + sage: F.reduced_form(prec=50, smallest_coeffs=False) # needs sage.modules sage.rings.complex_interval_field Traceback (most recent call last): ... ValueError: accuracy of Newton's root not within tolerance(0.000012... > 1e-06), increase precision - sage: F.reduced_form(prec=100, smallest_coeffs=False) # optional - sage.modules + sage: F.reduced_form(prec=100, smallest_coeffs=False) # needs sage.modules sage.rings.complex_interval_field ( [-1 -1] -x^5*y^2 - 24*x^3*y^4 - 3*x^2*y^5 - 2*x*y^6 + 16*y^7, [ 1 0] @@ -2372,14 +2390,14 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = - 8*x^4 - 3933*x^3*y - 725085*x^2*y^2 - 59411592*x*y^3 - 1825511633*y^4 - sage: F.reduced_form(return_conjugation=False) # optional - sage.modules + sage: F.reduced_form(return_conjugation=False) # needs sage.modules sage.rings.complex_interval_field x^4 + 9*x^3*y - 3*x*y^3 - 8*y^4 :: sage: R. = QQ[] sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3 - sage: F.reduced_form() # optional - sage.modules + sage: F.reduced_form() # needs sage.modules sage.rings.complex_interval_field ( [1 4] -2*x^3 - 22*x^2*y - 77*x*y^2 + 43*y^3, [0 1] @@ -2389,7 +2407,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = QQ[] sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3 - sage: F.reduced_form(norm_type='height') # optional - sage.modules + sage: F.reduced_form(norm_type='height') # needs sage.modules sage.rings.complex_interval_field ( [5 4] -58*x^3 - 47*x^2*y + 52*x*y^2 + 43*y^3, [1 1] @@ -2399,7 +2417,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: F = x^4 + x^3*y*z + y^2*z - sage: F.reduced_form() # optional - sage.modules + sage: F.reduced_form() # needs sage.modules sage.rings.complex_interval_field Traceback (most recent call last): ... ValueError: (=x^3*y*z + x^4 + y^2*z) must have two variables @@ -2408,7 +2426,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(ZZ) sage: F = - 8*x^6 - 3933*x^3*y - 725085*x^2*y^2 - 59411592*x*y^3 - 99*y^6 - sage: F.reduced_form(return_conjugation=False) # optional - sage.modules + sage: F.reduced_form(return_conjugation=False) # needs sage.modules sage.rings.complex_interval_field Traceback (most recent call last): ... ValueError: (=-8*x^6 - 99*y^6 - 3933*x^3*y - 725085*x^2*y^2 - @@ -2419,7 +2437,7 @@ cdef class MPolynomial(CommutativePolynomial): sage: R. = PolynomialRing(RR) sage: F = (217.992172373276*x^3 + 96023.1505442490*x^2*y ....: + 1.40987971253579e7*x*y^2 + 6.90016027113216e8*y^3) - sage: F.reduced_form(smallest_coeffs=False) # tol 1e-8 # optional - sage.modules + sage: F.reduced_form(smallest_coeffs=False) # tol 1e-8 # needs sage.modules sage.rings.complex_interval_field ( -39.5673942565918*x^3 + 111.874026298523*x^2*y + 231.052762985229*x*y^2 - 138.380829811096*y^3, @@ -2430,12 +2448,12 @@ cdef class MPolynomial(CommutativePolynomial): :: - sage: R. = PolynomialRing(CC) - sage: F = ((0.759099196558145 + 0.845425869641446*CC.0)*x^3 + sage: R. = PolynomialRing(CC) # needs sage.rings.real_mpfr + sage: F = ((0.759099196558145 + 0.845425869641446*CC.0)*x^3 # needs sage.rings.real_mpfr ....: + (84.8317207268542 + 93.8840848648033*CC.0)*x^2*y ....: + (3159.07040755858 + 3475.33037377779*CC.0)*x*y^2 ....: + (39202.5965389079 + 42882.5139724962*CC.0)*y^3) - sage: F.reduced_form(smallest_coeffs=False) # tol 1e-11 # optional - sage.modules + sage: F.reduced_form(smallest_coeffs=False) # tol 1e-11 # needs sage.modules sage.rings.complex_interval_field sage.rings.real_mpfr ( (-0.759099196558145 - 0.845425869641446*I)*x^3 + (-0.571709908900118 - 0.0418133346027929*I)*x^2*y @@ -2447,6 +2465,9 @@ cdef class MPolynomial(CommutativePolynomial): ) """ from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + from sage.rings.complex_interval_field import ComplexIntervalField + from sage.rings.real_mpfr import RealField if self.parent().ngens() != 2: raise ValueError("(=%s) must have two variables"%self) @@ -2459,7 +2480,7 @@ cdef class MPolynomial(CommutativePolynomial): emb = kwds.get('emb', None) # getting a numerical approximation of the roots of our polynomial - CF = ComplexIntervalField(prec=prec) # keeps trac of our precision error + CF = ComplexIntervalField(prec=prec) # keeps trac of our precision error RF = RealField(prec=prec) R = self.parent() x,y = R.gens() @@ -2527,16 +2548,17 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x + y).is_unit() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: (x + y).is_unit() False - sage: R(0).is_unit() # optional - sage.rings.number_field + sage: R(0).is_unit() False - sage: R(-1).is_unit() # optional - sage.rings.number_field + sage: R(-1).is_unit() True - sage: R(-1 + x).is_unit() # optional - sage.rings.number_field + sage: R(-1 + x).is_unit() False - sage: R(2).is_unit() # optional - sage.rings.number_field + sage: R(2).is_unit() True Check that :trac:`22454` is fixed:: @@ -2573,10 +2595,10 @@ cdef class MPolynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x + y).is_nilpotent() # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: (x + y).is_nilpotent() # needs sage.rings.number_field False - sage: R(0).is_nilpotent() # optional - sage.rings.number_field + sage: R(0).is_nilpotent() # needs sage.rings.number_field True sage: _. = Zmod(4)[] sage: (2*x).is_nilpotent() @@ -2605,8 +2627,8 @@ cdef class MPolynomial(CommutativePolynomial): TESTS:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x + y)._test_subs() # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: (x + y)._test_subs() # needs sage.rings.number_field """ if tester is None: tester = self._tester(**options) @@ -2758,6 +2780,8 @@ cdef class MPolynomial(CommutativePolynomial): if self.degree() == 2: quadratic_derivs = set([self]) else: + from sage.combinat.integer_lists.invlex import IntegerListsLex + gens = self.parent().gens() quadratic_derivs = set() multi_exponents = IntegerListsLex(self.degree() - 2, length=len(gens)) @@ -2890,7 +2914,7 @@ cdef class MPolynomial_libsingular(MPolynomial): sage: isinstance(x, MPolynomial_libsingular) False sage: R2. = QQ[] - sage: isinstance(y, MPolynomial_libsingular) # optional - sage.libs.singular + sage: isinstance(y, MPolynomial_libsingular) # needs sage.libs.singular True By design, there is a unique direct subclass:: diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 86d62c77bf9..27b6f577f16 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -31,8 +31,8 @@ We verify Lagrange's four squares identity:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: ((a0^2 + a1^2 + a2^2 + a3^2) * (b0^2 + b1^2 + b2^2 + b3^2) == # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: ((a0^2 + a1^2 + a2^2 + a3^2) * (b0^2 + b1^2 + b2^2 + b3^2) == # needs sage.rings.number_field ....: (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2 ....: + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2) True @@ -94,13 +94,14 @@ def __init__(self, parent, x): """ EXAMPLES:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: L. = K.extension(x^3 - 3) # optional - sage.rings.number_field - sage: S. = L.extension(x^2 - 2) # optional - sage.rings.number_field - sage: S # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 2) + sage: L. = K.extension(x^3 - 3) + sage: S. = L.extension(x^2 - 2) + sage: S Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field - sage: P. = PolynomialRing(S) # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(S) # indirect doctest """ CommutativeRingElement.__init__(self, parent) self.__element = x @@ -109,8 +110,8 @@ def _repr_(self): """ EXAMPLES:: - sage: P. = PolynomialRing(QQbar) # optional - sage.rings.number_field - sage: x + QQbar(sqrt(2) - 1/2*I) # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar) # needs sage.rings.number_field + sage: x + QQbar(sqrt(2) - 1/2*I) # indirect doctest # needs sage.rings.number_field sage.symbolic x + 1.414213562373095? - 0.50000000000000000?*I """ return "%s"%self.__element @@ -127,6 +128,7 @@ def __call__(self, *x, **kwds): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: R. = CC[] sage: f = x^2 + y^2 sage: f(1,2) @@ -136,9 +138,9 @@ def __call__(self, *x, **kwds): :: - sage: x = PolynomialRing(CC,3,'x').gens() - sage: f = x[0] + x[1] - 2*x[1]*x[2] - sage: f + sage: # needs sage.rings.real_mpfr + sage: x = PolynomialRing(CC, 3, 'x').gens() + sage: f = x[0] + x[1] - 2*x[1]*x[2]; f (-2.00000000000000)*x1*x2 + x0 + x1 sage: f(1,2,0) 3.00000000000000 @@ -187,26 +189,26 @@ def _richcmp_(self, right, op): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 3, order='lex') # optional - sage.rings.number_field - sage: x^1*y^2 > y^3*z^4 # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 3, order='lex') # needs sage.rings.number_field + sage: x^1*y^2 > y^3*z^4 # needs sage.rings.number_field True - sage: x^3*y^2*z^4 < x^3*y^2*z^1 # optional - sage.rings.number_field + sage: x^3*y^2*z^4 < x^3*y^2*z^1 # needs sage.rings.number_field False :: - sage: R. = PolynomialRing(CC, 3, order='deglex') - sage: x^1*y^2*z^3 > x^3*y^2*z^0 + sage: R. = PolynomialRing(CC, 3, order='deglex') # needs sage.rings.real_mpfr + sage: x^1*y^2*z^3 > x^3*y^2*z^0 # needs sage.rings.real_mpfr True - sage: x^1*y^2*z^4 < x^1*y^1*z^5 + sage: x^1*y^2*z^4 < x^1*y^1*z^5 # needs sage.rings.real_mpfr False :: - sage: R. = PolynomialRing(QQbar, 3, order='degrevlex') # optional - sage.rings.number_field - sage: x^1*y^5*z^2 > x^4*y^1*z^3 # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 3, order='degrevlex') # needs sage.rings.number_field + sage: x^1*y^5*z^2 > x^4*y^1*z^3 # needs sage.rings.number_field True - sage: x^4*y^7*z^1 < x^4*y^2*z^3 # optional - sage.rings.number_field + sage: x^4*y^7*z^1 < x^4*y^2*z^3 # needs sage.rings.number_field False """ return self.__element.rich_compare(right.__element, op, @@ -216,9 +218,9 @@ def _im_gens_(self, codomain, im_gens, base_map=None): """ EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field - sage: f = R.hom([y, x], R) # optional - sage.rings.number_field - sage: f(x^2 + 3*y^5) # indirect doctest # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 2) # needs sage.rings.number_field + sage: f = R.hom([y, x], R) # needs sage.rings.number_field + sage: f(x^2 + 3*y^5) # indirect doctest # needs sage.rings.number_field 3*x^5 + y^2 You can specify a map on the base ring:: @@ -250,6 +252,7 @@ def number_of_terms(self): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: R. = CC[] sage: f = x^3 - y sage: f.number_of_terms() @@ -262,7 +265,7 @@ def number_of_terms(self): The method :meth:`hamming_weight` is an alias:: - sage: f.hamming_weight() + sage: f.hamming_weight() # needs sage.rings.real_mpfr 101 """ return len(self.element().dict()) @@ -275,10 +278,10 @@ def __neg__(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: -x # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: -x # needs sage.rings.number_field -x - sage: -(y-1) # optional - sage.rings.number_field + sage: -(y-1) # needs sage.rings.number_field -y + 1 """ return self.__class__(self.parent(), -self.__element) @@ -289,8 +292,8 @@ def _add_(self, right): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x + y # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: x + y # needs sage.rings.number_field x + y """ elt = self.__element + right.__element @@ -303,8 +306,8 @@ def _sub_(self, right): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x - y # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: x - y # needs sage.rings.number_field x - y """ elt = self.__element - right.__element @@ -317,8 +320,8 @@ def _mul_(self, right): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x * y # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: x * y # needs sage.rings.number_field x*y """ elt = self.__element * right.__element @@ -337,9 +340,9 @@ def _lmul_(self, a): :: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = (x + y) # optional - sage.rings.number_field - sage: 3 * f # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: f = (x + y) # needs sage.rings.number_field + sage: 3 * f # needs sage.rings.number_field 3*x + 3*y """ elt = self.__element.scalar_lmult(a) @@ -358,9 +361,9 @@ def _rmul_(self, a): :: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = (x + y) # optional - sage.rings.number_field - sage: f * 3 # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: f = (x + y) # needs sage.rings.number_field + sage: f * 3 # needs sage.rings.number_field 3*x + 3*y """ elt = self.__element.scalar_rmult(a) @@ -371,19 +374,19 @@ def _div_(self, right): r""" EXAMPLES:: - sage: R. = CC['x,y'] - sage: f = (x + y)/x; f + sage: R. = CC['x,y'] # needs sage.rings.real_mpfr + sage: f = (x + y)/x; f # needs sage.rings.real_mpfr (x + y)/x - sage: f.parent() + sage: f.parent() # needs sage.rings.real_mpfr Fraction Field of Multivariate Polynomial Ring in x, y over Complex Field with 53 bits of precision If dividing by a scalar, there is no need to go to the fraction field of the polynomial ring:: - sage: f = (x + y)/2; f + sage: f = (x + y)/2; f # needs sage.rings.real_mpfr 0.500000000000000*x + 0.500000000000000*y - sage: f.parent() + sage: f.parent() # needs sage.rings.real_mpfr Multivariate Polynomial Ring in x, y over Complex Field with 53 bits of precision @@ -423,15 +426,16 @@ def change_ring(self, R): sage: R. = QQ[] sage: f = x^2 + 5*y - sage: f.change_ring(GF(5)) # optional - sage.rings.finite_rings + sage: f.change_ring(GF(5)) x^2 :: - sage: K. = CyclotomicField(5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: f = x^2 + w*y # optional - sage.rings.number_field - sage: f.change_ring(K.embeddings(QQbar)[1]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(5) + sage: R. = K[] + sage: f = x^2 + w*y + sage: f.change_ring(K.embeddings(QQbar)[1]) x^2 + (-0.8090169943749474? + 0.5877852522924731?*I)*y """ if isinstance(R, Morphism): @@ -452,10 +456,10 @@ def __init__(self, parent, x): """ EXAMPLES:: - sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() # optional - sage.rings.number_field - sage: x # optional - sage.rings.number_field + sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() # needs sage.rings.number_field + sage: x # needs sage.rings.number_field (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) - sage: loads(dumps(x)) == x # optional - sage.rings.number_field + sage: loads(dumps(x)) == x # needs sage.rings.number_field True """ if not isinstance(x, polydict.PolyDict): @@ -485,12 +489,13 @@ def _repr_(self): """ EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: repr(-x^2 - y + 1) # indirect doctest # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: repr(-x^2 - y + 1) # indirect doctest '-x^2 - y + 1' - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: repr(-I*y - x^2) # indirect doctest # optional - sage.rings.number_field + sage: K. = QuadraticField(-1) + sage: R. = K[] + sage: repr(-I*y - x^2) # indirect doctest '-x^2 + (-I)*y' """ try: @@ -506,12 +511,13 @@ def _latex_(self): r""" EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: latex(-x^2 - y + 1) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: latex(-x^2 - y + 1) -x^{2} - y + 1 - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: latex(-I*y + I*x^2) # optional - sage.rings.number_field + sage: K. = QuadraticField(-1) + sage: R. = K[] + sage: latex(-I*y + I*x^2) \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) y """ try: @@ -526,9 +532,9 @@ def _repr_with_changed_varnames(self, varnames): """ EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = -x^2 - y + 1 # optional - sage.rings.number_field - sage: f._repr_with_changed_varnames(['jack', 'jill']) # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: f = -x^2 - y + 1 # needs sage.rings.number_field + sage: f._repr_with_changed_varnames(['jack', 'jill']) # needs sage.rings.number_field '-jack^2 - jill + 1' """ try: @@ -543,8 +549,8 @@ def _macaulay2_(self, macaulay2=None): """ EXAMPLES:: - sage: R = GF(13)['a,b']['c,d'] # optional - sage.rings.finite_rings - sage: macaulay2(R('a^2 + c')) # optional - macaulay2 sage.rings.finite_rings + sage: R = GF(13)['a,b']['c,d'] + sage: macaulay2(R('a^2 + c')) # optional - macaulay2 2 c + a @@ -553,7 +559,7 @@ def _macaulay2_(self, macaulay2=None): Elements of the base ring are coerced to the polynomial ring correctly:: - sage: macaulay2(R('a^2')).ring()._operator('===', R) # optional - macaulay2 sage.rings.finite_rings + sage: macaulay2(R('a^2')).ring()._operator('===', R) # optional - macaulay2 true """ if macaulay2 is None: @@ -571,20 +577,21 @@ def degrees(self): EXAMPLES:: - sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.degrees() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar) + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.degrees() (2, 2, 0) - sage: f = x^2 + z^2 # optional - sage.rings.number_field - sage: f.degrees() # optional - sage.rings.number_field + sage: f = x^2 + z^2 + sage: f.degrees() (2, 0, 2) - sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees # optional - sage.rings.number_field + sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees 2 - sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field - sage: f = (1-x) * (1+y+z+x^3)^5 # optional - sage.rings.number_field - sage: f.degrees() # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar) + sage: f = (1-x) * (1+y+z+x^3)^5 + sage: f.degrees() (16, 5, 5, 0) - sage: R(0).degrees() # optional - sage.rings.number_field + sage: R(0).degrees() (0, 0, 0, 0) """ if not self: @@ -653,46 +660,47 @@ def degree(self, x=None, std_grading=False): :: sage: x, y = ZZ['x','y'].gens() - sage: GF(3037000453)['x','y'].gen(0).degree(x) + sage: GF(3037000453)['x','y'].gen(0).degree(x) # needs sage.rings.finite_rings 1 sage: x0, y0 = QQ['x','y'].gens() - sage: GF(3037000453)['x','y'].gen(0).degree(x0) + sage: GF(3037000453)['x','y'].gen(0).degree(x0) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: x must canonically coerce to parent - sage: GF(3037000453)['x','y'].gen(0).degree(x^2) # optional - sage.rings.finite_rings + sage: GF(3037000453)['x','y'].gen(0).degree(x^2) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: x must be one of the generators of the parent TESTS:: - sage: R = PolynomialRing(GF(2)['t'], 'x,y', order=TermOrder('wdeglex', (2,3))) # optional - sage.rings.finite_rings - sage: x, y = R.gens() # optional - sage.rings.finite_rings - sage: x.degree() # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(2)['t'], 'x,y', + ....: order=TermOrder('wdeglex', (2,3))) + sage: x, y = R.gens() + sage: x.degree() 2 - sage: y.degree() # optional - sage.rings.finite_rings + sage: y.degree() 3 - sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y) # optional - sage.rings.finite_rings + sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y) (0, 1, 0, 1) - sage: f = (x^2*y + x*y^2) # optional - sage.rings.finite_rings - sage: f.degree(x) # optional - sage.rings.finite_rings + sage: f = (x^2*y + x*y^2) + sage: f.degree(x) 2 - sage: f.degree(y) # optional - sage.rings.finite_rings + sage: f.degree(y) 2 - sage: f.degree() # optional - sage.rings.finite_rings + sage: f.degree() 8 - sage: f.degree(std_grading=True) # optional - sage.rings.finite_rings + sage: f.degree(std_grading=True) 3 - sage: R(0).degree() # optional - sage.rings.finite_rings + sage: R(0).degree() -1 Degree of zero polynomial for other implementation :trac:`20048` :: - sage: R. = GF(3037000453)[] # optional - sage.rings.finite_rings - sage: R.zero().degree(x) # optional - sage.rings.finite_rings + sage: R. = GF(3037000453)[] # needs sage.rings.finite_rings + sage: R.zero().degree(x) -1 """ if x is None: @@ -718,24 +726,25 @@ def total_degree(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 2*x*y^3*z^2 # optional - sage.rings.number_field - sage: f.total_degree() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 2*x*y^3*z^2 + sage: f.total_degree() 6 - sage: f = 4*x^2*y^2*z^3 # optional - sage.rings.number_field - sage: f.total_degree() # optional - sage.rings.number_field + sage: f = 4*x^2*y^2*z^3 + sage: f.total_degree() 7 - sage: f = 99*x^6*y^3*z^9 # optional - sage.rings.number_field - sage: f.total_degree() # optional - sage.rings.number_field + sage: f = 99*x^6*y^3*z^9 + sage: f.total_degree() 18 - sage: f = x*y^3*z^6 + 3*x^2 # optional - sage.rings.number_field - sage: f.total_degree() # optional - sage.rings.number_field + sage: f = x*y^3*z^6 + 3*x^2 + sage: f.total_degree() 10 - sage: f = z^3 + 8*x^4*y^5*z # optional - sage.rings.number_field - sage: f.total_degree() # optional - sage.rings.number_field + sage: f = z^3 + 8*x^4*y^5*z + sage: f.total_degree() 10 - sage: f = z^9 + 10*x^4 + y^8*x^2 # optional - sage.rings.number_field - sage: f.total_degree() # optional - sage.rings.number_field + sage: f = z^9 + 10*x^4 + y^8*x^2 + sage: f.total_degree() 10 """ return self.degree() @@ -766,33 +775,36 @@ def monomial_coefficient(self, mon): :: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 2 * x * y # optional - sage.rings.number_field - sage: c = f.monomial_coefficient(x*y); c # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 2 * x * y + sage: c = f.monomial_coefficient(x*y); c 2 - sage: c.parent() # optional - sage.rings.number_field + sage: c.parent() Algebraic Field :: - sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y # optional - sage.rings.number_field - sage: f.monomial_coefficient(y^2) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y + sage: f.monomial_coefficient(y^2) 1 - sage: f.monomial_coefficient(x*y) # optional - sage.rings.number_field + sage: f.monomial_coefficient(x*y) 5 - sage: f.monomial_coefficient(x^9) # optional - sage.rings.number_field + sage: f.monomial_coefficient(x^9) -1 - sage: f.monomial_coefficient(x^10) # optional - sage.rings.number_field + sage: f.monomial_coefficient(x^10) 0 :: + sage: # needs sage.rings.number_field sage: a = polygen(ZZ, 'a') - sage: K. = NumberField(a^2 + a + 1) # optional - sage.rings.number_field - sage: P. = K[] # optional - sage.rings.number_field - sage: f = (a*x - 1) * ((a+1)*y - 1); f # optional - sage.rings.number_field + sage: K. = NumberField(a^2 + a + 1) + sage: P. = K[] + sage: f = (a*x - 1) * ((a+1)*y - 1); f -x*y + (-a)*x + (-a - 1)*y + 1 - sage: f.monomial_coefficient(x) # optional - sage.rings.number_field + sage: f.monomial_coefficient(x) -a """ if parent(mon) is not self.parent(): @@ -814,23 +826,23 @@ def __iter__(self): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, order='lex') # optional - sage.rings.number_field - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field - sage: list(f) # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order='lex') # needs sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field + sage: list(f) # needs sage.rings.number_field [(1, x^4*y*z^3), (1, x^2*z), (1, x*y^5*z^2)] :: - sage: R. = PolynomialRing(QQbar, order='deglex') # optional - sage.rings.number_field - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field - sage: list(f) # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order='deglex') # needs sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field + sage: list(f) # needs sage.rings.number_field [(1, x^4*y*z^3), (1, x*y^5*z^2), (1, x^2*z)] :: - sage: R. = PolynomialRing(QQbar, order='degrevlex') # optional - sage.rings.number_field - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field - sage: list(f) # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order='degrevlex') # needs sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field + sage: list(f) # needs sage.rings.number_field [(1, x*y^5*z^2), (1, x^4*y*z^3), (1, x^2*z)] :: @@ -861,22 +873,23 @@ def __getitem__(self, x): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field - sage: f = -10*x^3*y + 17*x*y # optional - sage.rings.number_field - sage: f[3,1] # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 2) + sage: f = -10*x^3*y + 17*x*y + sage: f[3,1] -10 - sage: f[1,1] # optional - sage.rings.number_field + sage: f[1,1] 17 - sage: f[0,1] # optional - sage.rings.number_field + sage: f[0,1] 0 :: - sage: R. = PolynomialRing(QQbar, 1); R # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 1); R # needs sage.rings.number_field Multivariate Polynomial Ring in x over Algebraic Field - sage: f = 5*x^2 + 3; f # optional - sage.rings.number_field + sage: f = 5*x^2 + 3; f # needs sage.rings.number_field 5*x^2 + 3 - sage: f[2] # optional - sage.rings.number_field + sage: f[2] # needs sage.rings.number_field 5 """ if isinstance(x, MPolynomial): @@ -902,14 +915,14 @@ def iterator_exp_coeff(self, as_ETuples=True): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, order='lex') # optional - sage.rings.number_field - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field - sage: list(f.iterator_exp_coeff()) # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order='lex') # needs sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field + sage: list(f.iterator_exp_coeff()) # needs sage.rings.number_field [((4, 1, 3), 1), ((2, 0, 1), 1), ((1, 5, 2), 1)] - sage: R. = PolynomialRing(QQbar, order='deglex') # optional - sage.rings.number_field - sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # optional - sage.rings.number_field - sage: list(f.iterator_exp_coeff(as_ETuples=False)) # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order='deglex') # needs sage.rings.number_field + sage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3) # needs sage.rings.number_field + sage: list(f.iterator_exp_coeff(as_ETuples=False)) # needs sage.rings.number_field [((4, 1, 3), 1), ((1, 5, 2), 1), ((2, 0, 1), 1)] """ elt = self.element() @@ -954,35 +967,37 @@ def coefficient(self, degrees): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 2 * x * y # optional - sage.rings.number_field - sage: c = f.coefficient({x: 1, y: 1}); c # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 2 * x * y + sage: c = f.coefficient({x: 1, y: 1}); c 2 - sage: c.parent() # optional - sage.rings.number_field + sage: c.parent() Multivariate Polynomial Ring in x, y over Algebraic Field - sage: c in PolynomialRing(QQbar, 2, names=['x', 'y']) # optional - sage.rings.number_field + sage: c in PolynomialRing(QQbar, 2, names=['x', 'y']) True - sage: f = y^2 - x^9 - 7*x + 5*x*y # optional - sage.rings.number_field - sage: f.coefficient({y: 1}) # optional - sage.rings.number_field + sage: f = y^2 - x^9 - 7*x + 5*x*y + sage: f.coefficient({y: 1}) 5*x - sage: f.coefficient({y: 0}) # optional - sage.rings.number_field + sage: f.coefficient({y: 0}) -x^9 + (-7)*x - sage: f.coefficient({x: 0, y: 0}) # optional - sage.rings.number_field + sage: f.coefficient({x: 0, y: 0}) 0 - sage: f = (1+y+y^2) * (1+x+x^2) # optional - sage.rings.number_field - sage: f.coefficient({x: 0}) # optional - sage.rings.number_field + sage: f = (1+y+y^2) * (1+x+x^2) + sage: f.coefficient({x: 0}) y^2 + y + 1 - sage: f.coefficient([0, None]) # optional - sage.rings.number_field + sage: f.coefficient([0, None]) y^2 + y + 1 - sage: f.coefficient(x) # optional - sage.rings.number_field + sage: f.coefficient(x) y^2 + y + 1 sage: # Be aware that this may not be what you think! sage: # The physical appearance of the variable x is deceiving -- particularly if the exponent would be a variable. - sage: f.coefficient(x^0) # outputs the full polynomial # optional - sage.rings.number_field + sage: f.coefficient(x^0) # outputs the full polynomial x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1 :: + sage: # needs sage.rings.real_mpfr sage: R. = RR[] sage: f = x*y + 5 sage: c = f.coefficient({x: 0, y: 0}); c @@ -1026,42 +1041,44 @@ def global_height(self, prec=None): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field - sage: f = QQbar(i)*x^2 + 3*x*y # optional - sage.rings.number_field - sage: f.global_height() # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 2) # needs sage.rings.number_field + sage: f = QQbar(i)*x^2 + 3*x*y # needs sage.rings.number_field + sage: f.global_height() # needs sage.rings.number_field 1.09861228866811 Scaling should not change the result:: - sage: R. = PolynomialRing(QQbar, 2) # optional - sage.rings.number_field - sage: f = 1/25*x^2 + 25/3*x + 1 + QQbar(sqrt(2))*y^2 # optional - sage.rings.number_field sage.symbolic - sage: f.global_height() # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: R. = PolynomialRing(QQbar, 2) + sage: f = 1/25*x^2 + 25/3*x + 1 + QQbar(sqrt(2))*y^2 + sage: f.global_height() 6.43775164973640 - sage: g = 100 * f # optional - sage.rings.number_field sage.symbolic - sage: g.global_height() # optional - sage.rings.number_field sage.symbolic + sage: g = 100 * f + sage: g.global_height() 6.43775164973640 :: + sage: # needs sage.rings.number_field sage: R. = QQ[] - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: Q. = PolynomialRing(K, implementation='generic') # optional - sage.rings.number_field - sage: f = 12 * q # optional - sage.rings.number_field - sage: f.global_height() # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) + sage: Q. = PolynomialRing(K, implementation='generic') + sage: f = 12 * q + sage: f.global_height() 0.000000000000000 :: sage: R. = PolynomialRing(QQ, implementation='generic') sage: f = 1/123*x*y + 12 - sage: f.global_height(prec=2) + sage: f.global_height(prec=2) # needs sage.symbolic 8.0 :: sage: R. = PolynomialRing(QQ, implementation='generic') sage: f = 0*x*y - sage: f.global_height() + sage: f.global_height() # needs sage.rings.real_mpfr 0.000000000000000 """ if prec is None: @@ -1071,16 +1088,16 @@ def global_height(self, prec=None): from sage.rings.real_mpfr import RealField return RealField(prec).zero() - from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields - from sage.rings.qqbar import QQbar, number_field_elements_from_algebraics K = self.base_ring() - if K in NumberFields() or is_NumberFieldOrder(K): + if K in NumberFields() or isinstance(K, (sage.rings.abc.Order, sage.rings.integer_ring.IntegerRing_class)): from sage.schemes.projective.projective_space import ProjectiveSpace Pr = ProjectiveSpace(K, self.number_of_terms()-1) return Pr.point(self.coefficients()).global_height(prec=prec) - if K is QQbar: + if isinstance(K, sage.rings.abc.AlgebraicField): + from sage.rings.qqbar import number_field_elements_from_algebraics + K_pre, P, phi = number_field_elements_from_algebraics(list(self.coefficients())) from sage.schemes.projective.projective_space import ProjectiveSpace Pr = ProjectiveSpace(K_pre, len(P)-1) @@ -1106,34 +1123,34 @@ def local_height(self, v, prec=None): sage: R. = PolynomialRing(QQ, implementation='generic') sage: f = 1/1331*x^2 + 1/4000*y - sage: f.local_height(1331) + sage: f.local_height(1331) # needs sage.rings.real_mpfr 7.19368581839511 :: + sage: # needs sage.rings.number_field sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field - sage: T. = PolynomialRing(K, implementation='generic') # optional - sage.rings.number_field - sage: I = K.ideal(3) # optional - sage.rings.number_field - sage: f = 1/3*t*w + 3 # optional - sage.rings.number_field - sage: f.local_height(I) # optional - sage.rings.number_field sage.symbolic + sage: K. = NumberField(x^2 - 5) + sage: T. = PolynomialRing(K, implementation='generic') + sage: I = K.ideal(3) + sage: f = 1/3*t*w + 3 + sage: f.local_height(I) # needs sage.symbolic 1.09861228866811 :: sage: R. = PolynomialRing(QQ, implementation='generic') sage: f = 1/2*x*y + 2 - sage: f.local_height(2, prec=2) + sage: f.local_height(2, prec=2) # needs sage.rings.real_mpfr 0.75 """ - from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields if prec is None: prec = 53 K = FractionField(self.base_ring()) - if K not in NumberFields() or is_NumberFieldOrder(K): + if not (K in NumberFields() or isinstance(K, (sage.rings.abc.Order, IntegerRing_class))): raise TypeError("must be over a Numberfield or a Numberfield order") return max([K(c).local_height(v, prec=prec) for c in self.coefficients()]) @@ -1156,33 +1173,33 @@ def local_height_arch(self, i, prec=None): sage: R. = PolynomialRing(QQ, implementation='generic') sage: f = 210*x*y - sage: f.local_height_arch(0) + sage: f.local_height_arch(0) # needs sage.rings.real_mpfr 5.34710753071747 :: + sage: # needs sage.rings.number_field sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field - sage: T. = PolynomialRing(K, implementation='generic') # optional - sage.rings.number_field - sage: f = 1/2*t*w + 3 # optional - sage.rings.number_field - sage: f.local_height_arch(1, prec=52) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 5) + sage: T. = PolynomialRing(K, implementation='generic') + sage: f = 1/2*t*w + 3 + sage: f.local_height_arch(1, prec=52) 1.09861228866811 :: sage: R. = PolynomialRing(QQ, implementation='generic') sage: f = 1/2*x*y + 3 - sage: f.local_height_arch(0, prec=2) + sage: f.local_height_arch(0, prec=2) # needs sage.rings.real_mpfr 1.0 """ - from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields if prec is None: prec = 53 K = FractionField(self.base_ring()) - if K not in NumberFields() or is_NumberFieldOrder(K): + if not (K in NumberFields() or isinstance(K, (sage.rings.abc.Order, IntegerRing_class))): return TypeError("must be over a Numberfield or a Numberfield Order") if K == QQ: @@ -1197,9 +1214,9 @@ def _exponents(self): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 3) # optional - sage.rings.number_field - sage: f = a^3 + b + 2*b^2 # optional - sage.rings.number_field - sage: f._exponents # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 3) # needs sage.rings.number_field + sage: f = a^3 + b + 2*b^2 # needs sage.rings.number_field + sage: f._exponents # needs sage.rings.number_field [(3, 0, 0), (0, 2, 0), (0, 1, 0)] """ return sorted(self.element().dict(), key=self.parent().term_order().sortkey, reverse=True) @@ -1219,29 +1236,30 @@ def exponents(self, as_ETuples=True): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, 3) # optional - sage.rings.number_field - sage: f = a^3 + b + 2*b^2 # optional - sage.rings.number_field - sage: f.exponents() # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 3) # needs sage.rings.number_field + sage: f = a^3 + b + 2*b^2 # needs sage.rings.number_field + sage: f.exponents() # needs sage.rings.number_field [(3, 0, 0), (0, 2, 0), (0, 1, 0)] By default the list of exponents is a list of ETuples:: - sage: type(f.exponents()[0]) # optional - sage.rings.number_field + sage: type(f.exponents()[0]) # needs sage.rings.number_field - sage: type(f.exponents(as_ETuples=False)[0]) # optional - sage.rings.number_field + sage: type(f.exponents(as_ETuples=False)[0]) # needs sage.rings.number_field <... 'tuple'> TESTS: Check that we can mutate the list and not change the result:: - sage: R. = PolynomialRing(QQbar, 3) # optional - sage.rings.number_field - sage: f = a^3 + b + 2*b^2 # optional - sage.rings.number_field - sage: E = f.exponents(); E # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 3) + sage: f = a^3 + b + 2*b^2 + sage: E = f.exponents(); E [(3, 0, 0), (0, 2, 0), (0, 1, 0)] - sage: E.pop() # optional - sage.rings.number_field + sage: E.pop() (0, 1, 0) - sage: E != f.exponents() # optional - sage.rings.number_field + sage: E != f.exponents() True """ if as_ETuples: @@ -1273,18 +1291,19 @@ def is_homogeneous(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x + y).is_homogeneous() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: (x + y).is_homogeneous() True - sage: (x.parent()(0)).is_homogeneous() # optional - sage.rings.number_field + sage: (x.parent()(0)).is_homogeneous() True - sage: (x + y^2).is_homogeneous() # optional - sage.rings.number_field + sage: (x + y^2).is_homogeneous() False - sage: (x^2 + y^2).is_homogeneous() # optional - sage.rings.number_field + sage: (x^2 + y^2).is_homogeneous() True - sage: (x^2 + y^2*x).is_homogeneous() # optional - sage.rings.number_field + sage: (x^2 + y^2*x).is_homogeneous() False - sage: (x^2*y + y^2*x).is_homogeneous() # optional - sage.rings.number_field + sage: (x^2*y + y^2*x).is_homogeneous() True """ return self.element().is_homogeneous() @@ -1306,11 +1325,12 @@ def _homogenize(self, var): EXAMPLES:: - sage: P. = QQbar[] # optional - sage.rings.number_field - sage: f = x^2 + y + 1 + 5*x*y^1 # optional - sage.rings.number_field - sage: g = f.homogenize('z'); g # indirect doctest # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: P. = QQbar[] + sage: f = x^2 + y + 1 + 5*x*y^1 + sage: g = f.homogenize('z'); g # indirect doctest x^2 + 5*x*y + y*z + z^2 - sage: g.parent() # optional - sage.rings.number_field + sage: g.parent() Multivariate Polynomial Ring in x, y, z over Algebraic Field SEE: ``self.homogenize`` @@ -1328,12 +1348,13 @@ def is_generator(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x.is_generator() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: x.is_generator() True - sage: (x + y - y).is_generator() # optional - sage.rings.number_field + sage: (x + y - y).is_generator() True - sage: (x*y).is_generator() # optional - sage.rings.number_field + sage: (x*y).is_generator() False """ elt = self.element() @@ -1351,21 +1372,22 @@ def is_monomial(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x.is_monomial() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: x.is_monomial() True - sage: (x + 2*y).is_monomial() # optional - sage.rings.number_field + sage: (x + 2*y).is_monomial() False - sage: (2*x).is_monomial() # optional - sage.rings.number_field + sage: (2*x).is_monomial() False - sage: (x*y).is_monomial() # optional - sage.rings.number_field + sage: (x*y).is_monomial() True To allow a non-1 leading coefficient, use :meth:`is_term`:: - sage: (2*x*y).is_term() # optional - sage.rings.number_field + sage: (2*x*y).is_term() # needs sage.rings.number_field True - sage: (2*x*y).is_monomial() # optional - sage.rings.number_field + sage: (2*x*y).is_monomial() # needs sage.rings.number_field False """ return len(self.element()) == 1 and self.element().coefficients()[0] == 1 @@ -1380,21 +1402,22 @@ def is_term(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x.is_term() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: x.is_term() True - sage: (x + 2*y).is_term() # optional - sage.rings.number_field + sage: (x + 2*y).is_term() False - sage: (2*x).is_term() # optional - sage.rings.number_field + sage: (2*x).is_term() True - sage: (7*x^5*y).is_term() # optional - sage.rings.number_field + sage: (7*x^5*y).is_term() True To require leading coefficient 1, use :meth:`is_monomial`:: - sage: (2*x*y).is_monomial() # optional - sage.rings.number_field + sage: (2*x*y).is_monomial() # needs sage.rings.number_field False - sage: (2*x*y).is_term() # optional - sage.rings.number_field + sage: (2*x*y).is_term() # needs sage.rings.number_field True """ return len(self.element()) == 1 @@ -1421,11 +1444,12 @@ def subs(self, fixed=None, **kw): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = x^2 + y + x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f((5, y)) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = x^2 + y + x^2*y^2 + 5 + sage: f((5, y)) 25*y^2 + y + 30 - sage: f.subs({x: 5}) # optional - sage.rings.number_field + sage: f.subs({x: 5}) 25*y^2 + y + 30 """ variables = list(self.parent().gens()) @@ -1445,21 +1469,22 @@ def monomials(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.monomials() # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # needs sage.rings.number_field + sage: f.monomials() # needs sage.rings.number_field [x^2*y^2, x^2, y, 1] :: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: F = (fx*gy - fy*gx)^3; F # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: F = (fx*gy - fy*gx)^3; F -fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3 - sage: F.monomials() # optional - sage.rings.number_field + sage: F.monomials() [fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3] - sage: F.coefficients() # optional - sage.rings.number_field + sage: F.coefficients() [-1, 3, -3, 1] - sage: sum(map(mul, zip(F.coefficients(), F.monomials()))) == F # optional - sage.rings.number_field + sage: sum(map(mul, zip(F.coefficients(), F.monomials()))) == F True """ ring = self.parent() @@ -1473,12 +1498,13 @@ def constant_coefficient(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.constant_coefficient() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.constant_coefficient() 5 - sage: f = 3*x^2 # optional - sage.rings.number_field - sage: f.constant_coefficient() # optional - sage.rings.number_field + sage: f = 3*x^2 + sage: f.constant_coefficient() 0 """ #v = (0,)*int(self.parent().ngens()) @@ -1495,16 +1521,17 @@ def is_univariate(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.is_univariate() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.is_univariate() False - sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field + sage: g = f.subs({x: 10}); g 700*y^2 + (-2)*y + 305 - sage: g.is_univariate() # optional - sage.rings.number_field + sage: g.is_univariate() True - sage: f = x^0 # optional - sage.rings.number_field - sage: f.is_univariate() # optional - sage.rings.number_field + sage: f = x^0 + sage: f.is_univariate() True """ mons = self.element().dict() @@ -1537,17 +1564,18 @@ def univariate_polynomial(self, R=None): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.univariate_polynomial() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.univariate_polynomial() Traceback (most recent call last): ... TypeError: polynomial must involve at most one variable - sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field + sage: g = f.subs({x: 10}); g 700*y^2 + (-2)*y + 305 - sage: g.univariate_polynomial() # optional - sage.rings.number_field + sage: g.univariate_polynomial() 700*y^2 - 2*y + 305 - sage: g.univariate_polynomial(PolynomialRing(QQ, 'z')) # optional - sage.rings.number_field + sage: g.univariate_polynomial(PolynomialRing(QQ, 'z')) 700*z^2 - 2*z + 305 TESTS:: @@ -1602,13 +1630,14 @@ def variables(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.variables() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.variables() (x, y) - sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field + sage: g = f.subs({x: 10}); g 700*y^2 + (-2)*y + 305 - sage: g.variables() # optional - sage.rings.number_field + sage: g.variables() (y,) TESTS: @@ -1627,11 +1656,12 @@ def variable(self,i): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.variable(0) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.variable(0) x - sage: f.variable(1) # optional - sage.rings.number_field + sage: f.variable(1) y """ return self.variables()[int(i)] @@ -1642,13 +1672,14 @@ def nvariables(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.nvariables() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.nvariables() 2 - sage: g = f.subs({x: 10}); g # optional - sage.rings.number_field + sage: g = f.subs({x: 10}); g 700*y^2 + (-2)*y + 305 - sage: g.nvariables() # optional - sage.rings.number_field + sage: g.nvariables() 1 """ return len(self.degrees().nonzero_positions()) @@ -1659,12 +1690,13 @@ def is_constant(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 # optional - sage.rings.number_field - sage: f.is_constant() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.is_constant() False - sage: g = 10*x^0 # optional - sage.rings.number_field - sage: g.is_constant() # optional - sage.rings.number_field + sage: g = 10*x^0 + sage: g.is_constant() True """ return self.element().is_constant() @@ -1676,14 +1708,15 @@ def lm(self): EXAMPLES:: - sage: R. = PolynomialRing(GF(7), 3, order='lex') # optional - sage.rings.finite_rings - sage: (x^1*y^2 + y^3*z^4).lm() # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(7), 3, order='lex') + sage: (x^1*y^2 + y^3*z^4).lm() x*y^2 - sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm() # optional - sage.rings.finite_rings + sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm() x^3*y^2*z^4 :: + sage: # needs sage.rings.real_mpfr sage: R. = PolynomialRing(CC, 3, order='deglex') sage: (x^1*y^2*z^3 + x^3*y^2*z^0).lm() x*y^2*z^3 @@ -1692,18 +1725,19 @@ def lm(self): :: - sage: R. = PolynomialRing(QQbar, 3, order='degrevlex') # optional - sage.rings.number_field - sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, 3, order='degrevlex') + sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm() x*y^5*z^2 - sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm() # optional - sage.rings.number_field + sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm() x^4*y^7*z TESTS:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - sage: R. = MPolynomialRing_polydict(GF(2), 2, order='lex') # optional - sage.rings.finite_rings - sage: f = x + y # optional - sage.rings.finite_rings - sage: f.lm() # optional - sage.rings.finite_rings + sage: R. = MPolynomialRing_polydict(GF(2), 2, order='lex') + sage: f = x + y + sage: f.lm() x """ @@ -1725,9 +1759,9 @@ def lc(self): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = 3*x^2 - y^2 - x*y # optional - sage.rings.number_field - sage: f.lc() # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: f = 3*x^2 - y^2 - x*y # needs sage.rings.number_field + sage: f.lc() # needs sage.rings.number_field 3 """ try: @@ -1748,21 +1782,22 @@ def lt(self): EXAMPLES:: - sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field - sage: f = 3*x^2 - y^2 - x*y # optional - sage.rings.number_field - sage: f.lt() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar) + sage: f = 3*x^2 - y^2 - x*y + sage: f.lt() 3*x^2 - sage: R. = PolynomialRing(QQbar, order="invlex") # optional - sage.rings.number_field - sage: f = 3*x^2 - y^2 - x*y # optional - sage.rings.number_field - sage: f.lt() # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar, order="invlex") + sage: f = 3*x^2 - y^2 - x*y + sage: f.lt() -y^2 TESTS:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - sage: R. = MPolynomialRing_polydict(GF(2), 2, order='lex') # optional - sage.rings.finite_rings - sage: f = x + y # optional - sage.rings.finite_rings - sage: f.lt() # optional - sage.rings.finite_rings + sage: R. = MPolynomialRing_polydict(GF(2), 2, order='lex') + sage: f = x + y + sage: f.lt() x """ try: @@ -1816,14 +1851,15 @@ def _floordiv_(self, right): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: 2*x*y//y # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: 2*x*y//y 2*x - sage: 2*x//y # optional - sage.rings.number_field + sage: 2*x//y 0 - sage: 2*x//4 # optional - sage.rings.number_field + sage: 2*x//4 1/2*x - sage: type(0//y) # optional - sage.rings.number_field + sage: type(0//y) """ # handle division by monomials without using Singular @@ -1853,26 +1889,27 @@ def _derivative(self, var=None): EXAMPLES:: - sage: R. = PowerSeriesRing(QQbar) # optional - sage.rings.number_field - sage: S. = PolynomialRing(R) # optional - sage.rings.number_field - sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 # optional - sage.rings.number_field - sage: f.parent() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PowerSeriesRing(QQbar) + sage: S. = PolynomialRing(R) + sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 + sage: f.parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f._derivative(x) # with respect to x # optional - sage.rings.number_field + sage: f._derivative(x) # with respect to x (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2 - sage: f._derivative(x).parent() # optional - sage.rings.number_field + sage: f._derivative(x).parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f._derivative(y) # with respect to y # optional - sage.rings.number_field + sage: f._derivative(y) # with respect to y (3*t^2 + O(t^3))*x^2*y^2 - sage: f._derivative(t) # with respect to t (recurses into base ring) # optional - sage.rings.number_field + sage: f._derivative(t) # with respect to t (recurses into base ring) (2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3 - sage: f._derivative(x)._derivative(y) # with respect to x and then y # optional - sage.rings.number_field + sage: f._derivative(x)._derivative(y) # with respect to x and then y (6*t^2 + O(t^3))*x*y^2 - sage: f.derivative(y, 3) # with respect to y three times # optional - sage.rings.number_field + sage: f.derivative(y, 3) # with respect to y three times (6*t^2 + O(t^3))*x^2 - sage: f._derivative() # can't figure out the variable # optional - sage.rings.number_field + sage: f._derivative() # can't figure out the variable Traceback (most recent call last): ... ValueError: must specify which variable to differentiate with respect to @@ -1927,26 +1964,26 @@ def integral(self, var=None): On polynomials with coefficients in power series:: - sage: R. = PowerSeriesRing(QQbar) # optional - sage.rings.number_field - sage: S. = PolynomialRing(R) # optional - sage.rings.number_field - sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 # optional - sage.rings.number_field - sage: f.parent() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PowerSeriesRing(QQbar) + sage: S. = PolynomialRing(R) + sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 + sage: f.parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f.integral(x) # with respect to x # optional - sage.rings.number_field + sage: f.integral(x) # with respect to x (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4 - sage: f.integral(x).parent() # optional - sage.rings.number_field + sage: f.integral(x).parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - - sage: f.integral(y) # with respect to y # optional - sage.rings.number_field + sage: f.integral(y) # with respect to y (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y - sage: f.integral(t) # with respect to t (recurses into base ring) # optional - sage.rings.number_field + sage: f.integral(t) # with respect to t (recurses into base ring) (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3 TESTS:: - sage: f.integral() # can't figure out the variable # optional - sage.rings.number_field + sage: f.integral() # can't figure out the variable # needs sage.rings.number_field Traceback (most recent call last): ... ValueError: must specify which variable to integrate with respect to @@ -2023,22 +2060,23 @@ def factor(self, proof=None): Check if we can factor a constant polynomial, see :trac:`8207`:: - sage: R. = CC[] - sage: R(1).factor() + sage: R. = CC[] # needs sage.rings.real_mpfr + sage: R(1).factor() # needs sage.rings.real_mpfr 1.00000000000000 Check that we prohibit too large moduli, :trac:`11829`:: - sage: R. = GF(previous_prime(2^31))[] - sage: factor(x+y+1) + sage: R. = GF(previous_prime(2^31))[] # needs sage.rings.finite_rings + sage: factor(x + y + 1) # needs sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + NotImplementedError: Factorization of multivariate polynomials + over prime fields with characteristic > 2^29 is not implemented. Check that we can factor over the algebraic field (:trac:`25390`):: - sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field - sage: factor(x^2 + y^2) # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar) # needs sage.rings.number_field + sage: factor(x^2 + y^2) # needs sage.rings.number_field (x + (-1*I)*y) * (x + 1*I*y) Check that the global proof flag for polynomials is honored:: @@ -2049,7 +2087,9 @@ def factor(self, proof=None): ....: f.factor() Traceback (most recent call last): ... - NotImplementedError: Provably correct factorization not implemented. Disable this error by wrapping your code in a `with proof.WithProof('polynomial', False):` block. + NotImplementedError: Provably correct factorization not implemented. + Disable this error by wrapping your code in a + `with proof.WithProof('polynomial', False):` block. sage: with proof.WithProof('polynomial', False): ....: f.factor() Traceback (most recent call last): @@ -2060,7 +2100,7 @@ def factor(self, proof=None): sage: K. = PolynomialRing(QQ) sage: R. = PolynomialRing(FractionField(K)) - sage: factor(x) + sage: factor(x) # needs sage.libs.pari x In the example below, we set the special method @@ -2074,26 +2114,29 @@ def factor(self, proof=None): ... NotImplementedError: ... sage: R.base_ring()._factor_multivariate_polynomial = lambda f, **kwargs: f.change_ring(QQ).factor() - sage: (x*y).factor() + sage: (x*y).factor() # needs sage.libs.pari y * x sage: del R.base_ring()._factor_multivariate_polynomial # clean up Check that a "multivariate" polynomial in one variable is factored correctly:: - sage: R. = PolynomialRing(CC,1) - sage: f = z^4 - 6*z + 3 - sage: f.factor() - (z - 1.60443920904349) * (z - 0.511399619393097) * (z + 1.05791941421830 - 1.59281852704435*I) * (z + 1.05791941421830 + 1.59281852704435*I) + sage: R. = PolynomialRing(CC,1) # needs sage.rings.real_mpfr + sage: f = z^4 - 6*z + 3 # needs sage.rings.real_mpfr + sage: f.factor() # needs sage.rings.real_mpfr + (z - 1.60443920904349) * (z - 0.511399619393097) + * (z + 1.05791941421830 - 1.59281852704435*I) + * (z + 1.05791941421830 + 1.59281852704435*I) We check a case that failed with an exception at some point:: - sage: k. = GF(4) # optional - sage.rings.finite_rings - sage: R. = k[] # optional - sage.rings.finite_rings - sage: l. = R.quo(v^3 + v + 1) # optional - sage.rings.finite_rings - sage: R. = l[] # optional - sage.rings.finite_rings - sage: f = y^3 + x^3 + (u + 1)*x # optional - sage.rings.finite_rings - sage: f.factor() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(4) + sage: R. = k[] + sage: l. = R.quo(v^3 + v + 1) + sage: R. = l[] + sage: f = y^3 + x^3 + (u + 1)*x + sage: f.factor() x^3 + y^3 + (u + 1)*x """ @@ -2159,24 +2202,25 @@ def lift(self,I): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: A. = PolynomialRing(CC, 2, order='degrevlex') sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7]) sage: f = x*y^13 + y^12 - sage: M = f.lift(I) - sage: M + sage: M = f.lift(I); M # needs sage.libs.singular [y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 + y^4] - sage: sum( map( mul , zip( M, I.gens() ) ) ) == f + sage: sum(map(mul, zip(M, I.gens()))) == f # needs sage.libs.singular True TESTS: Check that this method works over ``QQbar`` (:trac:`25351`):: - sage: A. = QQbar[] # optional - sage.rings.number_field - sage: I = A.ideal([x^2 + y^2 - 1, x^2 - y^2]) # optional - sage.rings.number_field - sage: f = 2*x^2 - 1 # optional - sage.rings.number_field - sage: M = f.lift(I) # optional - sage.rings.number_field - sage: sum(map(mul, zip(M, I.gens()))) == f # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A. = QQbar[] + sage: I = A.ideal([x^2 + y^2 - 1, x^2 - y^2]) + sage: f = 2*x^2 - 1 + sage: M = f.lift(I) # needs sage.libs.singular + sage: sum(map(mul, zip(M, I.gens()))) == f # needs sage.libs.singular True """ fs = self._singular_() @@ -2196,19 +2240,19 @@ def quo_rem(self, right): EXAMPLES:: - sage: R. = CC[] - sage: f = y*x^2 + x + 1 - sage: f.quo_rem(x) + sage: R. = CC[] # needs sage.rings.real_mpfr + sage: f = y*x^2 + x + 1 # needs sage.rings.real_mpfr + sage: f.quo_rem(x) # needs sage.libs.singular sage.rings.real_mpfr (x*y + 1.00000000000000, 1.00000000000000) sage: R = QQ['a','b']['x','y','z'] sage: p1 = R('a + (1+2*b)*x*y + (3-a^2)*z') sage: p2 = R('x-1') - sage: p1.quo_rem(p2) + sage: p1.quo_rem(p2) # needs sage.libs.singular ((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a) - sage: R. = Qp(5)[] - sage: x.quo_rem(y) + sage: R. = Qp(5)[] # needs sage.rings.padics + sage: x.quo_rem(y) # needs sage.rings.padics Traceback (most recent call last): ... TypeError: no conversion of this ring to a Singular ring defined @@ -2219,9 +2263,9 @@ def quo_rem(self, right): Check that this method works over ``QQbar`` (:trac:`25351`):: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = y*x^2 + x + 1 # optional - sage.rings.number_field - sage: f.quo_rem(x) # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: f = y*x^2 + x + 1 # needs sage.rings.number_field + sage: f.quo_rem(x) # needs sage.rings.number_field (x*y + 1, 1) """ R = self.parent() @@ -2263,9 +2307,9 @@ def resultant(self, other, variable=None): sage: P. = PolynomialRing(QQ, 2) sage: a = x + y sage: b = x^3 - y^3 - sage: a.resultant(b) # optional - sage.libs.singular + sage: a.resultant(b) # needs sage.libs.singular -2*y^3 - sage: a.resultant(b, y) # optional - sage.libs.singular + sage: a.resultant(b, y) # needs sage.libs.singular 2*x^3 TESTS:: @@ -2274,15 +2318,15 @@ def resultant(self, other, variable=None): sage: P. = MPolynomialRing_polydict_domain(QQ, 2, order='degrevlex') sage: a = x + y sage: b = x^3 - y^3 - sage: a.resultant(b) # optional - sage.libs.singular + sage: a.resultant(b) # needs sage.libs.singular -2*y^3 - sage: a.resultant(b, y) # optional - sage.libs.singular + sage: a.resultant(b, y) # needs sage.libs.singular 2*x^3 Check that :trac:`15061` is fixed:: - sage: R. = AA[] # optional - sage.rings.number_field - sage: (x^2 + 1).resultant(x^2 - y) # optional - sage.rings.number_field + sage: R. = AA[] # needs sage.rings.number_field + sage: (x^2 + 1).resultant(x^2 - y) # needs sage.rings.number_field y^2 + 2*y + 1 Test for :trac:`2693`:: @@ -2290,17 +2334,18 @@ def resultant(self, other, variable=None): sage: R. = RR[] sage: p = x + y sage: q = x*y - sage: p.resultant(q) # optional - sage.libs.singular + sage: p.resultant(q) # needs sage.modules -y^2 Check that this method works over QQbar (:trac:`25351`):: - sage: P. = QQbar[] # optional - sage.rings.number_field - sage: a = x + y # optional - sage.rings.number_field - sage: b = x^3 - y^3 # optional - sage.rings.number_field - sage: a.resultant(b) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: P. = QQbar[] + sage: a = x + y + sage: b = x^3 - y^3 + sage: a.resultant(b) (-2)*y^3 - sage: a.resultant(b, y) # optional - sage.rings.number_field + sage: a.resultant(b, y) 2*x^3 """ R = self.parent() @@ -2330,13 +2375,14 @@ def subresultants(self, other, variable=None): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1) # optional - sage.rings.number_field - sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1) # optional - sage.rings.number_field - sage: p.subresultants(q, y) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1) + sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1) + sage: p.subresultants(q, y) [2*x^6 + (-22)*x^5 + 102*x^4 + (-274)*x^3 + 488*x^2 + (-552)*x + 288, -x^3 - x^2*y + 6*x^2 + 5*x*y + (-11)*x + (-6)*y + 6] - sage: p.subresultants(q, x) # optional - sage.rings.number_field + sage: p.subresultants(q, x) [2*y^6 + (-22)*y^5 + 102*y^4 + (-274)*y^3 + 488*y^2 + (-552)*y + 288, x*y^2 + y^3 + (-5)*x*y + (-6)*y^2 + 6*x + 11*y - 6] @@ -2360,48 +2406,50 @@ def reduce(self, I): EXAMPLES:: - sage: P. = QQbar[] # optional - sage.rings.number_field - sage: f1 = -2 * x^2 + x^3 # optional - sage.rings.number_field - sage: f2 = -2 * y + x * y # optional - sage.rings.number_field - sage: f3 = -x^2 + y^2 # optional - sage.rings.number_field - sage: F = Ideal([f1, f2, f3]) # optional - sage.rings.number_field - sage: g = x*y - 3*x*y^2 # optional - sage.rings.number_field - sage: g.reduce(F) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: P. = QQbar[] + sage: f1 = -2 * x^2 + x^3 + sage: f2 = -2 * y + x * y + sage: f3 = -x^2 + y^2 + sage: F = Ideal([f1, f2, f3]) + sage: g = x*y - 3*x*y^2 + sage: g.reduce(F) (-6)*y^2 + 2*y - sage: g.reduce(F.gens()) # optional - sage.rings.number_field + sage: g.reduce(F.gens()) (-6)*y^2 + 2*y :: - sage: f = 3*x # optional - sage.rings.number_field - sage: f.reduce([2*x, y]) # optional - sage.rings.number_field + sage: f = 3*x # needs sage.rings.number_field + sage: f.reduce([2*x, y]) # needs sage.rings.number_field 0 :: - sage: k. = CyclotomicField(3) # optional - sage.rings.number_field - sage: A. = PolynomialRing(k) # optional - sage.rings.number_field - sage: J = [y9 + y12] # optional - sage.rings.number_field - sage: f = y9 - y12; f.reduce(J) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: k. = CyclotomicField(3) + sage: A. = PolynomialRing(k) + sage: J = [y9 + y12] + sage: f = y9 - y12; f.reduce(J) -2*y12 - sage: f = y13*y15; f.reduce(J) # optional - sage.rings.number_field + sage: f = y13*y15; f.reduce(J) y13*y15 - sage: f = y13*y15 + y9 - y12; f.reduce(J) # optional - sage.rings.number_field + sage: f = y13*y15 + y9 - y12; f.reduce(J) y13*y15 - 2*y12 Make sure the remainder returns the correct type, fixing :trac:`13903`:: - sage: R. = PolynomialRing(Qp(5), 2, order='lex') # optional - sage.rings.padics - sage: G = [y1^2 + y2^2, y1*y2 + y2^2, y2^3] # optional - sage.rings.padics - sage: type((y2^3).reduce(G)) # optional - sage.rings.padics + sage: R. = PolynomialRing(Qp(5), 2, order='lex') # needs sage.rings.padics + sage: G = [y1^2 + y2^2, y1*y2 + y2^2, y2^3] # needs sage.rings.padics + sage: type((y2^3).reduce(G)) # needs sage.rings.padics TESTS: Verify that :trac:`34105` is fixed:: - sage: R. = AA[] # optional - sage.rings.number_field - sage: x.reduce(R.zero_ideal()) # optional - sage.rings.number_field + sage: R. = AA[] # needs sage.rings.number_field + sage: x.reduce(R.zero_ideal()) # needs sage.rings.number_field x """ from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal @@ -2465,11 +2513,11 @@ def degree_lowest_rational_function(r, x): EXAMPLES:: - sage: R1 = PolynomialRing(FiniteField(5), 3, names=["a", "b", "c"]) # optional - sage.rings.finite_rings - sage: F = FractionField(R1) # optional - sage.rings.finite_rings - sage: a,b,c = R1.gens() # optional - sage.rings.finite_rings - sage: f = 3*a*b^2*c^3 + 4*a*b*c # optional - sage.rings.finite_rings - sage: g = a^2*b*c^2 + 2*a^2*b^4*c^7 # optional - sage.rings.finite_rings + sage: R1 = PolynomialRing(FiniteField(5), 3, names=["a", "b", "c"]) + sage: F = FractionField(R1) + sage: a,b,c = R1.gens() + sage: f = 3*a*b^2*c^3 + 4*a*b*c + sage: g = a^2*b*c^2 + 2*a^2*b^4*c^7 Consider the quotient `f/g = \frac{4 + 3 bc^{2}}{ac + 2 ab^{3}c^{6}}` (note the @@ -2477,13 +2525,14 @@ def degree_lowest_rational_function(r, x): :: - sage: r = f/g; r # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: r = f/g; r (-2*b*c^2 - 1)/(2*a*b^3*c^6 + a*c) - sage: degree_lowest_rational_function(r, a) # optional - sage.rings.finite_rings + sage: degree_lowest_rational_function(r, a) -1 - sage: degree_lowest_rational_function(r, b) # optional - sage.rings.finite_rings + sage: degree_lowest_rational_function(r, b) 0 - sage: degree_lowest_rational_function(r, c) # optional - sage.rings.finite_rings + sage: degree_lowest_rational_function(r, c) -1 """ from sage.rings.fraction_field import FractionField diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index b6531026e77..22ada6de947 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.singular +# sage.doctest: needs sage.libs.singular r""" Ideals in multivariate polynomial rings @@ -234,36 +234,40 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from warnings import warn -from sage.interfaces.singular import singular as singular_default -from sage.interfaces.magma import magma as magma_default - -from sage.interfaces.expect import StdOutContext +import sage.rings.abc +import sage.rings.polynomial.toy_buchberger as toy_buchberger +import sage.rings.polynomial.toy_variety as toy_variety +import sage.rings.polynomial.toy_d_basis as toy_d_basis +from sage.misc.cachefunc import cached_method +from sage.misc.method_decorator import MethodDecorator +from sage.misc.misc_c import prod +from sage.misc.verbose import verbose, get_verbose from sage.rings.ideal import Ideal_generic -from sage.rings.noncommutative_ideals import Ideal_nc from sage.rings.integer import Integer +from sage.rings.integer_ring import ZZ +from sage.rings.noncommutative_ideals import Ideal_nc +from sage.rings.qqbar_decorators import handle_AA_and_QQbar from sage.structure.sequence import Sequence from sage.structure.richcmp import (richcmp_method, op_EQ, op_NE, op_LT, op_GT, op_LE, op_GE, rich_to_bool) -from sage.misc.cachefunc import cached_method -from sage.misc.misc_c import prod -from sage.misc.verbose import verbose, get_verbose -from sage.misc.method_decorator import MethodDecorator -from sage.rings.integer_ring import ZZ -import sage.rings.abc -import sage.rings.polynomial.toy_buchberger as toy_buchberger -import sage.rings.polynomial.toy_variety as toy_variety -import sage.rings.polynomial.toy_d_basis as toy_d_basis -from warnings import warn +try: + from sage.interfaces.expect import StdOutContext + from sage.interfaces.singular import singular as singular_default, singular_gb_standard_options + from sage.libs.singular.standard_options import libsingular_gb_standard_options +except ImportError: + singular_default = None + singular_gb_standard_options = libsingular_gb_standard_options = MethodDecorator -from sage.rings.qqbar_decorators import handle_AA_and_QQbar - -from sage.interfaces.magma import magma_gb_standard_options -from sage.interfaces.singular import singular_gb_standard_options -from sage.libs.singular.standard_options import libsingular_gb_standard_options +try: + from sage.interfaces.magma import magma as magma_default, magma_gb_standard_options +except ImportError: + magma_default = None + magma_gb_standard_options = MethodDecorator class RequireField(MethodDecorator): @@ -343,9 +347,10 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) # needs sage.rings.finite_rings - sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest # needs sage.rings.finite_rings - sage: magma(I) # optional - magma # needs sage.rings.finite_rings + sage: # optional - magma + sage: R. = PolynomialRing(GF(127), 10) + sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest + sage: magma(I) Ideal of Polynomial ring of rank 10 over GF(127) Order: Graded Reverse Lexicographical Variables: a, b, c, d, e, f, g, h, i, j @@ -380,27 +385,27 @@ def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default) EXAMPLES:: - sage: # needs sage.rings.finite_rings + sage: # optional - magma sage: R. = PolynomialRing(GF(127), 10) sage: I = sage.rings.ideal.Cyclic(R, 6) - sage: gb = I.groebner_basis('magma:GroebnerBasis') # optional - magma - sage: len(gb) # optional - magma + sage: gb = I.groebner_basis('magma:GroebnerBasis') + sage: len(gb) 45 We may also pass a degree bound to Magma:: - sage: # needs sage.rings.finite_rings + sage: # optional - magma sage: R. = PolynomialRing(GF(127), 10) sage: I = sage.rings.ideal.Cyclic(R, 6) - sage: gb = I.groebner_basis('magma:GroebnerBasis', deg_bound=4) # optional - magma - sage: len(gb) # optional - magma + sage: gb = I.groebner_basis('magma:GroebnerBasis', deg_bound=4) + sage: len(gb) 5 """ R = self.ring() if not deg_bound: mself = magma(self) else: - mself = magma(list(self.gens())) # PolynomialSequence converts to a Magma Ideal too, so we force a list + mself = magma(list(self.gens())) # PolynomialSequence converts to a Magma Ideal too, so we force a list if get_verbose() >= 2: prot = True @@ -1122,13 +1127,13 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): I = MPolynomialIdeal(P, self.interreduced_basis()[::-1]) else: I = self - I = MPolynomialIdeal(P, I.transformed_basis('fglm')[::-1]) # -> 'lex' - I = I.change_ring(Q) # transform to 'lex' GB + I = MPolynomialIdeal(P, I.transformed_basis('fglm')[::-1]) # -> 'lex' + I = I.change_ring(Q) # transform to 'lex' GB else: if Q == P: I = MPolynomialIdeal(P, self.groebner_basis()[::-1]) else: - I = self.change_ring(Q) # transform to 'lex' GB + I = self.change_ring(Q) # transform to 'lex' GB I = MPolynomialIdeal(Q, I.groebner_basis()[::-1]) if I.dimension() != 0: @@ -1350,14 +1355,14 @@ def _groebner_basis_ginv(self, algorithm="TQ", criteria='CritPartially', divisio Currently, only `\GF{p}` and `\QQ` are supported as base fields:: - sage: P. = PolynomialRing(QQ,order='degrevlex') + sage: # optional - ginv + sage: P. = PolynomialRing(QQ, order='degrevlex') sage: I = sage.rings.ideal.Katsura(P) - sage: I.groebner_basis(algorithm='ginv') # optional - ginv + sage: I.groebner_basis(algorithm='ginv') [z^3 - 79/210*z^2 + 1/30*y + 1/70*z, y^2 - 3/5*z^2 - 1/5*y + 1/5*z, y*z + 6/5*z^2 - 1/10*y - 2/5*z, x + 2*y + 2*z - 1] - - sage: P. = PolynomialRing(GF(127), order='degrevlex') # needs sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # needs sage.rings.finite_rings - sage: I.groebner_basis(algorithm='ginv') # optional - ginv # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127), order='degrevlex') + sage: I = sage.rings.ideal.Katsura(P) + sage: I.groebner_basis(algorithm='ginv') ... [z^3 + 22*z^2 - 55*y + 49*z, y^2 - 26*z^2 - 51*y + 51*z, y*z + 52*z^2 + 38*y + 25*z, x + 2*y + 2*z - 1] @@ -1489,7 +1494,7 @@ def _groebner_basis_singular_raw(self, algorithm="groebner", singular=singular_d sage: R. = PolynomialRing(QQ, 4, order='lex') sage: I = sage.rings.ideal.Cyclic(R,4) - sage: I._groebner_basis_singular() # indirect doctest + sage: I._groebner_basis_singular() # indirect doctest [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, b^2 + 2*b*d + d^2, a + b + c + d] @@ -1974,8 +1979,8 @@ def interreduced_basis(self): The interreduced basis of 0 is 0:: - sage: P. = GF(2)[] # needs sage.rings.finite_rings - sage: Ideal(P(0)).interreduced_basis() # needs sage.rings.finite_rings + sage: P. = GF(2)[] + sage: Ideal(P(0)).interreduced_basis() [0] ALGORITHM: @@ -2522,8 +2527,6 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True y^48 + y^41 - y^40 + y^37 - y^36 - y^33 + y^32 - y^29 + y^28 - y^25 + y^24 + y^2 + y + 1) of Multivariate Polynomial Ring in x, y over Finite Field in w of size 3^3 - - sage: # needs sage.rings.finite_rings sage: V = I.variety(); sage: sorted(V, key=str) [{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}] @@ -2606,9 +2609,10 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True If the ground field's characteristic is too large for Singular, we resort to a toy implementation:: - sage: R. = PolynomialRing(GF(2147483659^3), order='lex') # needs sage.rings.finite_rings - sage: I = ideal([x^3 - 2*y^2, 3*x + y^4]) # needs sage.rings.finite_rings - sage: I.variety() # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(2147483659^3), order='lex') + sage: I = ideal([x^3 - 2*y^2, 3*x + y^4]) + sage: I.variety() verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation. verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation. verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation. @@ -2619,22 +2623,23 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True But the mapping will also accept generators of the original ring, or even generator names as strings, when provided as keys:: + sage: # needs sage.rings.number_field sage: K. = QQ[] sage: I = ideal([x^2 + 2*y - 5, x + y + 3]) - sage: v = I.variety(AA)[0]; v[x], v[y] # needs sage.rings.number_field + sage: v = I.variety(AA)[0]; v[x], v[y] (4.464101615137755?, -7.464101615137755?) - sage: list(v)[0].parent() # needs sage.rings.number_field + sage: list(v)[0].parent() Multivariate Polynomial Ring in x, y over Algebraic Real Field - sage: v[x] # needs sage.rings.number_field + sage: v[x] 4.464101615137755? - sage: v["y"] # needs sage.rings.number_field + sage: v["y"] -7.464101615137755? ``msolve`` also works over finite fields:: sage: R. = PolynomialRing(GF(536870909), 2, order='lex') # needs sage.rings.finite_rings sage: I = Ideal([x^2 - 1, y^2 - 1]) # needs sage.rings.finite_rings - sage: sorted(I.variety(algorithm='msolve', # optional - msolve # needs sage.rings.finite_rings + sage: sorted(I.variety(algorithm='msolve', # optional - msolve, needs sage.rings.finite_rings ....: proof=False), ....: key=str) [{x: 1, y: 1}, @@ -2645,9 +2650,9 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True but may fail in small characteristic, especially with ideals of high degree with respect to the characteristic:: - sage: R. = PolynomialRing(GF(3), 2, order='lex') # needs sage.rings.finite_rings - sage: I = Ideal([x^2 - 1, y^2 - 1]) # needs sage.rings.finite_rings - sage: I.variety(algorithm='msolve', proof=False) # optional - msolve, needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(3), 2, order='lex') + sage: I = Ideal([x^2 - 1, y^2 - 1]) + sage: I.variety(algorithm='msolve', proof=False) # optional - msolve Traceback (most recent call last): ... NotImplementedError: characteristic 3 too small @@ -2694,8 +2699,8 @@ def _variety_triangular_decomposition(self, ring): Testing that a bug is indeed fixed :: - sage: R = PolynomialRing(GF(2), 30, ['x%d'%(i+1) for i in range(30)], order='lex') # needs sage.rings.finite_rings - sage: R.inject_variables() # needs sage.rings.finite_rings + sage: R = PolynomialRing(GF(2), 30, ['x%d'%(i+1) for i in range(30)], order='lex') + sage: R.inject_variables() Defining... sage: I = Ideal([x1 + 1, x2, x3 + 1, x5*x10 + x10 + x18, x5*x11 + x11, \ x5*x18, x6, x7 + 1, x9, x10*x11 + x10 + x18, x10*x18 + x18, \ @@ -2706,10 +2711,10 @@ def _variety_triangular_decomposition(self, ring): x11^2 + x11, x12^2 + x12, x13^2 + x13, x14^2 + x14, x15^2 + x15, \ x16^2 + x16, x17^2 + x17, x18^2 + x18, x19^2 + x19, x20^2 + x20, \ x21^2 + x21, x22^2 + x22, x23^2 + x23, x24^2 + x24, x25^2 + x25, \ - x26^2 + x26, x27^2 + x27, x28^2 + x28, x29^2 + x29, x30^2 + x30]) # optional - sage.rings.finite_rings - sage: I.basis_is_groebner() # needs sage.rings.finite_rings + x26^2 + x26, x27^2 + x27, x28^2 + x28, x29^2 + x29, x30^2 + x30]) + sage: I.basis_is_groebner() True - sage: sorted("".join(str(V[g]) for g in R.gens()) for V in I.variety()) # long time (6s on sage.math, 2011), needs sage.rings.finite_rings + sage: sorted("".join(str(V[g]) for g in R.gens()) for V in I.variety()) # long time (6s on sage.math, 2011) ['101000100000000110001000100110', '101000100000000110001000101110', '101000100100000101001000100110', @@ -2744,10 +2749,10 @@ def _variety_triangular_decomposition(self, ring): Check that the issue at :trac:`7425` is fixed:: - sage: S.=PolynomialRing(QQ) - sage: F.=QQ.extension(t^4+1) - sage: R.=PolynomialRing(F) - sage: I=R.ideal(x,y^4+1) + sage: S. = PolynomialRing(QQ) + sage: F. = QQ.extension(t^4 + 1) + sage: R. = PolynomialRing(F) + sage: I = R.ideal(x, y^4 + 1) sage: I.variety() [...{y: -q^3, x: 0}...] @@ -2761,7 +2766,7 @@ def _variety_triangular_decomposition(self, ring): Check that the issue at :trac:`16485` is fixed:: sage: R. = PolynomialRing(QQ, order='lex') - sage: I = R.ideal(c^2-2, b-c, a) + sage: I = R.ideal(c^2 - 2, b - c, a) sage: I.variety(QQbar) # needs sage.rings.number_field [...a: 0...] @@ -3204,7 +3209,7 @@ def _normal_basis_libsingular(self, degree, weights=None): sage: R. = PolynomialRing(QQ) sage: I = R.ideal(x^2-2*x*z+5, x*y^2+y*z+1, 3*y^2-8*x*z) - sage: I.normal_basis() #indirect doctest + sage: I.normal_basis() # indirect doctest [z^2, y*z, x*z, z, x*y, y, x, 1] sage: J = R.ideal(x^2-2*x*z+5) sage: J.normal_basis(3) # indirect doctest @@ -3519,7 +3524,7 @@ def __call_singular(self, cmd, arg=None): sage: H.inject_variables() Defining x, y, z sage: id = H.ideal(x + y, y + z) - sage: id.std() # indirect doctest # random + sage: id.std() # indirect doctest # random Left Ideal (z, y, x) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z} sage: sorted(id.std().gens(), key=str) @@ -3860,8 +3865,8 @@ def __init__(self, ring, gens, coerce=True): sage: R. = PolynomialRing(IntegerRing(), 2, order='lex') sage: R.ideal([x, y]) Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring - sage: R. = GF(3)[] # needs sage.rings.finite_rings - sage: R.ideal([x0^2, x1^3]) # needs sage.rings.finite_rings + sage: R. = GF(3)[] + sage: R.ideal([x0^2, x1^3]) Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 """ Ideal_generic.__init__(self, ring, gens, coerce=coerce) @@ -4297,37 +4302,37 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal :: sage: P. = PolynomialRing(QQ,3, order='lex') - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: I.groebner_basis() [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: I.groebner_basis('libsingular:groebner') [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: I.groebner_basis('libsingular:std') [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: I.groebner_basis('libsingular:stdhilb') [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: I.groebner_basis('libsingular:stdfglm') [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: I.groebner_basis('libsingular:slimgb') [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] @@ -4335,14 +4340,14 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal reverse lexicographical ordering here, in order to test against :trac:`21884`:: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: J = I.change_ring(P.change_ring(order='degrevlex')) - sage: gb = J.groebner_basis('giac') # random + sage: gb = J.groebner_basis('giac') # random sage: gb [c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1] sage: J.groebner_basis.set_cache(gb) - sage: ideal(J.transformed_basis()).change_ring(P).interreduced_basis() # testing trac 21884 + sage: ideal(J.transformed_basis()).change_ring(P).interreduced_basis() # testing issue #21884 ...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] Giac's gbasis over `\QQ` can benefit from a probabilistic lifting and @@ -4350,7 +4355,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal sage: A9 = PolynomialRing(QQ, 9, 'x') sage: I9 = sage.rings.ideal.Katsura(A9) - sage: print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=1e-7) # long time (3s) + sage: print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=1e-7) # long time (3s) possible output... Polynomial Sequence with 143 Polynomials in 9 Variables @@ -4359,7 +4364,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Note that ``toy:buchberger`` does not return the reduced Groebner basis, :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: gb = I.groebner_basis('toy:buchberger') sage: gb.is_groebner() True @@ -4368,7 +4373,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal but that ``toy:buchberger2`` does. :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: gb = I.groebner_basis('toy:buchberger2'); gb [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] sage: gb == gb.reduced() @@ -4377,32 +4382,36 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Here we use Macaulay2 with three different strategies over a finite field. :: - sage: R. = PolynomialRing(GF(101), 3) # needs sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # needs sage.rings.finite_rings - sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 # needs sage.rings.finite_rings - [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] - - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # needs sage.rings.finite_rings - sage: I.groebner_basis('macaulay2:f4') # optional - macaulay2 # needs sage.rings.finite_rings - [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] - - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # needs sage.rings.finite_rings - sage: I.groebner_basis('macaulay2:mgb') # optional - macaulay2 # needs sage.rings.finite_rings - [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] + sage: # optional - macaulay2 + sage: R. = PolynomialRing(GF(101), 3) + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching + sage: I.groebner_basis('macaulay2:gb') + [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, + b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching + sage: I.groebner_basis('macaulay2:f4') + [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, + b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching + sage: I.groebner_basis('macaulay2:mgb') + [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c, + b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1] Over prime fields of small characteristic, we can also use the `optional package msolve <../spkg/msolve.html>`_:: - sage: R. = PolynomialRing(GF(101), 3) # needs sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # needs sage.rings.finite_rings - sage: I.groebner_basis('msolve') # optional - msolve # needs sage.rings.finite_rings - [a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c, b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c] + sage: R. = PolynomialRing(GF(101), 3) + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching + sage: I.groebner_basis('msolve') # optional - msolve + [a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c, + b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c] :: - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.finite_rings - sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma, needs sage.rings.finite_rings - [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma + [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, + b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c] Singular and libSingular can compute Groebner basis with degree restrictions. :: @@ -4463,7 +4472,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal :: - sage: I.groebner_basis('macaulay2') # optional - macaulay2 + sage: I.groebner_basis('macaulay2') # optional - macaulay2 [b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2, 2*b*c^2 - 6*c^3 + b^2 + 5*b*c + 8*c^2 - b - 2*c, 42*c^3 + b^2 + 2*b*c - 14*c^2 + b, @@ -4472,7 +4481,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Groebner bases over `\ZZ/n\ZZ` are also supported:: - sage: P. = PolynomialRing(Zmod(1000),3) + sage: P. = PolynomialRing(Zmod(1000), 3) sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b) sage: I.groebner_basis() [b*c^2 + 732*b*c + 808*b, @@ -4505,11 +4514,11 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 ) sage: J = Ideal(I.groebner_basis()) sage: f = sum(P.random_element(terms=2)*f for f in I.gens()) - sage: f # random + sage: f # random 1/2*y^2*z^7 - 1/4*y*z^8 + 2*x*z^5 + 95*z^6 + 1/2*y^5 - 1/4*y^4*z + x^2*y^2 + 3/2*x^2*y*z + 95*x*y*z^2 - sage: f.lift(I.gens()) # random + sage: f.lift(I.gens()) # random [2*x + 95*z, 1/2*y^2 - 1/4*y*z, 0] - sage: l = f.lift(J.gens()); l # random + sage: l = f.lift(J.gens()); l # random [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1/2*y^2 + 1/4*y*z, 1/2*y^2*z^2 - 1/4*y*z^3 + 2*x + 95*z] sage: sum(map(mul, zip(l,J.gens()))) == f True @@ -4574,55 +4583,50 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal Check that this method works over QQbar (:trac:`25351`):: - sage: P. = PolynomialRing(QQbar, 3, order='lex') # needs sage.rings.number_field - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis() # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='lex') + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis() [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('libsingular:groebner') # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('libsingular:groebner') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('libsingular:std') # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('libsingular:std') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('libsingular:stdhilb') # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('libsingular:stdhilb') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('libsingular:stdfglm') # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('libsingular:stdfglm') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('libsingular:slimgb') # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('libsingular:slimgb') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] sage: # needs sage.rings.number_field - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching sage: J = I.change_ring(P.change_ring(order='degrevlex')) - sage: gb = J.groebner_basis('giac') # random + sage: gb = J.groebner_basis('giac') # random sage: gb [c^3 + (-79/210)*c^2 + 1/30*b + 1/70*c, b^2 + (-3/5)*c^2 + (-1/5)*b + 1/5*c, b*c + 6/5*c^2 + (-1/10)*b + (-2/5)*c, a + 2*b + 2*c - 1] - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('toy:buchberger2') # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('toy:buchberger2') [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 # needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2 [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] - - sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching # needs sage.rings.number_field - sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma, needs sage.rings.number_field + sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching + sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma [a + (-60)*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 + (-79/7)*c^2 + 3/7*c, c^4 + (-10/21)*c^3 + 1/84*c^2 + 1/84*c] msolve currently supports the degrevlex order only:: - sage: R. = PolynomialRing(GF(101), 3, order='lex') # needs sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching # needs sage.rings.finite_rings - sage: I.groebner_basis('msolve') # optional - msolve # needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(101), 3, order='lex') + sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching + sage: I.groebner_basis('msolve') # optional - msolve Traceback (most recent call last): ... NotImplementedError: msolve only supports the degrevlex order (use transformed_basis()) @@ -4646,10 +4650,10 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal if not algorithm: try: gb = self._groebner_basis_libsingular("groebner", deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds) - except (TypeError, NameError): # conversion to Singular not supported + except (TypeError, NameError, ImportError): # conversion to Singular not supported try: gb = self._groebner_basis_singular("groebner", deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds) - except (TypeError, NameError, NotImplementedError): # conversion to Singular not supported + except (TypeError, NameError, NotImplementedError, ImportError): # conversion to Singular not supported R = self.ring() B = R.base_ring() if R.ngens() == 0: @@ -4754,18 +4758,22 @@ def groebner_cover(self): sage: R. = F[] sage: I = R.ideal([-x+3*y+z-5,2*x+a*z+4,4*x-3*z-1/a]) sage: I.groebner_cover() - {Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field, where X is defined by: - 0 - and Y is defined by: - 2*a^2 + 3*a: [(2*a^2 + 3*a)*z + (8*a + 1), (12*a^2 + 18*a)*y + (-20*a^2 - 35*a - 2), (4*a + 6)*x + 11], - Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field, where X is defined by: - ... - and Y is defined by: - 1: [1], - Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field, where X is defined by: - ... - and Y is defined by: - 1: [1]} + {Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field, + where X is defined by: + 0 + and Y is defined by: + 2*a^2 + 3*a: [(2*a^2 + 3*a)*z + (8*a + 1), + (12*a^2 + 18*a)*y + (-20*a^2 - 35*a - 2), (4*a + 6)*x + 11], + Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field, + where X is defined by: + ... + and Y is defined by: + 1: [1], + Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field, + where X is defined by: + ... + and Y is defined by: + 1: [1]} """ from sage.schemes.affine.affine_space import AffineSpace gc = self._groebner_cover() @@ -4876,9 +4884,9 @@ def subs(self, in_dict=None, **kwds): sage: T. = PolynomialRing(QQ) sage: I.subs(a=t, b=t) Principal ideal (t^2 + 1) of Univariate Polynomial Ring in t over Rational Field - sage: var("z") + sage: var("z") # needs sage.symbolic z - sage: I.subs(a=z, b=z) + sage: I.subs(a=z, b=z) # needs sage.symbolic Principal ideal (2*z^2 + 2) of Symbolic Ring Variables that are not substituted remain unchanged:: @@ -4947,7 +4955,7 @@ def _contains_(self, f): sage: R. = QQ[] sage: I = (x^3 + y, y) * R - sage: x in I # indirect doctest + sage: x in I # indirect doctest False sage: y in I True @@ -4975,28 +4983,28 @@ def homogenize(self, var='h'): EXAMPLES:: - sage: P. = PolynomialRing(GF(2)) # needs sage.rings.finite_rings - sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(2)) + sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 :: - sage: I.homogenize() # needs sage.rings.finite_rings + sage: I.homogenize() Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) of Multivariate Polynomial Ring in x, y, z, h over Finite Field of size 2 :: - sage: I.homogenize(y) # needs sage.rings.finite_rings + sage: I.homogenize(y) Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 :: - sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1]) # needs sage.rings.finite_rings - sage: I.homogenize() # needs sage.rings.finite_rings + sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1]) + sage: I.homogenize() Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) of Multivariate Polynomial Ring in x, y, z, h over Finite Field of size 2 @@ -5072,51 +5080,51 @@ def degree_of_semi_regularity(self): We consider a homogeneous example:: sage: n = 8 - sage: K = GF(127) # needs sage.rings.finite_rings - sage: P = PolynomialRing(K, n, 'x') # needs sage.rings.finite_rings - sage: s = [K.random_element() for _ in range(n)] # needs sage.rings.finite_rings - sage: L = [] # needs sage.rings.finite_rings - sage: for i in range(2 * n): # needs sage.rings.finite_rings + sage: K = GF(127) + sage: P = PolynomialRing(K, n, 'x') + sage: s = [K.random_element() for _ in range(n)] + sage: L = [] + sage: for i in range(2 * n): ....: f = P.random_element(degree=2, terms=binomial(n, 2)) ....: f -= f(*s) ....: L.append(f.homogenize()) - sage: I = Ideal(L) # needs sage.rings.finite_rings - sage: I.degree_of_semi_regularity() # needs sage.rings.finite_rings + sage: I = Ideal(L) + sage: I.degree_of_semi_regularity() 4 From this, we expect a Groebner basis computation to reach at most degree 4. For homogeneous systems this is equivalent to the largest degree in the Groebner basis:: - sage: max(f.degree() for f in I.groebner_basis()) # needs sage.rings.finite_rings + sage: max(f.degree() for f in I.groebner_basis()) 4 We increase the number of polynomials and observe a decrease the degree of regularity:: - sage: for i in range(2 * n): # needs sage.rings.finite_rings + sage: for i in range(2 * n): ....: f = P.random_element(degree=2, terms=binomial(n, 2)) ....: f -= f(*s) ....: L.append(f.homogenize()) - sage: I = Ideal(L) # needs sage.rings.finite_rings - sage: I.degree_of_semi_regularity() # needs sage.rings.finite_rings + sage: I = Ideal(L) + sage: I.degree_of_semi_regularity() 3 - sage: max(f.degree() for f in I.groebner_basis()) # needs sage.rings.finite_rings + sage: max(f.degree() for f in I.groebner_basis()) 3 The degree of regularity approaches 2 for quadratic systems as the number of polynomials approaches `n^2`:: - sage: for i in range((n-4) * n): # needs sage.rings.finite_rings + sage: for i in range((n-4) * n): ....: f = P.random_element(degree=2, terms=binomial(n, 2)) ....: f -= f(*s) ....: L.append(f.homogenize()) - sage: I = Ideal(L) # needs sage.rings.finite_rings - sage: I.degree_of_semi_regularity() # needs sage.rings.finite_rings + sage: I = Ideal(L) + sage: I.degree_of_semi_regularity() 2 - sage: max(f.degree() for f in I.groebner_basis()) # needs sage.rings.finite_rings + sage: max(f.degree() for f in I.groebner_basis()) 2 .. NOTE:: @@ -5126,7 +5134,7 @@ def degree_of_semi_regularity(self): semi-regular sequences. For more details about semi-regular sequences see [BFS2004]_. """ - degs = [f.degree() for f in self.gens() if f!=0] # we ignore zeroes + degs = [f.degree() for f in self.gens() if f!=0] # we ignore zeroes m, n = self.ngens(), len(set(sum([f.variables() for f in self.gens()],()))) if m <= n: raise ValueError("This function requires an overdefined system of polynomials.") @@ -5282,7 +5290,6 @@ def random_element(self, degree, compute_gb=False, *args, **kwds): We compute a uniformly random element up to the provided degree. :: - sage: # needs sage.rings.finite_rings sage: P. = GF(127)[] sage: I = sage.rings.ideal.Katsura(P) sage: f = I.random_element(degree=4, compute_gb=True, terms=infinity) @@ -5296,26 +5303,26 @@ def random_element(self, degree, compute_gb=False, *args, **kwds): basis if we can sample uniformly at random from an ideal:: sage: n = 3; d = 4 - sage: P = PolynomialRing(GF(127), n, 'x') # needs sage.rings.finite_rings - sage: I = sage.rings.ideal.Cyclic(P) # needs sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), n, 'x') + sage: I = sage.rings.ideal.Cyclic(P) 1. We sample `n^d` uniformly random elements in the ideal:: - sage: F = Sequence(I.random_element(degree=d, compute_gb=True, # needs sage.rings.finite_rings + sage: F = Sequence(I.random_element(degree=d, compute_gb=True, ....: terms=infinity) ....: for _ in range(n^d)) 2. We linearize and compute the echelon form:: - sage: A, v = F.coefficient_matrix() # needs sage.rings.finite_rings - sage: A.echelonize() # needs sage.rings.finite_rings + sage: A, v = F.coefficient_matrix() + sage: A.echelonize() 3. The result is the desired Gröbner basis:: - sage: G = Sequence((A * v).list()) # needs sage.rings.finite_rings - sage: G.is_groebner() # needs sage.rings.finite_rings + sage: G = Sequence((A * v).list()) + sage: G.is_groebner() True - sage: Ideal(G) == I # needs sage.rings.finite_rings + sage: Ideal(G) == I True We return some element in the ideal with no guarantee on the distribution:: @@ -5414,8 +5421,7 @@ def weil_restriction(self): sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal sage: J.variety() [{y1: 1, y0: 0, x1: 1, x0: 1}] - - sage: J.weil_restriction() # returns J # needs sage.rings.finite_rings + sage: J.weil_restriction() # returns J Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2 @@ -5428,8 +5434,7 @@ def weil_restriction(self): 0 sage: I.variety() [{z: 0, y: 0, x: 1}] - - sage: J = I.weil_restriction(); J # needs sage.rings.finite_rings + sage: J = I.weil_restriction(); J Ideal (x0 - y0 - z0 - 1, x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - y4 - z4, x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 - x0, @@ -5454,9 +5459,9 @@ def weil_restriction(self): - y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 - y4) of Multivariate Polynomial Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, z0, z1, z2, z3, z4 over Finite Field of size 3 - sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal # needs sage.rings.finite_rings + sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal sage: from sage.doctest.fixtures import reproducible_repr - sage: print(reproducible_repr(J.variety())) # needs sage.rings.finite_rings + sage: print(reproducible_repr(J.variety())) [{x0: 1, x1: 0, x2: 0, x3: 0, x4: 0, y0: 0, y1: 0, y2: 0, y3: 0, y4: 0, z0: 0, z1: 0, z2: 0, z3: 0, z4: 0}] @@ -5493,8 +5498,7 @@ def weil_restriction(self): So we compute its Weil restriction:: - sage: J = I.weil_restriction() # needs sage.rings.number_field - sage: J # needs sage.rings.number_field + sage: J = I.weil_restriction(); J # needs sage.rings.number_field Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0 + 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3 - 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1 @@ -5513,13 +5517,14 @@ def weil_restriction(self): Example for relative number fields:: + sage: # needs sage.rings.number_field sage: R. = QQ[] - sage: K. = NumberField(x^5 - 2) # needs sage.rings.number_field - sage: R. = K[] # needs sage.rings.number_field - sage: L. = K.extension(x^2 + 1) # needs sage.rings.number_field - sage: S. = L[] # needs sage.rings.number_field - sage: I = S.ideal([y^2 - x^3 - 1]) # needs sage.rings.number_field - sage: I.weil_restriction() # needs sage.rings.number_field + sage: K. = NumberField(x^5 - 2) + sage: R. = K[] + sage: L. = K.extension(x^2 + 1) + sage: S. = L[] + sage: I = S.ideal([y^2 - x^3 - 1]) + sage: I.weil_restriction() Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) of Multivariate Polynomial Ring in x0, x1, y0, y1 over Number Field in w with defining polynomial x^5 - 2 diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 45e14eb320d..4392ae438be 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -30,21 +30,18 @@ We show how to construct various multivariate polynomial rings:: sage: P.term_order() Degree reverse lexicographic term order - sage: P = PolynomialRing(GF(127),3,names='abc', order='lex') - sage: P + sage: P = PolynomialRing(GF(127), 3, names='abc', order='lex'); P Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 - sage: a,b,c = P.gens() sage: f = 57 * a^2*b + 43 * c + 1; f 57*a^2*b + 43*c + 1 - sage: P.term_order() Lexicographic term order sage: z = QQ['z'].0 - sage: K. = NumberField(z^2 - 2) - sage: P. = PolynomialRing(K, 2) - sage: 1/2*s*x^2 + 3/4*s + sage: K. = NumberField(z^2 - 2) # needs sage.rings.number_field + sage: P. = PolynomialRing(K, 2) # needs sage.rings.number_field + sage: 1/2*s*x^2 + 3/4*s # needs sage.rings.number_field (1/2*s)*x^2 + (3/4*s) sage: P. = ZZ[]; P @@ -57,7 +54,8 @@ We show how to construct various multivariate polynomial rings:: Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049 sage: P. = Zmod(2^100)[]; P - Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1267650600228229401496703205376 + Multivariate Polynomial Ring in x, y, z over + Ring of integers modulo 1267650600228229401496703205376 sage: P. = Zmod(2521352)[]; P Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352 @@ -75,9 +73,9 @@ We construct the Frobenius morphism on `\GF{5}[x,y,z]` over `\GF{5}`:: sage: frob = R.hom([x^5, y^5, z^5]) sage: frob(x^2 + 2*y - z^4) -z^20 + x^10 + 2*y^5 - sage: frob((x + 2*y)^3) + sage: frob((x + 2*y)^3) # needs sage.rings.finite_rings x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15 - sage: (x^5 + 2*y^5)^3 + sage: (x^5 + 2*y^5)^3 # needs sage.rings.finite_rings x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15 We make a polynomial ring in one variable over a polynomial ring in @@ -95,7 +93,7 @@ TESTS:: True sage: loads(dumps(x)) == x True - sage: P. = GF(2^8,'a')[] + sage: P. = GF(2^8,'a')[] # needs sage.rings.finite_rings sage: loads(dumps(P)) == P True sage: loads(dumps(x)) == x @@ -120,9 +118,9 @@ TESTS:: Check if :trac:`6160` is fixed:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x - 1728) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: b - j*c # optional - sage.rings.number_field + sage: K. = NumberField(x - 1728) # needs sage.rings.number_field + sage: R. = K[] # needs sage.rings.number_field + sage: b - j*c # needs sage.rings.number_field b - 1728*c .. TODO:: @@ -297,31 +295,25 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): EXAMPLES:: - sage: P. = QQ[] - sage: P + sage: P. = QQ[]; P Multivariate Polynomial Ring in x, y, z over Rational Field - sage: f = 27/113 * x^2 + y*z + 1/2; f 27/113*x^2 + y*z + 1/2 - sage: P.term_order() Degree reverse lexicographic term order - sage: P = PolynomialRing(GF(127),3,names='abc', order='lex') - sage: P + sage: P = PolynomialRing(GF(127), 3, names='abc', order='lex'); P Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 - sage: a,b,c = P.gens() sage: f = 57 * a^2*b + 43 * c + 1; f 57*a^2*b + 43*c + 1 - sage: P.term_order() Lexicographic term order sage: z = QQ['z'].0 - sage: K. = NumberField(z^2 - 2) - sage: P. = PolynomialRing(K, 2) - sage: 1/2*s*x^2 + 3/4*s + sage: K. = NumberField(z^2 - 2) # needs sage.rings.number_field + sage: P. = PolynomialRing(K, 2) # needs sage.rings.number_field + sage: 1/2*s*x^2 + 3/4*s # needs sage.rings.number_field (1/2*s)*x^2 + (3/4*s) sage: P. = ZZ[]; P @@ -334,7 +326,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049 sage: P. = Zmod(2^100)[]; P - Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1267650600228229401496703205376 + Multivariate Polynomial Ring in x, y, z over + Ring of integers modulo 1267650600228229401496703205376 sage: P. = Zmod(2521352)[]; P Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352 @@ -342,11 +335,12 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P. = Zmod(25213521351515232)[]; P - Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232 + Multivariate Polynomial Ring in x, y, z over + Ring of integers modulo 25213521351515232 sage: type(P) - sage: P. = PolynomialRing(Integers(2^32),order='lex') + sage: P. = PolynomialRing(Integers(2^32), order='lex') sage: P(2^32-1) 4294967295 @@ -368,7 +362,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Traceback (most recent call last): ... NotImplementedError: polynomials over Ring of integers modulo 1 are not supported in Singular - sage: MPolynomialRing_libsingular(SR, 1, ["x"], "lex") # optional - sage.symbolic + sage: MPolynomialRing_libsingular(SR, 1, ["x"], "lex") # needs sage.symbolic Traceback (most recent call last): ... NotImplementedError: polynomials over Symbolic Ring are not supported in Singular @@ -403,9 +397,12 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: import gc sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular - sage: R1 = MPolynomialRing_libsingular(GF(5), 2, ('x', 'y'), TermOrder('degrevlex', 2)) - sage: R2 = MPolynomialRing_libsingular(GF(11), 2, ('x', 'y'), TermOrder('degrevlex', 2)) - sage: R3 = MPolynomialRing_libsingular(GF(13), 2, ('x', 'y'), TermOrder('degrevlex', 2)) + sage: R1 = MPolynomialRing_libsingular(GF(5), 2, ('x', 'y'), + ....: TermOrder('degrevlex', 2)) + sage: R2 = MPolynomialRing_libsingular(GF(11), 2, ('x', 'y'), + ....: TermOrder('degrevlex', 2)) + sage: R3 = MPolynomialRing_libsingular(GF(13), 2, ('x', 'y'), + ....: TermOrder('degrevlex', 2)) sage: _ = gc.collect() sage: foo = R1.gen(0) sage: del foo @@ -427,23 +424,24 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): TESTS:: + sage: # needs sage.rings.function_field sage: import gc sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular sage: from sage.libs.singular.ring import ring_refcount_dict sage: gc.collect() # random output sage: n = len(ring_refcount_dict) - sage: R = MPolynomialRing_libsingular(GF(547), 2, ('x', 'y'), TermOrder('degrevlex', 2)) + sage: R = MPolynomialRing_libsingular(GF(547), 2, ('x', 'y'), + ....: TermOrder('degrevlex', 2)) sage: len(ring_refcount_dict) == n + 1 True - sage: Q = copy(R) # indirect doctest - sage: p = R.gen(0) ^2+R.gen(1)^2 + sage: p = R.gen(0)^2 + R.gen(1)^2 sage: q = copy(p) sage: del R sage: del Q sage: del p sage: del q - sage: gc.collect() # random output + sage: gc.collect() # random output sage: len(ring_refcount_dict) == n False """ @@ -458,7 +456,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): TESTS:: sage: R. = GF(547)[] - sage: R is deepcopy(R) # indirect doctest + sage: R is deepcopy(R) True """ memo[id(self)] = self @@ -559,15 +557,15 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P.coerce(int(1)) 1 - sage: k. = GF(2^8) - sage: P. = PolynomialRing(k,2) - sage: P.coerce(a) + sage: k. = GF(2^8) # needs sage.rings.finite_rings + sage: P. = PolynomialRing(k,2) # needs sage.rings.finite_rings + sage: P.coerce(a) # needs sage.rings.finite_rings a sage: z = QQ['z'].0 - sage: K. = NumberField(z^2 - 2) - sage: P. = PolynomialRing(K, 2) - sage: P.coerce(1/2*s) + sage: K. = NumberField(z^2 - 2) # needs sage.rings.number_field + sage: P. = PolynomialRing(K, 2) # needs sage.rings.number_field + sage: P.coerce(1/2*s) # needs sage.rings.number_field (1/2*s) TESTS:: @@ -583,16 +581,16 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Check if :trac:`7582` is fixed:: - sage: R. = PolynomialRing(CyclotomicField(2),3) - sage: R.coerce(1) + sage: R. = PolynomialRing(CyclotomicField(2), 3) # needs sage.rings.number_field + sage: R.coerce(1) # needs sage.rings.number_field 1 Check if :trac:`6160` is fixed:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x - 1728) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: R.coerce(1) # optional - sage.rings.number_field + sage: K. = NumberField(x - 1728) # needs sage.rings.number_field + sage: R. = K[] # needs sage.rings.number_field + sage: R.coerce(1) # needs sage.rings.number_field 1 Check if coercion from zero variable polynomial rings work @@ -624,15 +622,15 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: P._singular_().set_ring() - sage: P(singular('x + 3/4')) + sage: P(singular('x + 3/4')) # needs sage.rings.function_field x + 3/4 Coercion from symbolic variables:: sage: R = QQ['x,y,z'] - sage: var('x') + sage: var('x') # needs sage.symbolic x - sage: R(x) + sage: R(x) # needs sage.symbolic x Coercion from 'similar' rings, which maps by index:: @@ -652,9 +650,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Coercion from PARI objects:: sage: P. = QQ[] - sage: P(pari('x^2 + y')) + sage: P(pari('x^2 + y')) # needs sage.libs.pari x^2 + y - sage: P(pari('x*y')) + sage: P(pari('x*y')) # needs sage.libs.pari x*y Coercion from boolean polynomials, also by index:: @@ -667,7 +665,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): If everything else fails, we try to convert to the base ring:: sage: R. = GF(3)[] - sage: R(1/2) + sage: R(1/2) # needs sage.rings.finite_rings -1 Finally, conversions from other polynomial rings which are not @@ -677,7 +675,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): preserving conversion:: sage: P. = GF(3)[] - sage: Q = GF(3)['y_4', 'y_3', 'y_2', 'y_1', 'z_5', 'z_4', 'z_3', 'z_2', 'z_1'] + sage: Q = GF(3)['y_4', 'y_3', 'y_2', 'y_1', + ....: 'z_5', 'z_4', 'z_3', 'z_2', 'z_1'] sage: Q(y_1*z_2^2*z_1) y_1*z_2^2*z_1 @@ -687,7 +686,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P. = GF(2)[] sage: Q = GF(2)['c','b','d','e'] sage: f = Q.convert_map_from(P) - sage: f(a), f(b), f(c) + sage: f(a), f(b), f(c) # needs sage.rings.finite_rings (c, b, d) :: @@ -703,14 +702,15 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P. = GF(2)[] sage: Q = GF(2)['c','d','e'] sage: f = Q.convert_map_from(P) - sage: f(a) + sage: f(a) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Could not find a mapping of the passed element to this ring. Coerce in a polydict where a coefficient reduces to 0 but isn't 0. :: - sage: R. = QQ[]; S. = GF(5)[]; S( (5*x*y + x + 17*y)._mpoly_dict_recursive() ) + sage: R. = QQ[]; S. = GF(5)[] + sage: S((5*x*y + x + 17*y)._mpoly_dict_recursive()) xx + 2*yy Coerce in a polynomial one of whose coefficients reduces to 0. :: @@ -721,7 +721,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Some other examples that illustrate the same coercion idea:: sage: R. = ZZ[] - sage: S. = GF(25,'a')[] + sage: S. = GF(25,'a')[] # needs sage.rings.finite_rings sage: S(5*x*y + x + 17*y) xx + 2*yy @@ -747,11 +747,11 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): And :trac:`7597` is fixed if this does not segfault:: sage: F2 = GF(2) - sage: F. = GF(2^8) + sage: F. = GF(2^8) # needs sage.rings.finite_rings sage: R4. = PolynomialRing(F) sage: R. = PolynomialRing(F2) sage: P = a - sage: (P(0,0).polynomial()[0])*u + sage: (P(0,0).polynomial()[0])*u # needs sage.rings.finite_rings 0 sage: P(a,b) a @@ -764,6 +764,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): Check that :trac:`17964` is fixed:: + sage: # needs sage.rings.number_field sage: K. = QuadraticField(17) sage: Q. = K[] sage: f = (-3*a)*y + (5*a) @@ -1031,9 +1032,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P.ngens() 2 - sage: k. = GF(2^16) - sage: P = PolynomialRing(k,1000,'x') - sage: P.ngens() + sage: k. = GF(2^16) # needs sage.rings.finite_rings + sage: P = PolynomialRing(k, 1000, 'x') # needs sage.rings.finite_rings + sage: P.ngens() # needs sage.rings.finite_rings 1000 """ return int(self.__ngens) @@ -1050,10 +1051,10 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): EXAMPLES:: sage: P. = QQ[] - sage: P.gen(),P.gen(1) + sage: P.gen(), P.gen(1) (x, y) - sage: P = PolynomialRing(GF(127),1000,'x') + sage: P = PolynomialRing(GF(127), 1000, 'x') sage: P.gen(500) x500 @@ -1089,11 +1090,13 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): EXAMPLES:: sage: P. = QQ[] - sage: sage.rings.ideal.Katsura(P) - Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y) of Multivariate Polynomial Ring in x, y, z over Rational Field + sage: sage.rings.ideal.Katsura(P) # needs sage.rings.function_field + Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y) + of Multivariate Polynomial Ring in x, y, z over Rational Field sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x]) - Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 + 2*y^2 + 2*z^2 - x) of Multivariate Polynomial Ring in x, y, z over Rational Field + Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 + 2*y^2 + 2*z^2 - x) + of Multivariate Polynomial Ring in x, y, z over Rational Field """ coerce = kwds.get('coerce', True) if len(gens) == 1: @@ -1136,7 +1139,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): QQ[x...y] sage: R. = GF(17)[] - sage: macaulay2(R) # optional - macaulay2 + sage: macaulay2(R) # optional - macaulay2 # needs sage.rings.finite_rings ZZ --[x...y] 17 @@ -1191,9 +1194,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P._singular_().name() == P._singular_().name() True - sage: k. = GF(3^3) - sage: P. = PolynomialRing(k,3) - sage: P._singular_() + sage: k. = GF(3^3) # needs sage.rings.finite_rings + sage: P. = PolynomialRing(k, 3) # needs sage.rings.finite_rings + sage: P._singular_() # needs sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/3[a]/(a^3-a+1) // number of vars : 3 @@ -1201,10 +1204,10 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // : names x y z // block 2 : ordering C - sage: P._singular_() is P._singular_() + sage: P._singular_() is P._singular_() # needs sage.rings.finite_rings True - sage: P._singular_().name() == P._singular_().name() + sage: P._singular_().name() == P._singular_().name() # needs sage.rings.finite_rings True TESTS:: @@ -1266,8 +1269,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): False sage: w = polygen(ZZ, 'w') - sage: R. = PolynomialRing(NumberField(w^2 + 1,'s')) # optional - sage.rings.number_field - sage: singular(R) # optional - sage.rings.number_field + sage: R. = PolynomialRing(NumberField(w^2 + 1,'s')) # needs sage.rings.number_field + sage: singular(R) # needs sage.rings.number_field polynomial ring, over a field, global ordering // coefficients: QQ[s]/(s^2+1) // number of vars : 2 @@ -1275,8 +1278,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // : names x y // block 2 : ordering C - sage: R = PolynomialRing(GF(2**8,'a'),10,'x', order='invlex') - sage: singular(R) + sage: R = PolynomialRing(GF(2**8,'a'),10,'x', order='invlex') # needs sage.rings.finite_rings + sage: singular(R) # needs sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/2[a]/(a^8+a^4+a^3+a^2+1) // number of vars : 10 @@ -1285,7 +1288,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = PolynomialRing(GF(127),2,'x', order='invlex') - sage: singular(R) + sage: singular(R) # needs sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 2 @@ -1294,7 +1297,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = PolynomialRing(QQ,2,'x', order='invlex') - sage: singular(R) + sage: singular(R) # needs sage.rings.function_field polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 2 @@ -1303,7 +1306,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = PolynomialRing(QQ,2,'x', order='degneglex') - sage: singular(R) + sage: singular(R) # needs sage.rings.function_field polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 2 @@ -1315,7 +1318,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 3 : ordering C sage: R = PolynomialRing(QQ,'x') - sage: singular(R) + sage: singular(R) # needs sage.rings.function_field polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -1324,7 +1327,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = PolynomialRing(GF(127),'x') - sage: singular(R) + sage: singular(R) # needs sage.rings.finite_rings polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 1 @@ -1333,7 +1336,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = ZZ['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.rings.function_field polynomial ring, over a domain, global ordering // coefficients: ZZ // number of vars : 2 @@ -1342,7 +1345,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = IntegerModRing(1024)['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.rings.function_field polynomial ring, over a ring (with zero-divisors), global ordering // coefficients: ZZ/(2^10) // number of vars : 2 @@ -1351,7 +1354,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): // block 2 : ordering C sage: R = IntegerModRing(15)['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.rings.function_field polynomial ring, over a ring (with zero-divisors), global ordering // coefficients: ZZ/...(15) // number of vars : 2 @@ -1430,7 +1433,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P == R False - sage: R. = PolynomialRing(QQ,order='invlex') + sage: R. = PolynomialRing(QQ, order='invlex') sage: P == R False @@ -1476,16 +1479,16 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P == loads(dumps(P)) True - sage: P = PolynomialRing(GF(2^8,'F'), names='abc') + sage: P = PolynomialRing(GF(2^8,'F'), names='abc') # needs sage.rings.finite_rings sage: P == loads(dumps(P)) True - sage: P = PolynomialRing(GF(2^16,'B'), names='abc') + sage: P = PolynomialRing(GF(2^16,'B'), names='abc') # needs sage.rings.finite_rings sage: P == loads(dumps(P)) True sage: z = QQ['z'].0 - sage: P = PolynomialRing(NumberField(z^2 + 3,'B'), names='abc') - sage: P == loads(dumps(P)) + sage: P = PolynomialRing(NumberField(z^2 + 3, 'B'), names='abc') # needs sage.rings.number_field + sage: P == loads(dumps(P)) # needs sage.rings.number_field True """ return unpickle_MPolynomialRing_libsingular, \ @@ -1904,8 +1907,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomial_libsingular - sage: P = PolynomialRing(GF(32003),3,'x') - sage: MPolynomial_libsingular(P) + sage: P = PolynomialRing(GF(32003), 3, 'x') # needs sage.rings.finite_rings + sage: MPolynomial_libsingular(P) # needs sage.rings.finite_rings 0 """ self._poly = NULL @@ -1932,6 +1935,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: F. = GF(7^2) sage: R. = F[] sage: p = a*x^2 + y + a^3; p @@ -2038,11 +2042,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): See :trac:`8502`:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: K. = NumberField(x^2+47) + sage: K. = NumberField(x^2 + 47) sage: R. = K[] - sage: f = X+Y+Z - sage: a = f(t,t,t); a + sage: f = X + Y + Z + sage: a = f(t, t, t); a 3*t sage: a.parent() is K True @@ -2056,6 +2061,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): See :trac:`33373`:: + sage: # needs sage.rings.finite_rings sage: k. = GF(2^4) sage: R. = PolynomialRing(k, 1) sage: f = R(1) @@ -2775,12 +2781,11 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - ``degrees`` - Can be any of: - - a dictionary of degree restrictions - - a list of degree restrictions (with None in the unrestricted variables) - - a monomial (very fast, but not as flexible) + - a dictionary of degree restrictions + - a list of degree restrictions (with ``None`` in the unrestricted variables) + - a monomial (very fast, but not as flexible) - OUTPUT: - element of the parent of this element. + OUTPUT: element of the parent of this element. .. NOTE:: @@ -2818,8 +2823,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f.coefficient(x^0) # outputs the full polynomial x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1 sage: R. = GF(389)[] - sage: f=x*y+5 - sage: c=f.coefficient({x:0,y:0}); c + sage: f = x*y + 5 + sage: c = f.coefficient({x:0, y:0}); c 5 sage: parent(c) Multivariate Polynomial Ring in x, y over Finite Field of size 389 @@ -3408,12 +3413,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f = x^2 + y + x^2*y^2 + 5 sage: f(5,y) 25*y^2 + y + 30 - sage: f.subs({x:5}) + sage: f.subs({x: 5}) 25*y^2 + y + 30 sage: f.subs(x=5) 25*y^2 + y + 30 - sage: P. = PolynomialRing(GF(2),3) + sage: P. = PolynomialRing(GF(2), 3) sage: f = x + y + 1 sage: f.subs({x:y+1}) 0 @@ -3421,14 +3426,14 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): 1 sage: f.subs(x=x) x + y + 1 - sage: f.subs({x:z}) + sage: f.subs({x: z}) y + z + 1 - sage: f.subs(x=z+1) + sage: f.subs(x=z + 1) y + z sage: f.subs(x=1/y) (y^2 + y + 1)/y - sage: f.subs({x:1/y}) + sage: f.subs({x: 1/y}) (y^2 + y + 1)/y The parameters are substituted in order and without side effects:: @@ -3459,8 +3464,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): We test that we change the ring even if there is nothing to do:: sage: P = QQ['x,y'] - sage: x = var('x') - sage: parent(P.zero().subs(x=x)) + sage: x = var('x') # needs sage.symbolic + sage: parent(P.zero().subs(x=x)) # needs sage.symbolic Symbolic Ring We are catching overflows:: @@ -3794,8 +3799,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def is_univariate(self): """ - Return ``True`` if self is a univariate polynomial, that is if - self contains only one variable. + Return ``True`` if ``self`` is a univariate polynomial, that is if + ``self`` contains only one variable. EXAMPLES:: @@ -3814,13 +3819,13 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def _variable_indices_(self, sort=True): """ - Return the indices of all variables occurring in self. This + Return the indices of all variables occurring in ``self``. This index is the index as Sage uses them (starting at zero), not as SINGULAR uses them (starting at one). INPUT: - - ``sort`` - specifies whether the indices shall be sorted + - ``sort`` -- specifies whether the indices shall be sorted EXAMPLES:: @@ -3847,7 +3852,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def variables(self): """ - Return a tuple of all variables occurring in self. + Return a tuple of all variables occurring in ``self``. EXAMPLES:: @@ -3878,8 +3883,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def variable(self, i=0): """ - - Return the i-th variable occurring in self. The index i is the + Return the `i`-th variable occurring in ``self``. The index `i` is the index in ``self.variables()``. EXAMPLES:: @@ -3925,13 +3929,13 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): def lm(MPolynomial_libsingular self): """ - Returns the lead monomial of self with respect to the term + Returns the lead monomial of ``self`` with respect to the term order of ``self.parent()``. In Sage a monomial is a product of variables in some power without a coefficient. EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') + sage: R. = PolynomialRing(GF(7), 3, order='lex') sage: f = x^1*y^2 + y^3*z^4 sage: f.lm() x*y^2 @@ -3939,7 +3943,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f.lm() x^3*y^2*z^4 - sage: R.=PolynomialRing(QQ,3,order='deglex') + sage: R.=PolynomialRing(QQ, 3, order='deglex') sage: f = x^1*y^2*z^3 + x^3*y^2*z^0 sage: f.lm() x*y^2*z^3 @@ -3947,7 +3951,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f.lm() x*y^2*z^4 - sage: R.=PolynomialRing(GF(127),3,order='degrevlex') + sage: R.=PolynomialRing(GF(127), 3, order='degrevlex') sage: f = x^1*y^5*z^2 + x^4*y^1*z^3 sage: f.lm() x*y^5*z^2 @@ -3972,7 +3976,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') + sage: R. = PolynomialRing(GF(7), 3, order='lex') sage: f = 3*x^1*y^2 + 2*y^3*z^4 sage: f.lc() 3 @@ -4006,7 +4010,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: - sage: R.=PolynomialRing(GF(7),3,order='lex') + sage: R. = PolynomialRing(GF(7), 3, order='lex') sage: f = 3*x^1*y^2 + 2*y^3*z^4 sage: f.lt() 3*x*y^2 @@ -4028,7 +4032,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: P. = PolynomialRing(QQ) sage: x.is_zero() False - sage: (x-x).is_zero() + sage: (x - x).is_zero() True """ if self._poly is NULL: @@ -4062,6 +4066,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: R. = GF(32003)[] sage: f = y*x^2 + x + 1 sage: f//x @@ -4156,15 +4161,14 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``proof`` - ignored. + - ``proof`` -- ignored. EXAMPLES:: sage: R. = QQ[] sage: f = (x^3 + 2*y^2*x) * (x^2 + x + 1); f x^5 + 2*x^3*y^2 + x^4 + 2*x^2*y^2 + x^3 + 2*x*y^2 - sage: F = f.factor() - sage: F + sage: F = f.factor(); F x * (x^2 + x + 1) * (x^2 + 2*y^2) Next we factor the same polynomial, but over the finite field @@ -4174,27 +4178,28 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f = (x^3 + 2*y^2*x) * (x^2 + x + 1); f x^5 - x^3*y^2 + x^4 - x^2*y^2 + x^3 - x*y^2 sage: F = f.factor() - sage: F # order is somewhat random + sage: F # order is somewhat random (-1) * x * (-x + y) * (x + y) * (x - 1)^2 Next we factor a polynomial, but over a finite field of order 9.:: + sage: # needs sage.rings.finite_rings sage: K. = GF(3^2) sage: R. = K[] sage: f = (x^3 + 2*a*y^2*x) * (x^2 + x + 1); f x^5 + (-a)*x^3*y^2 + x^4 + (-a)*x^2*y^2 + x^3 + (-a)*x*y^2 - sage: F = f.factor() - sage: F + sage: F = f.factor(); F ((-a)) * x * (x - 1)^2 * ((-a + 1)*x^2 + y^2) sage: f - F 0 Next we factor a polynomial over a number field.:: + sage: # needs sage.rings.number_field sage: p = polygen(ZZ, 'p') - sage: K. = NumberField(p^3 - 2) # optional - sage.rings.number_field - sage: KXY. = K[] # optional - sage.rings.number_field - sage: factor(x^3 - 2*y^3) # optional - sage.rings.number_field + sage: K. = NumberField(p^3 - 2) + sage: KXY. = K[] + sage: factor(x^3 - 2*y^3) (x + (-s)*y) * (x^2 + s*x*y + (s^2)*y^2) sage: k = (x^3-2*y^3)^5*(x+s*y)^2*(2/3 + s^2) sage: k.factor() @@ -4203,18 +4208,19 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): This shows that issue :trac:`2780` is fixed, i.e. that the unit part of the factorization is set correctly:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - sage: f = 2*y^2 + 2*z^2 # optional - sage.rings.number_field - sage: F = f.factor(); F.unit() # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) + sage: R. = PolynomialRing(K) + sage: f = 2*y^2 + 2*z^2 + sage: F = f.factor(); F.unit() 2 Another example:: - sage: R. = GF(32003)[] - sage: f = 9*(x-1)^2*(y+z) - sage: f.factor() + sage: R. = GF(32003)[] # needs sage.rings.finite_rings + sage: f = 9*(x-1)^2*(y+z) # needs sage.rings.finite_rings + sage: f.factor() # needs sage.rings.finite_rings (9) * (y + z) * (x - 1)^2 sage: R. = QQ['x','w','v','u'] @@ -4243,12 +4249,13 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): `> 2^{29}` is not supported :: sage: q = 1073741789 - sage: T. = PolynomialRing(GF(q)) - sage: f = aa^2 + 12124343*bb*aa + 32434598*bb^2 - sage: f.factor() + sage: T. = PolynomialRing(GF(q)) # needs sage.rings.finite_rings + sage: f = aa^2 + 12124343*bb*aa + 32434598*bb^2 # needs sage.rings.finite_rings + sage: f.factor() # needs sage.rings.finite_rings Traceback (most recent call last): ... - NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + NotImplementedError: Factorization of multivariate polynomials + over prime fields with characteristic > 2^29 is not implemented. Factorization over the integers is now supported, see :trac:`17840`:: @@ -4269,7 +4276,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: f.factor() Traceback (most recent call last): ... - NotImplementedError: Factorization of multivariate polynomials over Ring of integers modulo 4 is not implemented. + NotImplementedError: Factorization of multivariate polynomials + over Ring of integers modulo 4 is not implemented. TESTS: @@ -4282,6 +4290,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): This checks that :trac:`11838` is fixed:: + sage: # needs sage.rings.finite_rings sage: K = GF(4,'a') sage: a = K.gens()[0] sage: R. = K[] @@ -4308,8 +4317,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): :: sage: R. = GF(2)[] - sage: p=x^8 + y^8; q=x^2*y^4 + x - sage: f=p*q + sage: p = x^8 + y^8; q=x^2*y^4 + x + sage: f = p*q sage: lf = f.factor() sage: f-lf 0 @@ -4330,18 +4339,18 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): :: sage: R. = GF(5)[] - sage: p=x^27*y^9 + x^32*y^3 + 2*x^20*y^10 - x^4*y^24 - 2*x^17*y - sage: q=-2*x^10*y^24 + x^9*y^24 - 2*x^3*y^30 - sage: f=p*q; f-f.factor() + sage: p = x^27*y^9 + x^32*y^3 + 2*x^20*y^10 - x^4*y^24 - 2*x^17*y + sage: q = -2*x^10*y^24 + x^9*y^24 - 2*x^3*y^30 + sage: f = p*q; f - f.factor() 0 :: sage: R. = GF(7)[] - sage: p=-3*x^47*y^24 - sage: q=-3*x^47*y^37 - 3*x^24*y^49 + 2*x^56*y^8 + 3*x^29*y^15 - x^2*y^33 - sage: f=p*q - sage: f-f.factor() + sage: p = -3*x^47*y^24 + sage: q = -3*x^47*y^37 - 3*x^24*y^49 + 2*x^56*y^8 + 3*x^29*y^15 - x^2*y^33 + sage: f = p*q + sage: f - f.factor() 0 The following examples used to give a Segmentation Fault, see @@ -4368,13 +4377,14 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: U. = GF(2)[] sage: f = y*t^8 + y^5*t^2 + y*t^6 + t^7 + y^6 + y^5*t + y^2*t^4 + y^2*t^2 + y^2*t + t^3 + y^2 + t^2 sage: l = f.factor() - sage: l[0][0]==t^2 + y + t + 1 or l[1][0]==t^2 + y + t + 1 + sage: l[0][0] == t^2 + y + t + 1 or l[1][0] == t^2 + y + t + 1 True The following used to sometimes take a very long time or get stuck, see :trac:`12846`. These 100 iterations should take less than 1 second:: + sage: # needs sage.rings.finite_rings sage: K. = GF(4) sage: R. = K[] sage: f = (a + 1)*x^145*y^84 + (a + 1)*x^205*y^17 + x^32*y^112 + x^92*y^45 @@ -4384,7 +4394,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): Test for :trac:`20435`:: sage: x,y = polygen(ZZ,'x,y') - sage: p = x**2-y**2 + sage: p = x**2 - y**2 sage: z = factor(p); z (x - y) * (x + y) sage: z[0][0].parent() @@ -4718,11 +4728,11 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``right`` - polynomial + - ``right`` -- polynomial - ``algorithm`` - - ``ezgcd`` - EZGCD algorithm - - ``modular`` - multi-modular algorithm (default) - - ``**kwds`` - ignored + - ``'ezgcd'`` -- EZGCD algorithm + - ``'modular'`` -- multi-modular algorithm (default) + - ``**kwds`` -- ignored EXAMPLES:: @@ -4742,6 +4752,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): We compute a gcd over a finite field:: + sage: # needs sage.rings.finite_rings sage: F. = GF(31^2) sage: R. = F[] sage: p = x^3 + (1+u)*y^3 + z^3 @@ -4753,6 +4764,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): We compute a gcd over a number field:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) sage: F. = NumberField(x^3 - 2) sage: R. = F[] @@ -4770,10 +4782,11 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: x.gcd(1) 1 + sage: # needs sage.rings.finite_rings sage: k. = GF(9) sage: R. = PolynomialRing(k) sage: f = R.change_ring(GF(3)).gen() - sage: g = x+y + sage: g = x + y sage: g.gcd(f) 1 sage: x.gcd(R.change_ring(GF(3)).gen()) @@ -4844,17 +4857,19 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: lcm(p,q) 6*x*y*z^4 + 6*y^2*z^4 + 6*x*z^5 + 6*y*z^5 + 12*x*y + 12*y^2 + 12*x*z + 12*y*z + sage: # needs sage.rings.finite_rings sage: r. = PolynomialRing(GF(2**8, 'a'), 2) sage: a = r.base_ring().0 sage: f = (a^2+a)*x^2*y + (a^4+a^3+a)*y + a^5 sage: f.lcm(x^4) (a^2 + a)*x^6*y + (a^4 + a^3 + a)*x^4*y + (a^5)*x^4 + sage: # needs sage.rings.number_field sage: w = polygen(ZZ, 'w') - sage: r. = PolynomialRing(NumberField(w^4 + 1, 'a'), 2) # optional - sage.rings.number_field - sage: a = r.base_ring().0 # optional - sage.rings.number_field - sage: f = (a^2+a)*x^2*y + (a^4+a^3+a)*y + a^5 # optional - sage.rings.number_field - sage: f.lcm(x^4) # optional - sage.rings.number_field + sage: r. = PolynomialRing(NumberField(w^4 + 1, 'a'), 2) + sage: a = r.base_ring().0 + sage: f = (a^2+a)*x^2*y + (a^4+a^3+a)*y + a^5 + sage: f.lcm(x^4) (a^2 + a)*x^6*y + (a^3 + a - 1)*x^4*y + (-a)*x^4 TESTS:: @@ -4920,7 +4935,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): @coerce_binop def quo_rem(self, MPolynomial_libsingular right): """ - Returns quotient and remainder of self and right. + Return quotient and remainder of ``self`` and ``right``. EXAMPLES:: @@ -4989,15 +5004,15 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: - sage: P. = PolynomialRing(GF(127),3) - sage: x._singular_init_() + sage: P. = PolynomialRing(GF(127), 3) + sage: x._singular_init_() # needs sage.libs.singular 'x' - sage: (x^2+37*y+128)._singular_init_() + sage: (x^2+37*y+128)._singular_init_() # needs sage.libs.singular 'x2+37y+1' TESTS:: - sage: P(0)._singular_init_() + sage: P(0)._singular_init_() # needs sage.libs.singular '0' """ if singular is None: @@ -5017,17 +5032,17 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: - sage: P.=PolynomialRing(QQ,3) - sage: x.sub_m_mul_q(y,z) + sage: P. = PolynomialRing(QQ,3) + sage: x.sub_m_mul_q(y, z) -y*z + x TESTS:: - sage: Q.=PolynomialRing(QQ,3) - sage: P.=PolynomialRing(QQ,3) - sage: P(0).sub_m_mul_q(P(0),P(1)) + sage: Q. = PolynomialRing(QQ,3) + sage: P. = PolynomialRing(QQ,3) + sage: P(0).sub_m_mul_q(P(0), P(1)) 0 - sage: x.sub_m_mul_q(Q.gen(1),Q.gen(2)) + sage: x.sub_m_mul_q(Q.gen(1), Q.gen(2)) -y*z + x """ cdef ring *r = self._parent_ring @@ -5063,21 +5078,21 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: + sage: # optional - macaulay2 sage: R. = PolynomialRing(GF(7), 2) sage: f = (x^3 + 2*y^2*x)^7; f # indirect doctest x^21 + 2*x^7*y^14 - - sage: h = macaulay2(f); h # optional - macaulay2 + sage: h = macaulay2(f); h 21 7 14 x + 2x y - sage: k = macaulay2(x+y); k # optional - macaulay2 + sage: k = macaulay2(x+y); k x + y - sage: k + h # optional - macaulay2 + sage: k + h 21 7 14 x + 2x y + x + y - sage: R(h) # optional - macaulay2 + sage: R(h) x^21 + 2*x^7*y^14 - sage: R(h^20) == f^20 # optional - macaulay2 + sage: R(h^20) == f^20 True TESTS: @@ -5102,12 +5117,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - - ``m`` - a monomial - - ``q`` - a polynomial + - ``m`` -- a monomial + - ``q`` -- a polynomial EXAMPLES:: - sage: P.=PolynomialRing(QQ,3) + sage: P. = PolynomialRing(QQ,3) sage: x.add_m_mul_q(y,z) y*z + x @@ -5146,12 +5161,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): EXAMPLES:: - sage: P. = PolynomialRing(QQ,3, order='degrevlex') + sage: P. = PolynomialRing(QQ, 3, order='degrevlex') sage: f = 27/113 * x^2 + y*z + 1/2 sage: f == loads(dumps(f)) True - sage: P = PolynomialRing(GF(127),3,names='abc') + sage: P = PolynomialRing(GF(127), 3, names='abc') sage: a,b,c = P.gens() sage: f = 57 * a^2*b + 43 * c + 1 sage: f == loads(dumps(f)) @@ -5191,6 +5206,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): You can specify a map on the base ring:: + sage: # needs sage.rings.number_field sage: Zx. = ZZ[] sage: K. = NumberField(x^2 + 1) sage: cc = K.hom([-i]) @@ -5235,9 +5251,9 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): The derivative is also defined over finite fields:: - sage: R. = PolynomialRing(GF(2**8, 'a'),2) + sage: R. = PolynomialRing(GF(2**8, 'a'), 2) # needs sage.rings.finite_rings sage: f = x^3*y^2 + y^2 + x + 2 - sage: f._derivative(x) + sage: f._derivative(x) # needs sage.rings.finite_rings x^2*y^2 + 1 """ @@ -5375,16 +5391,16 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): The SINGULAR example:: - sage: R. = PolynomialRing(GF(32003),3) + sage: R. = PolynomialRing(GF(32003), 3) # needs sage.rings.finite_rings sage: f = 3 * (x+2)^3 + y - sage: g = x+y+z - sage: f.resultant(g,x) + sage: g = x + y + z # needs sage.rings.finite_rings + sage: f.resultant(g, x) # needs sage.rings.finite_rings 3*y^3 + 9*y^2*z + 9*y*z^2 + 3*z^3 - 18*y^2 - 36*y*z - 18*z^2 + 35*y + 36*z - 24 Resultants are also supported over the Integers:: - sage: R.=PolynomialRing(ZZ, 5, order='lex') - sage: r = (x^4*y^2+x^2*y-y).resultant(x*y-y*a-x*b+a*b+u,x) + sage: R. = PolynomialRing(ZZ, 5, order='lex') + sage: r = (x^4*y^2 + x^2*y - y).resultant(x*y - y*a - x*b + a*b + u, x) sage: r y^6*a^4 - 4*y^5*a^4*b - 4*y^5*a^3*u + y^5*a^2 - y^5 + 6*y^4*a^4*b^2 + 12*y^4*a^3*b*u - 4*y^4*a^2*b + 6*y^4*a^2*u^2 - 2*y^4*a*u + 4*y^4*b - 4*y^3*a^4*b^3 - 12*y^3*a^3*b^2*u + 6*y^3*a^2*b^2 - 12*y^3*a^2*b*u^2 + 6*y^3*a*b*u - 4*y^3*a*u^3 - 6*y^3*b^2 + y^3*u^2 + y^2*a^4*b^4 + 4*y^2*a^3*b^3*u - 4*y^2*a^2*b^3 + 6*y^2*a^2*b^2*u^2 - 6*y^2*a*b^2*u + 4*y^2*a*b*u^3 + 4*y^2*b^3 - 2*y^2*b*u^2 + y^2*u^4 + y*a^2*b^4 + 2*y*a*b^3*u - y*b^4 + y*b^2*u^2 @@ -5479,21 +5495,20 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): INPUT: - ``prec`` -- desired floating point precision (default: - default RealField precision). + default :class:`RealField` precision). - OUTPUT: - - - a real number. + OUTPUT: a real number. EXAMPLES:: sage: R. = PolynomialRing(QQ) sage: f = 3*x^3 + 2*x*y^2 - sage: exp(f.global_height()) + sage: exp(f.global_height()) # needs sage.symbolic 3.00000000000000 :: + sage: # needs sage.rings.number_field sage: K. = CyclotomicField(3) sage: R. = PolynomialRing(K, sparse=True) sage: f = k*x*y + 1 @@ -5504,10 +5519,10 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: R. = PolynomialRing(QQ) sage: f = 1/25*x^2 + 25/3*x*y + y^2 - sage: f.global_height() + sage: f.global_height() # needs sage.symbolic 6.43775164973640 sage: g = 100 * f - sage: g.global_height() + sage: g.global_height() # needs sage.symbolic 6.43775164973640 :: @@ -5516,14 +5531,14 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): sage: K. = NumberField(x^2 + 5) sage: T. = PolynomialRing(K) sage: f = 1/1331 * t^2 + 5 * w + 7 - sage: f.global_height() + sage: f.global_height() # needs sage.symbolic 9.13959596745043 :: sage: R. = QQ[] sage: f = 1/123*x*y + 12 - sage: f.global_height(prec=2) + sage: f.global_height(prec=2) # needs sage.symbolic 8.0 :: @@ -5559,11 +5574,9 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): - ``v`` -- a prime or prime ideal of the base ring. - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default :class:`RealField` precision). - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -5574,6 +5587,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): :: + sage: # needs sage.rings.number_field sage: R. = QQ[] sage: K. = NumberField(x^2 - 5) sage: T. = K[] @@ -5608,11 +5622,9 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): - ``i`` -- an integer. - ``prec`` -- desired floating point precision (default: - default RealField precision). - - OUTPUT: + default :class:`RealField` precision). - - a real number. + OUTPUT: a real number. EXAMPLES:: @@ -5623,6 +5635,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): :: + sage: # needs sage.rings.number_field sage: R. = QQ[] sage: K. = NumberField(x^2 - 5) sage: T. = K[] diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index acf72a9e175..f61d3103fa8 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -27,13 +27,13 @@ We construct the Frobenius morphism on `\GF{5}[x,y,z]` over `\GF{5}`:: - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: frob = R.hom([x^5, y^5, z^5]) # optional - sage.rings.finite_rings - sage: frob(x^2 + 2*y - z^4) # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: frob = R.hom([x^5, y^5, z^5]) + sage: frob(x^2 + 2*y - z^4) -z^20 + x^10 + 2*y^5 - sage: frob((x + 2*y)^3) # optional - sage.rings.finite_rings + sage: frob((x + 2*y)^3) # needs sage.rings.finite_rings x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15 - sage: (x^5 + 2*y^5)^3 # optional - sage.rings.finite_rings + sage: (x^5 + 2*y^5)^3 # needs sage.rings.finite_rings x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15 We make a polynomial ring in one variable over a polynomial ring in @@ -46,7 +46,7 @@ TESTS:: - sage: PolynomialRing(GF(5), 3, 'xyz').objgens() # optional - sage.rings.finite_rings + sage: PolynomialRing(GF(5), 3, 'xyz').objgens() (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5, (x, y, z)) """ @@ -63,8 +63,6 @@ from sage.rings.ring import IntegralDomain import sage.rings.fraction_field_element as fraction_field_element -import sage.rings.polynomial.multi_polynomial_ideal as multi_polynomial_ideal - from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base, is_MPolynomialRing from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr from sage.rings.polynomial.polydict import PolyDict, ETuple @@ -72,7 +70,10 @@ import sage.interfaces.abc -from sage.libs.pari.all import pari_gen +try: + from sage.libs.pari.all import pari_gen +except ImportError: + pari_gen = () from sage.structure.element import Element @@ -203,7 +204,7 @@ def __call__(self, x=0, check=True): sage: R. = QQ[] sage: S. = ZZ[] - sage: T. = GF(7)[] # optional - sage.rings.finite_rings + sage: T. = GF(7)[] We convert from integer polynomials to rational polynomials, and back:: @@ -219,9 +220,9 @@ def __call__(self, x=0, check=True): :: - sage: f = R(T.0^2 - 4*T.1^3); f # optional - sage.rings.finite_rings + sage: f = R(T.0^2 - 4*T.1^3); f 3*y^3 + x^2 - sage: parent(f) # optional - sage.rings.finite_rings + sage: parent(f) Multivariate Polynomial Ring in x, y over Rational Field We dump and load the polynomial ring S:: @@ -241,24 +242,25 @@ def __call__(self, x=0, check=True): variable names:: sage: R. = PolynomialRing(QQ,2) - sage: S. = PolynomialRing(GF(7),2) # optional - sage.rings.finite_rings + sage: S. = PolynomialRing(GF(7),2) sage: f = x^2 + 2/3*y^3 - sage: S(f) # optional - sage.rings.finite_rings + sage: S(f) 3*b^3 + a^2 Conversion from symbolic variables:: - sage: x,y,z = var('x,y,z') # optional - sage.symbolic - sage: R = QQ['x,y,z'] # optional - sage.symbolic - sage: type(x) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x,y,z = var('x,y,z') + sage: R = QQ['x,y,z'] + sage: type(x) - sage: type(R(x)) # optional - sage.symbolic + sage: type(R(x)) - sage: f = R(x^3 + y^3 - z^3); f # optional - sage.symbolic + sage: f = R(x^3 + y^3 - z^3); f x^3 + y^3 - z^3 - sage: type(f) # optional - sage.symbolic + sage: type(f) - sage: parent(f) # optional - sage.symbolic + sage: parent(f) Multivariate Polynomial Ring in x, y, z over Rational Field A more complicated symbolic and computational mix. Behind the @@ -266,12 +268,13 @@ def __call__(self, x=0, check=True): :: + sage: # needs sage.symbolic sage: R = QQ['x,y,z'] - sage: f = (x^3 + y^3 - z^3)^10; f # optional - sage.symbolic + sage: f = (x^3 + y^3 - z^3)^10; f (x^3 + y^3 - z^3)^10 - sage: g = R(f); parent(g) # optional - sage.symbolic + sage: g = R(f); parent(g) Multivariate Polynomial Ring in x, y, z over Rational Field - sage: (f - g).expand() # optional - sage.symbolic + sage: (f - g).expand() 0 It intelligently handles conversions from polynomial rings in a subset @@ -279,12 +282,12 @@ def __call__(self, x=0, check=True): :: - sage: R = GF(5)['x,y,z'] # optional - sage.rings.finite_rings + sage: R = GF(5)['x,y,z'] sage: S = ZZ['y'] - sage: R(7*S.0) # optional - sage.rings.finite_rings + sage: R(7*S.0) 2*y sage: T = ZZ['x,z'] - sage: R(2*T.0 + 6*T.1 + T.0*T.1^2) # optional - sage.rings.finite_rings + sage: R(2*T.0 + 6*T.1 + T.0*T.1^2) x*z^2 + 2*x + z :: @@ -375,16 +378,16 @@ def __call__(self, x=0, check=True): sage: A. = PolynomialRing(QQ) sage: B. = PolynomialRing(A) - sage: f = pari(a*d) + sage: f = pari(a*d) # needs sage.libs.pari sage: B(f) a*d - sage: f = pari(a*d - (a+1)*d*e^3 + a*d^2) + sage: f = pari(a*d - (a+1)*d*e^3 + a*d^2) # needs sage.libs.pari sage: B(f) (-a - 1)*d*e^3 + a*d^2 + a*d sage: A. = PolynomialRing(QQ) sage: B. = PolynomialRing(A) - sage: f = pari(a*d) + sage: f = pari(a*d) # needs sage.libs.pari sage: B(f) a*d @@ -402,7 +405,7 @@ def __call__(self, x=0, check=True): Check that :trac:`21999` is fixed:: - sage: R = QQbar['s,t'] + sage: R = QQbar['s,t'] # needs sage.rings.number_field sage: type(R({(1,2): 3}).coefficients()[0]) """ @@ -950,6 +953,9 @@ def ideal(self, *gens, **kwds): if not self._has_singular: # pass through MPolynomialRing_base.ideal(self, gens, **kwds) + + from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal + if isinstance(gens, (sage.interfaces.abc.SingularElement, sage.interfaces.abc.Macaulay2Element)): gens = list(gens) do_coerce = True @@ -957,4 +963,4 @@ def ideal(self, *gens, **kwds): gens = [gens] if ('coerce' in kwds and kwds['coerce']) or do_coerce: gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly! - return multi_polynomial_ideal.MPolynomialIdeal(self, gens, **kwds) + return MPolynomialIdeal(self, gens, **kwds) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 41b2e4c50ee..1d3fbc60944 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -3,8 +3,6 @@ Base class for multivariate polynomial rings """ import itertools from collections.abc import Iterable -from sage.matrix.constructor import matrix -from sage.modules.free_module_element import vector import sage.misc.latex from sage.misc.cachefunc import cached_method @@ -22,12 +20,9 @@ _CommutativeRings = CommutativeRings() from sage.arith.misc import binomial -from sage.combinat.integer_vector import IntegerVectors - from sage.rings.integer_ring import ZZ -from . import (multi_polynomial_ideal, - polynomial_ring) +from . import polynomial_ring from .term_order import TermOrder from .polynomial_ring_constructor import (PolynomialRing, polynomial_default_category) @@ -71,10 +66,10 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Check that :trac:`26958` is fixed:: - sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular # optional - sage.libs.singular - sage: class Foo(MPolynomialRing_libsingular): # optional - sage.libs.singular + sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular # needs sage.libs.singular + sage: class Foo(MPolynomialRing_libsingular): # needs sage.libs.singular ....: pass - sage: Foo(QQ, 2, ['x','y'], 'degrevlex') # optional - sage.libs.singular + sage: Foo(QQ, 2, ['x','y'], 'degrevlex') # needs sage.libs.singular Multivariate Polynomial Ring in x, y over Rational Field """ if base_ring not in _CommutativeRings: @@ -223,9 +218,9 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring sage: P. = PolynomialRing(ZZ) - sage: P.completion(prec=oo) + sage: P.completion(prec=oo) # needs sage.combinat Multivariate Lazy Taylor Series Ring in x, y, z, w over Integer Ring - sage: P.completion((w,x,y), prec=oo) + sage: P.completion((w,x,y), prec=oo) # needs sage.combinat Multivariate Lazy Taylor Series Ring in w, x, y over Univariate Polynomial Ring in z over Integer Ring @@ -234,7 +229,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: P. = PolynomialRing(ZZ) sage: P.completion([]) is P True - sage: P.completion(SR.var('x')) # optional - sage.symbolic + sage: P.completion(SR.var('x')) # needs sage.symbolic Traceback (most recent call last): ... TypeError: x is not an element of Multivariate Polynomial Ring @@ -395,14 +390,14 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) - sage: R.interpolation(4, F) # optional - sage.modules + sage: R.interpolation(4, F) # needs sage.modules x^3*y + z^2 + y + 25 sage: def F(a,b,c): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) - sage: R.interpolation([3,1,2], F) # optional - sage.modules + sage: R.interpolation([3,1,2], F) # needs sage.modules x^3*y + z^2 + y + 25 sage: def F(a,b,c): @@ -413,7 +408,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: (2,7,0),(1,10,13),(0,0,1),(-1,1,0),(2,5,3),(1,1,1),(7,4,11), ....: (12,1,9),(1,1,3),(4,-1,2),(0,1,5),(5,1,3),(3,1,-2),(2,11,3), ....: (4,12,19),(3,1,1),(5,2,-3),(12,1,1),(2,3,4)] - sage: R.interpolation([3,1,2], points, [F(*x) for x in points]) # optional - sage.modules + sage: R.interpolation([3,1,2], points, [F(*x) for x in points]) # needs sage.modules x^3*y + z^2 + y + 25 ALGORITHM: @@ -447,13 +442,16 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: return a^3*b + b + c^2 + 25 ....: sage: R. = PolynomialRing(QQ) - sage: R.interpolation(3, F) # optional - sage.modules + sage: R.interpolation(3, F) # needs sage.modules 1/2*x^3 + x*y + z^2 - 1/2*x + y + 25 .. SEEALSO:: :meth:`lagrange_polynomial` """ + from sage.matrix.constructor import matrix + from sage.modules.free_module_element import vector + # get ring and number of variables R = self.base_ring() n = self.ngens() @@ -576,14 +574,15 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): This fairly complicated code (from Michel Vandenbergh) ends up implicitly calling ``_coerce_c_impl``:: + sage: # needs sage.rings.number_field sage: z = polygen(QQ, 'z') - sage: W. = NumberField(z^2 + 1) # optional - sage.rings.number_field - sage: Q. = W[] # optional - sage.rings.number_field - sage: W1 = FractionField(Q) # optional - sage.rings.number_field - sage: S. = W1[] # optional - sage.rings.number_field - sage: u + x # optional - sage.rings.number_field + sage: W. = NumberField(z^2 + 1) + sage: Q. = W[] + sage: W1 = FractionField(Q) + sage: S. = W1[] + sage: u + x x + u - sage: x + 1/u # optional - sage.rings.number_field + sage: x + 1/u x + 1/u """ try: @@ -706,19 +705,21 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): return "%s[%s]" % (sage.misc.latex.latex(self.base_ring()), vars) def _ideal_class_(self, n=0): - return multi_polynomial_ideal.MPolynomialIdeal + from .multi_polynomial_ideal import MPolynomialIdeal + return MPolynomialIdeal def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): """ EXAMPLES:: + sage: # needs sage.rings.number_field sage: T. = ZZ[] - sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: Q5 = Qp(5); i5 = Q5(-1).sqrt() # optional - sage.rings.number_field - sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()]) # no coercion # optional - sage.rings.number_field + sage: K. = NumberField(t^2 + 1) + sage: R. = K[] + sage: Q5 = Qp(5); i5 = Q5(-1).sqrt() + sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()]) # no coercion False - sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()], base_map=K.hom([i5])) # optional - sage.rings.number_field + sage: R._is_valid_homomorphism_(Q5, [Q5.teichmuller(2), Q5(6).log()], base_map=K.hom([i5])) True """ if base_map is None: @@ -735,38 +736,39 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: R. = PolynomialRing(GF(127),10) # optional - sage.rings.finite_rings - sage: R._magma_init_(magma) # optional - magma # optional - sage.rings.finite_rings + sage: # optional - magma + sage: R. = PolynomialRing(GF(127),10) + sage: R._magma_init_(magma) 'SageCreateWithNames(PolynomialRing(_sage_ref...,10,"grevlex"),["a","b","c","d","e","f","g","h","i","j"])' - sage: R. = PolynomialRing(QQ, 3) # optional - sage.rings.finite_rings - sage: magma(R) # optional - magma # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(QQ, 3) + sage: magma(R) Polynomial ring of rank 3 over Rational Field Order: Graded Reverse Lexicographical Variables: y, z, w A complicated nested example:: - sage: R. = PolynomialRing(GF(9,'a')); S. = R[]; S # optional - sage.rings.finite_rings + sage: # optional - magma, needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(9,'a')); S. = R[]; S Multivariate Polynomial Ring in T, W over Multivariate Polynomial Ring in a, b, c over Finite Field in a of size 3^2 - sage: magma(S) # optional - magma # optional - sage.rings.finite_rings + sage: magma(S) Polynomial ring of rank 2 over Polynomial ring of rank 3 over GF(3^2) Order: Graded Reverse Lexicographical Variables: T, W - sage: magma(PolynomialRing(GF(7),4, 'x')) # optional - magma # optional - sage.rings.finite_rings + sage: # optional - magma + sage: magma(PolynomialRing(GF(7),4, 'x')) Polynomial ring of rank 4 over GF(7) Order: Graded Reverse Lexicographical Variables: x0, x1, x2, x3 - - sage: magma(PolynomialRing(GF(49,'a'),10, 'x')) # optional - magma # optional - sage.rings.finite_rings + sage: magma(PolynomialRing(GF(49,'a'),10, 'x')) # needs sage.rings.finite_rings Polynomial ring of rank 10 over GF(7^2) Order: Graded Reverse Lexicographical Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 - - sage: magma(PolynomialRing(ZZ['a,b,c'],3, 'x')) # optional - magma + sage: magma(PolynomialRing(ZZ['a,b,c'],3, 'x')) Polynomial ring of rank 3 over Polynomial ring of rank 3 over Integer Ring Order: Graded Reverse Lexicographical @@ -795,11 +797,12 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: F = CyclotomicField(8) # optional - sage.rings.number_field - sage: P. = F[] # optional - sage.rings.number_field - sage: gap(P) # indirect doctest # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F = CyclotomicField(8) + sage: P. = F[] + sage: gap(P) # indirect doctest PolynomialRing( CF(8), ["x", "y"] ) - sage: libgap(P) # optional - sage.rings.number_field + sage: libgap(P) [x,y] """ L = ['"%s"' % t for t in self.variable_names()] @@ -857,8 +860,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R = PolynomialRing(QQ, 'x', 3) sage: R.characteristic() 0 - sage: R = PolynomialRing(GF(7), 'x', 20) # optional - sage.rings.finite_rings - sage: R.characteristic() # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(7), 'x', 20) + sage: R.characteristic() 7 """ return self.base_ring().characteristic() @@ -1052,7 +1055,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: return 1.0/(8*total) sage: more_samples() - sage: while any(abs(prob(i) - dic[i]/counter) > 0.01 for i in dic): + sage: while any(abs(prob(i) - dic[i]/counter) > 0.01 for i in dic): # needs sage.symbolic ....: more_samples() """ # bug: doesn't handle n=1 @@ -1175,12 +1178,12 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Default values apply if no degree and/or number of terms is provided:: + sage: # needs sage.modules sage: M = random_matrix(QQ['x,y,z'], 2, 2) sage: all(a.degree() <= 2 for a in M.list()) True sage: all(len(list(a)) <= 5 for a in M.list()) True - sage: M = random_matrix(QQ['x,y,z'], 2, 2, terms=1, degree=2) sage: all(a.degree() <= 2 for a in M.list()) True @@ -1340,11 +1343,11 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: - sage: P. = PolynomialRing(GF(127), 3, order='lex') # optional - sage.rings.finite_rings - sage: x > y^2 # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127), 3, order='lex') + sage: x > y^2 True - sage: Q. = P.change_ring(order='degrevlex') # optional - sage.rings.finite_rings - sage: x > y^2 # optional - sage.rings.finite_rings + sage: Q. = P.change_ring(order='degrevlex') + sage: x > y^2 False """ if base_ring is None: @@ -1382,6 +1385,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: + sage: # needs sage.combinat sage: R. = ZZ[] sage: mons = R.monomials_of_degree(2) sage: mons @@ -1399,7 +1403,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): The number of such monomials equals `\binom{n+k-1}{k}` where `n` is the number of variables and `k` the degree:: - sage: len(mons) == binomial(3 + 2 - 1, 2) + sage: len(mons) == binomial(3 + 2 - 1, 2) # needs sage.combinat True """ deg_of_gens = [x.degree() for x in self.gens()] @@ -1500,6 +1504,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Polynomial Ring in u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11 over Integer Ring) """ + from sage.combinat.integer_vector import IntegerVectors + n = len(dlist) - 1 number_of_coeffs = sum([binomial(n + di, di) for di in dlist]) U = PolynomialRing(ZZ, 'u', number_of_coeffs) @@ -1565,7 +1571,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): The number of polynomials has to match the number of variables:: sage: R. = PolynomialRing(QQ, 3) - sage: R.macaulay_resultant([y, x + z]) # optional - sage.modules + sage: R.macaulay_resultant([y, x + z]) # needs sage.modules Traceback (most recent call last): ... TypeError: number of polynomials(= 2) must equal number of variables (= 3) @@ -1573,7 +1579,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): The polynomials need to be all homogeneous:: sage: R. = PolynomialRing(QQ, 3) - sage: R.macaulay_resultant([y, x + z, z + x^3]) # optional - sage.modules + sage: R.macaulay_resultant([y, x + z, z + x^3]) # needs sage.modules Traceback (most recent call last): ... TypeError: resultant for non-homogeneous polynomials is not supported @@ -1582,7 +1588,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: S. = PolynomialRing(QQ, 2) sage: R. = PolynomialRing(QQ,3) - sage: S.macaulay_resultant([y, z+x]) # optional - sage.modules + sage: S.macaulay_resultant([y, z+x]) # needs sage.modules Traceback (most recent call last): ... TypeError: not all inputs are polynomials in the calling ring @@ -1591,7 +1597,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: K. = PolynomialRing(ZZ, 2) sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2]) - sage: R.macaulay_resultant(flist) # optional - sage.modules + sage: R.macaulay_resultant(flist) # needs sage.modules u2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 + u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - @@ -1604,7 +1610,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: K. = PolynomialRing(ZZ, 2) sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,1]) - sage: R.macaulay_resultant(flist) # optional - sage.modules + sage: R.macaulay_resultant(flist) # needs sage.modules -u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8 The following example is by Patrick Ingram (:arxiv:`1310.4114`):: @@ -1615,38 +1621,38 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2 sage: f2 = x0*x1 - x2^2 sage: flist = [f0,f1,f2] - sage: R.macaulay_resultant([f0,f1,f2]) # optional - sage.modules + sage: R.macaulay_resultant([f0,f1,f2]) # needs sage.modules y0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27 A simple example with constant rational coefficients:: sage: R. = PolynomialRing(QQ, 4) - sage: R.macaulay_resultant([w, z, y, x]) # optional - sage.modules + sage: R.macaulay_resultant([w, z, y, x]) # needs sage.modules 1 An example where the resultant vanishes:: sage: R. = PolynomialRing(QQ, 3) - sage: R.macaulay_resultant([x + y, y^2, x]) # optional - sage.modules + sage: R.macaulay_resultant([x + y, y^2, x]) # needs sage.modules 0 An example of bad reduction at a prime `p = 5`:: sage: R. = PolynomialRing(QQ, 3) - sage: R.macaulay_resultant([y, x^3 + 25*y^2*x, 5*z]) # optional - sage.modules + sage: R.macaulay_resultant([y, x^3 + 25*y^2*x, 5*z]) # needs sage.libs.pari sage.modules 125 The input can given as an unpacked list of polynomials:: sage: R. = PolynomialRing(QQ, 3) - sage: R.macaulay_resultant(y, x^3 + 25*y^2*x, 5*z) # optional - sage.modules + sage: R.macaulay_resultant(y, x^3 + 25*y^2*x, 5*z) # needs sage.libs.pari sage.modules 125 An example when the coefficients live in a finite field:: - sage: F = FiniteField(11) # optional - sage.rings.finite_rings - sage: R. = PolynomialRing(F, 4) # optional - sage.rings.finite_rings - sage: R.macaulay_resultant([z, x^3, 5*y, w]) # optional - sage.modules sage.rings.finite_rings + sage: F = FiniteField(11) + sage: R. = PolynomialRing(F, 4) + sage: R.macaulay_resultant([z, x^3, 5*y, w]) # needs sage.modules sage.rings.finite_rings 4 Example when the denominator in the algorithm vanishes(in this case @@ -1654,7 +1660,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): char polynomials of numerator/denominator):: sage: R. = PolynomialRing(QQ, 3) - sage: R.macaulay_resultant([y, x + z, z^2]) # optional - sage.modules + sage: R.macaulay_resultant([y, x + z, z^2]) # needs sage.libs.pari sage.modules -1 When there are only 2 polynomials, the Macaulay resultant degenerates @@ -1665,12 +1671,13 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: fh = f.homogenize() sage: gh = g.homogenize() sage: RH = fh.parent() - sage: f.resultant(g) == RH.macaulay_resultant([fh, gh]) # optional - sage.modules + sage: f.resultant(g) == RH.macaulay_resultant([fh, gh]) # needs sage.modules True """ from sage.matrix.constructor import matrix from sage.matrix.constructor import zero_matrix + from sage.combinat.integer_vector import IntegerVectors if len(args) == 1 and isinstance(args[0], list): flist = args[0] @@ -1744,9 +1751,9 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): EXAMPLES:: sage: R = QQ['x,y,z'] - sage: W = R.weyl_algebra(); W # optional - sage.combinat sage.modules + sage: W = R.weyl_algebra(); W # needs sage.modules Differential Weyl algebra of polynomials in x, y, z over Rational Field - sage: W.polynomial_ring() == R # optional - sage.combinat sage.modules + sage: W.polynomial_ring() == R # needs sage.modules True """ from sage.algebras.weyl_algebra import DifferentialWeylAlgebra @@ -1763,8 +1770,8 @@ cdef class BooleanPolynomialRing_base(MPolynomialRing_base): EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRing_base - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: isinstance(R, BooleanPolynomialRing_base) # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: isinstance(R, BooleanPolynomialRing_base) # needs sage.rings.polynomial.pbori True By design, there is only one direct implementation subclass:: diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index 8168439c2df..22c92ba44d6 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -23,24 +23,24 @@ As an example consider a small scale variant of the AES:: - sage: sr = mq.SR(2, 1, 2, 4, gf2=True, polybori=True) # optional - sage.rings.polynomial.pbori - sage: sr # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(2, 1, 2, 4, gf2=True, polybori=True) # needs sage.rings.polynomial.pbori + sage: sr # needs sage.rings.polynomial.pbori SR(2,1,2,4) We can construct a polynomial sequence for a random plaintext-ciphertext pair and study it:: - sage: set_random_seed(1) # optional - sage.rings.polynomial.pbori - sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori + sage: set_random_seed(1) + sage: while True: # workaround (see :trac:`31891`) # needs sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: F # optional - sage.rings.polynomial.pbori + sage: F # needs sage.rings.polynomial.pbori Polynomial Sequence with 112 Polynomials in 64 Variables - sage: r2 = F.part(2); r2 # optional - sage.rings.polynomial.pbori + sage: r2 = F.part(2); r2 # needs sage.rings.polynomial.pbori (w200 + k100 + x100 + x102 + x103, w201 + k101 + x100 + x101 + x103 + 1, w202 + k102 + x100 + x101 + x102 + 1, @@ -76,7 +76,7 @@ We separate the system in independent subsystems:: - sage: C = Sequence(r2).connected_components(); C # optional - sage.rings.polynomial.pbori + sage: C = Sequence(r2).connected_components(); C # needs sage.rings.polynomial.pbori [[w200 + k100 + x100 + x102 + x103, w201 + k101 + x100 + x101 + x103 + 1, w202 + k102 + x100 + x101 + x102 + 1, @@ -109,37 +109,38 @@ x110*w110 + x110*w111 + x110*w112 + x111*w112 + x112*w110 + x112*w111 + x112*w113 + x113*w111 + w112, x110*w111 + x111*w110 + x111*w112 + x112*w110 + x113*w111 + x113*w113 + w113, x110*w112 + x111*w111 + x112*w110 + x113*w113 + 1]] - sage: C[0].groebner_basis() # optional - sage.rings.polynomial.pbori + sage: C[0].groebner_basis() # needs sage.rings.polynomial.pbori Polynomial Sequence with 30 Polynomials in 16 Variables and compute the coefficient matrix:: - sage: A,v = Sequence(r2).coefficient_matrix() # optional - sage.rings.polynomial.pbori - sage: A.rank() # optional - sage.rings.polynomial.pbori + sage: A,v = Sequence(r2).coefficient_matrix() # needs sage.rings.polynomial.pbori + sage: A.rank() # needs sage.rings.polynomial.pbori 32 Using these building blocks we can implement a simple XL algorithm easily:: - sage: sr = mq.SR(1,1,1,4, gf2=True, polybori=True, order='lex') # optional - sage.rings.polynomial.pbori - sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(1,1,1,4, gf2=True, polybori=True, order='lex') # needs sage.rings.polynomial.pbori + sage: while True: # workaround (see :trac:`31891`) # needs sage.rings.polynomial.pbori ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: monomials = [a*b for a in F.variables() for b in F.variables() if a < b] # optional - sage.rings.polynomial.pbori - sage: len(monomials) # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: monomials = [a*b for a in F.variables() for b in F.variables() if a < b] + sage: len(monomials) 190 - sage: F2 = Sequence(map(mul, cartesian_product_iterator((monomials, F)))) # optional - sage.rings.polynomial.pbori - sage: A, v = F2.coefficient_matrix(sparse=False) # optional - sage.rings.polynomial.pbori - sage: A.echelonize() # optional - sage.rings.polynomial.pbori - sage: A # optional - sage.rings.polynomial.pbori + sage: F2 = Sequence(map(mul, cartesian_product_iterator((monomials, F)))) + sage: A, v = F2.coefficient_matrix(sparse=False) + sage: A.echelonize() + sage: A 6840 x 4474 dense matrix over Finite Field of size 2... - sage: A.rank() # optional - sage.rings.polynomial.pbori + sage: A.rank() 4056 - sage: A[4055] * v # optional - sage.rings.polynomial.pbori + sage: A[4055] * v (k001*k003) TESTS:: @@ -161,22 +162,25 @@ """ from sage.misc.cachefunc import cached_method - from sage.misc.converting_dict import KeyConvertingDict - -from sage.structure.sequence import Sequence_generic - -from sage.rings.infinity import Infinity -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.misc.method_decorator import MethodDecorator from sage.rings.finite_rings.finite_field_base import FiniteField -from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing -from sage.rings.quotient_ring import is_QuotientRing +from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF +from sage.rings.infinity import Infinity from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal +from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.quotient_ring import is_QuotientRing +from sage.structure.sequence import Sequence_generic + + +try: + from sage.interfaces.singular import singular, singular_gb_standard_options + from sage.libs.singular.standard_options import libsingular_gb_standard_options +except ImportError: + singular = None + singular_gb_standard_options = libsingular_gb_standard_options = MethodDecorator -from sage.interfaces.singular import singular_gb_standard_options -from sage.libs.singular.standard_options import libsingular_gb_standard_options -from sage.interfaces.singular import singular def is_PolynomialSequence(F): """ @@ -220,12 +224,12 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): EXAMPLES:: - sage: P. = PolynomialRing(GF(127), 4) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127), 4) + sage: I = sage.rings.ideal.Katsura(P) # needs sage.libs.singular If a list of tuples is provided, those form the parts:: - sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest # optional - sage.rings.finite_rings + sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest # needs sage.libs.singular [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -234,12 +238,12 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F.nparts() # optional - sage.rings.finite_rings + sage: F.nparts() # needs sage.libs.singular 2 If an ideal is provided, the generators are used:: - sage: Sequence(I) # optional - sage.rings.finite_rings + sage: Sequence(I) # needs sage.libs.singular [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -247,22 +251,22 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): If a list of polynomials is provided, the system has only one part:: - sage: F = Sequence(I.gens(), I.ring()); F # optional - sage.rings.finite_rings + sage: F = Sequence(I.gens(), I.ring()); F # needs sage.libs.singular [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F.nparts() # optional - sage.rings.finite_rings + sage: F.nparts() # needs sage.libs.singular 1 We test that the ring is inferred correctly:: - sage: P. = GF(2)[] # optional - sage.rings.finite_rings + sage: P. = GF(2)[] sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence - sage: PolynomialSequence([1,x,y]).ring() # optional - sage.rings.finite_rings + sage: PolynomialSequence([1,x,y]).ring() Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 - sage: PolynomialSequence([[1,x,y], [0]]).ring() # optional - sage.rings.finite_rings + sage: PolynomialSequence([[1,x,y], [0]]).ring() Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 TESTS: @@ -271,10 +275,10 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): characteristic 2 (see :trac:`19452`):: sage: from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence - sage: F = GF(2) # optional - sage.rings.finite_rings - sage: L. = PowerSeriesRing(F,'t') # optional - sage.rings.finite_rings - sage: R. = PolynomialRing(L,'x,y') # optional - sage.rings.finite_rings - sage: PolynomialSequence([0], R) # optional - sage.rings.finite_rings + sage: F = GF(2) + sage: L. = PowerSeriesRing(F,'t') + sage: R. = PolynomialRing(L,'x,y') + sage: PolynomialSequence([0], R) [0] A PolynomialSequence can be created from an iterator (see :trac:`25989`):: @@ -288,7 +292,10 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): [x, y, z] """ from sage.structure.element import is_Matrix - from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid + try: + from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid + except ImportError: + BooleanMonomialMonoid = () is_ring = lambda r: is_MPolynomialRing(r) or isinstance(r, BooleanMonomialMonoid) or (is_QuotientRing(r) and is_MPolynomialRing(r.cover_ring())) @@ -386,23 +393,23 @@ def __init__(self, parts, ring, immutable=False, cr=False, cr_str=None): EXAMPLES:: - sage: P. = PolynomialRing(GF(127), 4) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127), 4) + sage: I = sage.rings.ideal.Katsura(P) # needs sage.rings.finite_rings - sage: Sequence([I.gens()], I.ring()) # indirect doctest # optional - sage.rings.finite_rings + sage: Sequence([I.gens()], I.ring()) # indirect doctest # needs sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] If an ideal is provided, the generators are used.:: - sage: Sequence(I) # optional - sage.rings.finite_rings + sage: Sequence(I) # needs sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] If a list of polynomials is provided, the system has only one part.:: - sage: Sequence(I.gens(), I.ring()) # optional - sage.rings.finite_rings + sage: Sequence(I.gens(), I.ring()) # needs sage.rings.finite_rings [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] """ @@ -418,11 +425,12 @@ def __copy__(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: copy(F) # indirect doctest # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) + sage: F,s = sr.polynomial_system() + sage: copy(F) # indirect doctest Polynomial Sequence with 40 Polynomials in 20 Variables - sage: type(F) == type(copy(F)) # optional - sage.rings.polynomial.pbori + sage: type(F) == type(copy(F)) True """ return self.__class__(self._parts, self._ring, immutable=self.is_immutable()) @@ -433,9 +441,9 @@ def ring(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True, gf2=True, order='block') # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: print(F.ring().repr_long()) # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True, order='block') # needs sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # needs sage.rings.polynomial.pbori + sage: print(F.ring().repr_long()) # needs sage.rings.polynomial.pbori Polynomial Ring Base Ring : Finite Field of size 2 Size : 20 Variables @@ -454,9 +462,9 @@ def nparts(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: F.nparts() # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system() # needs sage.rings.polynomial.pbori + sage: F.nparts() # needs sage.rings.polynomial.pbori 4 """ return len(self._parts) @@ -467,10 +475,11 @@ def parts(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: l = F.parts() # optional - sage.rings.polynomial.pbori - sage: len(l) # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) + sage: F, s = sr.polynomial_system() + sage: l = F.parts() + sage: len(l) 4 """ return tuple(self._parts) @@ -481,10 +490,11 @@ def part(self, i): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: R0 = F.part(1) # optional - sage.rings.polynomial.pbori - sage: R0 # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) + sage: F, s = sr.polynomial_system() + sage: R0 = F.part(1) + sage: R0 (k000^2 + k001, k001^2 + k002, k002^2 + k003, k003^2 + k000) """ return self._parts[i] @@ -495,14 +505,15 @@ def ideal(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: P = F.ring() # optional - sage.rings.polynomial.pbori - sage: I = F.ideal() # optional - sage.rings.polynomial.pbori - sage: J = I.elimination_ideal(P.gens()[4:-4]) # optional - sage.rings.polynomial.pbori - sage: J <= I # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) + sage: F, s = sr.polynomial_system() + sage: P = F.ring() + sage: I = F.ideal() + sage: J = I.elimination_ideal(P.gens()[4:-4]) + sage: J <= I True - sage: set(J.gens().variables()).issubset(P.gens()[:4] + P.gens()[-4:]) # optional - sage.rings.polynomial.pbori + sage: set(J.gens().variables()).issubset(P.gens()[:4] + P.gens()[-4:]) True """ return self._ring.ideal(tuple(self)) @@ -522,10 +533,11 @@ def groebner_basis(self, *args, **kwargs): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: gb = F.groebner_basis() # optional - sage.rings.polynomial.pbori - sage: Ideal(gb).basis_is_groebner() # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) + sage: F, s = sr.polynomial_system() + sage: gb = F.groebner_basis() + sage: Ideal(gb).basis_is_groebner() True TESTS: @@ -533,12 +545,13 @@ def groebner_basis(self, *args, **kwargs): Check that this method also works for boolean polynomials (:trac:`10680`):: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: F0 = Sequence(map(lambda f: f.lm(), [a,b,c,d])) # optional - sage.rings.polynomial.pbori - sage: F0.groebner_basis() # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() + sage: F0 = Sequence(map(lambda f: f.lm(), [a,b,c,d])) + sage: F0.groebner_basis() [a, b, c, d] - sage: F1 = Sequence([a,b,c*d,d^2]) # optional - sage.rings.polynomial.pbori - sage: F1.groebner_basis() # optional - sage.rings.polynomial.pbori + sage: F1 = Sequence([a,b,c*d,d^2]) + sage: F1.groebner_basis() [a, b, d] """ return self.ideal().groebner_basis(*args, **kwargs) @@ -549,9 +562,9 @@ def monomials(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: len(F.monomials()) # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # needs sage.rings.polynomial.pbori + sage: len(F.monomials()) # needs sage.rings.polynomial.pbori 49 """ M = set() @@ -566,9 +579,9 @@ def nmonomials(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: F.nmonomials() # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # needs sage.rings.polynomial.pbori + sage: F.nmonomials() # needs sage.rings.polynomial.pbori 49 """ return len(self.monomials()) @@ -580,9 +593,9 @@ def variables(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: F.variables()[:10] # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # needs sage.rings.polynomial.pbori + sage: F.variables()[:10] # needs sage.rings.polynomial.pbori (k003, k002, k001, k000, s003, s002, s001, s000, w103, w102) """ V = set() @@ -597,9 +610,9 @@ def nvariables(self): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: F.nvariables() # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system() # needs sage.rings.polynomial.pbori + sage: F.nvariables() # needs sage.rings.polynomial.pbori 20 """ return len(self.variables()) @@ -640,13 +653,13 @@ def algebraic_dependence(self): :: - sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: S = Sequence([x, (x^2 + y^2 - 1)^2, x*y - 2]) # optional - sage.rings.finite_rings - sage: I = S.algebraic_dependence(); I # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(7)) + sage: S = Sequence([x, (x^2 + y^2 - 1)^2, x*y - 2]) + sage: I = S.algebraic_dependence(); I # needs sage.rings.finite_rings Ideal (2 - 3*T2 - T0^2 + 3*T2^2 - T0^2*T2 + T2^3 + 2*T0^4 - 2*T0^2*T2^2 + T2^4 - T0^4*T1 + T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8) of Multivariate Polynomial Ring in T0, T1, T2 over Finite Field of size 7 - sage: [F(S) for F in I.gens()] # optional - sage.rings.finite_rings + sage: [F(S) for F in I.gens()] # needs sage.rings.finite_rings [0] .. NOTE:: @@ -707,23 +720,22 @@ def coefficient_matrix(self, sparse=True): EXAMPLES:: - sage: P. = PolynomialRing(GF(127), 4) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings - sage: I.gens() # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: P. = PolynomialRing(GF(127), 4) + sage: I = sage.rings.ideal.Katsura(P) + sage: I.gens() [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - - sage: F = Sequence(I) # optional - sage.rings.finite_rings - sage: A,v = F.coefficient_matrix() # optional - sage.rings.finite_rings - sage: A # optional - sage.rings.finite_rings + sage: F = Sequence(I) + sage: A,v = F.coefficient_matrix() + sage: A [ 0 0 0 0 0 0 0 0 0 1 2 2 2 126] [ 1 0 2 0 0 2 0 0 2 126 0 0 0 0] [ 0 2 0 0 2 0 0 2 0 0 126 0 0 0] [ 0 0 1 2 0 0 2 0 0 0 0 126 0 0] - - sage: v # optional - sage.rings.finite_rings + sage: v [a^2] [a*b] [b^2] @@ -738,8 +750,7 @@ def coefficient_matrix(self, sparse=True): [ c] [ d] [ 1] - - sage: A*v # optional - sage.rings.finite_rings + sage: A*v [ a + 2*b + 2*c + 2*d - 1] [a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a] [ 2*a*b + 2*b*c + 2*c*d - b] @@ -779,10 +790,10 @@ def subs(self, *args, **kwargs): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True) # optional - sage.rings.polynomial.pbori - sage: F, s = sr.polynomial_system(); F # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True) # needs sage.rings.polynomial.pbori + sage: F, s = sr.polynomial_system(); F # needs sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 20 Variables - sage: F = F.subs(s); F # optional - sage.rings.polynomial.pbori + sage: F = F.subs(s); F # needs sage.rings.polynomial.pbori Polynomial Sequence with 40 Polynomials in 16 Variables """ return PolynomialSequence(self._ring, [tuple([f.subs(*args,**kwargs) for f in r]) for r in self._parts]) @@ -793,14 +804,15 @@ def _singular_(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings - sage: F = Sequence(I); F # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: P. = PolynomialRing(GF(127)) + sage: I = sage.rings.ideal.Katsura(P) + sage: F = Sequence(I); F [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c] - sage: F._singular_() # optional - sage.rings.finite_rings + sage: F._singular_() a+2*b+2*c+2*d-1, a^2+2*b^2+2*c^2+2*d^2-a, 2*a*b+2*b*c+2*c*d-b, @@ -815,10 +827,11 @@ def _magma_init_(self, magma): EXAMPLES:: - sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system() # optional - sage.rings.polynomial.pbori - sage: F.set_immutable() # optional - sage.rings.polynomial.pbori - sage: magma(F) # indirect doctest; optional - magma # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) + sage: F,s = sr.polynomial_system() + sage: F.set_immutable() + sage: magma(F) # optional - magma Ideal of Boolean polynomial ring of rank 20 over GF(2) Order: Graded Lexicographical (bit vector word) Variables: k100, k101, k102, k103, x100, x101, x102, x103, w100, w101, w102, w103, s000, s001, s002, s003, k000, k001, k002, k003 @@ -837,9 +850,10 @@ def _repr_(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings - sage: F = Sequence(I); F # indirect doctest # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: P. = PolynomialRing(GF(127)) + sage: I = sage.rings.ideal.Katsura(P) + sage: F = Sequence(I); F # indirect doctest [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -848,8 +862,8 @@ def _repr_(self): If the system contains 20 or more polynomials, a short summary is printed:: - sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # optional - sage.rings.polynomial.pbori - sage: F,s = sr.polynomial_system(); F # optional - sage.rings.polynomial.pbori + sage: sr = mq.SR(allow_zero_inversions=True, gf2=True) # needs sage.rings.polynomial.pbori + sage: F,s = sr.polynomial_system(); F # needs sage.rings.polynomial.pbori Polynomial Sequence with 36 Polynomials in 20 Variables """ @@ -865,24 +879,23 @@ def __add__(self, right): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings - sage: F = Sequence(I) # optional - sage.rings.finite_rings - sage: F + [a^127 + a] # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: P. = PolynomialRing(GF(127)) + sage: I = sage.rings.ideal.Katsura(P) + sage: F = Sequence(I) + sage: F + [a^127 + a] [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c, a^127 + a] - - sage: F + P.ideal([a^127 + a]) # optional - sage.rings.finite_rings + sage: F + P.ideal([a^127 + a]) [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c, a^127 + a] - - sage: F + Sequence([a^127 + a], P) # optional - sage.rings.finite_rings + sage: F + Sequence([a^127 + a], P) [a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a, 2*a*b + 2*b*c + 2*c*d - b, @@ -909,35 +922,37 @@ def connection_graph(self): EXAMPLES:: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: F = Sequence([x*y + y + 1, z + 1]) # optional - sage.rings.polynomial.pbori - sage: G = F.connection_graph(); G # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() + sage: F = Sequence([x*y + y + 1, z + 1]) + sage: G = F.connection_graph(); G Graph on 3 vertices - sage: G.is_connected() # optional - sage.rings.polynomial.pbori + sage: G.is_connected() False - sage: F = Sequence([x]) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x]) + sage: F.connection_graph() Graph on 1 vertex TESTS:: - sage: F = Sequence([], B) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph() # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: F = Sequence([], B) + sage: F.connection_graph() Graph on 0 vertices - sage: F = Sequence([1], B) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([1], B) + sage: F.connection_graph() Graph on 0 vertices - sage: F = Sequence([x]) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x]) + sage: F.connection_graph() Graph on 1 vertex - sage: F = Sequence([x, y]) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x, y]) + sage: F.connection_graph() Graph on 2 vertices - sage: F = Sequence([x*y*z]) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph().is_clique() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x*y*z]) + sage: F.connection_graph().is_clique() True - sage: F = Sequence([x*y, y*z]) # optional - sage.rings.polynomial.pbori - sage: F.connection_graph().is_clique() # optional - sage.rings.polynomial.pbori + sage: F = Sequence([x*y, y*z]) + sage: F.connection_graph().is_clique() False """ from sage.graphs.graph import Graph @@ -956,15 +971,16 @@ def connected_components(self): As an example consider one part of AES, which naturally splits into four subsystems which are independent:: - sage: sr = mq.SR(2, 4, 4, 8, gf2=True, polybori=True) # optional - sage.rings.polynomial.pbori - sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(2, 4, 4, 8, gf2=True, polybori=True) + sage: while True: # workaround (see :trac:`31891`) ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: Fz = Sequence(F.part(2)) # optional - sage.rings.polynomial.pbori - sage: Fz.connected_components() # optional - sage.rings.polynomial.pbori + sage: Fz = Sequence(F.part(2)) + sage: Fz.connected_components() [Polynomial Sequence with 128 Polynomials in 128 Variables, Polynomial Sequence with 128 Polynomials in 128 Variables, Polynomial Sequence with 128 Polynomials in 128 Variables, @@ -1010,9 +1026,9 @@ def _groebner_strategy(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings - sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.finite_rings - sage: F._groebner_strategy() # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127)) + sage: F = Sequence([x*y + z, y + z + 1]) + sage: F._groebner_strategy() # needs sage.libs.singular Groebner Strategy for ideal generated by 2 elements over Multivariate Polynomial Ring in x, y, z over Finite Field of size 127 """ @@ -1025,13 +1041,13 @@ def maximal_degree(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: F = Sequence([x*y + x, x]) # optional - sage.rings.finite_rings - sage: F.maximal_degree() # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(7)) + sage: F = Sequence([x*y + x, x]) + sage: F.maximal_degree() 2 - sage: P. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: F = Sequence([], universe=P) # optional - sage.rings.finite_rings - sage: F.maximal_degree() # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(7)) + sage: F = Sequence([], universe=P) + sage: F.maximal_degree() -1 """ @@ -1044,15 +1060,15 @@ def __reduce__(self): """ TESTS:: - sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings - sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.finite_rings - sage: loads(dumps(F)) == F # indirect doctest # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127)) + sage: F = Sequence([x*y + z, y + z + 1]) + sage: loads(dumps(F)) == F True We check that :trac:`26354` is fixed:: - sage: f = P.hom([y,z,x]) # optional - sage.rings.finite_rings - sage: hash(f) == hash(loads(dumps(f))) # optional - sage.rings.finite_rings + sage: f = P.hom([y,z,x]) + sage: hash(f) == hash(loads(dumps(f))) True """ @@ -1124,7 +1140,7 @@ def reduced(self): Check that :trac:`26952` is fixed:: sage: Qp = pAdicField(2) - sage: R. = PolynomialRing(Qp, implementation="generic") + sage: R. = PolynomialRing(Qp, implementation="generic") # needs sage.rings.padics sage: F = Sequence([z*x+y^3,z+y^3,3*z+x*y]) sage: F.reduced() [y^3 + z, x*y + (1 + 2 + O(2^20))*z, x*z - z] @@ -1171,12 +1187,12 @@ def is_groebner(self, singular=singular): EXAMPLES:: - sage: R. = PolynomialRing(GF(127), 10) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Cyclic(R, 4) # optional - sage.rings.finite_rings - sage: I.basis.is_groebner() # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(127), 10) + sage: I = sage.rings.ideal.Cyclic(R, 4) + sage: I.basis.is_groebner() False - sage: I2 = Ideal(I.groebner_basis()) # optional - sage.rings.finite_rings - sage: I2.basis.is_groebner() # optional - sage.rings.finite_rings + sage: I2 = Ideal(I.groebner_basis()) + sage: I2.basis.is_groebner() True """ @@ -1235,37 +1251,38 @@ def eliminate_linear_variables(self, maxlength=Infinity, skip=None, return_reduc EXAMPLES:: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: F = Sequence([c + d + b + 1, a + c + d, a*b + c, b*c*d + c]) # optional - sage.rings.polynomial.pbori - sage: F.eliminate_linear_variables() # everything vanishes # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() + sage: F = Sequence([c + d + b + 1, a + c + d, a*b + c, b*c*d + c]) + sage: F.eliminate_linear_variables() # everything vanishes [] - sage: F.eliminate_linear_variables(maxlength=2) # optional - sage.rings.polynomial.pbori + sage: F.eliminate_linear_variables(maxlength=2) [b + c + d + 1, b*c + b*d + c, b*c*d + c] - sage: F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)=='a') # optional - sage.rings.polynomial.pbori + sage: F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)=='a') [a + c + d, a*c + a*d + a + c, c*d + c] The list of reductors can be requested by setting ``return_reductors`` to ``True``:: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: F = Sequence([a + b + d, a + b + c]) # optional - sage.rings.polynomial.pbori - sage: F, R = F.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori - sage: F # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() + sage: F = Sequence([a + b + d, a + b + c]) + sage: F, R = F.eliminate_linear_variables(return_reductors=True) + sage: F [] - sage: R # optional - sage.rings.polynomial.pbori + sage: R [a + b + d, c + d] If the input system is detected to be inconsistent then ``[1]`` is returned, and the list of reductors is empty:: - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # optional - sage.rings.polynomial.pbori - sage: S.eliminate_linear_variables() # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # needs sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables() # needs sage.rings.polynomial.pbori [1] - - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # optional - sage.rings.polynomial.pbori - sage: S.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # needs sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables(return_reductors=True) # needs sage.rings.polynomial.pbori ([1], []) @@ -1273,30 +1290,29 @@ def eliminate_linear_variables(self, maxlength=Infinity, skip=None, return_reduc The function should really dispose of linear equations (:trac:`13968`):: - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x + y + z + 1, y + z]) # optional - sage.rings.polynomial.pbori - sage: S.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: S = Sequence([x + y + z + 1, y + z]) # needs sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables(return_reductors=True) # needs sage.rings.polynomial.pbori ([], [x + 1, y + z]) The function should take care of linear variables created by previous substitution of linear variables :: - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y]) # optional - sage.rings.polynomial.pbori - sage: S.eliminate_linear_variables(return_reductors=True) # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y]) # needs sage.rings.polynomial.pbori + sage: S.eliminate_linear_variables(return_reductors=True) # needs sage.rings.polynomial.pbori ([], [x + y, z + 1]) We test a case which would increase the degree with ``polybori=True``:: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: f = a*d + a + b*d + c*d + 1 # optional - sage.rings.polynomial.pbori - sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables() # optional - sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: f = a*d + a + b*d + c*d + 1 # needs sage.rings.polynomial.pbori + sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables() # needs sage.rings.polynomial.pbori [a*d + a + b*d + c*d + 1, a + b*c + c + d + 1] - - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: f = a*d + a + b*d + c*d + 1 # optional - sage.rings.polynomial.pbori - sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables(use_polybori=True) # optional - sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: f = a*d + a + b*d + c*d + 1 # needs sage.rings.polynomial.pbori + sage: Sequence([f, a + b*c + c+d + 1]).eliminate_linear_variables(use_polybori=True) # needs sage.rings.polynomial.pbori [b*c*d + b*c + b*d + c + d] .. NOTE:: @@ -1377,15 +1393,16 @@ def _groebner_strategy(self): EXAMPLES:: - sage: P. = PolynomialRing(GF(2)) # optional - sage.rings.finite_rings - sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.finite_rings - sage: F._groebner_strategy() # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(2)) + sage: F = Sequence([x*y + z, y + z + 1]) + sage: F._groebner_strategy() Groebner Strategy for ideal generated by 2 elements over Multivariate Polynomial Ring in x, y, z over Finite Field of size 2 - sage: P. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: F = Sequence([x*y + z, y + z + 1]) # optional - sage.rings.polynomial.pbori - sage: F._groebner_strategy() # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: P. = BooleanPolynomialRing() + sage: F = Sequence([x*y + z, y + z + 1]) + sage: F._groebner_strategy() """ from sage.rings.polynomial.multi_polynomial_ring_base import BooleanPolynomialRing_base @@ -1440,64 +1457,66 @@ def solve(self, algorithm='polybori', n=1, eliminate_linear_variables=True, ver Without argument, a single arbitrary solution is returned:: + sage: # needs sage.rings.polynomial.pbori sage: from sage.doctest.fixtures import reproducible_repr - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1]) # optional - sage.rings.polynomial.pbori - sage: sol = S.solve() # optional - sage.rings.polynomial.pbori - sage: print(reproducible_repr(sol)) # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() + sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1]) + sage: sol = S.solve() + sage: print(reproducible_repr(sol)) [{x: 0, y: 1, z: 0}] We check that it is actually a solution:: - sage: S.subs(sol[0]) # optional - sage.rings.polynomial.pbori + sage: S.subs(sol[0]) # needs sage.rings.polynomial.pbori [0, 0, 0] We obtain all solutions:: - sage: sols = S.solve(n=Infinity) # optional - sage.rings.polynomial.pbori - sage: print(reproducible_repr(sols)) # optional - sage.rings.polynomial.pbori + sage: sols = S.solve(n=Infinity) # needs sage.rings.polynomial.pbori + sage: print(reproducible_repr(sols)) # needs sage.rings.polynomial.pbori [{x: 0, y: 1, z: 0}, {x: 1, y: 1, z: 1}] - sage: [S.subs(x) for x in sols] # optional - sage.rings.polynomial.pbori + sage: [S.subs(x) for x in sols] # needs sage.rings.polynomial.pbori [[0, 0, 0], [0, 0, 0]] We can force the use of exhaustive search if the optional package ``FES`` is present:: - sage: sol = S.solve(algorithm='exhaustive_search') # optional - FES # optional - sage.rings.polynomial.pbori - sage: print(reproducible_repr(sol)) # optional - FES # optional - sage.rings.polynomial.pbori + sage: sol = S.solve(algorithm='exhaustive_search') # optional - fes # needs sage.rings.polynomial.pbori + sage: print(reproducible_repr(sol)) # optional - fes # needs sage.rings.polynomial.pbori [{x: 1, y: 1, z: 1}] - sage: S.subs(sol[0]) # optional - FES # optional - sage.rings.polynomial.pbori + sage: S.subs(sol[0]) # optional - fes # needs sage.rings.polynomial.pbori [0, 0, 0] And we may use SAT-solvers if they are available:: - sage: sol = S.solve(algorithm='sat') # optional - pycryptosat # optional - sage.rings.polynomial.pbori - sage: print(reproducible_repr(sol)) # optional - pycryptosat # optional - sage.rings.polynomial.pbori + sage: sol = S.solve(algorithm='sat') # optional - pycryptosat # needs sage.rings.polynomial.pbori + sage: print(reproducible_repr(sol)) # optional - pycryptosat # needs sage.rings.polynomial.pbori [{x: 0, y: 1, z: 0}] - sage: S.subs(sol[0]) # optional - sage.rings.polynomial.pbori + sage: S.subs(sol[0]) # needs sage.rings.polynomial.pbori [0, 0, 0] TESTS: Make sure that variables not occurring in the equations are no problem:: - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1]) # optional - sage.rings.polynomial.pbori - sage: sols = S.solve(n=Infinity) # optional - sage.rings.polynomial.pbori - sage: [S.subs(x) for x in sols] # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() + sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1]) + sage: sols = S.solve(n=Infinity) + sage: [S.subs(x) for x in sols] [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] Not eliminating linear variables:: - sage: sols = S.solve(n=Infinity, eliminate_linear_variables=False) # optional - sage.rings.polynomial.pbori - sage: [S.subs(x) for x in sols] # optional - sage.rings.polynomial.pbori + sage: sols = S.solve(n=Infinity, eliminate_linear_variables=False) # needs sage.rings.polynomial.pbori + sage: [S.subs(x) for x in sols] # needs sage.rings.polynomial.pbori [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] A tricky case where the linear equations are insatisfiable:: - sage: R. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # optional - sage.rings.polynomial.pbori - sage: S.solve() # optional - sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing() # needs sage.rings.polynomial.pbori + sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z]) # needs sage.rings.polynomial.pbori + sage: S.solve() # needs sage.rings.polynomial.pbori [] """ @@ -1575,17 +1594,18 @@ def reduced(self): EXAMPLES:: - sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) # optional - sage.rings.polynomial.pbori - sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True) + sage: while True: # workaround (see :trac:`31891`) ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: g = F.reduced() # optional - sage.rings.polynomial.pbori - sage: len(g) == len(set(gi.lt() for gi in g)) # optional - sage.rings.polynomial.pbori + sage: g = F.reduced() + sage: len(g) == len(set(gi.lt() for gi in g)) True - sage: for i in range(len(g)): # optional - sage.rings.polynomial.pbori + sage: for i in range(len(g)): ....: for j in range(len(g)): ....: if i == j: ....: continue @@ -1623,27 +1643,29 @@ def weil_restriction(self): EXAMPLES:: - sage: k. = GF(2^2) # optional - sage.rings.finite_rings - sage: P. = PolynomialRing(k, 2) # optional - sage.rings.finite_rings - sage: a = P.base_ring().gen() # optional - sage.rings.finite_rings - sage: F = Sequence([x*y + 1, a*x + 1], P) # optional - sage.rings.finite_rings - sage: F2 = F.weil_restriction() # optional - sage.rings.finite_rings - sage: F2 # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(2^2) + sage: P. = PolynomialRing(k, 2) + sage: a = P.base_ring().gen() + sage: F = Sequence([x*y + 1, a*x + 1], P) + sage: F2 = F.weil_restriction() + sage: F2 [x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1] Another bigger example for a small scale AES:: - sage: sr = mq.SR(1, 1, 1, 4, gf2=False) # optional - sage.rings.polynomial.pbori - sage: while True: # workaround (see :trac:`31891`) # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: sr = mq.SR(1, 1, 1, 4, gf2=False) + sage: while True: # workaround (see :trac:`31891`) ....: try: ....: F, s = sr.polynomial_system() ....: break ....: except ZeroDivisionError: ....: pass - sage: F # optional - sage.rings.polynomial.pbori + sage: F Polynomial Sequence with 40 Polynomials in 20 Variables - sage: F2 = F.weil_restriction(); F2 # optional - sage.rings.polynomial.pbori + sage: F2 = F.weil_restriction(); F2 Polynomial Sequence with 240 Polynomials in 80 Variables """ from sage.rings.ideal import FieldIdeal diff --git a/src/sage/rings/polynomial/omega.py b/src/sage/rings/polynomial/omega.py index f2ab5232b2e..5f5dfb441e7 100644 --- a/src/sage/rings/polynomial/omega.py +++ b/src/sage/rings/polynomial/omega.py @@ -877,6 +877,7 @@ def _Omega_factors_denominator_(x, y): :: + sage: # needs sage.rings.number_field sage: B. = ZZ.extension(cyclotomic_polynomial(3)) sage: L. = LaurentPolynomialRing(B) sage: _Omega_factors_denominator_(((x, -x),), ((y,),)) diff --git a/src/sage/rings/polynomial/ore_polynomial_element.pyx b/src/sage/rings/polynomial/ore_polynomial_element.pyx index 5b19d50dc3d..d67c63b6be8 100644 --- a/src/sage/rings/polynomial/ore_polynomial_element.pyx +++ b/src/sage/rings/polynomial/ore_polynomial_element.pyx @@ -161,48 +161,50 @@ cdef class OrePolynomial(AlgebraElement): Here is another example over a finite field:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = x^4 + (4*t + 1)*x^3 + (t^2 + 3*t + 3)*x^2 + (3*t^2 + 2*t + 2)*x + (3*t^2 + 3*t + 1) # optional - sage.rings.finite_rings - sage: b = (2*t^2 + 3)*x^2 + (3*t^2 + 1)*x + 4*t + 2 # optional - sage.rings.finite_rings - sage: q, r = a.left_quo_rem(b) # optional - sage.rings.finite_rings - sage: q # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = x^4 + (4*t + 1)*x^3 + (t^2 + 3*t + 3)*x^2 + (3*t^2 + 2*t + 2)*x + (3*t^2 + 3*t + 1) + sage: b = (2*t^2 + 3)*x^2 + (3*t^2 + 1)*x + 4*t + 2 + sage: q, r = a.left_quo_rem(b) + sage: q (4*t^2 + t + 1)*x^2 + (2*t^2 + 2*t + 2)*x + 2*t^2 + 4*t + 3 - sage: r # optional - sage.rings.finite_rings + sage: r (t + 2)*x + 3*t^2 + 2*t + 4 - sage: a == b*q + r # optional - sage.rings.finite_rings + sage: a == b*q + r True Once we have Euclidean divisions, we have for free gcd and lcm (at least if the base ring is a field):: - sage: a = (x + t) * (x + t^2)^2 # optional - sage.rings.finite_rings - sage: b = (x + t) * (t*x + t + 1) * (x + t^2) # optional - sage.rings.finite_rings - sage: a.right_gcd(b) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: a = (x + t) * (x + t^2)^2 + sage: b = (x + t) * (t*x + t + 1) * (x + t^2) + sage: a.right_gcd(b) x + t^2 - sage: a.left_gcd(b) # optional - sage.rings.finite_rings + sage: a.left_gcd(b) x + t The left lcm has the following meaning: given Ore polynomials `a` and `b`, their left lcm is the least degree polynomial `c = ua = vb` for some Ore polynomials `u, v`. Such a `c` always exist if the base ring is a field:: - sage: c = a.left_lcm(b); c # optional - sage.rings.finite_rings + sage: c = a.left_lcm(b); c # needs sage.rings.finite_rings x^5 + (4*t^2 + t + 3)*x^4 + (3*t^2 + 4*t)*x^3 + 2*t^2*x^2 + (2*t^2 + t)*x + 4*t^2 + 4 - sage: c.is_right_divisible_by(a) # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(a) # needs sage.rings.finite_rings True - sage: c.is_right_divisible_by(b) # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(b) # needs sage.rings.finite_rings True The right lcm is defined similarly as the least degree polynomial `c = au = bv` for some `u,v`:: - sage: d = a.right_lcm(b); d # optional - sage.rings.finite_rings + sage: d = a.right_lcm(b); d # needs sage.rings.finite_rings x^5 + (t^2 + 1)*x^4 + (3*t^2 + 3*t + 3)*x^3 + (3*t^2 + t + 2)*x^2 + (4*t^2 + 3*t)*x + 4*t + 4 - sage: d.is_left_divisible_by(a) # optional - sage.rings.finite_rings + sage: d.is_left_divisible_by(a) # needs sage.rings.finite_rings True - sage: d.is_left_divisible_by(b) # optional - sage.rings.finite_rings + sage: d.is_left_divisible_by(b) # needs sage.rings.finite_rings True .. SEEALSO:: @@ -287,11 +289,12 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: OrePolynomialBaseringInjection(k, k['x', Frob]) #indirect doctest # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: OrePolynomialBaseringInjection(k, k['x', Frob]) #indirect doctest Ore Polynomial base injection morphism: From: Finite Field in t of size 5^3 To: Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 @@ -309,11 +312,12 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: k. = GF(5^3) - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = x + t # optional - sage.rings.finite_rings - sage: a[1] = t + 1 # optional - sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = x + t + sage: a[1] = t + 1 Traceback (most recent call last): ... IndexError: Ore polynomials are immutable @@ -481,26 +485,28 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 # optional - sage.rings.finite_rings - sage: b = a.left_monic(); b # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 + sage: b = a.left_monic(); b x^3 + (4*t^2 + 3*t)*x^2 + (4*t + 2)*x + 2*t^2 + 4*t + 3 Check list:: - sage: b.degree() == a.degree() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: b.degree() == a.degree() True - sage: a.is_left_divisible_by(b) # optional - sage.rings.finite_rings + sage: a.is_left_divisible_by(b) True - sage: twist = S.twisting_morphism(-a.degree()) # optional - sage.rings.finite_rings - sage: a == b * twist(a.leading_coefficient()) # optional - sage.rings.finite_rings + sage: twist = S.twisting_morphism(-a.degree()) + sage: a == b * twist(a.leading_coefficient()) True Note that `b` does not divide `a` on the right:: - sage: a.is_right_divisible_by(b) # optional - sage.rings.finite_rings + sage: a.is_right_divisible_by(b) # needs sage.rings.finite_rings False This function does not work if the leading coefficient is not a @@ -534,25 +540,26 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 # optional - sage.rings.finite_rings - sage: b = a.right_monic(); b # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 + sage: b = a.right_monic(); b x^3 + (2*t^2 + 3*t + 4)*x^2 + (3*t^2 + 4*t + 1)*x + 2*t^2 + 4*t + 3 Check list:: - sage: b.degree() == a.degree() # optional - sage.rings.finite_rings + sage: b.degree() == a.degree() # needs sage.rings.finite_rings True - sage: a.is_right_divisible_by(b) # optional - sage.rings.finite_rings + sage: a.is_right_divisible_by(b) # needs sage.rings.finite_rings True - sage: a == a.leading_coefficient() * b # optional - sage.rings.finite_rings + sage: a == a.leading_coefficient() * b # needs sage.rings.finite_rings True Note that `b` does not divide `a` on the right:: - sage: a.is_left_divisible_by(b) # optional - sage.rings.finite_rings + sage: a.is_left_divisible_by(b) # needs sage.rings.finite_rings False This function does not work if the leading coefficient is not a @@ -632,13 +639,14 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: R. = GF(11)[] # optional - sage.rings.finite_rings - sage: der = R.derivation() # optional - sage.rings.finite_rings - sage: S. = R['x', der] # optional - sage.rings.finite_rings - sage: f = t/x # optional - sage.rings.finite_rings - sage: f # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(11)[] + sage: der = R.derivation() + sage: S. = R['x', der] + sage: f = t/x + sage: f (x + 10/t)^(-1) * t - sage: f.parent() # optional - sage.rings.finite_rings + sage: f.parent() Ore Function Field in x over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 11 twisted by d/dt """ @@ -694,20 +702,21 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = x^2 + t*x + t^2 + 3 # optional - sage.rings.finite_rings - sage: b = x^3 + (t + 1)*x^2 + 1 # optional - sage.rings.finite_rings - sage: c = a*b # optional - sage.rings.finite_rings - sage: c.is_right_divisible_by(a) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = x^2 + t*x + t^2 + 3 + sage: b = x^3 + (t + 1)*x^2 + 1 + sage: c = a*b + sage: c.is_right_divisible_by(a) False - sage: c.is_right_divisible_by(b) # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(b) True Divisibility by `0` does not make sense:: - sage: c.is_right_divisible_by(S(0)) # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(S(0)) # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -743,20 +752,21 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = x^2 + t*x + t^2 + 3 # optional - sage.rings.finite_rings - sage: b = x^3 + (t + 1)*x^2 + 1 # optional - sage.rings.finite_rings - sage: c = a * b # optional - sage.rings.finite_rings - sage: a.left_divides(c) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = x^2 + t*x + t^2 + 3 + sage: b = x^3 + (t + 1)*x^2 + 1 + sage: c = a * b + sage: a.left_divides(c) True - sage: b.left_divides(c) # optional - sage.rings.finite_rings + sage: b.left_divides(c) False Divisibility by `0` does not make sense:: - sage: S(0).left_divides(c) # optional - sage.rings.finite_rings + sage: S(0).left_divides(c) # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -778,20 +788,21 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = x^2 + t*x + t^2 + 3 # optional - sage.rings.finite_rings - sage: b = x^3 + (t + 1)*x^2 + 1 # optional - sage.rings.finite_rings - sage: c = a * b # optional - sage.rings.finite_rings - sage: a.right_divides(c) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = x^2 + t*x + t^2 + 3 + sage: b = x^3 + (t + 1)*x^2 + 1 + sage: c = a * b + sage: a.right_divides(c) False - sage: b.right_divides(c) # optional - sage.rings.finite_rings + sage: b.right_divides(c) True Divisibility by `0` does not make sense:: - sage: S(0).right_divides(c) # optional - sage.rings.finite_rings + sage: S(0).right_divides(c) # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero is not valid @@ -856,21 +867,22 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (x + t) * (x^2 + t*x + 1) # optional - sage.rings.finite_rings - sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) # optional - sage.rings.finite_rings - sage: g,u,v = a.left_xgcd(b); g # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (x + t) * (x^2 + t*x + 1) + sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) + sage: g,u,v = a.left_xgcd(b); g x + t - sage: a*u + b*v == g # optional - sage.rings.finite_rings + sage: a*u + b*v == g True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: g,u,v = a.left_xgcd(b, monic=False); g # optional - sage.rings.finite_rings + sage: g,u,v = a.left_xgcd(b, monic=False); g # needs sage.rings.finite_rings 2*t*x + 4*t + 2 - sage: a*u + b*v == g # optional - sage.rings.finite_rings + sage: a*u + b*v == g # needs sage.rings.finite_rings True The base ring must be a field:: @@ -959,13 +971,14 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 # optional - sage.rings.finite_rings - sage: b = (3*t^2 + 4*t + 2)*x^2 + (2*t^2 + 4*t + 3)*x + 2*t^2 + t + 1 # optional - sage.rings.finite_rings - sage: q,r = a.left_quo_rem(b) # optional - sage.rings.finite_rings - sage: a == b*q + r # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (3*t^2 + 3*t + 2)*x^3 + (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2 + sage: b = (3*t^2 + 4*t + 2)*x^2 + (2*t^2 + 4*t + 3)*x + 2*t^2 + t + 1 + sage: q,r = a.left_quo_rem(b) + sage: a == b*q + r True In the following example, Sage does not know the inverse @@ -1088,21 +1101,22 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (x^2 + t*x + 1) * (x + t) # optional - sage.rings.finite_rings - sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) # optional - sage.rings.finite_rings - sage: g,u,v = a.right_xgcd(b); g # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (x^2 + t*x + 1) * (x + t) + sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) + sage: g,u,v = a.right_xgcd(b); g x + t - sage: u*a + v*b == g # optional - sage.rings.finite_rings + sage: u*a + v*b == g True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: g,u,v = a.right_xgcd(b, monic=False); g # optional - sage.rings.finite_rings + sage: g,u,v = a.right_xgcd(b, monic=False); g # needs sage.rings.finite_rings (4*t^2 + 4*t + 1)*x + 4*t^2 + 4*t + 3 - sage: u*a + v*b == g # optional - sage.rings.finite_rings + sage: u*a + v*b == g # needs sage.rings.finite_rings True The base ring must be a field:: @@ -1171,17 +1185,18 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (x^2 + t*x + 1) * (x + t) # optional - sage.rings.finite_rings - sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) # optional - sage.rings.finite_rings - sage: a.right_gcd(b) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (x^2 + t*x + 1) * (x + t) + sage: b = 2 * (x^3 + (t+1)*x^2 + t^2) * (x + t) + sage: a.right_gcd(b) x + t Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.right_gcd(b,monic=False) # optional - sage.rings.finite_rings + sage: a.right_gcd(b,monic=False) # needs sage.rings.finite_rings (4*t^2 + 4*t + 1)*x + 4*t^2 + 4*t + 3 The base ring need to be a field:: @@ -1238,23 +1253,25 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (x + t) * (x^2 + t*x + 1) # optional - sage.rings.finite_rings - sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) # optional - sage.rings.finite_rings - sage: a.left_gcd(b) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (x + t) * (x^2 + t*x + 1) + sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) + sage: a.left_gcd(b) x + t Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.left_gcd(b,monic=False) # optional - sage.rings.finite_rings + sage: a.left_gcd(b,monic=False) # needs sage.rings.finite_rings 2*t*x + 4*t + 2 The base ring needs to be a field:: - sage: R. = QQ[] # optional - sage.rings.finite_rings - sage: sigma = R.hom([t+1]) + sage: # needs sage.rings.finite_rings + sage: R. = QQ[] + sage: sigma = R.hom([t + 1]) sage: S. = R['x',sigma] sage: a = (x + t) * (x^2 + t*x + 1) sage: b = 2 * (x + t) * (x^3 + (t+1)*x^2 + t^2) @@ -1265,6 +1282,7 @@ cdef class OrePolynomial(AlgebraElement): And the twisting morphism needs to be bijective:: + sage: # needs sage.rings.finite_rings sage: FR = R.fraction_field() sage: f = FR.hom([FR(t)^2]) sage: S. = FR['x',f] @@ -1273,7 +1291,8 @@ cdef class OrePolynomial(AlgebraElement): sage: a.left_gcd(b) Traceback (most recent call last): ... - NotImplementedError: inversion of the twisting morphism Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field + NotImplementedError: inversion of the twisting morphism Ring endomorphism + of Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: t |--> t^2 """ if self.base_ring() not in _Fields: @@ -1299,23 +1318,22 @@ cdef class OrePolynomial(AlgebraElement): TESTS:: - sage: cython( # optional - sage.misc.cython + sage: # needs sage.misc.cython sage.rings.finite_rings + sage: cython( ....: ''' ....: from sage.rings.polynomial.ore_polynomial_element cimport OrePolynomial ....: def left_lcm_cofactor(OrePolynomial P, OrePolynomial Q): ....: return P._left_lcm_cofactor(Q) ....: ''') - - sage: k. = GF(7^5) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism(3) # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - - sage: D = S.random_element(degree=2) # optional - sage.rings.finite_rings - sage: P = S.random_element(degree=2) * D # optional - sage.rings.finite_rings - sage: Q = S.random_element(degree=2) * D # optional - sage.rings.finite_rings - sage: L = P.left_lcm(Q) # optional - sage.rings.finite_rings - sage: U = left_lcm_cofactor(P, Q) # optional - sage.misc.cython sage.rings.finite_rings - sage: (U*P).right_monic() == L # optional - sage.misc.cython sage.rings.finite_rings + sage: k. = GF(7^5) + sage: Frob = k.frobenius_endomorphism(3) + sage: S. = k['x', Frob] + sage: D = S.random_element(degree=2) + sage: P = S.random_element(degree=2) * D + sage: Q = S.random_element(degree=2) * D + sage: L = P.left_lcm(Q) + sage: U = left_lcm_cofactor(P, Q) + sage: (U*P).right_monic() == L True """ cdef OrePolynomial Q, R, T @@ -1342,18 +1360,19 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: P = (x + t^2) * (x + t) # optional - sage.rings.finite_rings - sage: Q = 2 * (x^2 + t + 1) * (x * t) # optional - sage.rings.finite_rings - sage: L, U, V = P.left_xlcm(Q) # optional - sage.rings.finite_rings - sage: L # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: P = (x + t^2) * (x + t) + sage: Q = 2 * (x^2 + t + 1) * (x * t) + sage: L, U, V = P.left_xlcm(Q) + sage: L x^5 + (2*t^2 + t + 4)*x^4 + (3*t^2 + 4)*x^3 + (3*t^2 + 3*t + 2)*x^2 + (t^2 + t + 2)*x - sage: U * P == L # optional - sage.rings.finite_rings + sage: U * P == L # needs sage.rings.finite_rings True - sage: V * Q == L # optional - sage.rings.finite_rings + sage: V * Q == L # needs sage.rings.finite_rings True """ if self.base_ring() not in _Fields: @@ -1377,23 +1396,22 @@ cdef class OrePolynomial(AlgebraElement): TESTS:: - sage: cython( # optional - sage.misc.cython + sage: # needs sage.misc.cython sage.rings.finite_rings + sage: cython( ....: ''' ....: from sage.rings.polynomial.ore_polynomial_element cimport OrePolynomial ....: def right_lcm_cofactor(OrePolynomial P, OrePolynomial Q): ....: return P._right_lcm_cofactor(Q) ....: ''') - - sage: k. = GF(7^5) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism(3) # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - - sage: D = S.random_element(degree=2) # optional - sage.rings.finite_rings - sage: P = D * S.random_element(degree=2) # optional - sage.rings.finite_rings - sage: Q = D * S.random_element(degree=2) # optional - sage.rings.finite_rings - sage: L = P.right_lcm(Q) # optional - sage.rings.finite_rings - sage: U = right_lcm_cofactor(P, Q) # optional - sage.misc.cython sage.rings.finite_rings - sage: (P*U).left_monic() == L # optional - sage.misc.cython sage.rings.finite_rings + sage: k. = GF(7^5) + sage: Frob = k.frobenius_endomorphism(3) + sage: S. = k['x', Frob] + sage: D = S.random_element(degree=2) + sage: P = D * S.random_element(degree=2) + sage: Q = D * S.random_element(degree=2) + sage: L = P.right_lcm(Q) + sage: U = right_lcm_cofactor(P, Q) + sage: (P*U).left_monic() == L True """ cdef OrePolynomial Q, R, T @@ -1427,17 +1445,18 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: P = (x + t) * (x + t^2) # optional - sage.rings.finite_rings - sage: Q = 2 * (x + t) * (x^2 + t + 1) # optional - sage.rings.finite_rings - sage: L, U, V = P.right_xlcm(Q) # optional - sage.rings.finite_rings - sage: L # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: P = (x + t) * (x + t^2) + sage: Q = 2 * (x + t) * (x^2 + t + 1) + sage: L, U, V = P.right_xlcm(Q) + sage: L x^4 + (2*t^2 + t + 2)*x^3 + (3*t^2 + 4*t + 1)*x^2 + (3*t^2 + 4*t + 1)*x + t^2 + 4 - sage: P * U == L # optional - sage.rings.finite_rings + sage: P * U == L True - sage: Q * V == L # optional - sage.rings.finite_rings + sage: Q * V == L True """ if self.base_ring() not in _Fields: @@ -1481,23 +1500,24 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (x + t^2) * (x + t) # optional - sage.rings.finite_rings - sage: b = 2 * (x^2 + t + 1) * (x * t) # optional - sage.rings.finite_rings - sage: c = a.left_lcm(b); c # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (x + t^2) * (x + t) + sage: b = 2 * (x^2 + t + 1) * (x * t) + sage: c = a.left_lcm(b); c x^5 + (2*t^2 + t + 4)*x^4 + (3*t^2 + 4)*x^3 + (3*t^2 + 3*t + 2)*x^2 + (t^2 + t + 2)*x - sage: c.is_right_divisible_by(a) # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(a) True - sage: c.is_right_divisible_by(b) # optional - sage.rings.finite_rings + sage: c.is_right_divisible_by(b) True - sage: a.degree() + b.degree() == c.degree() + a.right_gcd(b).degree() # optional - sage.rings.finite_rings + sage: a.degree() + b.degree() == c.degree() + a.right_gcd(b).degree() True Specifying ``monic=False``, we *can* get a nonmonic lcm:: - sage: a.left_lcm(b,monic=False) # optional - sage.rings.finite_rings + sage: a.left_lcm(b,monic=False) # needs sage.rings.finite_rings (t^2 + t)*x^5 + (4*t^2 + 4*t + 1)*x^4 + (t + 1)*x^3 + (t^2 + 2)*x^2 + (3*t + 4)*x The base ring needs to be a field:: @@ -1550,23 +1570,24 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = (x + t) * (x + t^2) # optional - sage.rings.finite_rings - sage: b = 2 * (x + t) * (x^2 + t + 1) # optional - sage.rings.finite_rings - sage: c = a.right_lcm(b); c # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = (x + t) * (x + t^2) + sage: b = 2 * (x + t) * (x^2 + t + 1) + sage: c = a.right_lcm(b); c x^4 + (2*t^2 + t + 2)*x^3 + (3*t^2 + 4*t + 1)*x^2 + (3*t^2 + 4*t + 1)*x + t^2 + 4 - sage: c.is_left_divisible_by(a) # optional - sage.rings.finite_rings + sage: c.is_left_divisible_by(a) True - sage: c.is_left_divisible_by(b) # optional - sage.rings.finite_rings + sage: c.is_left_divisible_by(b) True - sage: a.degree() + b.degree() == c.degree() + a.left_gcd(b).degree() # optional - sage.rings.finite_rings + sage: a.degree() + b.degree() == c.degree() + a.left_gcd(b).degree() True Specifying ``monic=False``, we *can* get a nonmonic gcd:: - sage: a.right_lcm(b,monic=False) # optional - sage.rings.finite_rings + sage: a.right_lcm(b,monic=False) # needs sage.rings.finite_rings 2*t*x^4 + (3*t + 1)*x^3 + (4*t^2 + 4*t + 3)*x^2 + (3*t^2 + 4*t + 2)*x + 3*t^2 + 2*t + 3 @@ -1592,7 +1613,8 @@ cdef class OrePolynomial(AlgebraElement): sage: a.right_lcm(b) Traceback (most recent call last): ... - NotImplementedError: inversion of the twisting morphism Ring endomorphism of Fraction Field of Univariate Polynomial Ring in t over Rational Field + NotImplementedError: inversion of the twisting morphism Ring endomorphism of + Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: t |--> t^2 """ if self.base_ring() not in _Fields: @@ -2048,12 +2070,13 @@ cdef class OrePolynomial(AlgebraElement): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: a = 1 + t*x^2 # optional - sage.rings.finite_rings - sage: b = x + 1 # optional - sage.rings.finite_rings - sage: a.left_mod(b) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: a = 1 + t*x^2 + sage: b = x + 1 + sage: a.left_mod(b) 2*t^2 + 4*t """ _, r = self.left_quo_rem(other) @@ -2866,55 +2889,56 @@ cdef class OrePolynomial_generic_dense(OrePolynomial): EXAMPLES:: - sage: R. = GF(7)[] # optional - sage.rings.finite_rings - sage: der = R.derivation() # optional - sage.rings.finite_rings - sage: A. = R['d', der] # optional - sage.rings.finite_rings + sage: R. = GF(7)[] + sage: der = R.derivation() + sage: A. = R['d', der] - sage: L = d^3 + t*d^2 # optional - sage.rings.finite_rings - sage: L.hilbert_shift(t) # optional - sage.rings.finite_rings + sage: L = d^3 + t*d^2 + sage: L.hilbert_shift(t) d^3 + 4*t*d^2 + (5*t^2 + 3)*d + 2*t^3 + 4*t - sage: (d+t)^3 + t*(d+t)^2 # optional - sage.rings.finite_rings + sage: (d+t)^3 + t*(d+t)^2 d^3 + 4*t*d^2 + (5*t^2 + 3)*d + 2*t^3 + 4*t One can specify another variable name:: - sage: L.hilbert_shift(t, var='x') # optional - sage.rings.finite_rings + sage: L.hilbert_shift(t, var='x') x^3 + 4*t*x^2 + (5*t^2 + 3)*x + 2*t^3 + 4*t When the twisting morphism is not trivial, the output lies in a different Ore polynomial ring:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - - sage: P = x^2 + a*x + a^2 # optional - sage.rings.finite_rings - sage: Q = P.hilbert_shift(a); Q # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: P = x^2 + a*x + a^2 + sage: Q = P.hilbert_shift(a); Q x^2 + (2*a^2 + a + 4)*x + a^2 + 3*a + 4 - - sage: Q.parent() # optional - sage.rings.finite_rings + sage: Q.parent() Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 and a*([a |--> a^5] - id) - sage: Q.parent() is S # optional - sage.rings.finite_rings + sage: Q.parent() is S False This behavior ensures that the Hilbert shift by a fixed element defines an homomorphism of rings:: - sage: U = S.random_element(degree=5) # optional - sage.rings.finite_rings - sage: V = S.random_element(degree=5) # optional - sage.rings.finite_rings - sage: s = k.random_element() # optional - sage.rings.finite_rings - sage: (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: U = S.random_element(degree=5) + sage: V = S.random_element(degree=5) + sage: s = k.random_element() + sage: (U+V).hilbert_shift(s) == U.hilbert_shift(s) + V.hilbert_shift(s) True - sage: (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s) # optional - sage.rings.finite_rings + sage: (U*V).hilbert_shift(s) == U.hilbert_shift(s) * V.hilbert_shift(s) True We check that shifting by an element and then by its opposite gives back the initial Ore polynomial:: - sage: P = S.random_element(degree=10) # optional - sage.rings.finite_rings - sage: s = k.random_element() # optional - sage.rings.finite_rings - sage: P.hilbert_shift(s).hilbert_shift(-s) == P # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P = S.random_element(degree=10) + sage: s = k.random_element() + sage: P.hilbert_shift(s).hilbert_shift(-s) == P True """ from sage.rings.polynomial.ore_polynomial_ring import OrePolynomialRing @@ -2960,7 +2984,8 @@ cdef class ConstantOrePolynomialSection(Map): sage: S. = R['x',sigma] sage: m = ConstantOrePolynomialSection(S, R); m Generic map: - From: Ore Polynomial Ring in x over Univariate Polynomial Ring in t over Rational Field twisted by t |--> t + 1 + From: Ore Polynomial Ring in x over Univariate Polynomial Ring in t + over Rational Field twisted by t |--> t + 1 To: Univariate Polynomial Ring in t over Rational Field """ cpdef Element _call_(self, x): @@ -3032,11 +3057,12 @@ cdef class OrePolynomialBaseringInjection(Morphism): TESTS:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: OrePolynomialBaseringInjection(k, k['x', Frob]) Ore Polynomial base injection morphism: From: Finite Field in t of size 5^3 To: Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 @@ -3059,12 +3085,13 @@ cdef class OrePolynomialBaseringInjection(Morphism): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings - sage: m.an_element() # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) + sage: m.an_element() x """ return self._an_element @@ -3084,14 +3111,15 @@ cdef class OrePolynomialBaseringInjection(Morphism): TESTS:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings - sage: m(4) # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) + sage: m(4) 4 - sage: parent(m(4)) # optional - sage.rings.finite_rings + sage: parent(m(4)) Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 """ try: @@ -3106,14 +3134,16 @@ cdef class OrePolynomialBaseringInjection(Morphism): TESTS:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) # optional - sage.rings.finite_rings - sage: m.section() # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: m = OrePolynomialBaseringInjection(k, k['x', Frob]) + sage: m.section() Generic map: - From: Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - To: Finite Field in t of size 5^3 + From: Ore Polynomial Ring in x over Finite Field in t of size 5^3 + twisted by t |--> t^5 + To: Finite Field in t of size 5^3 """ return ConstantOrePolynomialSection(self._codomain, self.domain()) diff --git a/src/sage/rings/polynomial/ore_polynomial_ring.py b/src/sage/rings/polynomial/ore_polynomial_ring.py index f7eacf3112a..88db16fd111 100644 --- a/src/sage/rings/polynomial/ore_polynomial_ring.py +++ b/src/sage/rings/polynomial/ore_polynomial_ring.py @@ -23,6 +23,7 @@ from sage.misc.prandom import randint from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import Infinity from sage.structure.category_object import normalize_names @@ -36,11 +37,12 @@ from sage.rings.ring import _Fields from sage.categories.morphism import Morphism -from sage.rings.derivation import RingDerivation from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.ore_polynomial_element import OrePolynomialBaseringInjection +lazy_import('sage.rings.derivation', 'RingDerivation') + WORKING_CENTER_MAX_TRIES = 1000 diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 38d52a6273d..07cc696477a 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -3719,7 +3719,7 @@ cdef class BooleanPolynomial(MPolynomial): sage: g = R(1) sage: h = g.univariate_polynomial(); h 1 - sage: h.parent() + sage: h.parent() # needs sage.libs.ntl Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) """ if not self.is_univariate(): @@ -3915,9 +3915,9 @@ cdef class BooleanPolynomial(MPolynomial): Evaluation of polynomials can be used fully symbolic:: - sage: f(x=var('a'),y=var('b'),z=var('c')) + sage: f(x=var('a'), y=var('b'), z=var('c')) # needs sage.symbolic a*b + c + 1 - sage: f(var('a'),var('b'),1) + sage: f(var('a'), var('b'), 1) # needs sage.symbolic a*b """ P = self._parent @@ -3996,9 +3996,9 @@ cdef class BooleanPolynomial(MPolynomial): This method can work fully symbolic:: - sage: f.subs(x=var('a'),y=var('b'),z=var('c')) + sage: f.subs(x=var('a'), y=var('b'), z=var('c')) # needs sage.symbolic a*b + b*c + c + 1 - sage: f.subs({'x':var('a'),'y':var('b'),'z':var('c')}) + sage: f.subs({'x': var('a'), 'y': var('b'), 'z': var('c')}) # needs sage.symbolic a*b + b*c + c + 1 """ P = self._parent diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index ebc17a01e50..9f93b79e3ee 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -2523,7 +2523,8 @@ cdef class NCPolynomial_plural(RingElement): Check if :trac:`7152` is fixed:: - sage: x=var('x') + sage: # needs sage.symbolic + sage: x = var('x') sage: K. = NumberField(x**2 + 1) sage: R. = QQ[] sage: p = rho*x diff --git a/src/sage/rings/polynomial/polydict.pyx b/src/sage/rings/polynomial/polydict.pyx index a0040f43e6b..0c847d125a4 100644 --- a/src/sage/rings/polynomial/polydict.pyx +++ b/src/sage/rings/polynomial/polydict.pyx @@ -133,7 +133,7 @@ cdef class PolyDict: sage: PolyDict({(2, 3): 0, (1, 2): 3, (2, 1): 4}) PolyDict with representation {(1, 2): 3, (2, 1): 4, (2, 3): 0} - sage: PolyDict({(0, 0): RIF(-1,1)}) + sage: PolyDict({(0, 0): RIF(-1,1)}) # needs sage.rings.real_interval_field PolyDict with representation {(0, 0): 0.?} TESTS:: @@ -781,7 +781,7 @@ cdef class PolyDict: Check that :trac:`29604` is fixed:: - sage: PolyDict({(1, 0): GF(2)(1)}).latex(['x', 'y']) # optional - sage.rings.finite_rings + sage: PolyDict({(1, 0): GF(2)(1)}).latex(['x', 'y']) 'x' """ if not self: @@ -869,15 +869,15 @@ cdef class PolyDict: We make sure that intervals are correctly represented. :: - sage: f = PolyDict({(2, 3): RIF(1/2,3/2), (1, 2): RIF(-1,1)}) - sage: f.poly_repr(['x', 'y']) + sage: f = PolyDict({(2, 3): RIF(1/2,3/2), (1, 2): RIF(-1,1)}) # needs sage.rings.real_interval_field + sage: f.poly_repr(['x', 'y']) # needs sage.rings.real_interval_field '1.?*x^2*y^3 + 0.?*x*y^2' TESTS: Check that :trac:`29604` is fixed:: - sage: PolyDict({(1, 0): GF(4)(1)}).poly_repr(['x', 'y']) + sage: PolyDict({(1, 0): GF(4)(1)}).poly_repr(['x', 'y']) # needs sage.rings.finite_rings 'x' sage: P. = LaurentPolynomialRing(GF(2), 2) sage: P.gens() @@ -1001,9 +1001,9 @@ cdef class PolyDict: sage: f + g PolyDict with representation {(1, 1): 3, (1, 2): 3, (1, 5): -3, (2, 1): 4, (2, 3): 0} - sage: K = GF(2) # optional - sage.rings.finite_rings - sage: f = PolyDict({(1, 1): K(1)}) # optional - sage.rings.finite_rings - sage: f + f # optional - sage.rings.finite_rings + sage: K = GF(2) + sage: f = PolyDict({(1, 1): K(1)}) + sage: f + f PolyDict with representation {(1, 1): 0} """ cdef dict D = self.__repn @@ -1071,14 +1071,16 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups - sage: f = PolyDict({(2, 3): x}) # optional - sage.groups - sage: f.scalar_rmult(y) # optional - sage.groups + + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # needs sage.combinat + sage: f = PolyDict({(2, 3): x}) # needs sage.combinat + sage: f.scalar_rmult(y) # needs sage.combinat PolyDict with representation {(2, 3): x*y} + sage: f = PolyDict({(2,3):2, (1, 2): 3, (2, 1): 4}) sage: f.scalar_rmult(-2) PolyDict with representation {(1, 2): -6, (2, 1): -8, (2, 3): -4} - sage: f.scalar_rmult(RIF(-1,1)) + sage: f.scalar_rmult(RIF(-1,1)) # needs sage.rings.real_interval_field PolyDict with representation {(1, 2): 0.?e1, (2, 1): 0.?e1, (2, 3): 0.?e1} """ cdef dict v = {} @@ -1093,14 +1095,16 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups - sage: f = PolyDict({(2,3):x}) # optional - sage.groups - sage: f.scalar_lmult(y) # optional - sage.groups + + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # needs sage.combinat + sage: f = PolyDict({(2,3):x}) # needs sage.combinat + sage: f.scalar_lmult(y) # needs sage.combinat PolyDict with representation {(2, 3): y*x} + sage: f = PolyDict({(2,3):2, (1,2):3, (2,1):4}) sage: f.scalar_lmult(-2) PolyDict with representation {(1, 2): -6, (2, 1): -8, (2, 3): -4} - sage: f.scalar_lmult(RIF(-1,1)) + sage: f.scalar_lmult(RIF(-1,1)) # needs sage.rings.real_interval_field PolyDict with representation {(1, 2): 0.?e1, (2, 1): 0.?e1, (2, 3): 0.?e1} """ cdef dict v = {} @@ -1122,9 +1126,10 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import ETuple, PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups - sage: f = PolyDict({(2, 3): x}) # optional - sage.groups - sage: f.term_lmult(ETuple((1, 2)), y) # optional - sage.groups + + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # needs sage.combinat + sage: f = PolyDict({(2, 3): x}) # needs sage.combinat + sage: f.term_lmult(ETuple((1, 2)), y) # needs sage.combinat PolyDict with representation {(3, 5): y*x} sage: f = PolyDict({(2,3): 2, (1,2): 3, (2,1): 4}) @@ -1151,9 +1156,10 @@ cdef class PolyDict: EXAMPLES:: sage: from sage.rings.polynomial.polydict import ETuple, PolyDict - sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # optional - sage.groups - sage: f = PolyDict({(2, 3): x}) # optional - sage.groups - sage: f.term_rmult(ETuple((1, 2)), y) # optional - sage.groups + + sage: x, y = FreeMonoid(2, 'x, y').gens() # a strange object to live in a polydict, but non-commutative! # needs sage.combinat + sage: f = PolyDict({(2, 3): x}) # needs sage.combinat + sage: f.term_rmult(ETuple((1, 2)), y) # needs sage.combinat PolyDict with representation {(3, 5): x*y} sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4}) @@ -1981,6 +1987,7 @@ cdef class ETuple: Verify that :trac:`6428` has been addressed:: + sage: # needs sage.libs.singular sage: R. = Frac(QQ['x'])[] sage: type(y) diff --git a/src/sage/rings/polynomial/polynomial_complex_arb.pyx b/src/sage/rings/polynomial/polynomial_complex_arb.pyx index 5fc4ff1f6af..e51268b4b54 100644 --- a/src/sage/rings/polynomial/polynomial_complex_arb.pyx +++ b/src/sage/rings/polynomial/polynomial_complex_arb.pyx @@ -47,7 +47,7 @@ cdef class Polynomial_complex_arb(Polynomial): sage: type(x) - sage: Pol(), Pol(1), Pol([0,1,2]), Pol({1: pi, 3: i}) + sage: Pol(), Pol(1), Pol([0,1,2]), Pol({1: pi, 3: i}) # needs sage.symbolic (0, 1.000000000000000, 2.000000000000000*x^2 + x, @@ -125,9 +125,9 @@ cdef class Polynomial_complex_arb(Polynomial): x + 2.000000000000000 sage: Polynomial_complex_arb(Pol, QQ['x'](0)) 0 - sage: Polynomial_complex_arb(Pol, {10: pi}) + sage: Polynomial_complex_arb(Pol, {10: pi}) # needs sage.symbolic ([3.141592653589793 +/- ...e-16])*x^10 - sage: Polynomial_complex_arb(Pol, pi) + sage: Polynomial_complex_arb(Pol, pi) # needs sage.symbolic [3.141592653589793 +/- ...e-16] """ cdef ComplexBall ball @@ -383,8 +383,11 @@ cdef class Polynomial_complex_arb(Polynomial): sage: Pol. = CBF[] - sage: (x^3/7 - CBF(i)).quo_rem(x + CBF(pi)) - (([0.1428571428571428 +/- ...e-17])*x^2 + ([-0.448798950512828 +/- ...e-16])*x + [1.409943485869908 +/- ...e-16], [-4.42946809718569 +/- ...e-15] - I) + sage: (x^3/7 - CBF(i)).quo_rem(x + CBF(pi)) # needs sage.symbolic + (([0.1428571428571428 +/- ...e-17])*x^2 + + ([-0.448798950512828 +/- ...e-16])*x + + [1.409943485869908 +/- ...e-16], + [-4.42946809718569 +/- ...e-15] - I) sage: Pol(0).quo_rem(x + 1) (0, 0) @@ -661,7 +664,7 @@ cdef class Polynomial_complex_arb(Polynomial): 0.5000000000000000*x^2 + x + 1.000000000000000 sage: (1 + x/3)._log_series(3)._exp_series(3) ([+/- ...e-17])*x^2 + ([0.3333333333333333 +/- ...e-17])*x + 1.000000000000000 - sage: (CBF(0, pi) + x)._exp_series(4) + sage: (CBF(0, pi) + x)._exp_series(4) # needs sage.symbolic ([-0.166...] + [+/- ...]*I)*x^3 + ([-0.500...] + [+/- ...]*I)*x^2 + ([-1.000...] + [+/- ...]*I)*x + [-1.000...] + [+/- ...]*I """ @@ -911,7 +914,7 @@ cdef class Polynomial_complex_arb(Polynomial): sage: Pol. = CBF[] sage: pol = x^2 - 1 - sage: pol(CBF(pi)) + sage: pol(CBF(pi)) # needs sage.symbolic [8.86960440108936 +/- ...e-15] sage: pol(x^3 + 1) x^6 + 2.000000000000000*x^3 diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index fcf63acf7fa..4d4b9dd10f5 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -72,7 +72,6 @@ import sage.rings.rational import sage.rings.integer import sage.rings.integer_ring import sage.rings.rational_field -import sage.rings.finite_rings.integer_mod_ring import sage.rings.fraction_field_element import sage.rings.infinity as infinity from sage.misc.latex import latex @@ -84,16 +83,18 @@ from sage.structure.factorization import Factorization from sage.structure.richcmp cimport (richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn) -from sage.libs.pari.all import pari, pari_gen, PariError +try: + from sage.libs.pari.all import pari, pari_gen, PariError +except ImportError: + pari_gen = () + pari = None -cimport sage.rings.abc -from sage.rings.real_mpfr import RealField, RR + class PariError(Exception): + pass -from sage.rings.complex_mpfr import ComplexField -from sage.rings.cc import CC +cimport sage.rings.abc from sage.rings.real_double import RDF -from sage.rings.complex_double import CDF import sage.rings.abc import sage.interfaces.abc @@ -120,7 +121,6 @@ from sage.arith.functions import lcm from . import polynomial_fateman from sage.rings.ideal import is_Ideal -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.polynomial.multi_polynomial cimport MPolynomial @@ -168,11 +168,13 @@ cpdef is_Polynomial(f): y^3 + x*y - 3*x sage: is_Polynomial(f) False - sage: var('x,y') # optional - sage.symbolic + + sage: # needs sage.symbolic + sage: var('x,y') (x, y) - sage: f = y^3 + x*y - 3*x; f # optional - sage.symbolic + sage: f = y^3 + x*y - 3*x; f y^3 + x*y - 3*x - sage: is_Polynomial(f) # optional - sage.symbolic + sage: is_Polynomial(f) False """ from sage.misc.superseded import deprecation @@ -294,12 +296,12 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R = GF(2)['x']['y'] # optional - sage.rings.finite_rings - sage: R([0,1]).is_zero() # optional - sage.rings.finite_rings + sage: R = GF(2)['x']['y'] + sage: R([0,1]).is_zero() False - sage: R([0]).is_zero() # optional - sage.rings.finite_rings + sage: R([0]).is_zero() True - sage: R([-1]).is_zero() # optional - sage.rings.finite_rings + sage: R([-1]).is_zero() False """ return self.degree() < 0 @@ -344,11 +346,11 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: x = polygen(GF(389)) # optional - sage.rings.finite_rings - sage: plot(x^2 + 1, rgbcolor=(0,0,1)) # optional - sage.rings.finite_rings sage.plot + sage: x = polygen(GF(389)) + sage: plot(x^2 + 1, rgbcolor=(0,0,1)) # needs sage.plot Graphics object consisting of 1 graphics primitive sage: x = polygen(QQ) - sage: plot(x^2 + 1, rgbcolor=(1,0,0)) # optional - sage.plot + sage: plot(x^2 + 1, rgbcolor=(1,0,0)) # needs sage.plot Graphics object consisting of 1 graphics primitive """ R = self.base_ring() @@ -484,12 +486,13 @@ cdef class Polynomial(CommutativePolynomial): We evaluate a polynomial over a quaternion algebra:: - sage: A. = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules - sage: R. = PolynomialRing(A, sparse=True) # optional - sage.combinat sage.modules - sage: f = i*j*w^5 - 13*i*w^2 + (i+j)*w + i # optional - sage.combinat sage.modules - sage: f(i+j+1) # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: A. = QuaternionAlgebra(QQ, -1, -1) + sage: R. = PolynomialRing(A, sparse=True) + sage: f = i*j*w^5 - 13*i*w^2 + (i+j)*w + i + sage: f(i+j+1) 24 + 26*i - 10*j - 25*k - sage: w = i+j+1; i*j*w^5 - 13*i*w^2 + (i+j)*w + i # optional - sage.combinat sage.modules + sage: w = i+j+1; i*j*w^5 - 13*i*w^2 + (i+j)*w + i 24 + 26*i - 10*j - 25*k The parent ring of the answer always "starts" with the parent of @@ -498,50 +501,51 @@ cdef class Polynomial(CommutativePolynomial): of that matrix may change depending on the base of the polynomial ring. :: + sage: # needs sage.combinat sage.modules sage: R. = QQ[] sage: f = R(2/3) - sage: a = matrix(ZZ, 2) # optional - sage.combinat sage.modules - sage: b = f(a); b # optional - sage.combinat sage.modules + sage: a = matrix(ZZ, 2) + sage: b = f(a); b [2/3 0] [ 0 2/3] - sage: b.parent() # optional - sage.combinat sage.modules + sage: b.parent() Full MatrixSpace of 2 by 2 dense matrices over Rational Field sage: f = R(1) - sage: b = f(a); b # optional - sage.combinat sage.modules + sage: b = f(a); b [1 0] [0 1] - sage: b.parent() # optional - sage.combinat sage.modules + sage: b.parent() Full MatrixSpace of 2 by 2 dense matrices over Rational Field :: - sage: R. = GF(17)[] # optional - sage.rings.finite_rings - sage: f = w^3 + 3*w +2 # optional - sage.rings.finite_rings - sage: f(5) # optional - sage.rings.finite_rings + sage: R. = GF(17)[] + sage: f = w^3 + 3*w +2 + sage: f(5) 6 - sage: f(w=5) # optional - sage.rings.finite_rings + sage: f(w=5) 6 - sage: f(x=10) # x isn't mentioned # optional - sage.rings.finite_rings + sage: f(x=10) # x isn't mentioned w^3 + 3*w + 2 Nested polynomial ring elements can be called like multivariate polynomials. Note the order of the arguments:: sage: R. = QQ[]; S. = R[] - sage: f = x+y*x+y^2 + sage: f = x + y*x + y^2 sage: f.parent() Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field sage: f(2) 3*x + 4 sage: f(2,4) 16 - sage: f(y=2,x=4) + sage: f(y=2, x=4) 16 - sage: f(2,x=4) + sage: f(2, x=4) 16 - sage: f(2,x=4,z=5) + sage: f(2, x=4, z=5) 16 - sage: f(2,4, z=10) + sage: f(2, 4, z=10) 16 sage: f(y=x) 2*x^2 + x @@ -561,16 +565,16 @@ cdef class Polynomial(CommutativePolynomial): tuple containing the values to be substituted, though it is perhaps more natural to just unpack the list:: - sage: f([2]) # calling with a list + sage: f([2]) # calling with a list 3*x + 4 - sage: f((2,)) # calling with a tuple + sage: f((2,)) # calling with a tuple 3*x + 4 - sage: f(*[2]) # unpacking the list to call normally + sage: f(*[2]) # unpacking the list to call normally 3*x + 4 The following results in an element of the symbolic ring. :: - sage: f(x=sqrt(2)) # optional - sage.symbolic + sage: f(x=sqrt(2)) # needs sage.symbolic y^2 + sqrt(2)*y + sqrt(2) :: @@ -596,7 +600,7 @@ cdef class Polynomial(CommutativePolynomial): 3 sage: parent(f(0)) Rational Field - sage: parent(f(Qp(5)(0))) # optional - sage.rings.padics + sage: parent(f(Qp(5)(0))) # needs sage.rings.padics 5-adic Field with capped relative precision 20 TESTS: @@ -624,6 +628,7 @@ cdef class Polynomial(CommutativePolynomial): The following test came up in :trac:`9051`:: + sage: # needs sage.rings.complex_interval_field sage: Cif = ComplexIntervalField(64) sage: R. = Cif[] sage: f = 2*x-1 @@ -661,8 +666,8 @@ cdef class Polynomial(CommutativePolynomial): Univariate Polynomial Ring in x over Rational Field sage: zero = QQ['x'](0) - sage: a = matrix(ZZ, [[1]]) - sage: zero(a).parent() + sage: a = matrix(ZZ, [[1]]) # needs sage.modules + sage: zero(a).parent() # needs sage.modules Full MatrixSpace of 1 by 1 dense matrices over Rational Field sage: pol(y, x).parent() is pol(x, y).parent() is pol(y, y).parent() is Pol_xy @@ -672,11 +677,11 @@ cdef class Polynomial(CommutativePolynomial): Univariate Polynomial Ring in x over Rational Field sage: one = Pol_xy(1) - sage: one(1, 1.).parent() + sage: one(1, 1.).parent() # needs sage.rings.real_mpfr Real Field with 53 bits of precision - sage: zero = GF(2)['x'](0) # optional - sage.rings.finite_rings - sage: zero(1.).parent() # should raise an error # optional - sage.rings.finite_rings + sage: zero = GF(2)['x'](0) + sage: zero(1.).parent() # needs sage.rings.real_mpfr Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -705,37 +710,40 @@ cdef class Polynomial(CommutativePolynomial): These were drastically slower prior to :trac:`33165`:: - sage: R. = GF(31337)[] # optional - sage.rings.finite_rings - sage: f = R(list(range(100, 201))) # optional - sage.rings.finite_rings - sage: g = R(list(range(1, 1001))) # optional - sage.rings.finite_rings - sage: S. = R.quotient(f) # optional - sage.rings.finite_rings - sage: g(y) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(31337)[] + sage: f = R(list(range(100, 201))) + sage: g = R(list(range(1, 1001))) + sage: S. = R.quotient(f) + sage: g(y) 22537*y^99 + 4686*y^98 + 13285*y^97 + 4216*y^96 + ... + 6389*y^3 + 30062*y^2 + 13755*y + 11875 :: - sage: T. = GF(31337)[] # optional - sage.rings.finite_rings - sage: g(z) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: T. = GF(31337)[] + sage: g(z) 1000*z^999 + 999*z^998 + 998*z^997 + 997*z^996 + ... + 5*z^4 + 4*z^3 + 3*z^2 + 2*z + 1 - sage: g(z^2) # optional - sage.rings.finite_rings + sage: g(z^2) 1000*z^1998 + 999*z^1996 + 998*z^1994 + 997*z^1992 + ... + 5*z^8 + 4*z^6 + 3*z^4 + 2*z^2 + 1 - sage: g(T([0, 1])) # optional - sage.rings.finite_rings + sage: g(T([0, 1])) 1000*z^999 + 999*z^998 + 998*z^997 + 997*z^996 + ... + 5*z^4 + 4*z^3 + 3*z^2 + 2*z + 1 - sage: g(T.zero()) # optional - sage.rings.finite_rings + sage: g(T.zero()) 1 - sage: g(T(2)) # optional - sage.rings.finite_rings + sage: g(T(2)) 23069 :: - sage: U. = GF(31337)[] # optional - sage.rings.finite_rings - sage: g(u) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: U. = GF(31337)[] + sage: g(u) 1000*u^999 + 999*u^998 + 998*u^997 + 997*u^996 + ... + 5*u^4 + 4*u^3 + 3*u^2 + 2*u + 1 - sage: g(u*v^2) # optional - sage.rings.finite_rings + sage: g(u*v^2) 1000*u^999*v^1998 + 999*u^998*v^1996 + 998*u^997*v^1994 + ... + 4*u^3*v^6 + 3*u^2*v^4 + 2*u*v^2 + 1 - sage: g(U.zero()) # optional - sage.rings.finite_rings + sage: g(U.zero()) 1 - sage: g(U(2)) # optional - sage.rings.finite_rings + sage: g(U(2)) -8268 Sparse tests for :trac:`33165`:: @@ -914,8 +922,8 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: Pol. = CBF[] - sage: (1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120).compose_trunc(1 + x, 2) + sage: Pol. = CBF[] # needs sage.libs.flint + sage: (1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120).compose_trunc(1 + x, 2) # needs sage.libs.flint ([2.708333333333333 +/- ...e-16])*x + [2.71666666666667 +/- ...e-15] sage: Pol. = QQ['y'][] @@ -1022,6 +1030,7 @@ cdef class Polynomial(CommutativePolynomial): Test that comparisons are consistent when using interval coefficients:: + sage: # needs sage.rings.real_interval_field sage: R. = RIF[] sage: a = RIF(0,1) * x sage: b = RIF(1,2) * x @@ -1042,9 +1051,9 @@ cdef class Polynomial(CommutativePolynomial): sage: a != b False - sage: R. = RBF[] - sage: pol = RBF(1.0, 0.1) - sage: pol == pol + sage: R. = RBF[] # needs sage.libs.flint + sage: pol = RBF(1.0, 0.1) # needs sage.libs.flint + sage: pol == pol # needs sage.libs.flint False """ cdef Polynomial pol = other @@ -1187,21 +1196,22 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: K. = Qq(4) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = x # optional - sage.rings.padics - sage: hash(f) # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K. = Qq(4) + sage: R. = K[] + sage: f = x + sage: hash(f) Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' - sage: f._cache_key() # optional - sage.rings.padics + sage: f._cache_key() (Univariate Polynomial Ring in x over 2-adic Unramified Extension Field in u defined by x^2 + x + 1, 0, 1 + O(2^20)) sage: @cached_function ....: def foo(t): return t ....: - sage: foo(x) # optional - sage.rings.padics + sage: foo(x) (1 + O(2^20))*x """ return (self._parent,) + tuple(self) @@ -1238,9 +1248,9 @@ cdef class Polynomial(CommutativePolynomial): Verify that :trac:`16251` has been resolved, i.e., polynomials with unhashable coefficients are unhashable:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: hash(t) # optional - sage.rings.padics + sage: K. = Qq(9) # needs sage.rings.padics + sage: R. = K[] # needs sage.rings.padics + sage: hash(t) # needs sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' @@ -1291,14 +1301,15 @@ cdef class Polynomial(CommutativePolynomial): Defn: x |--> 5 sage: f(x) 5 - sage: f(x^2 + 3) # indirect doctest + sage: f(x^2 + 3) # indirect doctest 28 - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: cc = K.hom([-i]) # optional - sage.rings.number_field - sage: S. = K[] # optional - sage.rings.number_field - sage: phi = S.hom([y^2], base_map=cc) # optional - sage.rings.number_field - sage: phi(i*y) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^2 + 1) + sage: cc = K.hom([-i]) + sage: S. = K[] + sage: phi = S.hom([y^2], base_map=cc) + sage: phi(i*y) -i*y^2 """ a = im_gens[0] @@ -1327,21 +1338,21 @@ cdef class Polynomial(CommutativePolynomial): sage: a = QQ['x'](1/5) sage: QQ(a) 1/5 - sage: AA(a) # optional - sage.rings.number_field + sage: AA(a) # needs sage.rings.number_field 1/5 - sage: QQbar(a) # optional - sage.rings.number_field + sage: QQbar(a) # needs sage.rings.number_field 1/5 sage: RDF(a) 0.2 - sage: CDF(a) + sage: CDF(a) # needs sage.rings.complex_double 0.2 sage: RR(a) 0.200000000000000 sage: CC(a) 0.200000000000000 - sage: RBF(a) + sage: RBF(a) # needs sage.libs.flint [0.2000000000000000 +/- 4.45e-17] - sage: CBF(a) + sage: CBF(a) # needs sage.libs.flint [0.2000000000000000 +/- 4.45e-17] sage: RIF(a) 0.2000000000000000? @@ -1352,30 +1363,32 @@ cdef class Polynomial(CommutativePolynomial): sage: complex(a) (0.2+0j) - sage: b = AA['x'](AA(2/3).sqrt()) # optional - sage.rings.number_field - sage: AA(b) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: b = AA['x'](AA(2/3).sqrt()) + sage: AA(b) 0.8164965809277260? - sage: RR(b) # optional - sage.rings.number_field + sage: RR(b) 0.816496580927726 - sage: RBF(b) # optional - sage.rings.number_field + sage: RBF(b) # needs sage.libs.flint [0.816496580927726 +/- 2.44e-16] - sage: RIF(b) # optional - sage.rings.number_field + sage: RIF(b) 0.8164965809277260? - sage: float(b) # optional - sage.rings.number_field + sage: float(b) 0.816496580927726 - sage: c = QQbar['x'](QQbar(-2/5).sqrt()) # optional - sage.rings.number_field - sage: QQbar(c) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: c = QQbar['x'](QQbar(-2/5).sqrt()) + sage: QQbar(c) 0.6324555320336758?*I - sage: CDF(c) # optional - sage.rings.number_field + sage: CDF(c) 0.6324555320336758*I - sage: CC(c) # optional - sage.rings.number_field + sage: CC(c) 0.632455532033676*I - sage: CBF(c) # abs tol 1e-16 # optional - sage.rings.number_field + sage: CBF(c) # abs tol 1e-16 # needs sage.libs.flint [0.6324555320336759 +/- 3.38e-17]*I - sage: CIF(c) # optional - sage.rings.number_field + sage: CIF(c) 0.6324555320336758?*I - sage: complex(c) # optional - sage.rings.number_field + sage: complex(c) 0.6324555320336758j sage: K. = Frac(RR['x']) @@ -1387,8 +1400,8 @@ cdef class Polynomial(CommutativePolynomial): TypeError: cannot convert nonconstant polynomial sage: x = polygen(QQ) - sage: A. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: A(A['x'](u)) # optional - sage.rings.number_field + sage: A. = NumberField(x^3 - 2) # needs sage.rings.number_field + sage: A(A['x'](u)) # needs sage.rings.number_field u """ if self.degree() > 0: @@ -1430,8 +1443,8 @@ cdef class Polynomial(CommutativePolynomial): r""" EXAMPLES:: - sage: p = PolynomialRing(QQbar, 'x')(1+I) # optional - sage.rings.number_field - sage: complex(p) # optional - sage.rings.number_field + sage: p = PolynomialRing(QQbar, 'x')(1+I) # needs sage.rings.number_field + sage: complex(p) # needs sage.rings.number_field (1+1j) """ return self._scalar_conversion(complex) @@ -1454,22 +1467,22 @@ cdef class Polynomial(CommutativePolynomial): """ EXAMPLES:: + sage: # needs sage.symbolic sage: R. = QQ[] sage: f = x^3 + x - sage: g = f._symbolic_(SR); g # optional - sage.symbolic + sage: g = f._symbolic_(SR); g x^3 + x - sage: g(x=2) # optional - sage.symbolic + sage: g(x=2) 10 - - sage: g = SR(f) # optional - sage.symbolic - sage: g(x=2) # optional - sage.symbolic + sage: g = SR(f) + sage: g(x=2) 10 The polynomial has to be over a field of characteristic 0 (see :trac:`24072`):: - sage: R. = GF(7)[] # optional - sage.rings.finite_rings - sage: f = SR(2*w^3 + 1); f # optional - sage.rings.finite_rings sage.symbolic + sage: R. = GF(7)[] + sage: f = SR(2*w^3 + 1); f # needs sage.symbolic Traceback (most recent call last): ... TypeError: positive characteristic not allowed in symbolic computations @@ -1556,24 +1569,25 @@ cdef class Polynomial(CommutativePolynomial): error the product may not always exactly equal the constant polynomial 1 and have extra terms with coefficients close to zero. :: + sage: # needs sage.modules sage: R. = RDF[] sage: epsilon = RDF(1).ulp()*50 # Allow an error of up to 50 ulp - sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14 # optional - sage.modules + sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14 0.4*x^4 - 0.2*x^3 - 0.4*x^2 + 0.2*x + 0.8 - sage: poly = f * (x^2 + 1) % (x^5 + x + 1) # optional - sage.modules + sage: poly = f * (x^2 + 1) % (x^5 + x + 1) sage: # Remove noisy zero terms: - sage: parent(poly)([0.0 if abs(c) <= epsilon else c # optional - sage.modules + sage: parent(poly)([0.0 if abs(c) <= epsilon else c ....: for c in poly.coefficients(sparse=False)]) 1.0 - sage: f = inverse_mod(x^3 - x + 1, x - 2); f # optional - sage.modules + sage: f = inverse_mod(x^3 - x + 1, x - 2); f 0.14285714285714285 - sage: f * (x^3 - x + 1) % (x - 2) # optional - sage.modules + sage: f * (x^3 - x + 1) % (x - 2) 1.0 - sage: g = 5*x^3 + x - 7; m = x^4 - 12*x + 13; f = inverse_mod(g, m); f # optional - sage.modules + sage: g = 5*x^3 + x - 7; m = x^4 - 12*x + 13; f = inverse_mod(g, m); f -0.0319636125...*x^3 - 0.0383269759...*x^2 - 0.0463050900...*x + 0.346479687... - sage: poly = f*g % m # optional - sage.modules + sage: poly = f*g % m sage: # Remove noisy zero terms: - sage: parent(poly)([0.0 if abs(c) <= epsilon else c # abs tol 1e-14 # optional - sage.modules + sage: parent(poly)([0.0 if abs(c) <= epsilon else c # abs tol 1e-14 ....: for c in poly.coefficients(sparse=False)]) 1.0000000000000004 @@ -1681,14 +1695,15 @@ cdef class Polynomial(CommutativePolynomial): Even noncommutative ones:: - sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules - sage: x = polygen(M) # optional - sage.modules - sage: p = M([1,2,3,4])*x^3 + M([-1,0,0,1])*x^2 + M([1,3,-1,0])*x + M.one() # optional - sage.modules - sage: q = p.inverse_series_trunc(5) # optional - sage.modules - sage: (p*q).truncate(5) == M.one() # optional - sage.modules + sage: # needs sage.modules + sage: M = MatrixSpace(ZZ, 2) + sage: x = polygen(M) + sage: p = M([1,2,3,4])*x^3 + M([-1,0,0,1])*x^2 + M([1,3,-1,0])*x + M.one() + sage: q = p.inverse_series_trunc(5) + sage: (p*q).truncate(5) == M.one() True - sage: q = p.inverse_series_trunc(13) # optional - sage.modules - sage: (p*q).truncate(13) == M.one() # optional - sage.modules + sage: q = p.inverse_series_trunc(13) + sage: (p*q).truncate(13) == M.one() True TESTS:: @@ -1739,11 +1754,13 @@ cdef class Polynomial(CommutativePolynomial): sage: Pol. = QQ[] sage: (x + x^3/6 + x^5/120).revert_series(6) 3/40*x^5 - 1/6*x^3 + x - sage: Pol. = CBF[] - sage: (x + x^3/6 + x^5/120).revert_series(6) + sage: Pol. = CBF[] # needs sage.libs.flint + sage: (x + x^3/6 + x^5/120).revert_series(6) # needs sage.libs.flint ([0.075000000000000 +/- ...e-17])*x^5 + ([-0.166666666666667 +/- ...e-16])*x^3 + x - sage: Pol. = SR[] # optional - sage.symbolic - sage: x.revert_series(6) # optional - sage.symbolic + + sage: # needs sage.symbolic + sage: Pol. = SR[] + sage: x.revert_series(6) Traceback (most recent call last): ... NotImplementedError: only implemented for certain base rings @@ -1772,20 +1789,21 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: Pol. = MatrixSpace(ZZ, 2)[] # optional - sage.modules - sage: a = matrix([[1,0], [0,0]]) # optional - sage.modules - sage: b = matrix([[1,2], [3,4]]) # optional - sage.modules - sage: list((a*x)*(b*x + 1)) # optional - sage.modules + sage: # needs sage.modules + sage: Pol. = MatrixSpace(ZZ, 2)[] + sage: a = matrix([[1,0], [0,0]]) + sage: b = matrix([[1,2], [3,4]]) + sage: list((a*x)*(b*x + 1)) [ [0 0] [1 0] [1 2] [0 0], [0 0], [0 0] ] - sage: list((b*x + 1)*(a*x)) # optional - sage.modules + sage: list((b*x + 1)*(a*x)) [ [0 0] [1 0] [1 0] [0 0], [0 0], [3 0] ] - sage: list((a*x + 1)*(b*x)) # optional - sage.modules + sage: list((a*x + 1)*(b*x)) [ [0 0] [1 2] [1 2] [0 0], [3 4], [0 0] @@ -1917,11 +1935,11 @@ cdef class Polynomial(CommutativePolynomial): sage: p = 37 * (x - 2/3)^2 sage: p.squarefree_decomposition() (37) * (x - 2/3)^2 - sage: x = polygen(GF(3)) # optional - sage.rings.finite_rings - sage: x.squarefree_decomposition() # optional - sage.rings.finite_rings + sage: x = polygen(GF(3)) + sage: x.squarefree_decomposition() x - sage: f = QQbar['x'](1) # optional - sage.rings.number_field - sage: f.squarefree_decomposition() # optional - sage.rings.number_field + sage: f = QQbar['x'](1) # needs sage.rings.number_field + sage: f.squarefree_decomposition() # needs sage.rings.number_field 1 """ @@ -2035,73 +2053,78 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = GF(11)[] # optional - sage.rings.finite_rings - sage: f = 7*x^7 + 8*x^6 + 4*x^5 + x^4 + 6*x^3 + 10*x^2 + 8*x + 5 # optional - sage.rings.finite_rings - sage: f.any_root() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(11)[] + sage: f = 7*x^7 + 8*x^6 + 4*x^5 + x^4 + 6*x^3 + 10*x^2 + 8*x + 5 + sage: f.any_root() 2 - sage: f.factor() # optional - sage.rings.finite_rings + sage: f.factor() (7) * (x + 9) * (x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2) - sage: f = x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2 # optional - sage.rings.finite_rings - sage: f.any_root(GF(11^6, 'a')) # optional - sage.rings.finite_rings + sage: f = x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2 + sage: f.any_root(GF(11^6, 'a')) a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a - sage: sorted(f.roots(GF(11^6, 'a'))) # optional - sage.rings.finite_rings + sage: sorted(f.roots(GF(11^6, 'a'))) [(10*a^5 + 2*a^4 + 8*a^3 + 9*a^2 + a, 1), (a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a, 1), (9*a^5 + 5*a^4 + 10*a^3 + 8*a^2 + 3*a + 1, 1), (2*a^5 + 8*a^4 + 3*a^3 + 6*a + 2, 1), (a^5 + 3*a^4 + 8*a^3 + 2*a^2 + 3*a + 4, 1), (10*a^5 + 3*a^4 + 8*a^3 + a^2 + 10*a + 4, 1)] - sage: f.any_root(GF(11^6, 'a')) # optional - sage.rings.finite_rings + sage: f.any_root(GF(11^6, 'a')) a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a - sage: g = (x-1)*(x^2 + 3*x + 9) * (x^5 + 5*x^4 + 8*x^3 + 5*x^2 + 3*x + 5) # optional - sage.rings.finite_rings - sage: g.any_root(ring=GF(11^10, 'b'), degree=1) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: g = (x-1)*(x^2 + 3*x + 9) * (x^5 + 5*x^4 + 8*x^3 + 5*x^2 + 3*x + 5) + sage: g.any_root(ring=GF(11^10, 'b'), degree=1) 1 - sage: g.any_root(ring=GF(11^10, 'b'), degree=2) # optional - sage.rings.finite_rings + sage: g.any_root(ring=GF(11^10, 'b'), degree=2) 5*b^9 + 4*b^7 + 4*b^6 + 8*b^5 + 10*b^2 + 10*b + 5 - sage: g.any_root(ring=GF(11^10, 'b'), degree=5) # optional - sage.rings.finite_rings + sage: g.any_root(ring=GF(11^10, 'b'), degree=5) 5*b^9 + b^8 + 3*b^7 + 2*b^6 + b^5 + 4*b^4 + 3*b^3 + 7*b^2 + 10*b TESTS:: - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: K. = GF(5^12) # optional - sage.rings.finite_rings - sage: for _ in range(40): # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: K. = GF(5^12) # needs sage.rings.finite_rings + sage: for _ in range(40): # needs sage.rings.finite_rings ....: f = R.random_element(degree=4) ....: assert f(f.any_root(K)) == 0 Check that our Cantor-Zassenhaus implementation does not loop over finite fields of even characteristic (see :trac:`16162`):: - sage: K. = GF(2**8) # optional - sage.rings.finite_rings - sage: x = polygen(K) # optional - sage.rings.finite_rings - sage: r = (x**2+x+1).any_root() # used to loop # optional - sage.rings.finite_rings - sage: r**2 + r # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(2**8) + sage: x = polygen(K) + sage: r = (x**2+x+1).any_root() # used to loop + sage: r**2 + r 1 - sage: (x**2+a+1).any_root() # optional - sage.rings.finite_rings + sage: (x**2+a+1).any_root() a^7 + a^2 Also check that such computations can be interrupted:: - sage: K. = GF(2^8) # optional - sage.rings.finite_rings - sage: x = polygen(K) # optional - sage.rings.finite_rings - sage: pol = x^1000000 + x + a # optional - sage.rings.finite_rings - sage: alarm(0.5); pol.any_root() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(2^8) + sage: x = polygen(K) + sage: pol = x^1000000 + x + a + sage: alarm(0.5); pol.any_root() Traceback (most recent call last): ... AlarmInterrupt Check root computation over large finite fields:: - sage: K. = GF(2**50) # optional - sage.rings.finite_rings - sage: x = polygen(K) # optional - sage.rings.finite_rings - sage: (x**10+x+a).any_root() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(2**50) + sage: x = polygen(K) + sage: (x**10+x+a).any_root() a^49 + a^47 + a^44 + a^42 + a^41 + a^39 + a^38 + a^37 + a^36 + a^34 + a^33 + a^29 + a^27 + a^26 + a^25 + a^23 + a^18 + a^13 + a^7 + a^5 + a^4 + a^3 + a^2 + a - sage: K. = GF(2**150) # optional - sage.rings.finite_rings - sage: x = polygen(K) # optional - sage.rings.finite_rings - sage: (x**10+x+a).any_root() # optional - sage.rings.finite_rings + sage: K. = GF(2**150) + sage: x = polygen(K) + sage: (x**10+x+a).any_root() a^149 + a^148 + a^146 + a^144 + a^143 + a^140 + a^138 + a^136 + a^134 + a^132 + a^131 + a^130 + a^129 + a^127 + a^123 + a^120 + a^118 + a^114 + a^113 + a^112 + a^111 + a^108 + a^104 + a^103 + a^102 + a^99 + a^98 @@ -2113,11 +2136,12 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`21998` has been resolved:: - sage: K. = GF(2^4) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: f = x^2 + x + a^2 + a # optional - sage.rings.finite_rings - sage: r = f.any_root() # optional - sage.rings.finite_rings - sage: r^2 + r # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(2^4) + sage: R. = K[] + sage: f = x^2 + x + a^2 + a + sage: r = f.any_root() + sage: r^2 + r a^2 + a """ if self.base_ring().is_finite() and self.base_ring().is_field(): @@ -2311,9 +2335,9 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: R. = PolynomialRing(GF(5^2, 'a'), 'x') # optional - sage.rings.finite_rings - sage: f = x^3 + 4*x # optional - sage.rings.finite_rings - sage: f / (x - 1) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(5^2, 'a'), 'x') # needs sage.rings.finite_rings + sage: f = x^3 + 4*x + sage: f / (x - 1) # needs sage.rings.finite_rings x^2 + x Be careful about coercions (this used to be broken):: @@ -2328,21 +2352,21 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`12217` is fixed:: - sage: P. = GF(5)[] # optional - sage.rings.finite_rings - sage: x/0 # optional - sage.rings.finite_rings + sage: P. = GF(5)[] + sage: x/0 Traceback (most recent call last): ... ZeroDivisionError: inverse of Mod(0, 5) does not exist - sage: P. = GF(25, 'a')[] # optional - sage.rings.finite_rings - sage: x/5 # optional - sage.rings.finite_rings + sage: P. = GF(25, 'a')[] # needs sage.rings.finite_rings + sage: x/5 # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: division by zero in finite field Check that :trac:`23611` is fixed:: - sage: int(1) / x # optional - sage.rings.finite_rings + sage: int(1) / x 1/x """ # Same parents => bypass coercion @@ -2375,10 +2399,10 @@ cdef class Polynomial(CommutativePolynomial): sage: f^3 x^3 - 3*x^2 + 3*x - 1 - sage: R = PolynomialRing(GF(2), 'x') # optional - sage.rings.finite_rings - sage: f = R(x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x) # optional - sage.rings.finite_rings - sage: h = R(x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1) # optional - sage.rings.finite_rings - sage: pow(f, 2, h) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(2), 'x') + sage: f = R(x^9 + x^7 + x^6 + x^5 + x^4 + x^2 + x) + sage: h = R(x^10 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + 1) + sage: pow(f, 2, h) x^9 + x^8 + x^7 + x^5 + x^3 TESTS:: @@ -2405,46 +2429,48 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: k = GF(5) # optional - sage.rings.finite_rings - sage: D. = k[] # optional - sage.rings.finite_rings - sage: l. = k.extension(x^2 + 2) # optional - sage.rings.finite_rings - sage: R. = l[] # optional - sage.rings.finite_rings - sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 # optional - sage.rings.finite_rings - sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 # optional - sage.rings.finite_rings - sage: pow(f, 2, h) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k = GF(5) + sage: D. = k[] + sage: l. = k.extension(x^2 + 2) + sage: R. = l[] + sage: f = t^4 + (2*x - 1)*t^3 + (2*x + 1)*t^2 + 3 + sage: h = t^4 - x*t^3 + (3*x + 1)*t^2 + 2*t + 2*x - 1 + sage: pow(f, 2, h) 3*t^3 + (2*x + 3)*t^2 + (2*x + 2)*t + 2*x + 2 - sage: pow(f, 10**7, h) # optional - sage.rings.finite_rings + sage: pow(f, 10**7, h) 4*x*t^3 + 2*x*t^2 + 4*x*t + 4 Check that :trac:`18457` is fixed:: - sage: R. = PolynomialRing(GF(5), sparse=True) # optional - sage.rings.finite_rings - sage: (1+x)^(5^10) # used to hang forever # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(5), sparse=True) + sage: (1+x)^(5^10) x^9765625 + 1 - sage: S. = GF(3)[] # optional - sage.rings.finite_rings - sage: R1. = PolynomialRing(S, sparse=True) # optional - sage.rings.finite_rings - sage: (1+x+t)^(3^10) # optional - sage.rings.finite_rings + sage: S. = GF(3)[] + sage: R1. = PolynomialRing(S, sparse=True) + sage: (1+x+t)^(3^10) x^59049 + t^59049 + 1 - sage: R2. = PolynomialRing(S, sparse=False) # optional - sage.rings.finite_rings - sage: (1+x+t)^(3^10) # optional - sage.rings.finite_rings + sage: R2. = PolynomialRing(S, sparse=False) + sage: (1+x+t)^(3^10) x^59049 + t^59049 + 1 Check that the algorithm used is indeed correct:: + sage: # needs sage.rings.finite_rings sage: from sage.arith.power import generic_power - sage: R1 = PolynomialRing(GF(8,'a'), 'x') # optional - sage.rings.finite_rings - sage: R2 = PolynomialRing(GF(9,'b'), 'x', sparse=True) # optional - sage.rings.finite_rings - sage: R3 = PolynomialRing(R2, 'y') # optional - sage.rings.finite_rings - sage: R4 = PolynomialRing(R1, 'y', sparse=True) # optional - sage.rings.finite_rings - sage: for d in range(20,40): # long time # optional - sage.rings.finite_rings + sage: R1 = PolynomialRing(GF(8,'a'), 'x') + sage: R2 = PolynomialRing(GF(9,'b'), 'x', sparse=True) + sage: R3 = PolynomialRing(R2, 'y') + sage: R4 = PolynomialRing(R1, 'y', sparse=True) + sage: for d in range(20,40): # long time ....: for R in [R1, R2, R3, R3]: ....: a = R.random_element() ....: assert a^d == generic_power(a, d) Test the powering modulo ``x^n`` (calling :meth:`power_trunc`):: - sage: R. = GF(3)[] # optional - sage.rings.finite_rings - sage: pow(x + 1, 51, x^7) # optional - sage.rings.finite_rings + sage: R. = GF(3)[] + sage: pow(x + 1, 51, x^7) x^6 + 2*x^3 + 1 sage: S. = QQ[] @@ -2455,10 +2481,11 @@ cdef class Polynomial(CommutativePolynomial): Check that fallback method is used when it is not possible to compute the characteristic of the base ring (:trac:`24308`):: - sage: kk. = GF(2)[] # optional - sage.rings.finite_rings - sage: k. = kk.quo(a^2+a+1) # optional - sage.rings.finite_rings - sage: K. = k[] # optional - sage.rings.finite_rings - sage: (T*y)^21 # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: kk. = GF(2)[] + sage: k. = kk.quo(a^2 + a + 1) + sage: K. = k[] + sage: (T*y)^21 T^21 """ if not isinstance(left, Polynomial): @@ -2550,18 +2577,18 @@ cdef class Polynomial(CommutativePolynomial): sage: ((x + y)^5).truncate(5) 5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5 - sage: R. = GF(3)[] # optional - sage.rings.finite_rings - sage: p = x^2 - x + 1 # optional - sage.rings.finite_rings - sage: q = p.power_trunc(80, 20); q # optional - sage.rings.finite_rings + sage: R. = GF(3)[] + sage: p = x^2 - x + 1 + sage: q = p.power_trunc(80, 20); q x^19 + x^18 + ... + 2*x^4 + 2*x^3 + x + 1 - sage: (p^80).truncate(20) == q # optional - sage.rings.finite_rings + sage: (p^80).truncate(20) == q True - sage: R. = GF(7)[] # optional - sage.rings.finite_rings - sage: p = (x^2 + x + 1).power_trunc(2^100, 100); p # optional - sage.rings.finite_rings + sage: R. = GF(7)[] + sage: p = (x^2 + x + 1).power_trunc(2^100, 100); p 2*x^99 + x^98 + x^95 + 2*x^94 + ... + 3*x^2 + 2*x + 1 - sage: for i in range(100): # optional - sage.rings.finite_rings + sage: for i in range(100): ....: q1 = (x^2 + x + 1).power_trunc(2^100 + i, 100) ....: q2 = p * (x^2 + x + 1).power_trunc(i, 100) ....: q2 = q2.truncate(100) @@ -2570,16 +2597,16 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: sage: x = polygen(QQ) - sage: (3*x-5).power_trunc(2^200, 0) + sage: (3*x - 5).power_trunc(2^200, 0) 0 sage: x.power_trunc(-1, 10) Traceback (most recent call last): ... ValueError: n must be a non-negative integer sage: R. = QQ['x'] - sage: y.power_trunc(2**32-1, 2) + sage: y.power_trunc(2**32 - 1, 2) 0 - sage: y.power_trunc(2**64-1, 2) + sage: y.power_trunc(2**64 - 1, 2) 0 """ cdef Integer ZZn = ZZ(n) @@ -2651,10 +2678,10 @@ cdef class Polynomial(CommutativePolynomial): elements in the Sage library yet that do not implement ``__bool__``, so we have to create one artificially.):: - sage: class PatchedAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # optional - sage.rings.number_field + sage: class PatchedAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # needs sage.rings.number_field ....: def __bool__(self): raise NotImplementedError() - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: R([PatchedAlgebraicNumber(0), 1]) # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: R([PatchedAlgebraicNumber(0), 1]) # needs sage.rings.number_field x + 0 """ if name is None: @@ -2729,11 +2756,13 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: C3. = CyclotomicField(3) # optional - sage.rings.number_field - sage: R. = C3[] # optional - sage.rings.number_field - sage: f = X^3 - omega*X # optional - sage.rings.number_field - sage: latex(f) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C3. = CyclotomicField(3) + sage: R. = C3[] + sage: f = X^3 - omega*X + sage: latex(f) X^{3} - \omega X + sage: R. = RDF[] sage: latex(x+2) x + 2.0 @@ -2745,9 +2774,9 @@ cdef class Polynomial(CommutativePolynomial): The following illustrates a (non-intentional) superfluity of parentheses - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: latex(I*x^2 - I*x) # optional - sage.rings.number_field + sage: K. = QuadraticField(-1) # needs sage.rings.number_field + sage: R. = K[] # needs sage.rings.number_field + sage: latex(I*x^2 - I*x) # needs sage.rings.number_field \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) x """ s = " " @@ -2816,11 +2845,11 @@ cdef class Polynomial(CommutativePolynomial): R1. = ZZ[] R2. = R1[] y^2 + (2*x + 2)*y + (x^2 + 2*x + 1) - sage: sage_input(RR(pi) * polygen(RR), verify=True) # optional - sage.symbolic + sage: sage_input(RR(pi) * polygen(RR), verify=True) # needs sage.symbolic # Verified R. = RR[] 3.1415926535897931*x - sage: sage_input(polygen(GF(7)) + 12, verify=True) # optional - sage.rings.finite_rings + sage: sage_input(polygen(GF(7)) + 12, verify=True) # Verified R. = GF(7)[] x + 5 @@ -2928,15 +2957,16 @@ cdef class Polynomial(CommutativePolynomial): Check the problem reported at :trac:`12529` is fixed:: + sage: # needs sage.rings.finite_rings sage: gens = 'y a0 a1 a2 b0 b1 b2 c1 c2 d0 d1 d2 d3 d4 d5 d6 d7'.split() - sage: R = PolynomialRing(GF(8), 17, gens) # optional - sage.rings.finite_rings - sage: R.inject_variables(verbose=False) # optional - sage.rings.finite_rings - sage: A, B, C = a0 + a1*y + a2*y^2, b0 + b1*y + b2*y^2, c1*y + c2*y^2 # optional - sage.rings.finite_rings - sage: D = d0 + d1*y + d2*y^2 + d3*y^3 + d4*y^4 + d5*y^5 + d6*y^6 + d7*y^7 # optional - sage.rings.finite_rings - sage: F = D.subs({y: B}) # optional - sage.rings.finite_rings - sage: G = A.subs({y: F}) + C # optional - sage.rings.finite_rings - sage: g = G.mod(y^8 + y) # optional - sage.rings.finite_rings - sage: g.degree(y) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(8), 17, gens) + sage: R.inject_variables(verbose=False) + sage: A, B, C = a0 + a1*y + a2*y^2, b0 + b1*y + b2*y^2, c1*y + c2*y^2 + sage: D = d0 + d1*y + d2*y^2 + d3*y^3 + d4*y^4 + d5*y^5 + d6*y^6 + d7*y^7 + sage: F = D.subs({y: B}) + sage: G = A.subs({y: F}) + C + sage: g = G.mod(y^8 + y) + sage: g.degree(y) 7 """ return self % other @@ -2975,21 +3005,22 @@ cdef class Polynomial(CommutativePolynomial): Show the product in the symbolic ring:: - sage: L = SR['x'] # optional - sage.symbolic - sage: var('a0,a1,b0,b1') # optional - sage.symbolic + sage: L = SR['x'] # needs sage.symbolic + sage: var('a0,a1,b0,b1') # needs sage.symbolic (a0, a1, b0, b1) - sage: L([a0, a1])._mul_generic(L([b0, b1])) # optional - sage.symbolic + sage: L([a0, a1])._mul_generic(L([b0, b1])) # needs sage.symbolic a1*b1*x^2 + (a1*b0 + a0*b1)*x + a0*b0 A non-commutative example:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules - sage: R. = PolynomialRing(A) # optional - sage.combinat sage.modules - sage: f = i*w + j # optional - sage.combinat sage.modules - sage: g = k*w + 1 # optional - sage.combinat sage.modules - sage: f._mul_generic(g) # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: A. = QuaternionAlgebra(QQ, -1,-1) + sage: R. = PolynomialRing(A) + sage: f = i*w + j + sage: g = k*w + 1 + sage: f._mul_generic(g) -j*w^2 + 2*i*w + j - sage: g._mul_generic(f) # optional - sage.combinat sage.modules + sage: g._mul_generic(f) j*w^2 + j @@ -3193,23 +3224,25 @@ cdef class Polynomial(CommutativePolynomial): Show the product in the symbolic ring:: - sage: L = SR['x'] # optional - sage.symbolic - sage: var('a0,a1,b0,b1') # optional - sage.symbolic + sage: # needs sage.symbolic + sage: L = SR['x'] + sage: var('a0,a1,b0,b1') (a0, a1, b0, b1) - sage: L([a0, a1])._mul_karatsuba(L([b0, b1]), 0) # optional - sage.symbolic + sage: L([a0, a1])._mul_karatsuba(L([b0, b1]), 0) a1*b1*x^2 + ((a0 + a1)*(b0 + b1) - a0*b0 - a1*b1)*x + a0*b0 - sage: L([a0, a1])._mul_karatsuba(L([b0, b1]), 2) # optional - sage.symbolic + sage: L([a0, a1])._mul_karatsuba(L([b0, b1]), 2) a1*b1*x^2 + (a1*b0 + a0*b1)*x + a0*b0 A noncommutative example:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules - sage: R. = PolynomialRing(A) # optional - sage.combinat sage.modules - sage: f = i*w + j # optional - sage.combinat sage.modules - sage: g = k*w + 1 # optional - sage.combinat sage.modules - sage: f._mul_karatsuba(g,0) # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: A. = QuaternionAlgebra(QQ, -1,-1) + sage: R. = PolynomialRing(A) + sage: f = i*w + j + sage: g = k*w + 1 + sage: f._mul_karatsuba(g,0) -j*w^2 + 2*i*w + j - sage: g._mul_karatsuba(f,0) # optional - sage.combinat sage.modules + sage: g._mul_karatsuba(f,0) j*w^2 + j TESTS:: @@ -3235,28 +3268,30 @@ cdef class Polynomial(CommutativePolynomial): Random tests for noncommutative rings:: - sage: A. = QuaternionAlgebra(QQ, -1,-1) # optional - sage.combinat sage.modules - sage: R. = PolynomialRing(A) # optional - sage.combinat sage.modules - sage: f = R.random_element(randint(10,100)) # optional - sage.combinat sage.modules - sage: g = R.random_element(randint(10,100)) # optional - sage.combinat sage.modules - sage: f._mul_generic(g) == f._mul_karatsuba(g,0) # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: A. = QuaternionAlgebra(QQ, -1,-1) + sage: R. = PolynomialRing(A) + sage: f = R.random_element(randint(10,100)) + sage: g = R.random_element(randint(10,100)) + sage: f._mul_generic(g) == f._mul_karatsuba(g,0) True - sage: f._mul_generic(g) == f._mul_karatsuba(g,16) # optional - sage.combinat sage.modules + sage: f._mul_generic(g) == f._mul_karatsuba(g,16) True - sage: g = R.random_element(0) # optional - sage.combinat sage.modules - sage: f._mul_karatsuba(g,0) == f._mul_generic(g) # optional - sage.combinat sage.modules + sage: g = R.random_element(0) + sage: f._mul_karatsuba(g,0) == f._mul_generic(g) True - sage: g._mul_karatsuba(f,0) == g._mul_generic(f) # optional - sage.combinat sage.modules + sage: g._mul_karatsuba(f,0) == g._mul_generic(f) True Polynomials over matrices:: - sage: K = PolynomialRing(MatrixSpace(QQ, 2), 'x') # optional - sage.modules - sage: f = K.random_element(randint(5, 10)) # optional - sage.modules - sage: g = K.random_element(randint(5, 10)) # optional - sage.modules - sage: h1 = f._mul_generic(g) # optional - sage.modules - sage: h2 = f._mul_karatsuba(g,randint(0, 10)) # optional - sage.modules - sage: h1 == h2 # optional - sage.modules + sage: # needs sage.modules + sage: K = PolynomialRing(MatrixSpace(QQ, 2), 'x') + sage: f = K.random_element(randint(5, 10)) + sage: g = K.random_element(randint(5, 10)) + sage: h1 = f._mul_generic(g) + sage: h2 = f._mul_karatsuba(g,randint(0, 10)) + sage: h1 == h2 True """ if self.is_zero(): @@ -3326,11 +3361,11 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 - 17*x + 3 - sage: f.base_extend(GF(7)) # optional - sage.rings.finite_rings + sage: f.base_extend(GF(7)) Traceback (most recent call last): ... TypeError: no such base extension - sage: f.change_ring(GF(7)) # optional - sage.rings.finite_rings + sage: f.change_ring(GF(7)) x^3 + 4*x + 3 """ S = self._parent.base_extend(R) @@ -3349,6 +3384,8 @@ cdef class Polynomial(CommutativePolynomial): sage: f.change_variable_name('theta') -2/7*theta^3 + 2/3*theta - 19/993 """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self._parent.base_ring(), names=var) return R(self) @@ -3363,24 +3400,25 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: f = K.defining_polynomial() # optional - sage.rings.number_field - sage: f.change_ring(GF(7)) # optional - sage.rings.finite_rings # optional - sage.rings.number_field + sage: K. = CyclotomicField(3) # needs sage.rings.number_field + sage: f = K.defining_polynomial() # needs sage.rings.number_field + sage: f.change_ring(GF(7)) # needs sage.rings.finite_rings sage.rings.number_field x^2 + x + 1 :: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: f = x^2 + z # optional - sage.rings.number_field - sage: f.change_ring(K.embeddings(CC)[1]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: R. = K[] + sage: f = x^2 + z + sage: f.change_ring(K.embeddings(CC)[1]) # needs sage.rings.real_mpfr x^2 - 0.500000000000000 - 0.866025403784438*I :: sage: R. = QQ[] sage: f = x^2 + 1 - sage: f.change_ring(QQ.embeddings(CC)[0]) + sage: f.change_ring(QQ.embeddings(CC)[0]) # needs sage.rings.real_mpfr x^2 + 1.00000000000000 TESTS: @@ -3388,17 +3426,18 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`25022` is fixed:: sage: K. = ZZ[] - sage: x.change_ring(SR) == SR['x'].gen() # optional - sage.symbolic + sage: x.change_ring(SR) == SR['x'].gen() # needs sage.symbolic True sage: x.change_ring(ZZ['x']) == ZZ['x']['x'].gen() True Check that :trac:`28541` is fixed:: - sage: F. = GF(7^2) # optional - sage.rings.finite_rings - sage: S. = F[] # optional - sage.rings.finite_rings - sage: P = x^2 + a*x + a^2 # optional - sage.rings.finite_rings - sage: P.change_ring(F.frobenius_endomorphism()) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = GF(7^2) + sage: S. = F[] + sage: P = x^2 + a*x + a^2 + sage: P.change_ring(F.frobenius_endomorphism()) x^2 + (6*a + 1)*x + 6*a + 5 """ if isinstance(R, Map): @@ -3597,15 +3636,15 @@ cdef class Polynomial(CommutativePolynomial): Check that the denominator is an element over the base whenever the base has no :meth:`denominator` method. This closes :trac:`9063`. :: - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: x = R(0) # optional - sage.rings.finite_rings - sage: x.denominator() # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: x = R(0) + sage: x.denominator() 1 - sage: type(x.denominator()) # optional - sage.rings.finite_rings + sage: type(x.denominator()) - sage: isinstance(x.numerator() / x.denominator(), Polynomial) # optional - sage.rings.finite_rings + sage: isinstance(x.numerator() / x.denominator(), Polynomial) True - sage: isinstance(x.numerator() / R(1), Polynomial) # optional - sage.rings.finite_rings + sage: isinstance(x.numerator() / R(1), Polynomial) False TESTS: @@ -3687,10 +3726,12 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: K = NumberField(symbolic_expression('x^3+2'), 'a')['s,t']['x'] # optional - sage.rings.number_field sage.symbolic - sage: f = K.random_element() # optional - sage.rings.number_field sage.symbolic - sage: f.numerator() / f.denominator() == f # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: K = NumberField(symbolic_expression('x^3+2'), 'a')['s,t']['x'] + sage: f = K.random_element() + sage: f.numerator() / f.denominator() == f True + sage: R = RR['x'] sage: f = R.random_element() sage: f.numerator() / f.denominator() == f @@ -3802,17 +3843,19 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`28147` is fixed:: - sage: R. = GF(65537)[] # optional - sage.rings.finite_rings - sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 # optional - sage.rings.finite_rings - sage: p.derivative() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(65537)[] + sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 + sage: p.derivative() 4*x^3 + 65486*x^2 + 4*x + 65536 - sage: R. = GF(19^2)[] # optional - sage.rings.finite_rings - sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 # optional - sage.rings.finite_rings - sage: p.derivative() # optional - sage.rings.finite_rings + sage: R. = GF(19^2)[] + sage: p = x^4 - 17*x^3 + 2*x^2 - x + 7 + sage: p.derivative() 4*x^3 + 6*x^2 + 4*x + 18 - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: p = x^4 + x^2 + x # optional - sage.rings.finite_rings - sage: p.derivative() # optional - sage.rings.finite_rings + + sage: R. = GF(2)[] + sage: p = x^4 + x^2 + x + sage: p.derivative() 1 sage: R. = Integers(77)[] @@ -3827,8 +3870,9 @@ cdef class Polynomial(CommutativePolynomial): ... ValueError: cannot differentiate with respect to 2*x - sage: y = var("y") # optional - sage.symbolic - sage: f._derivative(y) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: y = var("y") + sage: f._derivative(y) Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -3836,21 +3880,23 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`26844` is fixed by :trac:`28147`:: - sage: A = PolynomialRing(GF(3), name='t') # optional - sage.rings.finite_rings - sage: K = A.fraction_field() # optional - sage.rings.finite_rings - sage: t = K.gen() # optional - sage.rings.finite_rings - sage: t.derivative(t) # optional - sage.rings.finite_rings + sage: A = PolynomialRing(GF(3), name='t') + sage: K = A.fraction_field() + sage: t = K.gen() + sage: t.derivative(t) 1 Check that :trac:`28187` is fixed:: - sage: R. = GF(65537)[] # optional - sage.rings.finite_rings - sage: x._derivative(2*x) # optional - sage.rings.finite_rings + sage: R. = GF(65537)[] # needs sage.rings.finite_rings + sage: x._derivative(2*x) Traceback (most recent call last): ... ValueError: cannot differentiate with respect to 2*x - sage: y = var('y') # optional - sage.symbolic - sage: R.gen()._derivative(y) # optional - sage.rings.finite_rings sage.symbolic + + sage: # needs sage.symbolic + sage: y = var('y') + sage: R.gen()._derivative(y) Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -3927,16 +3973,18 @@ cdef class Polynomial(CommutativePolynomial): This shows that the issue at :trac:`7711` is resolved:: - sage: P. = PolynomialRing(GF(2147483647)) # optional - sage.rings.finite_rings - sage: Q. = PolynomialRing(P) # optional - sage.rings.finite_rings - sage: p = x + y + z # optional - sage.rings.finite_rings - sage: p.integral() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(2147483647)) + sage: Q. = PolynomialRing(P) + sage: p = x + y + z + sage: p.integral() -1073741823*y^2 + (x + z)*y - sage: P. = PolynomialRing(GF(next_prime(2147483647))) # optional - sage.rings.finite_rings - sage: Q. = PolynomialRing(P) # optional - sage.rings.finite_rings - sage: p = x + y + z # optional - sage.rings.finite_rings - sage: p.integral() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(next_prime(2147483647))) + sage: Q. = PolynomialRing(P) + sage: p = x + y + z + sage: p.integral() 1073741830*y^2 + (x + z)*y A truly convoluted example:: @@ -4069,39 +4117,40 @@ cdef class Polynomial(CommutativePolynomial): sage: x = QQ['x'].0 sage: f = (x^3 - 1)^2 - sage: f.factor() # optional - sage.libs.pari + sage: f.factor() # needs sage.libs.pari (x - 1)^2 * (x^2 + x + 1)^2 Since `\QQ` is a field, the irreducible factors are monic:: sage: f = 10*x^5 - 1 - sage: f.factor() # optional - sage.libs.pari + sage: f.factor() # needs sage.libs.pari (10) * (x^5 - 1/10) sage: f = 10*x^5 - 10 - sage: f.factor() # optional - sage.libs.pari + sage: f.factor() # needs sage.libs.pari (10) * (x - 1) * (x^4 + x^3 + x^2 + x + 1) Over `\ZZ` the irreducible factors need not be monic:: sage: x = ZZ['x'].0 sage: f = 10*x^5 - 1 - sage: f.factor() # optional - sage.libs.pari + sage: f.factor() # needs sage.libs.pari 10*x^5 - 1 We factor a non-monic polynomial over a finite field of 25 elements:: - sage: k. = GF(25) # optional - sage.rings.finite_rings - sage: R. = k[] # optional - sage.rings.finite_rings - sage: f = 2*x^10 + 2*x + 2*a # optional - sage.rings.finite_rings - sage: F = f.factor(); F # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(25) + sage: R. = k[] + sage: f = 2*x^10 + 2*x + 2*a + sage: F = f.factor(); F (2) * (x + a + 2) * (x^2 + 3*x + 4*a + 4) * (x^2 + (a + 1)*x + a + 2) * (x^5 + (3*a + 4)*x^4 + (3*a + 3)*x^3 + 2*a*x^2 + (3*a + 1)*x + 3*a + 1) Notice that the unit factor is included when we multiply `F` back out:: - sage: expand(F) # optional - sage.rings.finite_rings + sage: expand(F) # needs sage.rings.finite_rings sage.symbolic 2*x^10 + 2*x + 2*a A new ring. In the example below, we set the special method @@ -4110,21 +4159,23 @@ cdef class Polynomial(CommutativePolynomial): used to easily extend polynomial factorization to work over new rings you introduce:: - sage: R. = PolynomialRing(IntegerModRing(4), implementation="NTL") # optional - sage.libs.ntl - sage: (x^2).factor() # optional - sage.libs.ntl + sage: # needs sage.libs.ntl + sage: R. = PolynomialRing(IntegerModRing(4), implementation="NTL") + sage: (x^2).factor() Traceback (most recent call last): ... NotImplementedError: factorization of polynomials over rings with composite characteristic is not implemented sage: def my_factor(f): ....: return f.change_ring(ZZ).factor() - sage: R.base_ring()._factor_univariate_polynomial = my_factor # optional - sage.libs.ntl - sage: (x^2).factor() # optional - sage.libs.ntl sage.libs.pari + sage: R.base_ring()._factor_univariate_polynomial = my_factor + sage: (x^2).factor() # needs sage.libs.pari x^2 - sage: del R.base_ring()._factor_univariate_polynomial # clean up # optional - sage.libs.ntl + sage: del R.base_ring()._factor_univariate_polynomial # clean up Arbitrary precision real and complex factorization:: + sage: # needs sage.libs.pari sage.rings.real_mpfr sage: R. = RealField(100)[] sage: F = factor(x^2 - 3); F (x - 1.7320508075688772935274463415) * (x + 1.7320508075688772935274463415) @@ -4133,6 +4184,7 @@ cdef class Polynomial(CommutativePolynomial): sage: factor(x^2 + 1) x^2 + 1.0000000000000000000000000000 + sage: # needs sage.libs.pari sage.rings.real_mpfr sage: R. = ComplexField(100)[] sage: F = factor(x^2 + 3); F (x - 1.7320508075688772935274463415*I) * (x + 1.7320508075688772935274463415*I) @@ -4149,30 +4201,33 @@ cdef class Polynomial(CommutativePolynomial): Over a number field:: - sage: K. = CyclotomicField(15) # optional - sage.rings.number_field - sage: x = polygen(K) # optional - sage.rings.number_field - sage: ((x^3 + z*x + 1)^3 * (x - z)).factor() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(15) + sage: x = polygen(K) + sage: ((x^3 + z*x + 1)^3 * (x - z)).factor() (x - z) * (x^3 + z*x + 1)^3 - sage: cyclotomic_polynomial(12).change_ring(K).factor() # optional - sage.rings.number_field + sage: cyclotomic_polynomial(12).change_ring(K).factor() (x^2 - z^5 - 1) * (x^2 + z^5) - sage: ((x^3 + z*x + 1)^3 * (x/(z+2) - 1/3)).factor() # optional - sage.rings.number_field + sage: ((x^3 + z*x + 1)^3 * (x/(z+2) - 1/3)).factor() (-1/331*z^7 + 3/331*z^6 - 6/331*z^5 + 11/331*z^4 - 21/331*z^3 + 41/331*z^2 - 82/331*z + 165/331) * (x - 1/3*z - 2/3) * (x^3 + z*x + 1)^3 Over a relative number field:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: L. = K.extension(x^3 - 2) # optional - sage.rings.number_field - sage: t = polygen(L, 't') # optional - sage.rings.number_field - sage: f = (t^3 + t + a) * (t^5 + t + z); f # optional - sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: L. = K.extension(x^3 - 2) + sage: t = polygen(L, 't') + sage: f = (t^3 + t + a) * (t^5 + t + z); f t^8 + t^6 + a*t^5 + t^4 + z*t^3 + t^2 + (a + z)*t + z*a - sage: f.factor() # optional - sage.rings.number_field + sage: f.factor() (t^3 + t + a) * (t^5 + t + z) Over the real double field:: + sage: # needs numpy sage: R. = RDF[] sage: (-2*x^2 - 1).factor() (-2.0) * (x^2 + 0.5000000000000001) @@ -4186,19 +4241,24 @@ cdef class Polynomial(CommutativePolynomial): :meth:`.roots` method, which does not detect that all the roots are real:: - sage: f.roots() # abs tol 2e-5 + sage: f.roots() # abs tol 2e-5 # needs numpy [(1.0000065719436413, 1)] Over the complex double field the factors are approximate and therefore occur with multiplicity 1:: + sage: # needs numpy sage.rings.complex_double sage: R. = CDF[] sage: f = (x^2 + 2*R(I))^3 sage: F = f.factor() sage: F # abs tol 3e-5 - (x - 1.0000138879287663 + 1.0000013435286879*I) * (x - 0.9999942196864997 + 0.9999873009803959*I) * (x - 0.9999918923847313 + 1.0000113554909125*I) - * (x + 0.9999908759550227 - 1.0000069659624138*I) * (x + 0.9999985293216753 - 0.9999886153831807*I) * (x + 1.0000105947233 - 1.0000044186544053*I) - sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-13 + (x - 1.0000138879287663 + 1.0000013435286879*I) + * (x - 0.9999942196864997 + 0.9999873009803959*I) + * (x - 0.9999918923847313 + 1.0000113554909125*I) + * (x + 0.9999908759550227 - 1.0000069659624138*I) + * (x + 0.9999985293216753 - 0.9999886153831807*I) + * (x + 1.0000105947233 - 1.0000044186544053*I) + sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-13 [1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14, 3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14] @@ -4216,8 +4276,8 @@ cdef class Polynomial(CommutativePolynomial): Factoring polynomials over the algebraic numbers (see :trac:`8544`):: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x^8 - 1).factor() # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: (x^8 - 1).factor() # needs sage.rings.number_field (x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I) * (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I) * (x + 0.7071067811865475? - 0.7071067811865475?*I) @@ -4226,8 +4286,8 @@ cdef class Polynomial(CommutativePolynomial): Factoring polynomials over the algebraic reals (see :trac:`8544`):: - sage: R. = AA[] # optional - sage.rings.number_field - sage: (x^8 + 1).factor() # optional - sage.rings.number_field + sage: R. = AA[] # needs sage.rings.number_field + sage: (x^8 + 1).factor() # needs sage.rings.number_field (x^2 - 1.847759065022574?*x + 1.000000000000000?) * (x^2 - 0.7653668647301795?*x + 1.000000000000000?) * (x^2 + 0.7653668647301795?*x + 1.000000000000000?) @@ -4237,38 +4297,50 @@ cdef class Polynomial(CommutativePolynomial): This came up in :trac:`7088`:: - sage: R.=PolynomialRing(ZZ) + sage: R. = PolynomialRing(ZZ) sage: f = 12*x^10 + x^9 + 432*x^3 + 9011 sage: g = 13*x^11 + 89*x^3 + 1 sage: F = f^2 * g^3 - sage: F = f^2 * g^3; F.factor() + sage: F = f^2 * g^3; F.factor() # needs sage.libs.pari (12*x^10 + x^9 + 432*x^3 + 9011)^2 * (13*x^11 + 89*x^3 + 1)^3 - sage: F = f^2 * g^3 * 7; F.factor() + sage: F = f^2 * g^3 * 7; F.factor() # needs sage.libs.pari 7 * (12*x^10 + x^9 + 432*x^3 + 9011)^2 * (13*x^11 + 89*x^3 + 1)^3 This example came up in :trac:`7097`:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) sage: f = 8*x^9 + 42*x^6 + 6*x^3 - 1 - sage: g = x^24 - 12*x^23 + 72*x^22 - 286*x^21 + 849*x^20 - 2022*x^19 + 4034*x^18 - 6894*x^17 + 10182*x^16 - 13048*x^15 + 14532*x^14 - 13974*x^13 + 11365*x^12 - 7578*x^11 + 4038*x^10 - 1766*x^9 + 762*x^8 - 408*x^7 + 236*x^6 - 126*x^5 + 69*x^4 - 38*x^3 + 18*x^2 - 6*x + 1 - sage: assert g.is_irreducible() - sage: K. = NumberField(g) # optional - sage.rings.number_field - sage: len(f.roots(K)) # optional - sage.rings.number_field + sage: g = (x^24 - 12*x^23 + 72*x^22 - 286*x^21 + 849*x^20 - 2022*x^19 + 4034*x^18 + ....: - 6894*x^17 + 10182*x^16 - 13048*x^15 + 14532*x^14 - 13974*x^13 + ....: + 11365*x^12 - 7578*x^11 + 4038*x^10 - 1766*x^9 + 762*x^8 - 408*x^7 + ....: + 236*x^6 - 126*x^5 + 69*x^4 - 38*x^3 + 18*x^2 - 6*x + 1) + sage: assert g.is_irreducible() # needs sage.libs.pari + sage: K. = NumberField(g) + sage: len(f.roots(K)) 9 - sage: f.factor() + sage: f.factor() # needs sage.libs.pari (8) * (x^3 + 1/4) * (x^6 + 5*x^3 - 1/2) - sage: f.change_ring(K).factor() # optional - sage.rings.number_field - (8) * (x - 3260097/3158212*a^22 + 35861067/3158212*a^21 - 197810817/3158212*a^20 + 722970825/3158212*a^19 - 1980508347/3158212*a^18 + 4374189477/3158212*a^17 - 4059860553/1579106*a^16 + 6442403031/1579106*a^15 - 17542341771/3158212*a^14 + 20537782665/3158212*a^13 - 20658463789/3158212*a^12 + 17502836649/3158212*a^11 - 11908953451/3158212*a^10 + 6086953981/3158212*a^9 - 559822335/789553*a^8 + 194545353/789553*a^7 - 505969453/3158212*a^6 + 338959407/3158212*a^5 - 155204647/3158212*a^4 + 79628015/3158212*a^3 - 57339525/3158212*a^2 + 26692783/3158212*a - 1636338/789553) * ... - sage: f = QQbar['x'](1) # optional - sage.rings.number_field - sage: f.factor() # optional - sage.rings.number_field + sage: f.change_ring(K).factor() + (8) * (x - 3260097/3158212*a^22 + 35861067/3158212*a^21 - 197810817/3158212*a^20 + + 722970825/3158212*a^19 - 1980508347/3158212*a^18 + 4374189477/3158212*a^17 + - 4059860553/1579106*a^16 + 6442403031/1579106*a^15 - 17542341771/3158212*a^14 + + 20537782665/3158212*a^13 - 20658463789/3158212*a^12 + 17502836649/3158212*a^11 + - 11908953451/3158212*a^10 + 6086953981/3158212*a^9 - 559822335/789553*a^8 + + 194545353/789553*a^7 - 505969453/3158212*a^6 + 338959407/3158212*a^5 + - 155204647/3158212*a^4 + 79628015/3158212*a^3 - 57339525/3158212*a^2 + + 26692783/3158212*a - 1636338/789553) * ... + sage: f = QQbar['x'](1) + sage: f.factor() 1 Factorization also works even if the variable of the finite field is nefariously labeled `x`:: - sage: R. = GF(3^2, 'x')[] # optional - sage.rings.finite_rings - sage: f = x^10 +7*x -13 # optional - sage.rings.finite_rings - sage: G = f.factor(); G # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(3^2, 'x')[] + sage: f = x^10 + 7*x - 13 + sage: G = f.factor(); G (x + x) * (x + 2*x + 1) * (x^4 + (x + 2)*x^3 + (2*x + 2)*x + 2) * (x^4 + 2*x*x^3 + (x + 1)*x + 2) sage: prod(G) == f @@ -4276,70 +4348,70 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: R. = GF(9,'x')[] # purposely calling it x to test robustness # optional - sage.rings.finite_rings - sage: f = x0^3 + x0 + 1 # optional - sage.rings.finite_rings - sage: f.factor() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(9,'x')[] # purposely calling it x to test robustness + sage: f = x0^3 + x0 + 1 + sage: f.factor() (x0 + 2) * (x0 + x) * (x0 + 2*x + 1) - sage: f = 0*x0 # optional - sage.rings.finite_rings - sage: f.factor() # optional - sage.rings.finite_rings + sage: f = 0*x0 + sage: f.factor() Traceback (most recent call last): ... ArithmeticError: factorization of 0 is not defined :: - sage: f = x0^0 # optional - sage.rings.finite_rings - sage: f.factor() # optional - sage.rings.finite_rings + sage: f = x0^0 # needs sage.rings.finite_rings + sage: f.factor() # needs sage.rings.finite_rings 1 Over a complicated number field:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ, 'x') sage: f = x^6 + 10/7*x^5 - 867/49*x^4 - 76/245*x^3 + 3148/35*x^2 - 25944/245*x + 48771/1225 - sage: K. = NumberField(f) # optional - sage.rings.number_field - sage: S. = K[] # optional - sage.rings.number_field - sage: ff = S(f); ff # optional - sage.rings.number_field + sage: K. = NumberField(f) + sage: S. = K[] + sage: ff = S(f); ff T^6 + 10/7*T^5 - 867/49*T^4 - 76/245*T^3 + 3148/35*T^2 - 25944/245*T + 48771/1225 - sage: F = ff.factor() # optional - sage.rings.number_field - sage: len(F) # optional - sage.rings.number_field + sage: F = ff.factor() + sage: len(F) 4 - sage: F[:2] # optional - sage.rings.number_field + sage: F[:2] [(T - a, 1), - (T - 40085763200/924556084127*a^5 - 145475769880/924556084127*a^4 + 527617096480/924556084127*a^3 - + 1289745809920/924556084127*a^2 - 3227142391585/924556084127*a - 401502691578/924556084127, 1)] - sage: expand(F) # optional - sage.rings.number_field + (T - 40085763200/924556084127*a^5 - 145475769880/924556084127*a^4 + + 527617096480/924556084127*a^3 + 1289745809920/924556084127*a^2 + - 3227142391585/924556084127*a - 401502691578/924556084127, 1)] + sage: expand(F) T^6 + 10/7*T^5 - 867/49*T^4 - 76/245*T^3 + 3148/35*T^2 - 25944/245*T + 48771/1225 :: + sage: # needs sage.rings.number_field sage: f = x^2 - 1/3 - sage: K. = NumberField(f) # optional - sage.rings.number_field - sage: A. = K[] # optional - sage.rings.number_field - sage: A(x^2 - 1).factor() # optional - sage.rings.number_field + sage: K. = NumberField(f) + sage: A. = K[] + sage: A(x^2 - 1).factor() (T - 1) * (T + 1) - - :: - - sage: A(3*x^2 - 1).factor() # optional - sage.rings.number_field + sage: A(3*x^2 - 1).factor() (3) * (T - a) * (T + a) - - :: - - sage: A(x^2 - 1/3).factor() # optional - sage.rings.number_field + sage: A(x^2 - 1/3).factor() (T - a) * (T + a) Test that :trac:`10279` is fixed:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(t^4 - t^2 + 1) # optional - sage.rings.number_field - sage: pol = t^3 + (-4*a^3 + 2*a)*t^2 - 11/3*a^2*t + 2/3*a^3 - 4/3*a # optional - sage.rings.number_field - sage: pol.factor() # optional - sage.rings.number_field + sage: K. = NumberField(t^4 - t^2 + 1) + sage: pol = t^3 + (-4*a^3 + 2*a)*t^2 - 11/3*a^2*t + 2/3*a^3 - 4/3*a + sage: pol.factor() (t - 2*a^3 + a) * (t - 4/3*a^3 + 2/3*a) * (t - 2/3*a^3 + 1/3*a) Test that this factorization really uses ``nffactor()`` internally:: + sage: # needs sage.libs.pari sage.rings.number_field sage: pari.default("debug", 3) - sage: F = pol.factor() # optional - sage.rings.number_field + sage: F = pol.factor() Entering nffactor: ... @@ -4347,56 +4419,86 @@ cdef class Polynomial(CommutativePolynomial): Test that :trac:`10369` is fixed:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: K. = NumberField(x^6 + x^5 + x^4 + x^3 + x^2 + x + 1) # optional - sage.rings.number_field - sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - - sage: pol = (-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7)*t^10 + (4/7*a^5 - 2/7*a^4 - 2/7*a^3 - 2/7*a^2 - 2/7*a - 6/7)*t^9 + (90/49*a^5 + 152/49*a^4 + 18/49*a^3 + 24/49*a^2 + 30/49*a + 36/49)*t^8 + (-10/49*a^5 + 10/7*a^4 + 198/49*a^3 - 102/49*a^2 - 60/49*a - 26/49)*t^7 + (40/49*a^5 + 45/49*a^4 + 60/49*a^3 + 277/49*a^2 - 204/49*a - 78/49)*t^6 + (90/49*a^5 + 110/49*a^4 + 2*a^3 + 80/49*a^2 + 46/7*a - 30/7)*t^5 + (30/7*a^5 + 260/49*a^4 + 250/49*a^3 + 232/49*a^2 + 32/7*a + 8)*t^4 + (-184/49*a^5 - 58/49*a^4 - 52/49*a^3 - 66/49*a^2 - 72/49*a - 72/49)*t^3 + (18/49*a^5 - 32/49*a^4 + 10/49*a^3 + 4/49*a^2)*t^2 + (2/49*a^4 - 4/49*a^3 + 2/49*a^2)*t # optional - sage.rings.number_field - sage: pol.factor() # optional - sage.rings.number_field - (-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7) * t * (t - a^5 - a^4 - a^3 - a^2 - a - 1)^4 * (t^5 + (-12/7*a^5 - 10/7*a^4 - 8/7*a^3 - 6/7*a^2 - 4/7*a - 2/7)*t^4 + (12/7*a^5 - 8/7*a^3 + 16/7*a^2 + 2/7*a + 20/7)*t^3 + (-20/7*a^5 - 20/7*a^3 - 20/7*a^2 + 4/7*a - 2)*t^2 + (12/7*a^5 + 12/7*a^3 + 2/7*a + 16/7)*t - 4/7*a^5 - 4/7*a^3 - 4/7*a - 2/7) - - sage: pol = (1/7*a^2 - 1/7*a)*t^10 + (4/7*a - 6/7)*t^9 + (102/49*a^5 + 99/49*a^4 + 96/49*a^3 + 93/49*a^2 + 90/49*a + 150/49)*t^8 + (-160/49*a^5 - 36/49*a^4 - 48/49*a^3 - 8/7*a^2 - 60/49*a - 60/49)*t^7 + (30/49*a^5 - 55/49*a^4 + 20/49*a^3 + 5/49*a^2)*t^6 + (6/49*a^4 - 12/49*a^3 + 6/49*a^2)*t^5 # optional - sage.rings.number_field - sage: pol.factor() # optional - sage.rings.number_field - (1/7*a^2 - 1/7*a) * t^5 * (t^5 + (-40/7*a^5 - 38/7*a^4 - 36/7*a^3 - 34/7*a^2 - 32/7*a - 30/7)*t^4 + (60/7*a^5 - 30/7*a^4 - 18/7*a^3 - 9/7*a^2 - 3/7*a)*t^3 + (60/7*a^4 - 40/7*a^3 - 16/7*a^2 - 4/7*a)*t^2 + (30/7*a^3 - 25/7*a^2 - 5/7*a)*t + 6/7*a^2 - 6/7*a) - - sage: pol = x^10 + (4/7*a - 6/7)*x^9 + (9/49*a^2 - 3/7*a + 15/49)*x^8 + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^7 + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x^6 + (-6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807)*x^5 # optional - sage.rings.number_field - sage: pol.factor() # optional - sage.rings.number_field - x^5 * (x^5 + (4/7*a - 6/7)*x^4 + (9/49*a^2 - 3/7*a + 15/49)*x^3 + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^2 + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x - 6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807) + sage: K. = NumberField(x^6 + x^5 + x^4 + x^3 + x^2 + x + 1) + sage: R. = PolynomialRing(K) + sage: pol = ((-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7)*t^10 + ....: + (4/7*a^5 - 2/7*a^4 - 2/7*a^3 - 2/7*a^2 - 2/7*a - 6/7)*t^9 + ....: + (90/49*a^5 + 152/49*a^4 + 18/49*a^3 + 24/49*a^2 + 30/49*a + 36/49)*t^8 + ....: + (-10/49*a^5 + 10/7*a^4 + 198/49*a^3 - 102/49*a^2 - 60/49*a - 26/49)*t^7 + ....: + (40/49*a^5 + 45/49*a^4 + 60/49*a^3 + 277/49*a^2 - 204/49*a - 78/49)*t^6 + ....: + (90/49*a^5 + 110/49*a^4 + 2*a^3 + 80/49*a^2 + 46/7*a - 30/7)*t^5 + ....: + (30/7*a^5 + 260/49*a^4 + 250/49*a^3 + 232/49*a^2 + 32/7*a + 8)*t^4 + ....: + (-184/49*a^5 - 58/49*a^4 - 52/49*a^3 - 66/49*a^2 - 72/49*a - 72/49)*t^3 + ....: + (18/49*a^5 - 32/49*a^4 + 10/49*a^3 + 4/49*a^2)*t^2 + ....: + (2/49*a^4 - 4/49*a^3 + 2/49*a^2)*t) + sage: pol.factor() + (-1/7*a^5 - 1/7*a^4 - 1/7*a^3 - 1/7*a^2 - 2/7*a - 1/7) * t + * (t - a^5 - a^4 - a^3 - a^2 - a - 1)^4 + * (t^5 + (-12/7*a^5 - 10/7*a^4 - 8/7*a^3 - 6/7*a^2 - 4/7*a - 2/7)*t^4 + + (12/7*a^5 - 8/7*a^3 + 16/7*a^2 + 2/7*a + 20/7)*t^3 + + (-20/7*a^5 - 20/7*a^3 - 20/7*a^2 + 4/7*a - 2)*t^2 + + (12/7*a^5 + 12/7*a^3 + 2/7*a + 16/7)*t + - 4/7*a^5 - 4/7*a^3 - 4/7*a - 2/7) + sage: pol = ((1/7*a^2 - 1/7*a)*t^10 + (4/7*a - 6/7)*t^9 + ....: + (102/49*a^5 + 99/49*a^4 + 96/49*a^3 + 93/49*a^2 + 90/49*a + 150/49)*t^8 + ....: + (-160/49*a^5 - 36/49*a^4 - 48/49*a^3 - 8/7*a^2 - 60/49*a - 60/49)*t^7 + ....: + (30/49*a^5 - 55/49*a^4 + 20/49*a^3 + 5/49*a^2)*t^6 + ....: + (6/49*a^4 - 12/49*a^3 + 6/49*a^2)*t^5) + sage: pol.factor() + (1/7*a^2 - 1/7*a) * t^5 + * (t^5 + (-40/7*a^5 - 38/7*a^4 - 36/7*a^3 - 34/7*a^2 - 32/7*a - 30/7)*t^4 + + (60/7*a^5 - 30/7*a^4 - 18/7*a^3 - 9/7*a^2 - 3/7*a)*t^3 + + (60/7*a^4 - 40/7*a^3 - 16/7*a^2 - 4/7*a)*t^2 + + (30/7*a^3 - 25/7*a^2 - 5/7*a)*t + 6/7*a^2 - 6/7*a) + sage: pol = (x^10 + (4/7*a - 6/7)*x^9 + (9/49*a^2 - 3/7*a + 15/49)*x^8 + ....: + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^7 + ....: + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x^6 + ....: + (-6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807)*x^5) + sage: pol.factor() + x^5 * (x^5 + (4/7*a - 6/7)*x^4 + (9/49*a^2 - 3/7*a + 15/49)*x^3 + + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^2 + + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x + - 6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807) Factoring over a number field over which we cannot factor the discriminant by trial division:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: K. = NumberField(x^16 - x - 6) # optional - sage.rings.number_field - sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - sage: f = (x+a)^50 - (a-1)^50 # optional - sage.rings.number_field - sage: len(factor(f)) # optional - sage.rings.number_field + sage: K. = NumberField(x^16 - x - 6) + sage: R. = PolynomialRing(K) + sage: f = (x+a)^50 - (a-1)^50 + sage: len(factor(f)) 6 - sage: pari(K.discriminant()).factor(limit=10^6) # optional - sage.rings.number_field + sage: pari(K.discriminant()).factor(limit=10^6) [-1, 1; 3, 15; 23, 1; 887, 1; 12583, 1; 2354691439917211, 1] - sage: factor(K.discriminant()) # optional - sage.rings.number_field + sage: factor(K.discriminant()) -1 * 3^15 * 23 * 887 * 12583 * 6335047 * 371692813 Factoring over a number field over which we cannot factor the discriminant and over which `nffactor()` fails:: + sage: # needs sage.libs.pari sage.rings.number_field sage: p = next_prime(10^50); q = next_prime(10^51); n = p*q - sage: K. = QuadraticField(p*q) # optional - sage.rings.number_field - sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - sage: K.pari_polynomial('a').nffactor("x^2+1") # optional - sage.rings.number_field + sage: K. = QuadraticField(p*q) + sage: R. = PolynomialRing(K) + sage: K.pari_polynomial('a').nffactor("x^2+1") Mat([x^2 + 1, 1]) - sage: factor(x^2 + 1) # optional - sage.rings.number_field + sage: factor(x^2 + 1) x^2 + 1 - sage: factor((x - a) * (x + 2*a)) # optional - sage.rings.number_field + sage: factor((x - a) * (x + 2*a)) (x - a) * (x + 2*a) A test where nffactor used to fail without a nf structure:: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: K = NumberField([x^2 - 1099511627777, x^3 - 3], 'a') # optional - sage.rings.number_field - sage: x = polygen(K) # optional - sage.rings.number_field - sage: f = x^3 - 3 # optional - sage.rings.number_field - sage: factor(f) # optional - sage.rings.number_field + sage: K = NumberField([x^2 - 1099511627777, x^3 - 3], 'a') + sage: x = polygen(K) + sage: f = x^3 - 3 + sage: factor(f) (x - a1) * (x^2 + a1*x + a1^2) We check that :trac:`7554` is fixed:: @@ -4404,7 +4506,7 @@ cdef class Polynomial(CommutativePolynomial): sage: L. = LaurentPolynomialRing(QQ) sage: F = L.fraction_field() sage: R. = PolynomialRing(F) - sage: factor(x) + sage: factor(x) # needs sage.libs.pari x sage: factor(x^2 - q^2) (x - q) * (x + q) @@ -4576,35 +4678,38 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: R.=PolynomialRing(ZZ) + sage: # needs sage.libs.pari + sage: R. = PolynomialRing(ZZ) sage: f = (2*x + 1) * (3*x^2 - 5)^2 - sage: f._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari + sage: f._factor_pari_helper(pari(f).factor()) (2*x + 1) * (3*x^2 - 5)^2 - sage: f._factor_pari_helper(pari(f).factor(), unit=11) # optional - sage.libs.pari + sage: f._factor_pari_helper(pari(f).factor(), unit=11) 11 * (2*x + 1) * (3*x^2 - 5)^2 - sage: (8*f)._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari + sage: (8*f)._factor_pari_helper(pari(f).factor()) 8 * (2*x + 1) * (3*x^2 - 5)^2 - sage: (8*f)._factor_pari_helper(pari(f).factor(), unit=11) # optional - sage.libs.pari + sage: (8*f)._factor_pari_helper(pari(f).factor(), unit=11) 88 * (2*x + 1) * (3*x^2 - 5)^2 - sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari + sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) (18) * (x + 1/2) * (x^2 - 5/3)^2 - sage: QQ['x'](f)._factor_pari_helper(pari(f).factor(), unit=11) # optional - sage.libs.pari + sage: QQ['x'](f)._factor_pari_helper(pari(f).factor(), unit=11) (198) * (x + 1/2) * (x^2 - 5/3)^2 - sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) # optional - sage.libs.pari - sage: F = f._factor_pari_helper(pari(f).factor()); F # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: f = prod((k^2*x^k + k)^(k-1) for k in primes(10)) + sage: F = f._factor_pari_helper(pari(f).factor()); F 1323551250 * (2*x^2 + 1) * (3*x^3 + 1)^2 * (5*x^5 + 1)^4 * (7*x^7 + 1)^6 - sage: F.prod() == f # optional - sage.libs.pari + sage: F.prod() == f True - sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) # optional - sage.libs.pari + sage: QQ['x'](f)._factor_pari_helper(pari(f).factor()) (1751787911376562500) * (x^2 + 1/2) * (x^3 + 1/3)^2 * (x^5 + 1/5)^4 * (x^7 + 1/7)^6 - sage: g = GF(19)['x'](f) # optional - sage.libs.pari - sage: G = g._factor_pari_helper(pari(g).factor()); G # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: g = GF(19)['x'](f) + sage: G = g._factor_pari_helper(pari(g).factor()); G (4) * (x + 3) * (x + 16)^5 * (x + 11)^6 * (x^2 + 7*x + 9)^4 * (x^2 + 15*x + 9)^4 * (x^3 + 13)^2 * (x^6 + 8*x^5 + 7*x^4 + 18*x^3 + 11*x^2 + 12*x + 1)^6 - sage: G.prod() == g # optional - sage.libs.pari + sage: G.prod() == g True """ pols, exps = G @@ -4665,26 +4770,27 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: K. = (x^3 + 2).splitting_field(); K # optional - sage.rings.number_field + sage: K. = (x^3 + 2).splitting_field(); K # needs sage.rings.number_field Number Field in a with defining polynomial x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1 - sage: K. = (x^3 - 3*x + 1).splitting_field(); K # optional - sage.rings.number_field + sage: K. = (x^3 - 3*x + 1).splitting_field(); K # needs sage.rings.number_field Number Field in a with defining polynomial x^3 - 3*x + 1 Relative situation:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3 + 2) # optional - sage.rings.number_field - sage: S. = PolynomialRing(K) # optional - sage.rings.number_field - sage: L. = (t^2 - a).splitting_field() # optional - sage.rings.number_field - sage: L # optional - sage.rings.number_field + sage: K. = NumberField(x^3 + 2) + sage: S. = PolynomialRing(K) + sage: L. = (t^2 - a).splitting_field() + sage: L Number Field in b with defining polynomial t^6 + 2 With ``map=True``, we also get the embedding of the base field into the splitting field:: - sage: L., phi = (t^2 - a).splitting_field(map=True) # optional - sage.rings.number_field - sage: phi # optional - sage.rings.number_field + sage: L., phi = (t^2 - a).splitting_field(map=True) # needs sage.rings.number_field + sage: phi # needs sage.rings.number_field Ring morphism: From: Number Field in a with defining polynomial x^3 + 2 To: Number Field in b with defining polynomial t^6 + 2 @@ -4692,14 +4798,14 @@ cdef class Polynomial(CommutativePolynomial): An example over a finite field:: - sage: P. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: t = x^2 + 1 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(7)) + sage: t = x^2 + 1 + sage: t.splitting_field('b') # needs sage.rings.finite_rings Finite Field in b of size 7^2 - sage: P. = PolynomialRing(GF(7^3, 'a')) # optional - sage.rings.finite_rings - sage: t = x^2 + 1 # optional - sage.rings.finite_rings - sage: t.splitting_field('b', map=True) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(7^3, 'a')) # needs sage.rings.finite_rings + sage: t = x^2 + 1 + sage: t.splitting_field('b', map=True) # needs sage.rings.finite_rings (Finite Field in b of size 7^6, Ring morphism: From: Finite Field in a of size 7^3 @@ -4709,13 +4815,13 @@ cdef class Polynomial(CommutativePolynomial): If the extension is trivial and the generators have the same name, the map will be the identity:: - sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings - sage: t.splitting_field('a', map=True) # optional - sage.rings.finite_rings + sage: t = 24*x^13 + 2*x^12 + 14 + sage: t.splitting_field('a', map=True) # needs sage.rings.finite_rings (Finite Field in a of size 7^3, Identity endomorphism of Finite Field in a of size 7^3) - sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings - sage: t.splitting_field('b', map=True) # optional - sage.rings.finite_rings + sage: t = x^56 - 14*x^3 + sage: t.splitting_field('b', map=True) # needs sage.rings.finite_rings (Finite Field in b of size 7^3, Ring morphism: From: Finite Field in a of size 7^3 @@ -4737,48 +4843,52 @@ cdef class Polynomial(CommutativePolynomial): ... NotImplementedError: splitting_field() is only implemented over number fields and finite fields - sage: P. = PolynomialRing(GF(11^5, 'a')) # optional - sage.rings.finite_rings - sage: t = x^2 + 1 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(11^5, 'a')) + sage: t = x^2 + 1 + sage: t.splitting_field('b') Finite Field in b of size 11^10 - sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = 24*x^13 + 2*x^12 + 14 + sage: t.splitting_field('b') Finite Field in b of size 11^30 - sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = x^56 - 14*x^3 + sage: t.splitting_field('b') Finite Field in b of size 11^130 - sage: P. = PolynomialRing(GF(19^6, 'a')) # optional - sage.rings.finite_rings - sage: t = -x^6 + x^2 + 1 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(19^6, 'a')) + sage: t = -x^6 + x^2 + 1 + sage: t.splitting_field('b') Finite Field in b of size 19^6 - sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = 24*x^13 + 2*x^12 + 14 + sage: t.splitting_field('b') Finite Field in b of size 19^18 - sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = x^56 - 14*x^3 + sage: t.splitting_field('b') Finite Field in b of size 19^156 - sage: P. = PolynomialRing(GF(83^6, 'a')) # optional - sage.rings.finite_rings - sage: t = 2*x^14 - 5 + 6*x # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(83^6, 'a')) + sage: t = 2*x^14 - 5 + 6*x + sage: t.splitting_field('b') Finite Field in b of size 83^84 - sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = 24*x^13 + 2*x^12 + 14 + sage: t.splitting_field('b') Finite Field in b of size 83^78 - sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = x^56 - 14*x^3 + sage: t.splitting_field('b') Finite Field in b of size 83^12 - sage: P. = PolynomialRing(GF(401^13, 'a')) # optional - sage.rings.finite_rings - sage: t = 2*x^14 - 5 + 6*x # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: P. = PolynomialRing(GF(401^13, 'a')) + sage: t = 2*x^14 - 5 + 6*x + sage: t.splitting_field('b') Finite Field in b of size 401^104 - sage: t = 24*x^13 + 2*x^12 + 14 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = 24*x^13 + 2*x^12 + 14 + sage: t.splitting_field('b') Finite Field in b of size 401^156 - sage: t = x^56 - 14*x^3 # optional - sage.rings.finite_rings - sage: t.splitting_field('b') # optional - sage.rings.finite_rings + sage: t = x^56 - 14*x^3 + sage: t.splitting_field('b') Finite Field in b of size 401^52 sage: R. = QQ[] @@ -4908,22 +5018,23 @@ cdef class Polynomial(CommutativePolynomial): One can easily add gcd functionality to new rings by providing a method ``_gcd_univariate_polynomial``:: - sage: O = ZZ[-sqrt(5)] # optional - sage.rings.number_field sage.symbolic - sage: R. = O[] # optional - sage.rings.number_field sage.symbolic - sage: a = O.1 # optional - sage.rings.number_field sage.symbolic - sage: p = x + a # optional - sage.rings.number_field sage.symbolic - sage: q = x^2 - 5 # optional - sage.rings.number_field sage.symbolic - sage: p.gcd(q) # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: O = ZZ[-sqrt(5)] + sage: R. = O[] + sage: a = O.1 + sage: p = x + a + sage: q = x^2 - 5 + sage: p.gcd(q) Traceback (most recent call last): ... NotImplementedError: Order in Number Field in a with defining polynomial x^2 - 5 with a = -2.236067977499790? does not provide a gcd implementation for univariate polynomials - sage: S. = O.number_field()[] # optional - sage.rings.number_field sage.symbolic - sage: O._gcd_univariate_polynomial = lambda f, g: R(S(f).gcd(S(g))) # optional - sage.rings.number_field sage.symbolic - sage: p.gcd(q) # optional - sage.rings.number_field sage.symbolic + sage: S. = O.number_field()[] + sage: O._gcd_univariate_polynomial = lambda f, g: R(S(f).gcd(S(g))) + sage: p.gcd(q) x + a - sage: del O._gcd_univariate_polynomial # optional - sage.rings.number_field sage.symbolic + sage: del O._gcd_univariate_polynomial Use multivariate implementation for polynomials over polynomials rings:: @@ -4933,7 +5044,7 @@ cdef class Polynomial(CommutativePolynomial): sage: r = 2*x*y + z sage: p = r * (3*x*y*z - 1) sage: q = r * (x + y + z - 2) - sage: p.gcd(q) # optional - sage.libs.singular + sage: p.gcd(q) # needs sage.libs.singular z + 2*x*y sage: R. = QQ[] @@ -4941,13 +5052,13 @@ cdef class Polynomial(CommutativePolynomial): sage: r = 2*x*y + 1 sage: p = r * (x - 1/2 * y) sage: q = r * (x*y^2 - x + 1/3) - sage: p.gcd(q) # optional - sage.libs.singular + sage: p.gcd(q) # needs sage.libs.singular 2*x*y + 1 TESTS:: sage: Pol = QQ['x','y']['x'] - sage: Pol.one().gcd(1) # optional - sage.libs.singular + sage: Pol.one().gcd(1) 1 """ cdef Polynomial _other = other @@ -4977,8 +5088,8 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`32033` has been fixed:: - sage: R. = GF(3)[] # optional - sage.rings.finite_rings - sage: lcm(R(0), R(0)) # optional - sage.rings.finite_rings + sage: R. = GF(3)[] + sage: lcm(R(0), R(0)) 0 :: @@ -5053,26 +5164,27 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: R. = GF(2)['x'] # optional - sage.rings.finite_rings - sage: f = x^4 + x^3 + x^2 + x + 1 # optional - sage.rings.finite_rings - sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(2)['x'] + sage: f = x^4 + x^3 + x^2 + x + 1 + sage: f.is_irreducible(), f.is_primitive() (True, False) - sage: f = x^3 + x + 1 # optional - sage.rings.finite_rings - sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings + sage: f = x^3 + x + 1 + sage: f.is_irreducible(), f.is_primitive() (True, True) - sage: R. = GF(3)[] # optional - sage.rings.finite_rings - sage: f = x^3 - x + 1 # optional - sage.rings.finite_rings - sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings + sage: R. = GF(3)[] + sage: f = x^3 - x + 1 + sage: f.is_irreducible(), f.is_primitive() (True, True) - sage: f = x^2 + 1 # optional - sage.rings.finite_rings - sage: f.is_irreducible(), f.is_primitive() # optional - sage.rings.finite_rings + sage: f = x^2 + 1 + sage: f.is_irreducible(), f.is_primitive() (True, False) - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: f = x^2 + x + 1 # optional - sage.rings.finite_rings - sage: f.is_primitive() # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: f = x^2 + x + 1 + sage: f.is_primitive() False - sage: f = x^2 - x + 2 # optional - sage.rings.finite_rings - sage: f.is_primitive() # optional - sage.rings.finite_rings + sage: f = x^2 - x + 2 + sage: f.is_primitive() True sage: x = polygen(QQ); f = x^2 + 1 sage: f.is_primitive() @@ -5084,7 +5196,7 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: x=polygen(ZZ) + sage: x = polygen(ZZ) sage: f = 5*x^2 + 2 sage: f.is_primitive() True @@ -5092,16 +5204,17 @@ cdef class Polynomial(CommutativePolynomial): sage: f.is_primitive() False - sage: K = NumberField(x^2 + 5, 'a') # optional - sage.rings.number_field - sage: R = K.ring_of_integers() # optional - sage.rings.number_field - sage: a = R.gen(1) # optional - sage.rings.number_field - sage: a^2 # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K = NumberField(x^2 + 5, 'a') + sage: R = K.ring_of_integers() + sage: a = R.gen(1) + sage: a^2 -5 - sage: f = a*x + 2 # optional - sage.rings.number_field - sage: f.is_primitive() # optional - sage.rings.number_field + sage: f = a*x + 2 + sage: f.is_primitive() True - sage: f = (1+a)*x + 2 # optional - sage.rings.number_field - sage: f.is_primitive() # optional - sage.rings.number_field + sage: f = (1+a)*x + 2 + sage: f.is_primitive() False sage: x = polygen(Integers(10)) @@ -5112,33 +5225,34 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: R. = GF(2)['x'] # optional - sage.rings.finite_rings - sage: f = x^4 + x^3 + x^2 + x + 1 # optional - sage.rings.finite_rings - sage: f.is_primitive(15) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(2)['x'] + sage: f = x^4 + x^3 + x^2 + x + 1 + sage: f.is_primitive(15) False - sage: f.is_primitive(15, [3,5]) # optional - sage.rings.finite_rings + sage: f.is_primitive(15, [3,5]) False - sage: f.is_primitive(n_prime_divs=[3,5]) # optional - sage.rings.finite_rings + sage: f.is_primitive(n_prime_divs=[3,5]) False - sage: f = x^3 + x + 1 # optional - sage.rings.finite_rings - sage: f.is_primitive(7, [7]) # optional - sage.rings.finite_rings + sage: f = x^3 + x + 1 + sage: f.is_primitive(7, [7]) True - sage: R. = GF(3)[] # optional - sage.rings.finite_rings - sage: f = x^3 - x + 1 # optional - sage.rings.finite_rings - sage: f.is_primitive(26, [2,13]) # optional - sage.rings.finite_rings + sage: R. = GF(3)[] + sage: f = x^3 - x + 1 + sage: f.is_primitive(26, [2,13]) True - sage: f = x^2 + 1 # optional - sage.rings.finite_rings - sage: f.is_primitive(8, [2]) # optional - sage.rings.finite_rings + sage: f = x^2 + 1 + sage: f.is_primitive(8, [2]) False - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: f = x^2 + x + 1 # optional - sage.rings.finite_rings - sage: f.is_primitive(24, [2,3]) # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: f = x^2 + x + 1 + sage: f.is_primitive(24, [2,3]) False - sage: f = x^2 - x + 2 # optional - sage.rings.finite_rings - sage: f.is_primitive(24, [2,3]) # optional - sage.rings.finite_rings + sage: f = x^2 - x + 2 + sage: f.is_primitive(24, [2,3]) True sage: x = polygen(Integers(103)); f = x^2 + 1 - sage: f.is_primitive() # optional - sage.rings.finite_rings + sage: f.is_primitive() False """ R = self.base_ring() @@ -5255,56 +5369,58 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ['x'] sage: f = x^3 + x + 17 - sage: f.root_field('a') # optional - sage.rings.number_field + sage: f.root_field('a') # needs sage.rings.number_field Number Field in a with defining polynomial x^3 + x + 17 :: sage: R. = QQ['x'] sage: f = x - 3 - sage: f.root_field('b') # optional - sage.rings.number_field + sage: f.root_field('b') # needs sage.rings.number_field Rational Field :: sage: R. = ZZ['x'] sage: f = x^3 + x + 17 - sage: f.root_field('b') # optional - sage.rings.number_field + sage: f.root_field('b') # needs sage.rings.number_field Number Field in b with defining polynomial x^3 + x + 17 :: + sage: # needs sage.rings.number_field sage: y = QQ['x'].0 - sage: L. = NumberField(y^3 - 2) # optional - sage.rings.number_field - sage: R. = L['x'] # optional - sage.rings.number_field - sage: f = x^3 + x + 17 # optional - sage.rings.number_field - sage: f.root_field('c') # optional - sage.rings.number_field + sage: L. = NumberField(y^3 - 2) + sage: R. = L['x'] + sage: f = x^3 + x + 17 + sage: f.root_field('c') Number Field in c with defining polynomial x^3 + x + 17 over its base field :: - sage: R. = PolynomialRing(GF(9, 'a')) # optional - sage.rings.finite_rings - sage: f = x^3 + x^2 + 8 # optional - sage.rings.finite_rings - sage: K. = f.root_field(); K # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(9, 'a')) + sage: f = x^3 + x^2 + 8 + sage: K. = f.root_field(); K Univariate Quotient Polynomial Ring in alpha over Finite Field in a of size 3^2 with modulus x^3 + x^2 + 2 - sage: alpha^2 + 1 # optional - sage.rings.finite_rings + sage: alpha^2 + 1 alpha^2 + 1 - sage: alpha^3 + alpha^2 # optional - sage.rings.finite_rings + sage: alpha^3 + alpha^2 1 :: sage: R. = QQ[] sage: f = x^2 - sage: K. = f.root_field() # optional - sage.libs.pari + sage: K. = f.root_field() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: polynomial must be irreducible TESTS:: - sage: (PolynomialRing(Integers(31), name='x').0 + 5).root_field('a') # optional - sage.rings.finite_rings + sage: (PolynomialRing(Integers(31), name='x').0 + 5).root_field('a') # needs sage.rings.finite_rings Ring of integers modulo 31 """ R = self.base_ring() @@ -5317,6 +5433,8 @@ cdef class Polynomial(CommutativePolynomial): if self.degree() <= 1: return R.fraction_field() + from sage.rings.number_field.number_field import is_NumberField, NumberField + if is_IntegerRing(R): from sage.rings.number_field.number_field import NumberField return NumberField(self, names) @@ -5347,7 +5465,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(ZZ) sage: f = (6*x + 47) * (7*x^2 - 2*x + 38) sage: g = (6*x + 47) * (3*x^3 + 2*x + 1) - sage: M = f.sylvester_matrix(g); M # optional - sage.modules + sage: M = f.sylvester_matrix(g); M # needs sage.modules [ 42 317 134 1786 0 0 0] [ 0 42 317 134 1786 0 0] [ 0 0 42 317 134 1786 0] @@ -5359,7 +5477,7 @@ cdef class Polynomial(CommutativePolynomial): If the polynomials share a non-constant common factor then the determinant of the Sylvester matrix will be zero:: - sage: M.determinant() # optional - sage.modules + sage: M.determinant() # needs sage.modules 0 If ``self`` and ``right`` are polynomials of positive degree, the determinant @@ -5367,16 +5485,16 @@ cdef class Polynomial(CommutativePolynomial): sage: h1 = R._random_nonzero_element() sage: h2 = R._random_nonzero_element() - sage: M1 = h1.sylvester_matrix(h2) # optional - sage.modules - sage: M1.determinant() == h1.resultant(h2) # optional - sage.libs.pari sage.modules + sage: M1 = h1.sylvester_matrix(h2) # needs sage.modules + sage: M1.determinant() == h1.resultant(h2) # needs sage.libs.pari sage.modules True The rank of the Sylvester matrix is related to the degree of the gcd of ``self`` and ``right``:: - sage: f.gcd(g).degree() == f.degree() + g.degree() - M.rank() # optional - sage.modules + sage: f.gcd(g).degree() == f.degree() + g.degree() - M.rank() # needs sage.modules True - sage: h1.gcd(h2).degree() == h1.degree() + h2.degree() - M1.rank() # optional - sage.modules + sage: h1.gcd(h2).degree() == h1.degree() + h2.degree() - M1.rank() # needs sage.modules True TESTS: @@ -5386,10 +5504,10 @@ cdef class Polynomial(CommutativePolynomial): sage: K. = QQ['x'] sage: f = x + 1 sage: g = QQ['y']([1, 0, 1]) - sage: f.sylvester_matrix(f, x) # optional - sage.modules + sage: f.sylvester_matrix(f, x) # needs sage.modules [1 1] [1 1] - sage: f.sylvester_matrix(g, x) # optional - sage.modules + sage: f.sylvester_matrix(g, x) Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -5400,18 +5518,18 @@ cdef class Polynomial(CommutativePolynomial): sage: f = QQ['x']([1, 0, 1]) sage: g = ZZ['x']([1, 0, 1]) - sage: h = GF(25, 'a')['x']([1, 0, 1]) # optional - sage.rings.finite_rings - sage: f.sylvester_matrix(g) # optional - sage.modules + sage: h = GF(25, 'a')['x']([1, 0, 1]) # needs sage.rings.finite_rings + sage: f.sylvester_matrix(g) # needs sage.modules [1 0 1 0] [0 1 0 1] [1 0 1 0] [0 1 0 1] - sage: g.sylvester_matrix(h) # optional - sage.rings.finite_rings sage.modules + sage: g.sylvester_matrix(h) # needs sage.modules sage.rings.finite_rings [1 0 1 0] [0 1 0 1] [1 0 1 0] [0 1 0 1] - sage: f.sylvester_matrix(h) # optional - sage.rings.finite_rings sage.modules + sage: f.sylvester_matrix(h) # needs sage.modules sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -5423,30 +5541,31 @@ cdef class Polynomial(CommutativePolynomial): sage: K. = QQ['x,y'] sage: g = K.random_element() - sage: f.sylvester_matrix(g) == K(f).sylvester_matrix(g, x) # optional - sage.modules + sage: f.sylvester_matrix(g) == K(f).sylvester_matrix(g, x) # needs sage.modules True Corner cases:: + sage: # needs sage.modules sage: K. = QQ[] sage: f = x^2 + 1 sage: g = K(0) - sage: f.sylvester_matrix(g) # optional - sage.modules + sage: f.sylvester_matrix(g) Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(f) # optional - sage.modules + sage: g.sylvester_matrix(f) Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: g.sylvester_matrix(g) # optional - sage.modules + sage: g.sylvester_matrix(g) Traceback (most recent call last): ... ValueError: The Sylvester matrix is not defined for zero polynomials - sage: K(3).sylvester_matrix(x^2) # optional - sage.modules + sage: K(3).sylvester_matrix(x^2) [3 0] [0 3] - sage: K(3).sylvester_matrix(K(4)) # optional - sage.modules + sage: K(3).sylvester_matrix(K(4)) [] """ @@ -5518,10 +5637,10 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = PolynomialRing(GF(9, 'a'), sparse=True) # optional - sage.rings.finite_rings - sage: a = w._new_constant_poly(0, R); a # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(9, 'a'), sparse=True) # needs sage.rings.finite_rings + sage: a = w._new_constant_poly(0, R); a # needs sage.rings.finite_rings 0 - sage: a.coefficients() # optional - sage.rings.finite_rings + sage: a.coefficients() # needs sage.rings.finite_rings [] """ t = type(self) @@ -5564,12 +5683,14 @@ cdef class Polynomial(CommutativePolynomial): sage: b = a(2*191*236607587) sage: b.is_nilpotent() True - sage: R. = a[] # optional - sage.libs.pari - sage: f = 3 + b*x + b^2*x^2 # optional - sage.libs.pari - sage: f.is_unit() # optional - sage.libs.pari + + sage: # needs sage.libs.pari + sage: R. = a[] + sage: f = 3 + b*x + b^2*x^2 + sage: f.is_unit() True - sage: f = 3 + b*x + b^2*x^2 + 17*x^3 # optional - sage.libs.pari - sage: f.is_unit() # optional - sage.libs.pari + sage: f = 3 + b*x + b^2*x^2 + 17*x^3 + sage: f.is_unit() False EXERCISE (Atiyah-McDonald, Ch 1): Let `A[x]` be a @@ -5830,72 +5951,73 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = 3*x^3 + 2*x^2 + x - sage: exp(f.global_height()) + sage: exp(f.global_height()) # needs sage.symbolic 3.00000000000000 Scaling should not change the result:: sage: R. = PolynomialRing(QQ) sage: f = 1/25*x^2 + 25/3*x + 1 - sage: f.global_height() + sage: f.global_height() # needs sage.symbolic 6.43775164973640 sage: g = 100 * f - sage: g.global_height() + sage: g.global_height() # needs sage.symbolic 6.43775164973640 :: - sage: R. = PolynomialRing(QQbar) # optional - sage.rings.number_field - sage: f = QQbar(i)*x^2 + 3*x # optional - sage.rings.number_field - sage: f.global_height() # optional - sage.rings.number_field + sage: R. = PolynomialRing(QQbar) # needs sage.rings.number_field + sage: f = QQbar(i)*x^2 + 3*x # needs sage.rings.number_field + sage: f.global_height() # needs sage.rings.number_field 1.09861228866811 :: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2 + 5) # optional - sage.rings.number_field - sage: T. = PolynomialRing(K) # optional - sage.rings.number_field - sage: f = 1/1331 * t^2 + 5 * t + 7 # optional - sage.rings.number_field - sage: f.global_height() # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 5) + sage: T. = PolynomialRing(K) + sage: f = 1/1331 * t^2 + 5 * t + 7 + sage: f.global_height() 9.13959596745043 :: sage: R. = QQ[] sage: f = 1/123*x^2 + 12 - sage: f.global_height(prec=2) + sage: f.global_height(prec=2) # needs sage.symbolic 8.0 :: sage: R. = QQ[] sage: f = 0*x - sage: f.global_height() + sage: f.global_height() # needs sage.rings.real_mpfr 0.000000000000000 """ if prec is None: prec = 53 if self.is_zero(): + from sage.rings.real_mpfr import RealField return RealField(prec).zero() - from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields - from sage.rings.qqbar import QQbar, number_field_elements_from_algebraics K = self.base_ring() - if K in NumberFields() or is_NumberFieldOrder(K): + if K in NumberFields() or isinstance(K, sage.rings.abc.Order) or is_IntegerRing(K): from sage.schemes.projective.projective_space import ProjectiveSpace P = ProjectiveSpace(K, self.number_of_terms()-1) return P.point(self.coefficients()).global_height(prec=prec) - elif K is QQbar: - K_pre, P, phi = number_field_elements_from_algebraics(self.coefficients()) + elif isinstance(K, sage.rings.abc.AlgebraicField): + from sage.rings.qqbar import number_field_elements_from_algebraics from sage.schemes.projective.projective_space import ProjectiveSpace + + K_pre, P, phi = number_field_elements_from_algebraics(self.coefficients()) Pr = ProjectiveSpace(K_pre, len(P)-1) return Pr.point(P).global_height(prec=prec) raise TypeError("Must be over a Numberfield or a Numberfield Order.") - def local_height(self, v, prec=None): """ Return the maximum of the local height of the coefficients of @@ -5914,34 +6036,34 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = 1/1331*x^2 + 1/4000*x - sage: f.local_height(1331) + sage: f.local_height(1331) # needs sage.rings.real_mpfr 7.19368581839511 :: + sage: # needs sage.rings.number_field sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field - sage: T. = K[] # optional - sage.rings.number_field - sage: I = K.ideal(3) # optional - sage.rings.number_field - sage: f = 1/3*t^2 + 3 # optional - sage.rings.number_field - sage: f.local_height(I) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 5) + sage: T. = K[] + sage: I = K.ideal(3) + sage: f = 1/3*t^2 + 3 + sage: f.local_height(I) 1.09861228866811 :: sage: R. = QQ[] sage: f = 1/2*x^2 + 2 - sage: f.local_height(2, prec=2) + sage: f.local_height(2, prec=2) # needs sage.rings.real_mpfr 0.75 """ - from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields if prec is None: prec = 53 K = FractionField(self.base_ring()) - if K not in NumberFields() or is_NumberFieldOrder(K): + if not (K in NumberFields() or isinstance(K, sage.rings.abc.Order) or is_IntegerRing(K)): raise TypeError("must be over a Numberfield or a Numberfield order") return max([K(c).local_height(v, prec=prec) for c in self.coefficients()]) @@ -5964,33 +6086,33 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = PolynomialRing(QQ) sage: f = 210*x^2 - sage: f.local_height_arch(0) + sage: f.local_height_arch(0) # needs sage.rings.real_mpfr 5.34710753071747 :: + sage: # needs sage.rings.number_field sage: R. = QQ[] - sage: K. = NumberField(x^2 - 5) # optional - sage.rings.number_field - sage: T. = K[] # optional - sage.rings.number_field - sage: f = 1/2*t^2 + 3 # optional - sage.rings.number_field - sage: f.local_height_arch(1, prec=52) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 5) + sage: T. = K[] + sage: f = 1/2*t^2 + 3 + sage: f.local_height_arch(1, prec=52) 1.09861228866811 :: sage: R. = QQ[] sage: f = 1/2*x^2 + 3 - sage: f.local_height_arch(0, prec=2) + sage: f.local_height_arch(0, prec=2) # needs sage.rings.real_mpfr 1.0 """ - from sage.rings.number_field.order import is_NumberFieldOrder from sage.categories.number_fields import NumberFields if prec is None: prec = 53 K = FractionField(self.base_ring()) - if K not in NumberFields() or is_NumberFieldOrder(K): + if not (K in NumberFields() or isinstance(K, sage.rings.abc.Order) or is_IntegerRing(K)): return TypeError("must be over a Numberfield or a Numberfield Order") if K == QQ: @@ -6186,11 +6308,13 @@ cdef class Polynomial(CommutativePolynomial): sage: f = - 1/2*x^2 + x^9 + 7*x + 5/11 sage: f.monomials() [x^9, x^2, x, 1] + + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x**2 + 1) # optional - sage.rings.number_field - sage: R. = QQ[] # optional - sage.rings.number_field - sage: p = rho * y # optional - sage.rings.number_field - sage: p.monomials() # optional - sage.rings.number_field + sage: K. = NumberField(x**2 + 1) + sage: R. = QQ[] + sage: p = rho * y + sage: p.monomials() [y] """ if self.is_zero(): @@ -6225,9 +6349,9 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: x = PolynomialRing(RealField(), 'x').gen() - sage: f = x^2 - 2 - sage: f.newton_raphson(4, 1) + sage: x = PolynomialRing(RealField(), 'x').gen() # needs sage.rings.real_mpfr + sage: f = x^2 - 2 # needs sage.rings.real_mpfr + sage: f.newton_raphson(4, 1) # needs sage.rings.real_mpfr [1.50000000000000, 1.41666666666667, 1.41421568627451, 1.41421356237469] AUTHORS: @@ -6287,11 +6411,11 @@ cdef class Polynomial(CommutativePolynomial): sage: x = QQ['x'].0 sage: f = x^3 + 2 - sage: f.newton_slopes(2) # optional - sage.libs.pari + sage: f.newton_slopes(2) # needs sage.libs.pari [1/3, 1/3, 1/3] sage: R. = PolynomialRing(ZZ, sparse=True) sage: p = x^5 + 6*x^2 + 4 - sage: p.newton_slopes(2) # optional - sage.libs.pari + sage: p.newton_slopes(2) # needs sage.libs.pari [1/2, 1/2, 1/3, 1/3, 1/3] sage: p.newton_slopes(2, lengths=True) [(1/2, 2), (1/3, 3)] @@ -6348,13 +6472,13 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: Pol. = QQ[] - sage: x.dispersion_set(x + 1) # optional - sage.libs.pari + sage: x.dispersion_set(x + 1) # needs sage.libs.pari [1] - sage: (x + 1).dispersion_set(x) # optional - sage.libs.pari + sage: (x + 1).dispersion_set(x) # needs sage.libs.pari [] sage: pol = x^3 + x - 7 - sage: (pol*pol(x+3)^2).dispersion_set() # optional - sage.libs.pari + sage: (pol*pol(x+3)^2).dispersion_set() # needs sage.libs.pari [0, 3] """ other = self if other is None else self._parent.coerce(other) @@ -6395,16 +6519,17 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: Pol. = QQ[] - sage: x.dispersion(x + 1) # optional - sage.libs.pari + sage: x.dispersion(x + 1) # needs sage.libs.pari 1 - sage: (x + 1).dispersion(x) # optional - sage.libs.pari + sage: (x + 1).dispersion(x) # needs sage.libs.pari -Infinity - sage: Pol. = QQbar[] # optional - sage.libs.pari sage.rings.number_field - sage: pol = Pol([sqrt(5), 1, 3/2]) # optional - sage.libs.pari sage.rings.number_field sage.symbolic - sage: pol.dispersion() # optional - sage.libs.pari sage.rings.number_field sage.symbolic + sage: # needs sage.libs.pari sage.rings.number_field sage.symbolic + sage: Pol. = QQbar[] + sage: pol = Pol([sqrt(5), 1, 3/2]) + sage: pol.dispersion() 0 - sage: (pol*pol(x+3)).dispersion() # optional - sage.libs.pari sage.rings.number_field sage.symbolic + sage: (pol*pol(x+3)).dispersion() 3 """ dispersions = self.dispersion_set(other) @@ -6425,7 +6550,7 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: f = QQ['x']([0,1,2/3,3]) - sage: pari(f) # optional - sage.libs.pari + sage: pari(f) # needs sage.libs.pari 3*x^3 + 2/3*x^2 + x :: @@ -6433,18 +6558,19 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = QQ['a'] sage: R. = S['x'] sage: f = R([0, a]) + R([0, 0, 2/3]) - sage: pari(f) # optional - sage.libs.pari + sage: pari(f) # needs sage.libs.pari 2/3*x^2 + a*x Polynomials over a number field work, provided that the variable is called 'x':: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: K. = NumberField(x^2 + x + 1) # optional - sage.rings.number_field - sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - sage: pol = (b + x)^3; pol # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + x + 1) + sage: R. = PolynomialRing(K) + sage: pol = (b + x)^3; pol x^3 + 3*b*x^2 + (-3*b - 3)*x + 1 - sage: pari(pol) # optional - sage.libs.pari sage.rings.number_field + sage: pari(pol) # needs sage.libs.pari Mod(1, y^2 + y + 1)*x^3 + Mod(3*y, y^2 + y + 1)*x^2 + Mod(-3*y - 3, y^2 + y + 1)*x + Mod(1, y^2 + y + 1) @@ -6455,7 +6581,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = y^3 + a - sage: pari(f) # optional - sage.libs.pari + sage: pari(f) # needs sage.libs.pari Traceback (most recent call last): ... PariError: incorrect priority in gtopoly: variable x <= a @@ -6465,9 +6591,9 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = QQ['a'] sage: R. = S['x'] - sage: pari(x^2 + 2*x) # optional - sage.libs.pari + sage: pari(x^2 + 2*x) # needs sage.libs.pari x^2 + 2*x - sage: pari(a*x + 2*x^3) # optional - sage.libs.pari + sage: pari(a*x + 2*x^3) # needs sage.libs.pari 2*x^3 + a*x Stacked polynomial rings, second with a multivariate ring on the @@ -6475,27 +6601,27 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = ZZ['a', 'b'] sage: R. = S['x'] - sage: pari(x^2 + 2*x) # optional - sage.libs.pari + sage: pari(x^2 + 2*x) # needs sage.libs.pari x^2 + 2*x - sage: pari(a*x + 2*b*x^3) # optional - sage.libs.pari + sage: pari(a*x + 2*b*x^3) # needs sage.libs.pari 2*b*x^3 + a*x Stacked polynomial rings with exotic base rings:: - sage: S. = GF(7)['a', 'b'] # optional - sage.rings.finite_rings - sage: R. = S['x'] # optional - sage.rings.finite_rings - sage: pari(x^2 + 9*x) # optional - sage.rings.finite_rings + sage: S. = GF(7)['a', 'b'] + sage: R. = S['x'] + sage: pari(x^2 + 9*x) # needs sage.libs.pari x^2 + 2*x - sage: pari(a*x + 9*b*x^3) # optional - sage.rings.finite_rings + sage: pari(a*x + 9*b*x^3) # needs sage.libs.pari 2*b*x^3 + a*x :: sage: S. = Integers(8)['a'] sage: R. = S['x'] - sage: pari(x^2 + 2*x) # optional - sage.libs.pari + sage: pari(x^2 + 2*x) # needs sage.libs.pari Mod(1, 8)*x^2 + Mod(2, 8)*x - sage: pari(a*x + 10*x^3) # optional - sage.libs.pari + sage: pari(a*x + 10*x^3) # needs sage.libs.pari Mod(2, 8)*x^3 + Mod(1, 8)*a*x """ return self._pari_with_name(self._parent.variable_name()) @@ -6514,20 +6640,21 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.pari sage: R. = PolynomialRing(ZZ) sage: pol = 2*x^2 + 7*x - 5 - sage: pol._pari_or_constant() # optional - sage.libs.pari + sage: pol._pari_or_constant() 2*x^2 + 7*x - 5 - sage: pol._pari_or_constant('a') # optional - sage.libs.pari + sage: pol._pari_or_constant('a') 2*a^2 + 7*a - 5 sage: pol = R(7) - sage: pol._pari_or_constant() # optional - sage.libs.pari + sage: pol._pari_or_constant() 7 - sage: pol._pari_or_constant().type() # optional - sage.libs.pari + sage: pol._pari_or_constant().type() 't_INT' - sage: pol.__pari__().type() # optional - sage.libs.pari + sage: pol.__pari__().type() 't_POL' - sage: PolynomialRing(IntegerModRing(101), 't')()._pari_or_constant() # optional - sage.libs.pari + sage: PolynomialRing(IntegerModRing(101), 't')()._pari_or_constant() Mod(0, 101) """ if self.is_constant(): @@ -6546,9 +6673,9 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: (2*a^2 + a)._pari_with_name() # optional - sage.libs.pari + sage: (2*a^2 + a)._pari_with_name() # needs sage.libs.pari 2*x^2 + x - sage: (2*a^2 + a)._pari_with_name('y') # optional - sage.libs.pari + sage: (2*a^2 + a)._pari_with_name('y') # needs sage.libs.pari 2*y^2 + y """ vals = [x.__pari__() for x in self.list()] @@ -6563,12 +6690,13 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: magma = Magma() # new session # optional - magma + sage: # optional - magma + sage: magma = Magma() # new session sage: R. = ZZ[] sage: f = y^3 - 17*y + 5 - sage: f._magma_init_(magma) # optional - magma + sage: f._magma_init_(magma) '_sage_[...]![5,-17,0,1]' - sage: g = magma(f); g # optional - magma + sage: g = magma(f); g y^3 - 17*y + 5 Note that in Magma there is only one polynomial ring over each @@ -6577,20 +6705,21 @@ cdef class Polynomial(CommutativePolynomial): we already defined:: sage: R. = ZZ[] - sage: magma(R) # optional - magma + sage: magma(R) # optional - magma Univariate Polynomial Ring in z over Integer Ring - sage: g # optional - magma + sage: g # optional - magma z^3 - 17*z + 5 In Sage the variable name does not change:: - sage: f + sage: f # optional - magma y^3 - 17*y + 5 A more complicated nested example:: - sage: k. = GF(9); R. = k[]; S. = R[] # optional - sage.rings.finite_rings - sage: magma(a*W^20 + s*t/a) # optional - magma # optional - sage.rings.finite_rings + sage: # optional - magma, needs sage.rings.finite_rings + sage: k. = GF(9); R. = k[]; S. = R[] + sage: magma(a*W^20 + s*t/a) a*W^20 + a^7*s*t """ # Get a reference to Magma version of parent. @@ -6609,35 +6738,37 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.gap sage: R. = ZZ[] sage: f = y^3 - 17*y + 5 - sage: g = gap(f); g # indirect doctest # optional - sage.libs.gap + sage: g = gap(f); g # indirect doctest y^3-17*y+5 - sage: f._gap_init_() # optional - sage.libs.gap + sage: f._gap_init_() 'y^3 - 17*y + 5' sage: R. = ZZ[] - sage: gap(R) # optional - sage.libs.gap + sage: gap(R) PolynomialRing( Integers, ["z"] ) - sage: g # optional - sage.libs.gap + sage: g y^3-17*y+5 - sage: gap(z^2 + z) # optional - sage.libs.gap + sage: gap(z^2 + z) z^2+z - sage: libgap(z^2 + z) # optional - sage.libs.gap + sage: libgap(z^2 + z) z^2+z Coefficients in a finite field:: - sage: R. = GF(7)[] # optional - sage.rings.finite_rings - sage: f = y^3 - 17*y + 5 # optional - sage.rings.finite_rings - sage: g = gap(f); g # optional - sage.libs.gap sage.rings.finite_rings + sage: # needs sage.libs.gap + sage: R. = GF(7)[] + sage: f = y^3 - 17*y + 5 + sage: g = gap(f); g y^3+Z(7)^4*y+Z(7)^5 - sage: h = libgap(f); h # optional - sage.libs.gap sage.rings.finite_rings + sage: h = libgap(f); h y^3+Z(7)^4*y+Z(7)^5 - sage: g.Factors() # optional - sage.libs.gap sage.rings.finite_rings + sage: g.Factors() [ y+Z(7)^0, y+Z(7)^0, y+Z(7)^5 ] - sage: h.Factors() # optional - sage.libs.gap sage.rings.finite_rings + sage: h.Factors() [ y+Z(7)^0, y+Z(7)^0, y+Z(7)^5 ] - sage: f.factor() # optional - sage.libs.gap sage.rings.finite_rings + sage: f.factor() (y + 5) * (y + 1)^2 """ R = gap(self._parent) @@ -6649,9 +6780,9 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: sage: R. = ZZ[] - sage: libgap(-x^3 + 3*x) # indirect doctest # optional - sage.libs.gap + sage: libgap(-x^3 + 3*x) # indirect doctest # needs sage.libs.gap -x^3+3*x - sage: libgap(R.zero()) # indirect doctest # optional - sage.libs.gap + sage: libgap(R.zero()) # indirect doctest # needs sage.libs.gap 0 """ from sage.libs.gap.libgap import libgap @@ -6663,13 +6794,14 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: R. = GF(101)['e,i'][] # optional - sage.rings.finite_rings - sage: f = R('e*i') * x + x^2 # optional - sage.rings.finite_rings - sage: f._giac_init_() # optional - sage.rings.finite_rings + sage: # needs sage.libs.giac + sage: R. = GF(101)['e,i'][] + sage: f = R('e*i') * x + x^2 + sage: f._giac_init_() '((1)*1)*sageVARx^2+((1)*sageVARe*sageVARi)*sageVARx' - sage: giac(f) # optional - sage.rings.finite_rings + sage: giac(f) sageVARx^2+sageVARe*sageVARi*sageVARx - sage: giac(R.zero()) # optional - sage.rings.finite_rings + sage: giac(R.zero()) 0 """ g = 'sageVAR' + self.variable_name() @@ -6700,9 +6832,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + x + 1; g = x^3 - x - 1 - sage: r = f.resultant(g); r # optional - sage.libs.pari + sage: r = f.resultant(g); r # needs sage.libs.pari -8 - sage: r.parent() is QQ # optional - sage.libs.pari + sage: r.parent() is QQ # needs sage.libs.pari True We can compute resultants over univariate and multivariate @@ -6711,9 +6843,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = x^3 + a - sage: r = f.resultant(g); r # optional - sage.libs.pari + sage: r = f.resultant(g); r # needs sage.libs.pari a^3 + a^2 - sage: r.parent() is R # optional - sage.libs.pari + sage: r.parent() is R # needs sage.libs.pari True :: @@ -6721,9 +6853,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = x^3 + b - sage: r = f.resultant(g); r # optional - sage.libs.pari + sage: r = f.resultant(g); r # needs sage.libs.pari a^3 + b^2 - sage: r.parent() is R # optional - sage.libs.pari + sage: r.parent() is R # needs sage.libs.pari True TESTS:: @@ -6731,18 +6863,18 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a; g = y^3 + a - sage: h = f.resultant(g); h # optional - sage.libs.pari + sage: h = f.resultant(g); h # needs sage.libs.pari y^3 - x^2 - sage: h.parent() is R # optional - sage.libs.pari + sage: h.parent() is R # needs sage.libs.pari True Check that :trac:`13672` is fixed:: - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: S. = R[] # optional - sage.rings.finite_rings - sage: f = (t^2 + t)*x + t^2 + t # optional - sage.rings.finite_rings - sage: g = (t + 1)*x + t^2 # optional - sage.rings.finite_rings - sage: f.resultant(g) # optional - sage.rings.finite_rings + sage: R. = GF(2)[] + sage: S. = R[] + sage: f = (t^2 + t)*x + t^2 + t + sage: g = (t + 1)*x + t^2 + sage: f.resultant(g) # needs sage.libs.pari t^4 + t Check that :trac:`15061` is fixed:: @@ -6751,23 +6883,24 @@ cdef class Polynomial(CommutativePolynomial): sage: F = R([1,1],2) sage: RP. = PolynomialRing(R) sage: P = x^2 - F - sage: P.resultant(P.derivative()) # optional - sage.libs.pari + sage: P.resultant(P.derivative()) # needs sage.libs.pari -4 - 4*T + O(T^2) Check that :trac:`16360` is fixed:: sage: K. = FunctionField(QQ) sage: R. = K[] - sage: y.resultant(y + x) # optional - sage.libs.pari + sage: y.resultant(y + x) # needs sage.libs.pari x + sage: # needs sage.libs.singular sage: K. = FunctionField(QQ) sage: R. = K[] - sage: L. = K.extension(b^2 - a) # optional - sage.libs.singular - sage: R. = L[] # optional - sage.libs.singular - sage: f = x^2 - a # optional - sage.libs.singular - sage: g = x - b # optional - sage.libs.singular - sage: f.resultant(g) # optional - sage.libs.pari sage.libs.singular + sage: L. = K.extension(b^2 - a) + sage: R. = L[] + sage: f = x^2 - a + sage: g = x - b + sage: f.resultant(g) # needs sage.libs.pari 0 Check that :trac:`17817` is fixed:: @@ -6778,16 +6911,19 @@ cdef class Polynomial(CommutativePolynomial): sage: S. = PolynomialRing(R,'y') sage: p = ((1/b^2*d^2+1/a)*x*y^2+a*b/c*y+e+x^2) sage: q = -4*c^2*y^3+1 - sage: p.resultant(q) # optional - sage.libs.pari - (16*c^4)*x^6 + (48*c^4)*e*x^4 + (1/(b^6)*d^6 + 3/(a*b^4)*d^4 + (-12*a^3*b*c + 3)/(a^2*b^2)*d^2 + (-12*a^3*b*c + 1)/(a^3))*x^3 + (48*c^4)*e^2*x^2 + ((-12*a*c)/b*d^2*e + (-12*b*c)*e)*x + (16*c^4)*e^3 + (4*a^3*b^3)/c + sage: p.resultant(q) # needs sage.libs.pari + (16*c^4)*x^6 + (48*c^4)*e*x^4 + (1/(b^6)*d^6 + 3/(a*b^4)*d^4 + + (-12*a^3*b*c + 3)/(a^2*b^2)*d^2 + (-12*a^3*b*c + 1)/(a^3))*x^3 + + (48*c^4)*e^2*x^2 + ((-12*a*c)/b*d^2*e + (-12*b*c)*e)*x + (16*c^4)*e^3 + (4*a^3*b^3)/c Test for :trac:`10978`:: + sage: # needs sage.libs.pari sage.rings.complex_double sage.symbolic sage: R. = PolynomialRing(CDF) sage: f = R(1 - I*x + (0.5)*x^2 + (1.7)*x^3) sage: g = f.derivative() - sage: f.resultant(g) # optional - sage.libs.pari + sage: f.resultant(g) 133.92599999999996 + 37.56999999999999*I """ variable = self.variable_name() @@ -6937,45 +7073,47 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(ZZ) sage: p1 = x^2 - 1 sage: p2 = x^4 - 1 - sage: p1.composed_op(p2, operator.add) # optional - sage.libs.singular + sage: p1.composed_op(p2, operator.add) # needs sage.libs.singular x^8 - 4*x^6 + 4*x^4 - 16*x^2 - sage: p1.composed_op(p2, operator.mul) # optional - sage.libs.singular + sage: p1.composed_op(p2, operator.mul) # needs sage.libs.singular x^8 - 2*x^4 + 1 - sage: p1.composed_op(p2, operator.truediv) # optional - sage.libs.singular + sage: p1.composed_op(p2, operator.truediv) # needs sage.libs.singular x^8 - 2*x^4 + 1 This function works over any field. However for base rings other than `\ZZ` and `\QQ` only the resultant algorithm is available:: - sage: x = polygen(QQbar) # optional - sage.rings.number_field - sage: p1 = x**2 - AA(2).sqrt() # optional - sage.rings.number_field - sage: p2 = x**3 - AA(3).sqrt() # optional - sage.rings.number_field - sage: r1 = p1.roots(multiplicities=False) # optional - sage.rings.number_field - sage: r2 = p2.roots(multiplicities=False) # optional - sage.rings.number_field - sage: p = p1.composed_op(p2, operator.add); p # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: x = polygen(QQbar) + sage: p1 = x**2 - AA(2).sqrt() + sage: p2 = x**3 - AA(3).sqrt() + sage: r1 = p1.roots(multiplicities=False) + sage: r2 = p2.roots(multiplicities=False) + sage: p = p1.composed_op(p2, operator.add); p x^6 - 4.242640687119285?*x^4 - 3.464101615137755?*x^3 + 6*x^2 - 14.69693845669907?*x + 0.1715728752538099? - sage: all(p(x+y).is_zero() for x in r1 for y in r2) # optional - sage.rings.number_field + sage: all(p(x+y).is_zero() for x in r1 for y in r2) True - sage: x = polygen(GF(2)) # optional - sage.rings.finite_rings - sage: p1 = x**2 + x - 1 # optional - sage.rings.finite_rings - sage: p2 = x**3 + x - 1 # optional - sage.rings.finite_rings - sage: p_add = p1.composed_op(p2, operator.add); p_add # optional - sage.rings.finite_rings + sage: x = polygen(GF(2)) + sage: p1 = x**2 + x - 1 + sage: p2 = x**3 + x - 1 + sage: p_add = p1.composed_op(p2, operator.add); p_add # needs sage.libs.singular x^6 + x^5 + x^3 + x^2 + 1 - sage: p_mul = p1.composed_op(p2, operator.mul); p_mul # optional - sage.rings.finite_rings + sage: p_mul = p1.composed_op(p2, operator.mul); p_mul # needs sage.libs.singular x^6 + x^4 + x^2 + x + 1 - sage: p_div = p1.composed_op(p2, operator.truediv); p_div # optional - sage.rings.finite_rings + sage: p_div = p1.composed_op(p2, operator.truediv); p_div # needs sage.libs.singular x^6 + x^5 + x^4 + x^2 + 1 - sage: K = GF(2**6, 'a') # optional - sage.rings.finite_rings - sage: r1 = p1.roots(K, multiplicities=False) # optional - sage.rings.finite_rings - sage: r2 = p2.roots(K, multiplicities=False) # optional - sage.rings.finite_rings - sage: all(p_add(x1+x2).is_zero() for x1 in r1 for x2 in r2) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K = GF(2**6, 'a') + sage: r1 = p1.roots(K, multiplicities=False) + sage: r2 = p2.roots(K, multiplicities=False) + sage: all(p_add(x1+x2).is_zero() for x1 in r1 for x2 in r2) # needs sage.libs.singular True - sage: all(p_mul(x1*x2).is_zero() for x1 in r1 for x2 in r2) # optional - sage.rings.finite_rings + sage: all(p_mul(x1*x2).is_zero() for x1 in r1 for x2 in r2) # needs sage.libs.singular True - sage: all(p_div(x1/x2).is_zero() for x1 in r1 for x2 in r2) # optional - sage.rings.finite_rings + sage: all(p_div(x1/x2).is_zero() for x1 in r1 for x2 in r2) # needs sage.libs.singular True TESTS: @@ -6983,7 +7121,7 @@ cdef class Polynomial(CommutativePolynomial): :: sage: y = polygen(ZZ) - sage: for p1 in [2*y^3 - y + 3, -y^5 - 2, 4*y - 3]: # optional - sage.libs.singular + sage: for p1 in [2*y^3 - y + 3, -y^5 - 2, 4*y - 3]: # needs sage.libs.singular ....: for p2 in [5*y^2 - 7, -3*y - 1]: ....: for monic in [True,False]: ....: for op in [operator.add, operator.sub, operator.mul, operator.truediv]: @@ -7131,21 +7269,22 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: x = polygen(R) sage: f = (x - a) * (x - b) * (x - c) - sage: f.compose_power(2).factor() # optional - sage.libs.singular sage.modules + sage: f.compose_power(2).factor() # needs sage.libs.singular sage.modules (x - c^2) * (x - b^2) * (x - a^2) * (x - b*c)^2 * (x - a*c)^2 * (x - a*b)^2 + sage: # needs sage.libs.singular sage.modules sage: x = polygen(QQ) sage: f = x^2 - 2*x + 2 sage: f2 = f.compose_power(2); f2 x^4 - 4*x^3 + 8*x^2 - 16*x + 16 - sage: f2 == f.composed_op(f, operator.mul) # optional - sage.libs.singular sage.modules + sage: f2 == f.composed_op(f, operator.mul) True - sage: f3 = f.compose_power(3); f3 # optional - sage.libs.singular sage.modules + sage: f3 = f.compose_power(3); f3 x^8 - 8*x^7 + 32*x^6 - 64*x^5 + 128*x^4 - 512*x^3 + 2048*x^2 - 4096*x + 4096 - sage: f3 == f2.composed_op(f, operator.mul) # optional - sage.libs.singular sage.modules + sage: f3 == f2.composed_op(f, operator.mul) True - sage: f4 = f.compose_power(4) # optional - sage.libs.singular sage.modules - sage: f4 == f3.composed_op(f, operator.mul) # optional - sage.libs.singular sage.modules + sage: f4 = f.compose_power(4) + sage: f4 == f3.composed_op(f, operator.mul) True """ try: @@ -7185,21 +7324,22 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: f = cyclotomic_polynomial(30) # optional - sage.libs.pari - sage: f.adams_operator(7)==f # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: f = cyclotomic_polynomial(30) + sage: f.adams_operator(7)==f True - sage: f.adams_operator(6) == cyclotomic_polynomial(5)**2 # optional - sage.libs.pari + sage: f.adams_operator(6) == cyclotomic_polynomial(5)**2 True - sage: f.adams_operator(10) == cyclotomic_polynomial(3)**4 # optional - sage.libs.pari + sage: f.adams_operator(10) == cyclotomic_polynomial(3)**4 True - sage: f.adams_operator(15) == cyclotomic_polynomial(2)**8 # optional - sage.libs.pari + sage: f.adams_operator(15) == cyclotomic_polynomial(2)**8 True - sage: f.adams_operator(30) == cyclotomic_polynomial(1)**8 # optional - sage.libs.pari + sage: f.adams_operator(30) == cyclotomic_polynomial(1)**8 True sage: x = polygen(QQ) sage: f = x^2 - 2*x + 2 - sage: f.adams_operator(10) # optional - sage.libs.singular + sage: f.adams_operator(10) # needs sage.libs.singular x^2 + 1024 When ``self`` is monic, the output will have leading coefficient @@ -7209,12 +7349,14 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: x = polygen(R) sage: f = (x - a) * (x - b) * (x - c) - sage: f.adams_operator(3).factor() # optional - sage.libs.singular + sage: f.adams_operator(3).factor() # needs sage.libs.singular (-1) * (x - c^3) * (x - b^3) * (x - a^3) - sage: f.adams_operator(3, monic=True).factor() # optional - sage.libs.singular + sage: f.adams_operator(3, monic=True).factor() # needs sage.libs.singular (x - c^3) * (x - b^3) * (x - a^3) """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + u, v = PolynomialRing(self._parent.base_ring(), ['u', 'v']).gens() R = (u - v**n).resultant(self(v), v) R = R([self.variables()[0], 0]) @@ -7231,11 +7373,11 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(QQ) sage: f = x^4 - x + 2 - sage: [f.symmetric_power(k) for k in range(5)] # optional - sage.libs.singular + sage: [f.symmetric_power(k) for k in range(5)] # needs sage.libs.singular [x - 1, x^4 - x + 2, x^6 - 2*x^4 - x^3 - 4*x^2 + 8, x^4 - x^3 + 8, x - 2] sage: f = x^5 - 2*x + 2 - sage: [f.symmetric_power(k) for k in range(6)] # optional - sage.libs.singular + sage: [f.symmetric_power(k) for k in range(6)] # needs sage.libs.singular [x - 1, x^5 - 2*x + 2, x^10 + 2*x^8 - 4*x^6 - 8*x^5 - 8*x^4 - 8*x^3 + 16, @@ -7246,7 +7388,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: x = polygen(R) sage: f = (x - a) * (x - b) * (x - c) * (x - d) - sage: [f.symmetric_power(k).factor() for k in range(5)] # optional - sage.libs.singular + sage: [f.symmetric_power(k).factor() for k in range(5)] # needs sage.libs.singular [x - 1, (-x + d) * (-x + c) * (-x + b) * (-x + a), (x - c*d) * (x - b*d) * (x - a*d) * (x - b*c) * (x - a*c) * (x - a*b), @@ -7341,18 +7483,18 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: f = x^3 + x + 1 - sage: d = f.discriminant(); d # optional - sage.libs.pari + sage: d = f.discriminant(); d # needs sage.libs.pari -31 - sage: d.parent() is QQ # optional - sage.libs.pari + sage: d.parent() is QQ # needs sage.libs.pari True - sage: EllipticCurve([1, 1]).discriminant()/16 # optional - sage.libs.pari + sage: EllipticCurve([1, 1]).discriminant()/16 # needs sage.libs.pari -31 :: sage: R. = QQ[] sage: f = 2*x^3 + x + 1 - sage: d = f.discriminant(); d # optional - sage.libs.pari + sage: d = f.discriminant(); d # needs sage.libs.pari -116 We can compute discriminants over univariate and multivariate @@ -7361,9 +7503,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = a*x + x + a + 1 - sage: d = f.discriminant(); d # optional - sage.libs.pari + sage: d = f.discriminant(); d # needs sage.libs.pari 1 - sage: d.parent() is R # optional - sage.libs.pari + sage: d.parent() is R # needs sage.libs.pari True :: @@ -7371,9 +7513,9 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a + b - sage: d = f.discriminant(); d # optional - sage.libs.pari + sage: d = f.discriminant(); d # needs sage.libs.pari -4*a - 4*b - sage: d.parent() is R # optional - sage.libs.pari + sage: d.parent() is R # needs sage.libs.pari True TESTS:: @@ -7381,41 +7523,42 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = QQ[] sage: S. = R[] sage: f = x^2 + a - sage: f.discriminant() # optional - sage.libs.pari + sage: f.discriminant() # needs sage.libs.pari 1 Check that :trac:`13672` is fixed:: - sage: R. = GF(5)[] # optional - sage.rings.finite_rings - sage: S. = R[] # optional - sage.rings.finite_rings - sage: f = x^10 + 2*x^6 + 2*x^5 + x + 2 # optional - sage.rings.finite_rings - sage: (f - t).discriminant() # optional - sage.rings.finite_rings + sage: R. = GF(5)[] + sage: S. = R[] + sage: f = x^10 + 2*x^6 + 2*x^5 + x + 2 + sage: (f - t).discriminant() # needs sage.rings.finite_rings 4*t^5 The following examples show that :trac:`11782` has been fixed:: - sage: var('x') # optional - sage.symbolic + sage: var('x') # needs sage.symbolic x - sage: ZZ.quo(81)['x'](3*x^2 + 3*x + 3).discriminant() # optional - sage.libs.pari sage.symbolic + sage: ZZ.quo(81)['x'](3*x^2 + 3*x + 3).discriminant() # needs sage.libs.pari sage.symbolic 54 - sage: ZZ.quo(9)['x'](2*x^3 + x^2 + x).discriminant() # optional - sage.libs.pari sage.symbolic + sage: ZZ.quo(9)['x'](2*x^3 + x^2 + x).discriminant() # needs sage.libs.pari sage.symbolic 2 This was fixed by :trac:`15422`:: - sage: R. = PolynomialRing(Qp(2)) # optional - sage.rings.padics - sage: (s^2).discriminant() # optional - sage.rings.padics + sage: R. = PolynomialRing(Qp(2)) # needs sage.rings.padics + sage: (s^2).discriminant() # needs sage.rings.padics 0 This was fixed by :trac:`16014`:: + sage: # needs sage.modules sage: PR. = QQ[] sage: PRmu. = PR[] - sage: E1 = diagonal_matrix(PR, [1, b^2, -b^2]) # optional - sage.modules - sage: M = matrix(PR, [[1,-t1,x1-t1*y1], [t1,1,y1+t1*x1], [0,0,1]]) # optional - sage.modules - sage: E1 = M.transpose()*E1*M # optional - sage.modules - sage: E2 = E1.subs(t1=t2, x1=x2, y1=y2) # optional - sage.modules - sage: det(mu*E1 + E2).discriminant().degrees() # optional - sage.modules sage.libs.pari + sage: E1 = diagonal_matrix(PR, [1, b^2, -b^2]) + sage: M = matrix(PR, [[1,-t1,x1-t1*y1], [t1,1,y1+t1*x1], [0,0,1]]) + sage: E1 = M.transpose()*E1*M + sage: E2 = E1.subs(t1=t2, x1=x2, y1=y2) + sage: det(mu*E1 + E2).discriminant().degrees() # needs sage.libs.pari (24, 12, 12, 8, 8, 8, 8) This addresses an issue raised by :trac:`15061`:: @@ -7424,7 +7567,7 @@ cdef class Polynomial(CommutativePolynomial): sage: F = R([1,1],2) sage: RP. = PolynomialRing(R) sage: P = x^2 - F - sage: P.discriminant() # optional - sage.libs.pari + sage: P.discriminant() # needs sage.libs.pari 4 + 4*T + O(T^2) """ # Late import to avoid cyclic dependencies: @@ -7567,36 +7710,35 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.pari sage: x = QQ['x'].0 sage: f = x^3 - 1 - sage: f.roots() # optional - sage.libs.pari + sage: f.roots() [(1, 1)] - sage: f.roots(ring=CC) # ... - low order bits slightly different on ppc # optional - sage.libs.pari + sage: f.roots(ring=CC) # ... - low order bits slightly different on ppc [(1.00000000000000, 1), (-0.500000000000000 - 0.86602540378443...*I, 1), (-0.500000000000000 + 0.86602540378443...*I, 1)] sage: f = (x^3 - 1)^2 - sage: f.roots() # optional - sage.libs.pari + sage: f.roots() [(1, 2)] - - :: - sage: f = -19*x + 884736 - sage: f.roots() # optional - sage.libs.pari + sage: f.roots() [(884736/19, 1)] - sage: (f^20).roots() # optional - sage.libs.pari + sage: (f^20).roots() [(884736/19, 20)] :: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: f = K.defining_polynomial() # optional - sage.rings.number_field - sage: f.roots(ring=GF(7)) # optional - sage.rings.finite_rings sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: f = K.defining_polynomial() + sage: f.roots(ring=GF(7)) [(4, 1), (2, 1)] - sage: g = f.change_ring(GF(7)) # optional - sage.rings.finite_rings sage.rings.number_field - sage: g.roots() # optional - sage.rings.finite_rings sage.rings.number_field + sage: g = f.change_ring(GF(7)) + sage: g.roots() [(4, 1), (2, 1)] - sage: g.roots(multiplicities=False) # optional - sage.rings.finite_rings sage.rings.number_field + sage: g.roots(multiplicities=False) [4, 2] A new ring. In the example below, we add the special method @@ -7607,18 +7749,19 @@ cdef class Polynomial(CommutativePolynomial): introduce:: sage: R. = QQ[] - sage: (x^2 + 1).roots() # optional - sage.libs.pari + sage: (x^2 + 1).roots() # needs sage.libs.pari [] sage: def my_roots(f, *args, **kwds): ....: return f.change_ring(CDF).roots() sage: QQ._roots_univariate_polynomial = my_roots - sage: (x^2 + 1).roots() # abs tol 1e-14 + sage: (x^2 + 1).roots() # abs tol 1e-14 # needs numpy [(2.7755575615628914e-17 - 1.0*I, 1), (0.9999999999999997*I, 1)] sage: del QQ._roots_univariate_polynomial An example over RR, which illustrates that only the roots in RR are returned:: + sage: # needs numpy sage.rings.real_mpfr sage: x = RR['x'].0 sage: f = x^3 - 2 sage: f.roots() @@ -7634,11 +7777,11 @@ cdef class Polynomial(CommutativePolynomial): sage: x = CC['x'].0 sage: f = x^3 - 2 - sage: f.roots() + sage: f.roots() # needs numpy [(1.25992104989487, 1), (-0.62996052494743... - 1.09112363597172*I, 1), (-0.62996052494743... + 1.09112363597172*I, 1)] - sage: f.roots(algorithm='pari') # optional - sage.libs.pari + sage: f.roots(algorithm='pari') # needs sage.libs.pari [(1.25992104989487, 1), (-0.629960524947437 - 1.09112363597172*I, 1), (-0.629960524947437 + 1.09112363597172*I, 1)] @@ -7648,9 +7791,9 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(ZZ) sage: f = (2*x - 3) * (x - 1) * (x + 1) - sage: f.roots() + sage: f.roots() # needs sage.libs.pari [(1, 1), (-1, 1)] - sage: f.roots(ring=QQ) + sage: f.roots(ring=QQ) # needs sage.libs.pari [(3/2, 1), (1, 1), (-1, 1)] An example where we compute the roots lying in a subring of the @@ -7658,11 +7801,12 @@ cdef class Polynomial(CommutativePolynomial): sage: Pols. = QQ[] sage: pol = (n - 1/2)^2 * (n - 1)^2 * (n - 2) - sage: pol.roots(ZZ) + sage: pol.roots(ZZ) # needs sage.libs.pari [(2, 1), (1, 2)] An example involving large numbers:: + sage: # needs numpy sage.rings.real_mpfr sage: x = RR['x'].0 sage: f = x^2 - 1e100 sage: f.roots() @@ -7673,6 +7817,7 @@ cdef class Polynomial(CommutativePolynomial): :: + sage: # needs numpy sage.rings.real_mpfr sage: x = CC['x'].0 sage: i = CC.0 sage: f = (x - 1) * (x - i) @@ -7686,15 +7831,15 @@ cdef class Polynomial(CommutativePolynomial): sage: x = QQ['x'].0 sage: f = x^2 + 2 - sage: f.roots(SR) # optional - sage.symbolic + sage: f.roots(SR) # needs sage.symbolic [(-I*sqrt(2), 1), (I*sqrt(2), 1)] - sage: f.roots(SR, multiplicities=False) # optional - sage.symbolic + sage: f.roots(SR, multiplicities=False) # needs sage.symbolic [-I*sqrt(2), I*sqrt(2)] The roots of some polynomials cannot be described using radical expressions:: - sage: (x^5 - x + 1).roots(SR) # optional - sage.symbolic + sage: (x^5 - x + 1).roots(SR) # needs sage.symbolic [] For some other polynomials, no roots can be found at the moment @@ -7703,28 +7848,30 @@ cdef class Polynomial(CommutativePolynomial): is the following:: sage: f = x^6 - 300*x^5 + 30361*x^4 - 1061610*x^3 + 1141893*x^2 - 915320*x + 101724 - sage: f.roots() + sage: f.roots() # needs sage.libs.pari [] A purely symbolic roots example:: - sage: X = var('X') # optional - sage.symbolic - sage: f = expand((X - 1) * (X - I)^3 * (X^2 - sqrt(2))); f # optional - sage.symbolic + sage: # needs sage.symbolic + sage: X = var('X') + sage: f = expand((X - 1) * (X - I)^3 * (X^2 - sqrt(2))); f X^6 - (3*I + 1)*X^5 - sqrt(2)*X^4 + (3*I - 3)*X^4 + (3*I + 1)*sqrt(2)*X^3 + (I + 3)*X^3 - (3*I - 3)*sqrt(2)*X^2 - I*X^2 - (I + 3)*sqrt(2)*X + I*sqrt(2) - sage: f.roots() # optional - sage.symbolic + sage: f.roots() [(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)] The same operation, performed over a polynomial ring with symbolic coefficients:: - sage: X = SR['X'].0 # optional - sage.symbolic - sage: f = (X - 1) * (X - I)^3 * (X^2 - sqrt(2)); f # optional - sage.symbolic + sage: # needs sage.symbolic + sage: X = SR['X'].0 + sage: f = (X - 1) * (X - I)^3 * (X^2 - sqrt(2)); f X^6 + (-3*I - 1)*X^5 + (-sqrt(2) + 3*I - 3)*X^4 + ((3*I + 1)*sqrt(2) + I + 3)*X^3 + (-(3*I - 3)*sqrt(2) - I)*X^2 + (-(I + 3)*sqrt(2))*X + I*sqrt(2) - sage: f.roots() # optional - sage.symbolic + sage: f.roots() [(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)] - sage: f.roots(multiplicities=False) # optional - sage.symbolic + sage: f.roots(multiplicities=False) [I, -2^(1/4), 2^(1/4), 1] A couple of examples where the base ring does not have a @@ -7739,18 +7886,19 @@ cdef class Polynomial(CommutativePolynomial): ... NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) - sage: p.roots(multiplicities=False) + sage: p.roots(multiplicities=False) # needs sage.libs.pari [5, 1] sage: R = Integers(9) sage: A = PolynomialRing(R, 'y') sage: y = A.gen() sage: f = 10*y^2 - y^3 - 9 - sage: f.roots(multiplicities=False) + sage: f.roots(multiplicities=False) # needs sage.libs.pari [1, 0, 3, 6] An example over the complex double field (where root finding is fast, thanks to NumPy):: + sage: # needs numpy sage.rings.complex_double sage: R. = CDF[] sage: f = R.cyclotomic_polynomial(5); f x^4 + x^3 + x^2 + x + 1.0 @@ -7769,13 +7917,14 @@ cdef class Polynomial(CommutativePolynomial): Another example over RDF:: sage: x = RDF['x'].0 - sage: ((x^3 - 1)).roots() # abs tol 4e-16 + sage: ((x^3 - 1)).roots() # abs tol 4e-16 # needs numpy [(1.0000000000000002, 1)] - sage: ((x^3 - 1)).roots(multiplicities=False) # abs tol 4e-16 + sage: ((x^3 - 1)).roots(multiplicities=False) # abs tol 4e-16 # needs numpy [1.0000000000000002] More examples involving the complex double field:: + sage: # needs numpy sage.rings.complex_double sage.rings.real_mpfr sage: x = CDF['x'].0 sage: i = CDF.0 sage: f = x^3 + 2*i; f @@ -7802,8 +7951,12 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(ZZ) sage: f = x^2 - x - 1 - sage: f.roots() + sage: f.roots() # needs sage.libs.pari [] + sage: f.roots(ring=AA) # needs sage.rings.number_field + [(-0.618033988749895?, 1), (1.618033988749895?, 1)] + + sage: # needs sage.rings.real_interval_field sage: f.roots(ring=RIF) [(-0.6180339887498948482045868343657?, 1), (1.6180339887498948482045868343657?, 1)] sage: f.roots(ring=RIF, multiplicities=False) @@ -7811,8 +7964,6 @@ cdef class Polynomial(CommutativePolynomial): sage: f.roots(ring=RealIntervalField(150)) [(-0.6180339887498948482045868343656381177203091798057628621354486227?, 1), (1.618033988749894848204586834365638117720309179805762862135448623?, 1)] - sage: f.roots(ring=AA) # optional - sage.rings.number_field - [(-0.618033988749895?, 1), (1.618033988749895?, 1)] sage: f = f^2 * (x - 1) sage: f.roots(ring=RIF) [(-0.6180339887498948482045868343657?, 2), @@ -7827,29 +7978,42 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(ZZ) sage: p = x^5 - x - 1 - sage: p.roots() + sage: p.roots() # needs sage.libs.pari [] - sage: p.roots(ring=CIF) + sage: p.roots(ring=CIF) # needs sage.rings.complex_interval_field [(1.167303978261419?, 1), (-0.764884433600585? - 0.352471546031727?*I, 1), (-0.764884433600585? + 0.352471546031727?*I, 1), (0.181232444469876? - 1.083954101317711?*I, 1), (0.181232444469876? + 1.083954101317711?*I, 1)] - sage: p.roots(ring=ComplexIntervalField(200)) - [(1.167303978261418684256045899854842180720560371525489039140082?, 1), (-0.76488443360058472602982318770854173032899665194736756700778? - 0.35247154603172624931794709140258105439420648082424733283770?*I, 1), (-0.76488443360058472602982318770854173032899665194736756700778? + 0.35247154603172624931794709140258105439420648082424733283770?*I, 1), (0.18123244446987538390180023778112063996871646618462304743774? - 1.08395410131771066843034449298076657427364024315511565430114?*I, 1), (0.18123244446987538390180023778112063996871646618462304743774? + 1.08395410131771066843034449298076657427364024315511565430114?*I, 1)] - sage: rts = p.roots(ring=QQbar); rts # optional - sage.rings.number_field - [(1.167303978261419?, 1), (-0.7648844336005847? - 0.3524715460317263?*I, 1), (-0.7648844336005847? + 0.3524715460317263?*I, 1), (0.1812324444698754? - 1.083954101317711?*I, 1), (0.1812324444698754? + 1.083954101317711?*I, 1)] - sage: p.roots(ring=AA) # optional - sage.rings.number_field + sage: p.roots(ring=ComplexIntervalField(200)) # needs sage.rings.complex_interval_field + [(1.167303978261418684256045899854842180720560371525489039140082?, 1), + (-0.76488443360058472602982318770854173032899665194736756700778? - 0.35247154603172624931794709140258105439420648082424733283770?*I, 1), + (-0.76488443360058472602982318770854173032899665194736756700778? + 0.35247154603172624931794709140258105439420648082424733283770?*I, 1), + (0.18123244446987538390180023778112063996871646618462304743774? - 1.08395410131771066843034449298076657427364024315511565430114?*I, 1), + (0.18123244446987538390180023778112063996871646618462304743774? + 1.08395410131771066843034449298076657427364024315511565430114?*I, 1)] + sage: rts = p.roots(ring=QQbar); rts # needs sage.rings.number_field + [(1.167303978261419?, 1), + (-0.7648844336005847? - 0.3524715460317263?*I, 1), + (-0.7648844336005847? + 0.3524715460317263?*I, 1), + (0.1812324444698754? - 1.083954101317711?*I, 1), + (0.1812324444698754? + 1.083954101317711?*I, 1)] + sage: p.roots(ring=AA) # needs sage.rings.number_field [(1.167303978261419?, 1)] - sage: p = (x - rts[4][0])^2 * (3*x^2 + x + 1) - sage: p.roots(ring=QQbar) # optional - sage.rings.number_field - [(-0.1666666666666667? - 0.552770798392567?*I, 1), (-0.1666666666666667? + 0.552770798392567?*I, 1), (0.1812324444698754? + 1.083954101317711?*I, 2)] - sage: p.roots(ring=CIF) - [(-0.1666666666666667? - 0.552770798392567?*I, 1), (-0.1666666666666667? + 0.552770798392567?*I, 1), (0.1812324444698754? + 1.083954101317711?*I, 2)] + sage: p = (x - rts[4][0])^2 * (3*x^2 + x + 1) # needs sage.rings.number_field + sage: p.roots(ring=QQbar) # needs sage.rings.number_field + [(-0.1666666666666667? - 0.552770798392567?*I, 1), + (-0.1666666666666667? + 0.552770798392567?*I, 1), + (0.1812324444698754? + 1.083954101317711?*I, 2)] + sage: p.roots(ring=CIF) # needs sage.rings.complex_interval_field + [(-0.1666666666666667? - 0.552770798392567?*I, 1), + (-0.1666666666666667? + 0.552770798392567?*I, 1), + (0.1812324444698754? + 1.083954101317711?*I, 2)] In some cases, it is possible to isolate the roots of polynomials over complex ball fields:: + sage: # needs sage.libs.flint sage: Pol. = CBF[] sage: (x^2 + 2).roots(multiplicities=False) [[+/- ...e-19] + [-1.414213562373095 +/- ...e-17]*I, @@ -7868,16 +8032,17 @@ cdef class Polynomial(CommutativePolynomial): :: - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: y = polygen(K) # optional - sage.rings.number_field - sage: p = y^4 - 2 - im # optional - sage.rings.number_field - sage: p.roots(ring=CC) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-1) + sage: y = polygen(K) + sage: p = y^4 - 2 - im + sage: p.roots(ring=CC) [(-1.2146389322441... - 0.14142505258239...*I, 1), (-0.14142505258239... + 1.2146389322441...*I, 1), (0.14142505258239... - 1.2146389322441...*I, 1), (1.2146389322441... + 0.14142505258239...*I, 1)] - sage: p = p^2 * (y^2 - 2) # optional - sage.rings.number_field - sage: p.roots(ring=CIF) # optional - sage.rings.number_field + sage: p = p^2 * (y^2 - 2) + sage: p.roots(ring=CIF) [(-1.414213562373095?, 1), (1.414213562373095?, 1), (-1.214638932244183? - 0.141425052582394?*I, 2), (-0.141425052582394? + 1.214638932244183?*I, 2), @@ -7887,21 +8052,22 @@ cdef class Polynomial(CommutativePolynomial): Note that one should not use NumPy when wanting high precision output as it does not support any of the high precision types:: + sage: # needs numpy sage.rings.real_mpfr sage.symbolic sage: R. = RealField(200)[] - sage: f = x^2 - R(pi) # optional - sage.symbolic - sage: f.roots() # optional - sage.symbolic + sage: f = x^2 - R(pi) + sage: f.roots() [(-1.7724538509055160272981674833411451827975494561223871282138, 1), (1.7724538509055160272981674833411451827975494561223871282138, 1)] - sage: f.roots(algorithm='numpy') # optional - numpy sage.symbolic + sage: f.roots(algorithm='numpy') doctest... UserWarning: NumPy does not support arbitrary precision arithmetic. The roots found will likely have less precision than you expect. [(-1.77245385090551..., 1), (1.77245385090551..., 1)] We can also find roots over number fields:: - sage: K. = CyclotomicField(15) # optional - sage.rings.number_field - sage: R. = PolynomialRing(K) # optional - sage.rings.number_field - sage: (x^2 + x + 1).roots() # optional - sage.rings.number_field + sage: K. = CyclotomicField(15) # needs sage.rings.number_field + sage: R. = PolynomialRing(K) # needs sage.rings.number_field + sage: (x^2 + x + 1).roots() # needs sage.rings.number_field [(z^5, 1), (-z^5 - 1, 1)] There are many combinations of floating-point input and output @@ -7910,6 +8076,7 @@ cdef class Polynomial(CommutativePolynomial): :: + sage: # needs sage.rings.complex_double sage.rings.real_mpfr sage: rflds = (RR, RDF, RealField(100)) sage: cflds = (CC, CDF, ComplexField(100)) sage: def cross(a, b): @@ -7937,16 +8104,17 @@ cdef class Polynomial(CommutativePolynomial): Note that we can find the roots of a polynomial with algebraic coefficients:: - sage: rt2 = sqrt(AA(2)) # optional - sage.rings.number_field - sage: rt3 = sqrt(AA(3)) # optional - sage.rings.number_field - sage: x = polygen(AA) # optional - sage.rings.number_field - sage: f = (x - rt2) * (x - rt3); f # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: rt2 = sqrt(AA(2)) + sage: rt3 = sqrt(AA(3)) + sage: x = polygen(AA) + sage: f = (x - rt2) * (x - rt3); f x^2 - 3.146264369941973?*x + 2.449489742783178? - sage: rts = f.roots(); rts # optional - sage.rings.number_field + sage: rts = f.roots(); rts [(1.414213562373095?, 1), (1.732050807568878?, 1)] - sage: rts[0][0] == rt2 # optional - sage.rings.number_field + sage: rts[0][0] == rt2 True - sage: f.roots(ring=RealIntervalField(150)) # optional - sage.rings.number_field + sage: f.roots(ring=RealIntervalField(150)) [(1.414213562373095048801688724209698078569671875376948073176679738?, 1), (1.732050807568877293527446341505872366942805253810380628055806980?, 1)] @@ -7956,9 +8124,9 @@ cdef class Polynomial(CommutativePolynomial): ``RR`` and ``CC`` allow a much larger range of floating-point numbers:: sage: bigc = 2^1500 - sage: CDF(bigc) + sage: CDF(bigc) # needs sage.rings.complex_double +infinity - sage: CC(bigc) + sage: CC(bigc) # needs sage.rings.real_mpfr 3.50746621104340e451 Polynomials using such large coefficients can't be handled by @@ -7966,37 +8134,37 @@ cdef class Polynomial(CommutativePolynomial): sage: x = polygen(QQ) sage: p = x + bigc - sage: p.roots(ring=RR, algorithm='numpy') # optional - numpy + sage: p.roots(ring=RR, algorithm='numpy') # needs numpy Traceback (most recent call last): ... LinAlgError: Array must not contain infs or NaNs - sage: p.roots(ring=RR, algorithm='pari') # optional - sage.libs.pari + sage: p.roots(ring=RR, algorithm='pari') # needs sage.libs.pari [(-3.50746621104340e451, 1)] - sage: p.roots(ring=AA) # optional - sage.rings.number_field + sage: p.roots(ring=AA) # needs sage.rings.number_field [(-3.5074662110434039?e451, 1)] - sage: p.roots(ring=QQbar) # optional - sage.rings.number_field + sage: p.roots(ring=QQbar) # needs sage.rings.number_field [(-3.5074662110434039?e451, 1)] sage: p = bigc*x + 1 - sage: p.roots(ring=RR) + sage: p.roots(ring=RR) # needs numpy [(-2.85106096489671e-452, 1)] - sage: p.roots(ring=AA) # optional - sage.rings.number_field + sage: p.roots(ring=AA) # needs sage.rings.number_field [(-2.8510609648967059?e-452, 1)] - sage: p.roots(ring=QQbar) # optional - sage.rings.number_field + sage: p.roots(ring=QQbar) # needs sage.rings.number_field [(-2.8510609648967059?e-452, 1)] sage: p = x^2 - bigc - sage: p.roots(ring=RR) + sage: p.roots(ring=RR) # needs numpy [(-5.92238652153286e225, 1), (5.92238652153286e225, 1)] - sage: p.roots(ring=QQbar) # optional - sage.rings.number_field + sage: p.roots(ring=QQbar) # needs sage.rings.number_field [(-5.9223865215328558?e225, 1), (5.9223865215328558?e225, 1)] Check that :trac:`30522` is fixed:: - sage: PolynomialRing(SR, names="x")("x^2").roots() # optional - sage.symbolic + sage: PolynomialRing(SR, names="x")("x^2").roots() # needs sage.symbolic [(0, 2)] Check that :trac:`30523` is fixed:: - sage: PolynomialRing(SR, names="x")("x^2 + q").roots() # optional - sage.symbolic + sage: PolynomialRing(SR, names="x")("x^2 + q").roots() # needs sage.symbolic [(-sqrt(-q), 1), (sqrt(-q), 1)] ALGORITHM: @@ -8088,40 +8256,41 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: K. = CyclotomicField(2) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: factor(x^3 - 1) # optional - sage.rings.number_field + sage: K. = CyclotomicField(2) # needs sage.rings.number_field + sage: R. = K[] # needs sage.rings.number_field + sage: factor(x^3 - 1) # needs sage.rings.number_field (x - 1) * (x^2 + x + 1) This shows that the issue from :trac:`6237` is fixed:: sage: R. = QQ[] sage: g = -27*u^14 - 32*u^9 - sage: g.roots(CDF, multiplicities=False) # abs tol 2e-15 + sage: g.roots(CDF, multiplicities=False) # abs tol 2e-15 # needs numpy [-1.0345637159435719, 0.0, -0.3196977699902601 - 0.9839285635706636*I, -0.3196977699902601 + 0.9839285635706636*I, 0.8369796279620465 - 0.6081012947885318*I, 0.8369796279620465 + 0.6081012947885318*I] - sage: g.roots(CDF) # abs tol 2e-15 + sage: g.roots(CDF) # abs tol 2e-15 # needs numpy [(-1.0345637159435719, 1), (0.0, 9), (-0.3196977699902601 - 0.9839285635706636*I, 1), (-0.3196977699902601 + 0.9839285635706636*I, 1), (0.8369796279620465 - 0.6081012947885318*I, 1), (0.8369796279620465 + 0.6081012947885318*I, 1)] This shows that the issue at :trac:`2418` is fixed:: sage: x = polygen(QQ) - sage: p = (x^50/2^100 + x^10 + x + 1).change_ring(ComplexField(106)) - sage: rts = (p/2^100).roots(multiplicities=False) + sage: p = (x^50/2^100 + x^10 + x + 1).change_ring(ComplexField(106)) # needs sage.rings.real_mpfr + sage: rts = (p/2^100).roots(multiplicities=False) # needs sage.libs.pari sage: eps = 2^(-50) # we test the roots numerically - sage: [abs(p(rt)) < eps for rt in rts] == [True]*50 + sage: [abs(p(rt)) < eps for rt in rts] == [True]*50 # needs sage.rings.number_field True This shows that the issue at :trac:`10901` is fixed:: - sage: a = var('a'); R. = SR[] # optional - sage.symbolic - sage: f = x - a # optional - sage.symbolic - sage: f.roots(RR) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: a = var('a'); R. = SR[] + sage: f = x - a + sage: f.roots(RR) Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value - sage: f.roots(CC) # optional - sage.symbolic + sage: f.roots(CC) Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value @@ -8131,24 +8300,24 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: pol = (x - 1)^2 - sage: pol.roots(Qp(3, 5)) # optional - sage.rings.padics + sage: pol.roots(Qp(3, 5)) # needs sage.rings.padics [(1 + O(3^5), 2)] We lose precision if we first change coefficients to `\QQ_p`:: - sage: pol.change_ring(Qp(3, 5)).roots() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: pol.change_ring(Qp(3, 5)).roots() [(1 + O(3^3), 2)] - - sage: (pol - 3^6).roots(Qp(3, 5)) # optional - sage.rings.padics + sage: (pol - 3^6).roots(Qp(3, 5)) [(1 + 2*3^3 + 2*3^4 + O(3^5), 1), (1 + 3^3 + O(3^5), 1)] - sage: r = pol.roots(Zp(3, 5), multiplicities=False); r # optional - sage.rings.padics + sage: r = pol.roots(Zp(3, 5), multiplicities=False); r [1 + O(3^5)] - sage: parent(r[0]) # optional - sage.rings.padics + sage: parent(r[0]) 3-adic Ring with capped relative precision 5 Spurious crash with pari-2.5.5, see :trac:`16165`:: - sage: f=(1+x+x^2)^3 + sage: f = (1+x+x^2)^3 sage: f.roots(ring=CC) [(-0.500000000000000 - 0.866025403784439*I, 3), (-0.500000000000000 + 0.866025403784439*I, 3)] @@ -8165,14 +8334,14 @@ cdef class Polynomial(CommutativePolynomial): Test that some large finite rings can be handled (:trac:`13825`):: - sage: R. = IntegerModRing(20000009)[] + sage: R. = IntegerModRing(20000009)[] # needs sage.libs.pari sage: eq = x^6+x-17 - sage: eq.roots(multiplicities=False) + sage: eq.roots(multiplicities=False) # needs sage.libs.pari [3109038, 17207405] Test that roots in fixed modulus p-adic fields work (:trac:`17598`):: - sage: len(cyclotomic_polynomial(3).roots(ZpFM(739, 566))) # optional - sage.rings.padics + sage: len(cyclotomic_polynomial(3).roots(ZpFM(739, 566))) # needs sage.rings.padics 2 Check that :trac:`26421` is fixed:: @@ -8186,15 +8355,16 @@ cdef class Polynomial(CommutativePolynomial): Check that :trac:`31040` is fixed:: sage: R. = QQ[] - sage: K. = Qq(3).extension(x^2 + 1) # optional - sage.rings.padics - sage: (x^2 + 1).roots(K) # optional - sage.rings.padics + sage: K. = Qq(3).extension(x^2 + 1) # needs sage.rings.padics + sage: (x^2 + 1).roots(K) # needs sage.rings.padics [(a + O(3^20), 1), - (2*a + 2*a*3 + 2*a*3^2 + 2*a*3^3 + 2*a*3^4 + 2*a*3^5 + 2*a*3^6 + 2*a*3^7 + 2*a*3^8 + 2*a*3^9 + 2*a*3^10 + 2*a*3^11 + 2*a*3^12 + 2*a*3^13 + 2*a*3^14 + 2*a*3^15 + 2*a*3^16 + 2*a*3^17 + 2*a*3^18 + 2*a*3^19 + O(3^20), + (2*a + 2*a*3 + 2*a*3^2 + 2*a*3^3 + 2*a*3^4 + 2*a*3^5 + 2*a*3^6 + 2*a*3^7 + 2*a*3^8 + 2*a*3^9 + 2*a*3^10 + + 2*a*3^11 + 2*a*3^12 + 2*a*3^13 + 2*a*3^14 + 2*a*3^15 + 2*a*3^16 + 2*a*3^17 + 2*a*3^18 + 2*a*3^19 + O(3^20), 1)] Check that :trac:`31710` is fixed:: - sage: CBF['x'].zero().roots(multiplicities=False) + sage: CBF['x'].zero().roots(multiplicities=False) # needs sage.libs.flint Traceback (most recent call last): ... ArithmeticError: taking the roots of the zero polynomial @@ -8207,7 +8377,7 @@ cdef class Polynomial(CommutativePolynomial): sage: a = randint(0, n - 1) sage: b = randint(0, n - 1) sage: f = (x - a) * (x - b) - sage: all(r.parent() is K for r in f.roots(multiplicities=False)) + sage: all(r.parent() is K for r in f.roots(multiplicities=False)) # needs sage.rings.finite_rings True """ from sage.rings.finite_rings.finite_field_constructor import GF @@ -8268,6 +8438,8 @@ cdef class Polynomial(CommutativePolynomial): import numpy from numpy.linalg.linalg import LinAlgError + from sage.rings.complex_double import CDF + numpy_dtype = ('complex' if input_complex else 'double') ty = (complex if input_complex else float) coeffs = self.list() @@ -8287,6 +8459,8 @@ cdef class Polynomial(CommutativePolynomial): if algorithm == 'pari': if not input_arbprec: + from sage.rings.real_mpfr import RR + from sage.rings.cc import CC self = self.change_ring(CC if input_complex else RR) ext_rts = self.__pari__().polroots(precision=L.prec()) @@ -8398,6 +8572,7 @@ cdef class Polynomial(CommutativePolynomial): if isinstance(L, sage.rings.abc.ComplexDoubleField): real_field = RDF else: + from sage.rings.real_mpfr import RealField real_field = RealField(L.prec()) return self.change_ring(real_field).roots(ring=L, multiplicities=multiplicities, algorithm=algorithm) @@ -8472,11 +8647,11 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: pol = 20*x^3 - 50*x^2 + 20*x - sage: F = pol.factor(); F # optional - sage.libs.pari + sage: F = pol.factor(); F # needs sage.libs.pari 2 * 5 * (x - 2) * x * (2*x - 1) - sage: pol._roots_from_factorization(F, multiplicities=True) # optional - sage.libs.pari + sage: pol._roots_from_factorization(F, multiplicities=True) # needs sage.libs.pari [(2, 1), (0, 1)] - sage: pol.change_ring(QQ)._roots_from_factorization(F, multiplicities=False) # optional - sage.libs.pari + sage: pol.change_ring(QQ)._roots_from_factorization(F, multiplicities=False) # needs sage.libs.pari [2, 0, 1/2] """ seq = [] @@ -8506,14 +8681,14 @@ cdef class Polynomial(CommutativePolynomial): sage: Pols. = QQ[] sage: pol = (n - 1/2)^2 * (n - 1)^2 * (n - 2) - sage: rts = pol.roots(ZZ, multiplicities=False); rts # optional - sage.libs.pari + sage: rts = pol.roots(ZZ, multiplicities=False); rts # needs sage.libs.pari [2, 1] - sage: rts[0].parent() # optional - sage.libs.pari + sage: rts[0].parent() # needs sage.libs.pari Integer Ring sage: Pols_x. = QQ[] sage: Pols_xy. = Pols_x[] - sage: ((y - 1)*(y - x))._roots_in_subring(QQ, True, None) # optional - sage.libs.singular + sage: ((y - 1)*(y - x))._roots_in_subring(QQ, True, None) # needs sage.libs.singular [(1, 1)] """ K = self._parent.base_ring() @@ -8546,26 +8721,28 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(ZZ) - sage: (x^2 - x - 1).real_roots() + sage: (x^2 - x - 1).real_roots() # needs sage.rings.real_mpfr [-0.618033988749895, 1.61803398874989] TESTS:: - sage: x = polygen(RealField(100)) - sage: (x^2 - x - 1).real_roots()[0].parent() + sage: x = polygen(RealField(100)) # needs sage.rings.real_mpfr + sage: (x^2 - x - 1).real_roots()[0].parent() # needs sage.rings.real_mpfr Real Field with 100 bits of precision sage: x = polygen(RDF) - sage: (x^2 - x - 1).real_roots()[0].parent() + sage: (x^2 - x - 1).real_roots()[0].parent() # needs numpy Real Double Field - sage: x=polygen(ZZ,'x'); v=(x^2-x-1).real_roots() - sage: v[0].parent() is RR + sage: x = polygen(ZZ,'x'); v = (x^2 - x - 1).real_roots() # needs sage.rings.real_mpfr + sage: v[0].parent() is RR # needs sage.rings.real_mpfr True """ K = self.base_ring() if isinstance(K, (sage.rings.abc.RealField, sage.rings.abc.RealDoubleField)): return self.roots(multiplicities=False) + from sage.rings.real_mpfr import RR + return self.roots(ring=RR, multiplicities=False) def complex_roots(self): @@ -8580,38 +8757,48 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(ZZ) - sage: (x^3 - 1).complex_roots() # note: low order bits slightly different on ppc. - [1.00000000000000, -0.500000000000000 - 0.86602540378443...*I, -0.500000000000000 + 0.86602540378443...*I] + sage: (x^3 - 1).complex_roots() # note: low order bits slightly different on ppc. # needs sage.rings.real_mpfr + [1.00000000000000, + -0.500000000000000 - 0.86602540378443...*I, + -0.500000000000000 + 0.86602540378443...*I] TESTS:: - sage: x = polygen(RR) - sage: (x^3 - 1).complex_roots()[0].parent() + sage: x = polygen(RR) # needs sage.rings.real_mpfr + sage: (x^3 - 1).complex_roots()[0].parent() # needs sage.rings.real_mpfr Complex Field with 53 bits of precision + sage: x = polygen(RDF) - sage: (x^3 - 1).complex_roots()[0].parent() + sage: (x^3 - 1).complex_roots()[0].parent() # needs numpy Complex Double Field - sage: x = polygen(RealField(200)) - sage: (x^3 - 1).complex_roots()[0].parent() + + sage: x = polygen(RealField(200)) # needs sage.rings.real_mpfr + sage: (x^3 - 1).complex_roots()[0].parent() # needs sage.rings.real_mpfr Complex Field with 200 bits of precision - sage: x = polygen(CDF) - sage: (x^3 - 1).complex_roots()[0].parent() + + sage: x = polygen(CDF) # needs sage.rings.complex_double + sage: (x^3 - 1).complex_roots()[0].parent() # needs numpy sage.rings.complex_double Complex Double Field + + + sage: # needs sage.rings.real_mpfr sage: x = polygen(ComplexField(200)) sage: (x^3 - 1).complex_roots()[0].parent() Complex Field with 200 bits of precision - sage: x=polygen(ZZ,'x'); v=(x^2-x-1).complex_roots() + sage: x = polygen(ZZ,'x'); v=(x^2-x-1).complex_roots() sage: v[0].parent() is CC True """ K = self.base_ring() if isinstance(K, sage.rings.abc.RealField): + from sage.rings.complex_mpfr import ComplexField return self.roots(ring=ComplexField(K.prec()), multiplicities=False) if isinstance(K, sage.rings.abc.RealDoubleField): + from sage.rings.complex_double import CDF return self.roots(ring=CDF, multiplicities=False) if isinstance(K, (sage.rings.abc.ComplexField, sage.rings.abc.ComplexDoubleField)): return self.roots(multiplicities=False) - + from sage.rings.cc import CC return self.roots(ring=CC, multiplicities=False) def number_of_roots_in_interval(self, a=None, b=None): @@ -8630,37 +8817,41 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.pari sage: R. = PolynomialRing(ZZ) sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) - sage: pol.number_of_roots_in_interval(1, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(1, 2) 2 - sage: pol.number_of_roots_in_interval(1.01, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(1.01, 2) 1 - sage: pol.number_of_roots_in_interval(None, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(None, 2) 2 - sage: pol.number_of_roots_in_interval(1, Infinity) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(1, Infinity) 3 - sage: pol.number_of_roots_in_interval() # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval() 3 sage: pol = (x - 1) * (x - 2) * (x - 3) + + sage: # needs sage.libs.pari sage.rings.real_mpfr sage: pol2 = pol.change_ring(CC) - sage: pol2.number_of_roots_in_interval() # optional - sage.libs.pari + sage: pol2.number_of_roots_in_interval() 3 sage: R. = PolynomialRing(CC) sage: pol = (x - 1) * (x - CC(I)) - sage: pol.number_of_roots_in_interval(0, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(0, 2) 1 TESTS:: + sage: # needs sage.libs.pari sage: R. = PolynomialRing(ZZ) sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) - sage: pol.number_of_roots_in_interval(1, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(1, 2) 2 sage: pol = chebyshev_T(5,x) - sage: pol.number_of_roots_in_interval(-1, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(-1, 2) 5 - sage: pol.number_of_roots_in_interval(0, 2) # optional - sage.libs.pari + sage: pol.number_of_roots_in_interval(0, 2) 3 """ @@ -8688,17 +8879,20 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.pari sage: R. = PolynomialRing(ZZ) sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) - sage: pol.number_of_real_roots() # optional - sage.libs.pari + sage: pol.number_of_real_roots() 3 sage: pol = (x - 1) * (x - 2) * (x - 3) + + sage: # needs sage.libs.pari sage.rings.real_mpfr sage: pol2 = pol.change_ring(CC) - sage: pol2.number_of_real_roots() # optional - sage.libs.pari + sage: pol2.number_of_real_roots() 3 sage: R. = PolynomialRing(CC) sage: pol = (x - 1) * (x - CC(I)) - sage: pol.number_of_real_roots() # optional - sage.libs.pari + sage: pol.number_of_real_roots() 1 """ return self.number_of_roots_in_interval() @@ -8710,19 +8904,20 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.pari sage: R. = PolynomialRing(ZZ) sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3) - sage: pol.all_roots_in_interval(1, 3) # optional - sage.libs.pari + sage: pol.all_roots_in_interval(1, 3) True - sage: pol.all_roots_in_interval(1.01, 3) # optional - sage.libs.pari + sage: pol.all_roots_in_interval(1.01, 3) False sage: pol = chebyshev_T(5, x) - sage: pol.all_roots_in_interval(-1, 1) # optional - sage.libs.pari + sage: pol.all_roots_in_interval(-1, 1) True sage: pol = chebyshev_T(5, x/2) - sage: pol.all_roots_in_interval(-1, 1) # optional - sage.libs.pari + sage: pol.all_roots_in_interval(-1, 1) False - sage: pol.all_roots_in_interval() # optional - sage.libs.pari + sage: pol.all_roots_in_interval() True """ pol = self // self.gcd(self.derivative()) @@ -8734,12 +8929,13 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.libs.pari sage: R. = PolynomialRing(ZZ) sage: pol = chebyshev_T(5, x) - sage: pol.is_real_rooted() # optional - sage.libs.pari + sage: pol.is_real_rooted() True sage: pol = x^2 + 1 - sage: pol.is_real_rooted() # optional - sage.libs.pari + sage: pol.is_real_rooted() False """ return self.all_roots_in_interval() @@ -8820,22 +9016,23 @@ cdef class Polynomial(CommutativePolynomial): We check that this function works for rings that have a coercion to the reals:: - sage: K. = NumberField(x^2 - 2, embedding=1.4) # optional - sage.rings.number_field - sage: u = x^4 + a*x^3 + 3*x^2 + 2*a*x + 4 # optional - sage.rings.number_field - sage: u.trace_polynomial() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^2 - 2, embedding=1.4) + sage: u = x^4 + a*x^3 + 3*x^2 + 2*a*x + 4 + sage: u.trace_polynomial() (x^2 + a*x - 1, 1, 2) - sage: (u*(x^2-2)).trace_polynomial() # optional - sage.rings.number_field + sage: (u*(x^2-2)).trace_polynomial() (x^2 + a*x - 1, x^2 - 2, 2) - sage: (u*(x^2-2)^2).trace_polynomial() # optional - sage.rings.number_field + sage: (u*(x^2-2)^2).trace_polynomial() (x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, 1, 2) - sage: (u*(x^2-2)^3).trace_polynomial() # optional - sage.rings.number_field + sage: (u*(x^2-2)^3).trace_polynomial() (x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, x^2 - 2, 2) - sage: u = x^4 + a*x^3 + 3*x^2 + 4*a*x + 16 # optional - sage.rings.number_field - sage: u.trace_polynomial() # optional - sage.rings.number_field + sage: u = x^4 + a*x^3 + 3*x^2 + 4*a*x + 16 + sage: u.trace_polynomial() (x^2 + a*x - 5, 1, 4) - sage: (u*(x-2)).trace_polynomial() # optional - sage.rings.number_field + sage: (u*(x-2)).trace_polynomial() (x^2 + a*x - 5, x - 2, 4) - sage: (u*(x+2)).trace_polynomial() # optional - sage.rings.number_field + sage: (u*(x+2)).trace_polynomial() (x^2 + a*x - 5, x + 2, 4) TESTS: @@ -8900,15 +9097,15 @@ cdef class Polynomial(CommutativePolynomial): sage: P0 = x^4 + 5*x^3 + 15*x^2 + 25*x + 25 sage: P1 = x^4 + 25*x^3 + 15*x^2 + 5*x + 25 sage: P2 = x^4 + 5*x^3 + 25*x^2 + 25*x + 25 - sage: P0.is_weil_polynomial(return_q=True) # optional - sage.libs.pari + sage: P0.is_weil_polynomial(return_q=True) # needs sage.libs.pari (True, 5) - sage: P0.is_weil_polynomial(return_q=False) # optional - sage.libs.pari + sage: P0.is_weil_polynomial(return_q=False) # needs sage.libs.pari True - sage: P1.is_weil_polynomial(return_q=True) # optional - sage.libs.pari + sage: P1.is_weil_polynomial(return_q=True) (False, 0) - sage: P1.is_weil_polynomial(return_q=False) # optional - sage.libs.pari + sage: P1.is_weil_polynomial(return_q=False) False - sage: P2.is_weil_polynomial() # optional - sage.libs.pari + sage: P2.is_weil_polynomial() # needs sage.libs.pari False .. SEEALSO:: @@ -8923,7 +9120,7 @@ cdef class Polynomial(CommutativePolynomial): sage: P. = QQ[] sage: u = t^10 + 4*t^9 + 8*t^8 + 18*t^7 + 81*t^6 + 272*t^5 + 567*t^4 + 882*t^3 + 2744*t^2 + 9604*t + 16807 - sage: u.is_weil_polynomial() # optional - sage.libs.pari + sage: u.is_weil_polynomial() # needs sage.libs.pari True AUTHORS: @@ -9002,6 +9199,8 @@ cdef class Polynomial(CommutativePolynomial): For full definitions and related discussion, see [BrHu2019]_ and [HMMS2019]_. """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self.base_ring(), 1, [self.variable_name()]) return R(self).is_lorentzian(explain=explain) @@ -9044,12 +9243,13 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (2*x^2).gcd(2*x) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: (2*x^2).gcd(2*x) x - sage: R.zero().gcd(0) # optional - sage.rings.number_field + sage: R.zero().gcd(0) 0 - sage: (2*x).gcd(0) # optional - sage.rings.number_field + sage: (2*x).gcd(0) x One can easily add xgcd functionality to new rings by providing a @@ -9175,11 +9375,12 @@ cdef class Polynomial(CommutativePolynomial): Over `\QQ_5`:: - sage: x = PolynomialRing(Qp(5), 'x').gen() # optional - sage.rings.padics - sage: p = 4*x^5 + 3*x^4 + 2*x^3 + 2*x^2 + 4*x + 2 # optional - sage.rings.padics - sage: m = x^6 # optional - sage.rings.padics - sage: n, d = p.rational_reconstruction(m, 3, 2) # optional - sage.rings.padics - sage: ((p*d - n) % m).is_zero() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: x = PolynomialRing(Qp(5), 'x').gen() + sage: p = 4*x^5 + 3*x^4 + 2*x^3 + 2*x^2 + 4*x + 2 + sage: m = x^6 + sage: n, d = p.rational_reconstruction(m, 3, 2) + sage: ((p*d - n) % m).is_zero() True Can also be used to obtain known Padé approximations:: @@ -9427,11 +9628,11 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: R. = ZZ[] - sage: (x^3 + 1).is_irreducible() # optional - sage.libs.pari + sage: (x^3 + 1).is_irreducible() # needs sage.libs.pari False - sage: (x^2 - 1).is_irreducible() # optional - sage.libs.pari + sage: (x^2 - 1).is_irreducible() # needs sage.libs.pari False - sage: (x^3 + 2).is_irreducible() # optional - sage.libs.pari + sage: (x^3 + 2).is_irreducible() # needs sage.libs.pari True sage: R(0).is_irreducible() False @@ -9440,31 +9641,32 @@ cdef class Polynomial(CommutativePolynomial): polynomial in `\QQ[x]`, but not in `\ZZ[x]`:: sage: R. = ZZ[] - sage: R(2*x).is_irreducible() # optional - sage.libs.pari + sage: R(2*x).is_irreducible() # needs sage.libs.pari False sage: R. = QQ[] - sage: R(2*x).is_irreducible() # optional - sage.libs.pari + sage: R(2*x).is_irreducible() # needs sage.libs.pari True TESTS:: - sage: F. = NumberField(x^2 - 5) # optional - sage.rings.number_field - sage: Fx. = PolynomialRing(F) # optional - sage.rings.number_field - sage: f = Fx([2*t - 5, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) # optional - sage.rings.number_field - sage: f.is_irreducible() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = NumberField(x^2 - 5) + sage: Fx. = PolynomialRing(F) + sage: f = Fx([2*t - 5, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) + sage: f.is_irreducible() False - sage: f = Fx([2*t - 3, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) # optional - sage.rings.number_field - sage: f.is_irreducible() # optional - sage.rings.number_field + sage: f = Fx([2*t - 3, 5*t - 10, 3*t - 6, -t, -t + 2, 1]) + sage: f.is_irreducible() True If the base ring implements `_is_irreducible_univariate_polynomial`, then this method gets used instead of the generic algorithm which just factors the input:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: hasattr(QQbar, "_is_irreducible_univariate_polynomial") # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: hasattr(QQbar, "_is_irreducible_univariate_polynomial") # needs sage.rings.number_field True - sage: (x^2 + 1).is_irreducible() # optional - sage.rings.number_field + sage: (x^2 + 1).is_irreducible() # needs sage.rings.number_field False Constants can be irreducible if they are not units:: @@ -9472,17 +9674,17 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: R(1).is_irreducible() False - sage: R(4).is_irreducible() # optional - sage.libs.pari + sage: R(4).is_irreducible() False - sage: R(5).is_irreducible() # optional - sage.libs.pari + sage: R(5).is_irreducible() True Check that caching works:: sage: R. = ZZ[] - sage: x.is_irreducible() # optional - sage.libs.pari + sage: x.is_irreducible() # needs sage.libs.pari True - sage: x.is_irreducible.cache # optional - sage.libs.pari + sage: x.is_irreducible.cache # needs sage.libs.pari True @@ -9629,56 +9831,58 @@ cdef class Polynomial(CommutativePolynomial): A generic implementation is available, which relies on gcd computations:: + sage: # needs sage.libs.pari sage: R. = ZZ[] - sage: (2*x).is_squarefree() # optional - sage.libs.pari + sage: (2*x).is_squarefree() # needs sage.libs.pari True - sage: (4*x).is_squarefree() # optional - sage.libs.pari + sage: (4*x).is_squarefree() # needs sage.libs.pari False - sage: (2*x^2).is_squarefree() # optional - sage.libs.pari + sage: (2*x^2).is_squarefree() # needs sage.libs.pari False - sage: R(0).is_squarefree() # optional - sage.libs.pari + sage: R(0).is_squarefree() # needs sage.libs.pari False - sage: S. = QQ[] # optional - sage.libs.pari - sage: R. = S[] # optional - sage.libs.pari - sage: (2*x*y).is_squarefree() # optional - sage.libs.pari + + sage: S. = QQ[] + sage: R. = S[] + sage: (2*x*y).is_squarefree() True - sage: (2*x*y^2).is_squarefree() # optional - sage.libs.pari + sage: (2*x*y^2).is_squarefree() False In positive characteristic, we compute the square-free decomposition or a full factorization, depending on which is available:: - sage: K. = FunctionField(GF(3)) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: (x^3 - x).is_squarefree() # optional - sage.rings.finite_rings + sage: K. = FunctionField(GF(3)) + sage: R. = K[] + sage: (x^3 - x).is_squarefree() True - sage: (x^3 - 1).is_squarefree() # optional - sage.rings.finite_rings + sage: (x^3 - 1).is_squarefree() # needs sage.libs.pari False - sage: (x^3 + t).is_squarefree() # optional - sage.rings.finite_rings + sage: (x^3 + t).is_squarefree() # needs sage.libs.pari True - sage: (x^3 + t^3).is_squarefree() # optional - sage.rings.finite_rings + sage: (x^3 + t^3).is_squarefree() # needs sage.libs.pari False In the following example, `t^2` is a unit in the base field:: - sage: R(t^2).is_squarefree() # optional - sage.rings.finite_rings + sage: R(t^2).is_squarefree() True This method is not consistent with :meth:`.squarefree_decomposition`:: sage: R. = ZZ[] sage: f = 4 * x - sage: f.is_squarefree() # optional - sage.rings.finite_rings + sage: f.is_squarefree() # needs sage.libs.pari False - sage: f.squarefree_decomposition() # optional - sage.rings.finite_rings + sage: f.squarefree_decomposition() # needs sage.libs.pari (4) * x If you want this method equally not to consider the content, you can remove it as in the following example:: sage: c = f.content() - sage: (f/c).is_squarefree() # optional - sage.rings.finite_rings + sage: (f/c).is_squarefree() # needs sage.libs.pari True If the base ring is not an integral domain, the question is not @@ -9699,7 +9903,7 @@ cdef class Polynomial(CommutativePolynomial): sage: R. = ZZ[] sage: f = x^2 - sage: f.is_squarefree() + sage: f.is_squarefree() # needs sage.libs.pari False sage: f.is_squarefree.cache False @@ -9708,15 +9912,16 @@ cdef class Polynomial(CommutativePolynomial): then this method gets used instead of the generic algorithm in :meth:`_is_squarefree_generic`:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x^2).is_squarefree() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: (x^2).is_squarefree() False - sage: hasattr(QQbar, '_is_squarefree_univariate_polynomial') # optional - sage.rings.number_field + sage: hasattr(QQbar, '_is_squarefree_univariate_polynomial') False - sage: QQbar._is_squarefree_univariate_polynomial = lambda self: True # optional - sage.rings.number_field - sage: (x^2).is_squarefree() # optional - sage.rings.number_field + sage: QQbar._is_squarefree_univariate_polynomial = lambda self: True + sage: (x^2).is_squarefree() True - sage: del(QQbar._is_squarefree_univariate_polynomial) # optional - sage.rings.number_field + sage: del(QQbar._is_squarefree_univariate_polynomial) """ B = self._parent.base_ring() @@ -9736,10 +9941,10 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: (x^2*(x + 1)).is_squarefree() # indirect doctest # optional - sage.rings.number_field + sage: R. = QQbar[] # needs sage.rings.number_field + sage: (x^2*(x + 1)).is_squarefree() # indirect doctest # needs sage.rings.number_field False - sage: (x*(x+1)).is_squarefree() # indirect doctest # optional - sage.rings.number_field + sage: (x*(x+1)).is_squarefree() # indirect doctest # needs sage.rings.number_field True """ @@ -9790,8 +9995,8 @@ cdef class Polynomial(CommutativePolynomial): If self has a factor of multiplicity divisible by the characteristic (see :trac:`8736`):: - sage: P. = GF(2)[] # optional - sage.rings.finite_rings - sage: (x^3 + x^2).radical() # optional - sage.rings.finite_rings + sage: P. = GF(2)[] + sage: (x^3 + x^2).radical() # needs sage.rings.finite_rings x^2 + x """ P = self._parent @@ -9850,38 +10055,39 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: R. = RR[] sage: f = x^6 + x^2 + -x^4 - 2*x^3 sage: f.norm(2) 2.64575131106459 - sage: (sqrt(1^2 + 1^2 + (-1)^2 + (-2)^2)).n() + sage: (sqrt(1^2 + 1^2 + (-1)^2 + (-2)^2)).n() # needs sage.symbolic 2.64575131106459 :: - sage: f.norm(1) + sage: f.norm(1) # needs sage.rings.real_mpfr 5.00000000000000 - sage: f.norm(infinity) + sage: f.norm(infinity) # needs sage.rings.real_mpfr 2.00000000000000 :: - sage: f.norm(-1) + sage: f.norm(-1) # needs sage.rings.real_mpfr Traceback (most recent call last): ... ValueError: The degree of the norm must be positive TESTS:: - sage: R. = RR[] - sage: f = x^6 + x^2 + -x^4 -x^3 - sage: f.norm(int(2)) + sage: R. = RR[] # needs sage.rings.real_mpfr + sage: f = x^6 + x^2 + -x^4 -x^3 # needs sage.rings.real_mpfr + sage: f.norm(int(2)) # needs sage.rings.real_mpfr 2.00000000000000 Check that :trac:`18600` is fixed:: sage: R. = PolynomialRing(ZZ, sparse=True) - sage: (x^2^100 + 1).norm(1) + sage: (x^2^100 + 1).norm(1) # needs sage.rings.real_mpfr 2.00000000000000 AUTHORS: @@ -9889,7 +10095,9 @@ cdef class Polynomial(CommutativePolynomial): - Didier Deshommes - William Stein: fix bugs, add definition, etc. """ - if p <= 0 : + from sage.rings.real_mpfr import RR + + if p <= 0: raise ValueError("The degree of the norm must be positive") coeffs = self.coefficients() @@ -9920,10 +10128,10 @@ cdef class Polynomial(CommutativePolynomial): sage: f = (x + 1)^100 sage: f.number_of_terms() 101 - sage: S = GF(5)['y'] # optional - sage.rings.finite_rings - sage: S(f).number_of_terms() # optional - sage.rings.finite_rings + sage: S = GF(5)['y'] + sage: S(f).number_of_terms() 5 - sage: cyclotomic_polynomial(105).number_of_terms() # optional - sage.rings.finite_rings + sage: cyclotomic_polynomial(105).number_of_terms() 33 The method :meth:`hamming_weight` is an alias:: @@ -9959,41 +10167,43 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: R. = SR[] # optional - sage.symbolic - sage: f = (1+I)*x^2 + 3*x - I # optional - sage.symbolic - sage: f.map_coefficients(lambda z: z.conjugate()) # optional - sage.symbolic - (-I + 1)*x^2 + 3*x + I sage: R. = ZZ[] sage: f = x^2 + 2 sage: f.map_coefficients(lambda a: a + 42) 43*x^2 + 44 - sage: R. = PolynomialRing(SR, sparse=True) # optional - sage.symbolic - sage: f = (1+I)*x^(2^32) - I # optional - sage.symbolic - sage: f.map_coefficients(lambda z: z.conjugate()) # optional - sage.symbolic - (-I + 1)*x^4294967296 + I sage: R. = PolynomialRing(ZZ, sparse=True) sage: f = x^(2^32) + 2 sage: f.map_coefficients(lambda a: a + 42) 43*x^4294967296 + 44 + sage: # needs sage.symbolic + sage: R. = SR[] + sage: f = (1+I)*x^2 + 3*x - I + sage: f.map_coefficients(lambda z: z.conjugate()) + (-I + 1)*x^2 + 3*x + I + sage: R. = PolynomialRing(SR, sparse=True) + sage: f = (1+I)*x^(2^32) - I + sage: f.map_coefficients(lambda z: z.conjugate()) + (-I + 1)*x^4294967296 + I + Examples with different base ring:: sage: R. = ZZ[] - sage: k = GF(2) # optional - sage.rings.finite_rings - sage: residue = lambda x: k(x) # optional - sage.rings.finite_rings - sage: f = 4*x^2 + x + 3 # optional - sage.rings.finite_rings - sage: g = f.map_coefficients(residue); g # optional - sage.rings.finite_rings + sage: k = GF(2) + sage: residue = lambda x: k(x) + sage: f = 4*x^2 + x + 3 + sage: g = f.map_coefficients(residue); g x + 1 - sage: g.parent() # optional - sage.rings.finite_rings + sage: g.parent() Univariate Polynomial Ring in x over Integer Ring - sage: g = f.map_coefficients(residue, new_base_ring=k); g # optional - sage.rings.finite_rings + sage: g = f.map_coefficients(residue, new_base_ring=k); g x + 1 - sage: g.parent() # optional - sage.rings.finite_rings + sage: g.parent() # needs sage.libs.ntl Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: residue = k.coerce_map_from(ZZ) # optional - sage.rings.finite_rings - sage: g = f.map_coefficients(residue); g # optional - sage.rings.finite_rings + sage: residue = k.coerce_map_from(ZZ) + sage: g = f.map_coefficients(residue); g x + 1 - sage: g.parent() # optional - sage.rings.finite_rings + sage: g.parent() # needs sage.libs.ntl Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) """ R = self._parent @@ -10040,54 +10250,55 @@ cdef class Polynomial(CommutativePolynomial): Quick tests:: + sage: # needs sage.libs.pari sage: P. = ZZ['x'] - sage: (x - 1).is_cyclotomic() # optional - sage.libs.pari + sage: (x - 1).is_cyclotomic() True - sage: (x + 1).is_cyclotomic() # optional - sage.libs.pari + sage: (x + 1).is_cyclotomic() True - sage: (x^2 - 1).is_cyclotomic() # optional - sage.libs.pari + sage: (x^2 - 1).is_cyclotomic() False - sage: (x^2 + x + 1).is_cyclotomic(certificate=True) # optional - sage.libs.pari + sage: (x^2 + x + 1).is_cyclotomic(certificate=True) 3 - sage: (x^2 + 2*x + 1).is_cyclotomic(certificate=True) # optional - sage.libs.pari + sage: (x^2 + 2*x + 1).is_cyclotomic(certificate=True) 0 Test first 100 cyclotomic polynomials:: - sage: all(cyclotomic_polynomial(i).is_cyclotomic() for i in range(1, 101)) # optional - sage.libs.pari + sage: all(cyclotomic_polynomial(i).is_cyclotomic() for i in range(1, 101)) # needs sage.libs.pari True Some more tests:: + sage: # needs sage.libs.pari sage: f = x^16 + x^14 - x^10 + x^8 - x^6 + x^2 + 1 - sage: f.is_cyclotomic(algorithm="pari") # optional - sage.libs.pari + sage: f.is_cyclotomic(algorithm="pari") False - sage: f.is_cyclotomic(algorithm="sage") # optional - sage.libs.pari + sage: f.is_cyclotomic(algorithm="sage") False - sage: g = x^16 + x^14 - x^10 - x^8 - x^6 + x^2 + 1 - sage: g.is_cyclotomic(algorithm="pari") # optional - sage.libs.pari + sage: g.is_cyclotomic(algorithm="pari") True - sage: g.is_cyclotomic(algorithm="sage") # optional - sage.libs.pari + sage: g.is_cyclotomic(algorithm="sage") True sage: y = polygen(QQ) - sage: (y/2 - 1/2).is_cyclotomic() # optional - sage.libs.pari + sage: (y/2 - 1/2).is_cyclotomic() False - sage: (2*(y/2 - 1/2)).is_cyclotomic() # optional - sage.libs.pari + sage: (2*(y/2 - 1/2)).is_cyclotomic() # needs sage.libs.pari True Invalid arguments:: - sage: (x - 3).is_cyclotomic(algorithm="sage", certificate=True) + sage: (x - 3).is_cyclotomic(algorithm="sage", certificate=True) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: no implementation of the certificate within Sage Test using other rings:: - sage: z = polygen(GF(5)) # optional - sage.rings.finite_rings - sage: (z - 1).is_cyclotomic() # optional - sage.rings.finite_rings + sage: z = polygen(GF(5)) + sage: (z - 1).is_cyclotomic() Traceback (most recent call last): ... NotImplementedError: not implemented in non-zero characteristic @@ -10095,28 +10306,28 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: sage: R = ZZ['x'] - sage: for _ in range(20): # optional - sage.libs.pari + sage: for _ in range(20): # needs sage.libs.pari ....: p = R.random_element(degree=randint(10,20)) ....: ans_pari = p.is_cyclotomic(algorithm="pari") ....: ans_sage = p.is_cyclotomic(algorithm="sage") ....: assert ans_pari == ans_sage, "problem with p={}".format(p) - sage: for d in range(2, 20): # optional - sage.libs.pari + sage: for d in range(2, 20): # needs sage.libs.pari ....: p = cyclotomic_polynomial(d) ....: assert p.is_cyclotomic(algorithm="pari"), "pari problem with p={}".format(p) ....: assert p.is_cyclotomic(algorithm="sage"), "sage problem with p={}".format(p) Test the output type when ``certificate=True``:: - sage: type((x^2 - 2).is_cyclotomic(certificate=True)) # optional - sage.libs.pari + sage: type((x^2 - 2).is_cyclotomic(certificate=True)) # needs sage.libs.pari - sage: type((x - 1).is_cyclotomic(certificate=True)) # optional - sage.libs.pari + sage: type((x - 1).is_cyclotomic(certificate=True)) # needs sage.libs.pari Check that the arguments are forwarded when the input is not a polynomial with coefficients in `\ZZ`:: sage: x = polygen(QQ) - sage: (x - 1).is_cyclotomic(certificate=True) # optional - sage.libs.pari + sage: (x - 1).is_cyclotomic(certificate=True) # needs sage.libs.pari 1 """ S = self.base_ring() @@ -10193,20 +10404,20 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: sage: x = polygen(ZZ) - sage: (x^5 - 1).is_cyclotomic_product() # optional - sage.libs.pari + sage: (x^5 - 1).is_cyclotomic_product() # needs sage.libs.pari True - sage: (x^5 + x^4 - x^2 + 1).is_cyclotomic_product() # optional - sage.libs.pari + sage: (x^5 + x^4 - x^2 + 1).is_cyclotomic_product() # needs sage.libs.pari False - sage: p = prod(cyclotomic_polynomial(i) for i in [2, 5, 7, 12]) # optional - sage.libs.pari - sage: p.is_cyclotomic_product() # optional - sage.libs.pari + sage: p = prod(cyclotomic_polynomial(i) for i in [2, 5, 7, 12]) + sage: p.is_cyclotomic_product() # needs sage.libs.pari True - sage: (x^5 - 1/3).is_cyclotomic_product() # optional - sage.libs.pari + sage: (x^5 - 1/3).is_cyclotomic_product() False sage: x = polygen(Zmod(5)) - sage: (x - 1).is_cyclotomic_product() # optional - sage.libs.pari + sage: (x - 1).is_cyclotomic_product() Traceback (most recent call last): ... NotImplementedError: not implemented in non-zero characteristic @@ -10327,8 +10538,8 @@ cdef class Polynomial(CommutativePolynomial): True sage: u = x^5 - 2; u.has_cyclotomic_factor() False - sage: u = pol(cyclotomic_polynomial(7)) * pol.random_element() # random # optional - sage.libs.pari - sage: u.has_cyclotomic_factor() # random # optional - sage.libs.pari + sage: u = pol(cyclotomic_polynomial(7)) * pol.random_element() # random + sage: u.has_cyclotomic_factor() # random True """ if not QQ.has_coerce_map_from(self.base_ring()): @@ -10419,9 +10630,9 @@ cdef class Polynomial(CommutativePolynomial): In positive characteristic, the degree can drop in this case:: - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: f = x + 1 # optional - sage.rings.finite_rings - sage: f.homogenize(x) # optional - sage.rings.finite_rings + sage: R. = GF(2)[] + sage: f = x + 1 + sage: f.homogenize(x) 0 For compatibility with the multivariate case, the parameter ``var`` can @@ -10450,6 +10661,8 @@ cdef class Polynomial(CommutativePolynomial): if var == x_name: return sum(self.coefficients())*x**self.degree() + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + P = PolynomialRing(self.base_ring(), [x_name, var]) return P(self)._homogenize(1) @@ -10498,43 +10711,46 @@ cdef class Polynomial(CommutativePolynomial): sage: a.nth_root(2) 1/56*x^3 + 103/336*x^2 + 365/252*x + 25/12 - sage: K. = QuadraticField(2) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: a = (x + sqrt2)^3 * ((1+sqrt2)*x - 1/sqrt2)^6 # optional - sage.rings.number_field - sage: b = a.nth_root(3); b # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(2) + sage: R. = K[] + sage: a = (x + sqrt2)^3 * ((1+sqrt2)*x - 1/sqrt2)^6 + sage: b = a.nth_root(3); b (2*sqrt2 + 3)*x^3 + (2*sqrt2 + 2)*x^2 + (-2*sqrt2 - 3/2)*x + 1/2*sqrt2 - sage: b^3 == a # optional - sage.rings.number_field + sage: b^3 == a True - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: p = x**3 + QQbar(2).sqrt() * x - QQbar(3).sqrt() # optional - sage.rings.number_field - sage: r = (p**5).nth_root(5) # optional - sage.rings.number_field - sage: r * p[0] == p * r[0] # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: p = x**3 + QQbar(2).sqrt() * x - QQbar(3).sqrt() + sage: r = (p**5).nth_root(5) + sage: r * p[0] == p * r[0] True - sage: p = (x+1)^20 + x^20 # optional - sage.rings.number_field - sage: p.nth_root(20) # optional - sage.rings.number_field + sage: p = (x+1)^20 + x^20 + sage: p.nth_root(20) Traceback (most recent call last): ... ValueError: not a 20th power - sage: z = GF(4).gen() # optional - sage.rings.finite_rings - sage: R. = GF(4)[] # optional - sage.rings.finite_rings - sage: p = z*x**4 + 2*x - 1 # optional - sage.rings.finite_rings - sage: r = (p**15).nth_root(15) # optional - sage.rings.finite_rings - sage: r * p[0] == p * r[0] # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: z = GF(4).gen() + sage: R. = GF(4)[] + sage: p = z*x**4 + 2*x - 1 + sage: r = (p**15).nth_root(15) + sage: r * p[0] == p * r[0] True - sage: ((x+1)**2).nth_root(2) # optional - sage.rings.finite_rings + sage: ((x+1)**2).nth_root(2) x + 1 - sage: ((x+1)**4).nth_root(4) # optional - sage.rings.finite_rings + sage: ((x+1)**4).nth_root(4) x + 1 - sage: ((x+1)**12).nth_root(12) # optional - sage.rings.finite_rings + sage: ((x+1)**12).nth_root(12) x + 1 - sage: (x^4 + x^3 + 1).nth_root(2) # optional - sage.rings.finite_rings + sage: (x^4 + x^3 + 1).nth_root(2) Traceback (most recent call last): ... ValueError: not a 2nd power - sage: p = (x+1)^17 + x^17 # optional - sage.rings.finite_rings - sage: r = p.nth_root(17) # optional - sage.rings.finite_rings + sage: p = (x+1)^17 + x^17 + sage: r = p.nth_root(17) Traceback (most recent call last): ... ValueError: not a 17th power @@ -10550,15 +10766,16 @@ cdef class Polynomial(CommutativePolynomial): Here we consider a base ring without ``nth_root`` method. The third example with a non-trivial coefficient of lowest degree raises an error:: + sage: # needs sage.libs.pari sage: R. = QQ[] - sage: R2 = R.quotient(x**2 + 1) # optional - sage.libs.pari - sage: x = R2.gen() # optional - sage.libs.pari - sage: R3. = R2[] # optional - sage.libs.pari - sage: (y**2 - 2*y + 1).nth_root(2) # optional - sage.libs.pari + sage: R2 = R.quotient(x**2 + 1) + sage: x = R2.gen() + sage: R3. = R2[] + sage: (y**2 - 2*y + 1).nth_root(2) -y + 1 - sage: (y**3).nth_root(3) # optional - sage.libs.pari + sage: (y**3).nth_root(3) y - sage: (y**2 + x).nth_root(2) # optional - sage.libs.pari + sage: (y**2 + x).nth_root(2) Traceback (most recent call last): ... AttributeError: ... has no attribute 'nth_root' @@ -10594,7 +10811,7 @@ cdef class Polynomial(CommutativePolynomial): Some random tests:: - sage: for R in [QQ['x'], GF(4)['x']]: # optional - sage.rings.finite_rings + sage: for R in [QQ['x'], GF(4)['x']]: # needs sage.rings.finite_rings ....: for _ in range(30): ....: p = R.random_element(degree=randint(10,20)) ....: n = ZZ.random_element(2,20) @@ -10678,10 +10895,11 @@ cdef class Polynomial(CommutativePolynomial): sage: R.one()._nth_root_series(3, 5) 1 - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: p = 2 + 3*x^2 # optional - sage.rings.number_field - sage: q = p._nth_root_series(3, 20) # optional - sage.rings.number_field - sage: (q**3).truncate(20) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: p = 2 + 3*x^2 + sage: q = p._nth_root_series(3, 20) + sage: (q**3).truncate(20) 3*x^2 + 2 The exponent must be invertible in the base ring:: @@ -10703,12 +10921,12 @@ cdef class Polynomial(CommutativePolynomial): Finite characteristic:: - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: (1 + x)._nth_root_series(3, 10) # optional - sage.rings.finite_rings + sage: R. = GF(2)[] + sage: (1 + x)._nth_root_series(3, 10) x^9 + x^8 + x^3 + x^2 + x + 1 - sage: (1 + x^2)._nth_root_series(2, 10) # optional - sage.rings.finite_rings + sage: (1 + x^2)._nth_root_series(2, 10) x + 1 - sage: (1 + x)._nth_root_series(2, 10) # optional - sage.rings.finite_rings + sage: (1 + x)._nth_root_series(2, 10) Traceback (most recent call last): ... ValueError: not a 2nd power @@ -10821,21 +11039,24 @@ cdef class Polynomial(CommutativePolynomial): TESTS:: - sage: R. = PolynomialRing(ZZ, implementation="NTL") # optional - sage.libs.ntl - sage: (2*x + 1).divides(4*x**2 + 1) # optional - sage.libs.ntl + sage: R. = PolynomialRing(ZZ, implementation="NTL") # needs sage.libs.ntl + sage: (2*x + 1).divides(4*x**2 + 1) # needs sage.libs.ntl False - sage: K. = GF(4) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: S. = R[] # optional - sage.rings.finite_rings - sage: p = ((3*z + 2)*x + 2*z - 1) * y + 2*x + z # optional - sage.rings.finite_rings - sage: q = y^2 + z*y*x + 2*y + z # optional - sage.rings.finite_rings - sage: p.divides(q), p.divides(p*q) # optional - sage.rings.finite_rings + + sage: # needs sage.rings.finite_rings + sage: K. = GF(4) + sage: R. = K[] + sage: S. = R[] + sage: p = ((3*z + 2)*x + 2*z - 1) * y + 2*x + z + sage: q = y^2 + z*y*x + 2*y + z + sage: p.divides(q), p.divides(p*q) (False, True) - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: S. = R[] # optional - sage.rings.finite_rings - sage: p = (x+y+1) * z + x*y # optional - sage.rings.finite_rings - sage: q = (y^2-x^2) * z^2 + z + x-y # optional - sage.rings.finite_rings - sage: p.divides(q), p.divides(p*q) # optional - sage.rings.finite_rings + + sage: R. = GF(2)[] + sage: S. = R[] + sage: p = (x+y+1) * z + x*y + sage: q = (y^2-x^2) * z^2 + z + x-y + sage: p.divides(q), p.divides(p*q) # needs sage.libs.singular (False, True) """ if not self.base_ring().is_integral_domain(): @@ -10909,8 +11130,8 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: Pol. = CBF[] - sage: (1 + x)._log_series(3) + sage: Pol. = CBF[] # needs sage.libs.flint + sage: (1 + x)._log_series(3) # needs sage.libs.flint -0.5000000000000000*x^2 + x """ raise NotImplementedError @@ -10922,8 +11143,8 @@ cdef class Polynomial(CommutativePolynomial): EXAMPLES:: - sage: Pol. = CBF[] - sage: x._exp_series(3) + sage: Pol. = CBF[] # needs sage.libs.flint + sage: x._exp_series(3) # needs sage.libs.flint 0.5000000000000000*x^2 + x + 1.000000000000000 """ raise NotImplementedError @@ -11304,6 +11525,7 @@ cdef class Polynomial_generic_dense(Polynomial): TESTS:: + sage: # needs sage.rings.real_mpfr sage: from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_dense sage: isinstance(f, Polynomial_generic_dense) True @@ -11434,14 +11656,15 @@ cdef class Polynomial_generic_dense(Polynomial): EXAMPLES:: - sage: R. = SR[] # optional - sage.symbolic - sage: R(0).is_term() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: R. = SR[] + sage: R(0).is_term() False - sage: R(1).is_term() # optional - sage.symbolic + sage: R(1).is_term() True - sage: (3*x^5).is_term() # optional - sage.symbolic + sage: (3*x^5).is_term() True - sage: (1 + 3*x^5).is_term() # optional - sage.symbolic + sage: (1 + 3*x^5).is_term() False """ if not self.__coeffs: @@ -11565,30 +11788,32 @@ cdef class Polynomial_generic_dense(Polynomial): EXAMPLES:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: f = (1+2*x)^3 + 3*x; f # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: f = (1+2*x)^3 + 3*x; f 8*x^3 + 12*x^2 + 9*x + 1 - sage: g = f // (1+2*x); g # optional - sage.rings.number_field + sage: g = f // (1+2*x); g 4*x^2 + 4*x + 5/2 - sage: f - g * (1+2*x) # optional - sage.rings.number_field + sage: f - g * (1+2*x) -3/2 - sage: f.quo_rem(1+2*x) # optional - sage.rings.number_field + sage: f.quo_rem(1+2*x) (4*x^2 + 4*x + 5/2, -3/2) TESTS: Check that :trac:`13048` and :trac:`2034` are fixed:: - sage: R. = QQbar[] # optional - sage.rings.number_field - sage: x // x # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQbar[] + sage: x // x 1 - sage: x // 1 # optional - sage.rings.number_field + sage: x // 1 x - sage: x // int(1) # optional - sage.rings.number_field + sage: x // int(1) x - sage: x //= int(1); x # optional - sage.rings.number_field + sage: x //= int(1); x x - sage: int(1) // x # check that this doesn't segfault # optional - sage.rings.number_field + sage: int(1) // x # check that this doesn't segfault Traceback (most recent call last): ... AttributeError: type object 'int' has no attribute 'base_ring' @@ -11702,10 +11927,10 @@ cdef class Polynomial_generic_dense(Polynomial): EXAMPLES:: - sage: R. = GF(17)[] # optional - sage.rings.finite_rings - sage: f = (1+2*x)^3 + 3*x; f # optional - sage.rings.finite_rings + sage: R. = GF(17)[] + sage: f = (1+2*x)^3 + 3*x; f 8*x^3 + 12*x^2 + 9*x + 1 - sage: f.list() # optional - sage.rings.finite_rings + sage: f.list() [1, 9, 12, 8] """ if copy: @@ -11809,12 +12034,13 @@ cdef class Polynomial_generic_dense(Polynomial): Polynomials over noncommutative rings are also allowed (after :trac:`34733`):: - sage: HH = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules - sage: P. = HH[] # optional - sage.combinat sage.modules - sage: f = P.random_element(5) # optional - sage.combinat sage.modules - sage: g = P.random_element((0, 5)) # optional - sage.combinat sage.modules - sage: q, r = f.quo_rem(g) # optional - sage.combinat sage.modules - sage: f == q*g + r # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: HH = QuaternionAlgebra(QQ, -1, -1) + sage: P. = HH[] + sage: f = P.random_element(5) + sage: g = P.random_element((0, 5)) + sage: q, r = f.quo_rem(g) + sage: f == q*g + r True TESTS: @@ -11945,19 +12171,22 @@ def universal_discriminant(n): EXAMPLES:: + sage: # needs sage.libs.pari sage: from sage.rings.polynomial.polynomial_element import universal_discriminant - sage: universal_discriminant(1) # optional - sage.libs.pari + sage: universal_discriminant(1) 1 - sage: universal_discriminant(2) # optional - sage.libs.pari + sage: universal_discriminant(2) a1^2 - 4*a0*a2 - sage: universal_discriminant(3) # optional - sage.libs.pari + sage: universal_discriminant(3) a1^2*a2^2 - 4*a0*a2^3 - 4*a1^3*a3 + 18*a0*a1*a2*a3 - 27*a0^2*a3^2 - sage: universal_discriminant(4).degrees() # optional - sage.libs.pari + sage: universal_discriminant(4).degrees() (3, 4, 4, 4, 3) .. SEEALSO:: :meth:`Polynomial.discriminant` """ + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + pr1 = PolynomialRing(ZZ, n + 1, 'a') pr2 = PolynomialRing(pr1, 'x') p = pr2(list(pr1.gens())) @@ -11982,7 +12211,7 @@ cpdef Polynomial generic_power_trunc(Polynomial p, Integer n, long prec): sage: from sage.rings.polynomial.polynomial_element import generic_power_trunc - sage: for S in [ZZ, GF(3)]: # known bug # not tested (see :trac:`32075`) # optional - sage.rings.finite_rings + sage: for S in [ZZ, GF(3)]: # known bug, not tested (see :trac:`32075`) ....: R = PolynomialRing(S, 'x') ....: for _ in range(100): ....: p = R.random_element() @@ -12082,9 +12311,9 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): Coefficients indistinguishable from 0 are not removed. - sage: R = Zp(5) # optional - sage.rings.padics - sage: S. = R[] # optional - sage.rings.padics - sage: S([1, R(0, 20)]) # optional - sage.rings.padics + sage: R = Zp(5) # needs sage.rings.padics + sage: S. = R[] # needs sage.rings.padics + sage: S([1, R(0, 20)]) # needs sage.rings.padics O(5^20)*x + 1 + O(5^20) """ cdef list x = self.__coeffs @@ -12116,27 +12345,29 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): EXAMPLES:: - sage: K = Qp(3, 10) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = T + 2; f # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(3, 10) + sage: R. = K[] + sage: f = T + 2; f (1 + O(3^10))*T + 2 + O(3^10) - sage: f.degree() # optional - sage.rings.padics + sage: f.degree() 1 - sage: (f - T).degree() # optional - sage.rings.padics + sage: (f - T).degree() 0 - sage: (f - T).degree(secure=True) # optional - sage.rings.padics + sage: (f - T).degree(secure=True) Traceback (most recent call last): ... PrecisionError: the leading coefficient is indistinguishable from 0 - sage: x = O(3^5) # optional - sage.rings.padics - sage: li = [3^i * x for i in range(0,5)]; li # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: x = O(3^5) + sage: li = [3^i * x for i in range(0,5)]; li [O(3^5), O(3^6), O(3^7), O(3^8), O(3^9)] - sage: f = R(li); f # optional - sage.rings.padics + sage: f = R(li); f O(3^9)*T^4 + O(3^8)*T^3 + O(3^7)*T^2 + O(3^6)*T + O(3^5) - sage: f.degree() # optional - sage.rings.padics + sage: f.degree() -1 - sage: f.degree(secure=True) # optional - sage.rings.padics + sage: f.degree(secure=True) Traceback (most recent call last): ... PrecisionError: the leading coefficient is indistinguishable from 0 @@ -12168,20 +12399,21 @@ cdef class Polynomial_generic_dense_inexact(Polynomial_generic_dense): EXAMPLES:: - sage: K = Qp(3, 10) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = T + 2; f # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(3, 10) + sage: R. = K[] + sage: f = T + 2; f (1 + O(3^10))*T + 2 + O(3^10) - sage: f.degree() # optional - sage.rings.padics + sage: f.degree() 1 - sage: f.prec_degree() # optional - sage.rings.padics + sage: f.prec_degree() 1 - sage: g = f - T; g # optional - sage.rings.padics + sage: g = f - T; g # needs sage.rings.padics O(3^10)*T + 2 + O(3^10) - sage: g.degree() # optional - sage.rings.padics + sage: g.degree() # needs sage.rings.padics 0 - sage: g.prec_degree() # optional - sage.rings.padics + sage: g.prec_degree() # needs sage.rings.padics 1 AUTHOR: @@ -12200,20 +12432,20 @@ cdef class ConstantPolynomialSection(Map): EXAMPLES:: - sage: P0. = GF(3)[] # optional - sage.rings.finite_rings - sage: P1. = GF(3)[] # optional - sage.rings.finite_rings - sage: P0(-y_1) # indirect doctest # optional - sage.rings.finite_rings + sage: P0. = GF(3)[] + sage: P1. = GF(3)[] + sage: P0(-y_1) 2*y_1 - sage: phi = GF(3).convert_map_from(P0); phi # optional - sage.rings.finite_rings + sage: phi = GF(3).convert_map_from(P0); phi Generic map: From: Univariate Polynomial Ring in y_1 over Finite Field of size 3 To: Finite Field of size 3 - sage: type(phi) # optional - sage.rings.finite_rings + sage: type(phi) - sage: phi(P0.one()) # optional - sage.rings.finite_rings + sage: phi(P0.one()) 1 - sage: phi(y_1) # optional - sage.rings.finite_rings + sage: phi(y_1) Traceback (most recent call last): ... TypeError: not a constant polynomial @@ -12228,7 +12460,7 @@ cdef class ConstantPolynomialSection(Map): Generic map: From: Univariate Polynomial Ring in x over Rational Field To: Rational Field - sage: m(x-x+1/2) # implicit + sage: m(x-x+1/2) # implicit 1/2 sage: m(x-x) 0 @@ -12264,18 +12496,20 @@ cdef class PolynomialBaseringInjection(Morphism): supposed to be the fastest maps for that purpose. See :trac:`9944`. :: - sage: R. = Qp(3)[] # optional - sage.rings.padics - sage: R.coerce_map_from(R.base_ring()) # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R. = Qp(3)[] + sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: 3-adic Field with capped relative precision 20 To: Univariate Polynomial Ring in x over 3-adic Field with capped relative precision 20 - sage: R. = Qp(3)[] # optional - sage.rings.padics - sage: R.coerce_map_from(R.base_ring()) # optional - sage.rings.padics + sage: R. = Qp(3)[] + sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: From: 3-adic Field with capped relative precision 20 To: Multivariate Polynomial Ring in x, y over 3-adic Field with capped relative precision 20 + sage: R. = QQ[] sage: R.coerce_map_from(R.base_ring()) Polynomial base injection morphism: @@ -12314,11 +12548,12 @@ cdef class PolynomialBaseringInjection(Morphism): :: - sage: R. = Qp(2)[] # optional - sage.rings.padics - sage: f = R.convert_map_from(R.base_ring()) # indirect doctest # optional - sage.rings.padics - sage: f(Qp(2).one()*3) # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R. = Qp(2)[] + sage: f = R.convert_map_from(R.base_ring()) # indirect doctest + sage: f(Qp(2).one()*3) 1 + 2 + O(2^20) - sage: (Qp(2).one()*3)*t # optional - sage.rings.padics + sage: (Qp(2).one()*3)*t (1 + 2 + O(2^20))*t """ assert codomain.base_ring() is domain, "domain must be basering" @@ -12370,7 +12605,7 @@ cdef class PolynomialBaseringInjection(Morphism): Polynomial base injection morphism: From: Integer Ring To: Univariate Polynomial Ring in x over Integer Ring - sage: m(2) # indirect doctest + sage: m(2) # indirect doctest 2 sage: parent(m(2)) Univariate Polynomial Ring in x over Integer Ring @@ -12382,8 +12617,8 @@ cdef class PolynomialBaseringInjection(Morphism): TESTS:: sage: from sage.rings.polynomial.polynomial_element import PolynomialBaseringInjection - sage: m = PolynomialBaseringInjection(Qp(5), Qp(5)['x']) # optional - sage.rings.padics - sage: m(1 + O(5^11), absprec=5) # indirect doctest # optional - sage.rings.padics + sage: m = PolynomialBaseringInjection(Qp(5), Qp(5)['x']) # needs sage.rings.padics + sage: m(1 + O(5^11), absprec=5) # indirect doctest # needs sage.rings.padics 1 + O(5^11) """ try: @@ -12421,7 +12656,7 @@ cdef class PolynomialBaseringInjection(Morphism): Check that :trac:`23203` has been resolved:: - sage: R.is_subring(S) # indirect doctest + sage: R.is_subring(S) # indirect doctest True """ diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index cf4e6344a8c..77b9a7d8c92 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -14,10 +14,10 @@ sage: W. = QQ['w'] sage: WZ. = W['z'] - sage: m = matrix(WZ, 2, 2, [1, z, z, z^2]) # optional - sage.modules - sage: a = m.charpoly() # optional - sage.modules - sage: R. = WZ[] # optional - sage.modules - sage: R(a) # optional - sage.modules + sage: m = matrix(WZ, 2, 2, [1, z, z, z^2]) # needs sage.modules + sage: a = m.charpoly() # needs sage.modules + sage: R. = WZ[] + sage: R(a) # needs sage.modules x^2 + (-z^2 - 1)*x """ @@ -34,7 +34,11 @@ from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr -from sage.libs.pari.all import pari_gen +try: + from sage.libs.pari.all import pari_gen +except ImportError: + pari_gen = () + from sage.structure.richcmp import richcmp, richcmp_item, rich_to_bool, rich_to_bool_sgn from sage.structure.element import coerce_binop, parent @@ -65,15 +69,16 @@ class Polynomial_generic_sparse(Polynomial): A more extensive example:: - sage: A. = PolynomialRing(Integers(5), sparse=True) # optional - sage.libs.pari - sage: f = T^2 + 1; B = A.quo(f) # optional - sage.libs.pari - sage: C. = PolynomialRing(B) # optional - sage.libs.pari - sage: C # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: A. = PolynomialRing(Integers(5), sparse=True) + sage: f = T^2 + 1; B = A.quo(f) + sage: C. = PolynomialRing(B) + sage: C Univariate Polynomial Ring in s over Univariate Quotient Polynomial Ring in Tbar over Ring of integers modulo 5 with modulus T^2 + 1 - sage: s + T # optional - sage.libs.pari + sage: s + T s + Tbar - sage: (s + T)**2 # optional - sage.libs.pari + sage: (s + T)**2 s^2 + 2*Tbar*s + 4 """ @@ -81,11 +86,11 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): """ TESTS:: - sage: PolynomialRing(RIF, 'z', sparse=True)([RIF(-1, 1), RIF(-1,1)]) + sage: PolynomialRing(RIF, 'z', sparse=True)([RIF(-1, 1), RIF(-1,1)]) # needs sage.rings.real_interval_field 0.?*z + 0.? - sage: PolynomialRing(RIF, 'z', sparse=True)((RIF(-1, 1), RIF(-1,1))) + sage: PolynomialRing(RIF, 'z', sparse=True)((RIF(-1, 1), RIF(-1,1))) # needs sage.rings.real_interval_field 0.?*z + 0.? - sage: PolynomialRing(CIF, 'z', sparse=True)([CIF(RIF(-1,1), RIF(-1,1)), RIF(-1,1)]) + sage: PolynomialRing(CIF, 'z', sparse=True)([CIF(RIF(-1,1), RIF(-1,1)), RIF(-1,1)]) # needs sage.rings.complex_interval_field 0.?*z + 0.? + 0.?*I """ Polynomial.__init__(self, parent, is_gen=is_gen) @@ -190,13 +195,14 @@ def valuation(self, p=None): EXAMPLES:: - sage: R. = PolynomialRing(GF(9, 'a'), sparse=True) # optional - sage.rings.finite_rings - sage: f = w^1997 - w^10000 # optional - sage.rings.finite_rings - sage: f.valuation() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = PolynomialRing(GF(9, 'a'), sparse=True) + sage: f = w^1997 - w^10000 + sage: f.valuation() 1997 - sage: R(19).valuation() # optional - sage.rings.finite_rings + sage: R(19).valuation() 0 - sage: R(0).valuation() # optional - sage.rings.finite_rings + sage: R(0).valuation() +Infinity """ if not self.__coeffs: @@ -245,10 +251,10 @@ def _derivative(self, var=None): Check that :trac:`28187` is fixed:: sage: R = PolynomialRing(ZZ, 't', sparse=True) - sage: t, u = var('t, u') # optional - sage.symbolic - sage: R.gen()._derivative(t) # optional - sage.symbolic + sage: t, u = var('t, u') # needs sage.symbolic + sage: R.gen()._derivative(t) # needs sage.symbolic 1 - sage: R.gen()._derivative(u) # optional - sage.symbolic + sage: R.gen()._derivative(u) # needs sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to u @@ -356,6 +362,7 @@ def _repr(self, name=None): r""" EXAMPLES:: + sage: # needs sage.rings.complex_double sage.symbolic sage: R. = PolynomialRing(CDF, sparse=True) sage: f = CDF(1,2) + w^5 - CDF(pi)*w + CDF(e) sage: f._repr() # abs tol 1e-15 @@ -365,8 +372,8 @@ def _repr(self, name=None): TESTS:: - sage: pol = RIF['x']([0, 0, (-1,1)]) - sage: PolynomialRing(RIF, 'x', sparse=True)(pol) + sage: pol = RIF['x']([0, 0, (-1,1)]) # needs sage.rings.real_interval_field + sage: PolynomialRing(RIF, 'x', sparse=True)(pol) # needs sage.rings.real_interval_field 0.?*x^2 AUTHOR: @@ -418,40 +425,42 @@ def __getitem__(self, n): EXAMPLES:: + sage: # needs sage.symbolic sage: R. = PolynomialRing(RDF, sparse=True) - sage: e = RDF(e) # optional - sage.symbolic - sage: f = sum(e^n*w^n for n in range(4)); f # abs tol 1.1e-14 # optional - sage.symbolic + sage: e = RDF(e) + sage: f = sum(e^n*w^n for n in range(4)); f # abs tol 1.1e-14 20.085536923187664*w^3 + 7.3890560989306495*w^2 + 2.718281828459045*w + 1.0 - sage: f[1] # abs tol 5e-16 # optional - sage.symbolic + sage: f[1] # abs tol 5e-16 2.718281828459045 - sage: f[5] # optional - sage.symbolic + sage: f[5] 0.0 - sage: f[-1] # optional - sage.symbolic + sage: f[-1] 0.0 - sage: R. = PolynomialRing(RealField(19), sparse=True) - sage: f = (2-3.5*x)^3; f + + sage: R. = PolynomialRing(RealField(19), sparse=True) # needs sage.rings.real_mpfr + sage: f = (2-3.5*x)^3; f # needs sage.rings.real_mpfr -42.875*x^3 + 73.500*x^2 - 42.000*x + 8.0000 Using slices, we can truncate polynomials:: - sage: f[:2] + sage: f[:2] # needs sage.rings.real_mpfr -42.000*x + 8.0000 Any other kind of slicing is an error, see :trac:`18940`:: - sage: f[1:3] + sage: f[1:3] # needs sage.rings.real_mpfr Traceback (most recent call last): ... IndexError: polynomial slicing with a start is not defined - sage: f[1:3:2] + sage: f[1:3:2] # needs sage.rings.real_mpfr Traceback (most recent call last): ... IndexError: polynomial slicing with a step is not defined TESTS:: - sage: f["hello"] + sage: f["hello"] # needs sage.rings.real_mpfr Traceback (most recent call last): ... TypeError: list indices must be integers, not str @@ -486,6 +495,7 @@ def _unsafe_mutate(self, n, value): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: R. = PolynomialRing(CC, sparse=True) sage: f = z^2 + CC.0; f 1.00000000000000*z^2 + 1.00000000000000*I @@ -495,8 +505,8 @@ def _unsafe_mutate(self, n, value): Much more nasty:: - sage: z._unsafe_mutate(1, 0) - sage: z + sage: z._unsafe_mutate(1, 0) # needs sage.rings.real_mpfr + sage: z # needs sage.rings.real_mpfr 0 """ n = int(n) @@ -549,14 +559,15 @@ def __floordiv__(self, right): EXAMPLES:: - sage: R. = PolynomialRing(QQbar, sparse=True) # optional - sage.rings.number_field - sage: f = (1+2*x)^3 + 3*x; f # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = PolynomialRing(QQbar, sparse=True) + sage: f = (1+2*x)^3 + 3*x; f 8*x^3 + 12*x^2 + 9*x + 1 - sage: g = f // (1+2*x); g # optional - sage.rings.number_field + sage: g = f // (1+2*x); g 4*x^2 + 4*x + 5/2 - sage: f - g * (1+2*x) # optional - sage.rings.number_field + sage: f - g * (1+2*x) -3/2 - sage: f.quo_rem(1+2*x) # optional - sage.rings.number_field + sage: f.quo_rem(1+2*x) (4*x^2 + 4*x + 5/2, -3/2) """ @@ -827,12 +838,13 @@ def quo_rem(self, other): Polynomials over noncommutative rings are also allowed:: - sage: HH = QuaternionAlgebra(QQ, -1, -1) # optional - sage.combinat sage.modules - sage: P. = PolynomialRing(HH, sparse=True) # optional - sage.combinat sage.modules - sage: f = P.random_element(5) # optional - sage.combinat sage.modules - sage: g = P.random_element((0, 5)) # optional - sage.combinat sage.modules - sage: q, r = f.quo_rem(g) # optional - sage.combinat sage.modules - sage: f == q*g + r # optional - sage.combinat sage.modules + sage: # needs sage.combinat sage.modules + sage: HH = QuaternionAlgebra(QQ, -1, -1) + sage: P. = PolynomialRing(HH, sparse=True) + sage: f = P.random_element(5) + sage: g = P.random_element((0, 5)) + sage: q, r = f.quo_rem(g) + sage: f == q*g + r True TESTS:: @@ -1066,12 +1078,13 @@ def quo_rem(self, other): EXAMPLES:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(y^2 - 2) # optional - sage.rings.number_field - sage: P. = PolynomialRing(K) # optional - sage.rings.number_field - sage: x.quo_rem(K(1)) # optional - sage.rings.number_field + sage: K. = NumberField(y^2 - 2) + sage: P. = PolynomialRing(K) + sage: x.quo_rem(K(1)) (x, 0) - sage: x.xgcd(K(1)) # optional - sage.rings.number_field + sage: x.xgcd(K(1)) (1, 0, 1) """ P = self.parent() @@ -1142,15 +1155,16 @@ def newton_slopes(self, repetition=True): EXAMPLES:: - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics - sage: f.newton_polygon() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5) + sage: R. = K[] + sage: f = 5 + 3*t + t^4 + 25*t^10 + sage: f.newton_polygon() Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2) - sage: f.newton_slopes() # optional - sage.rings.padics + sage: f.newton_slopes() [1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3] - sage: f.newton_slopes(repetition=False) # optional - sage.rings.padics + sage: f.newton_slopes(repetition=False) # needs sage.rings.padics [1, 0, -1/3] AUTHOR: @@ -1170,15 +1184,16 @@ def newton_polygon(self): EXAMPLES:: - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics - sage: f.newton_polygon() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5) + sage: R. = K[] + sage: f = 5 + 3*t + t^4 + 25*t^10 + sage: f.newton_polygon() Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2) - sage: g = f + K(0,0)*t^4; g # optional - sage.rings.padics + sage: g = f + K(0,0)*t^4; g # needs sage.rings.padics (5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21) - sage: g.newton_polygon() # optional - sage.rings.padics + sage: g.newton_polygon() # needs sage.rings.padics Traceback (most recent call last): ... PrecisionError: The coefficient of t^4 has not enough precision @@ -1187,10 +1202,10 @@ def newton_polygon(self): Check that :trac:`22936` is fixed:: - sage: S. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings - sage: R. = S[] # optional - sage.rings.finite_rings - sage: p = x^2 + y + x*y^2 # optional - sage.rings.finite_rings - sage: p.newton_polygon() # optional - sage.rings.finite_rings + sage: S. = PowerSeriesRing(GF(5)) + sage: R. = S[] + sage: p = x^2 + y + x*y^2 + sage: p.newton_polygon() # needs sage.geometry.polyhedron Finite Newton polygon with 3 vertices: (0, 2), (1, 0), (2, 1) AUTHOR: @@ -1225,16 +1240,17 @@ def hensel_lift(self, a): EXAMPLES:: - sage: K = Qp(5, 10) # optional - sage.rings.padics - sage: P. = PolynomialRing(K) # optional - sage.rings.padics - sage: f = x^2 + 1 # optional - sage.rings.padics - sage: root = f.hensel_lift(2); root # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5, 10) + sage: P. = PolynomialRing(K) + sage: f = x^2 + 1 + sage: root = f.hensel_lift(2); root 2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10) - sage: f(root) # optional - sage.rings.padics + sage: f(root) O(5^10) - sage: g = (x^2 + 1) * (x - 7) # optional - sage.rings.padics - sage: g.hensel_lift(2) # here, 2 is a multiple root modulo p # optional - sage.rings.padics + sage: g = (x^2 + 1) * (x - 7) # needs sage.rings.padics + sage: g.hensel_lift(2) # here, 2 is a multiple root modulo p # needs sage.rings.padics Traceback (most recent call last): ... ValueError: a is not close enough to a root of this polynomial @@ -1273,27 +1289,28 @@ def _factor_of_degree(self, deg): EXAMPLES:: - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5) + sage: R. = K[] + sage: K = Qp(5) + sage: R. = K[] + sage: f = 5 + 3*t + t^4 + 25*t^10 - sage: g = f._factor_of_degree(4) # optional - sage.rings.padics - sage: (f % g).is_zero() # optional - sage.rings.padics + sage: g = f._factor_of_degree(4) # needs sage.rings.padics + sage: (f % g).is_zero() # needs sage.rings.padics True - sage: g = f._factor_of_degree(3) # not tested # optional - sage.rings.padics + sage: g = f._factor_of_degree(3) # not tested # needs sage.rings.padics Traceback (most recent call last) ... KeyboardInterrupt: TESTS:: - sage: S. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings - sage: R. = S[] # optional - sage.rings.finite_rings - sage: p = x^2 + y + x*y^2 # optional - sage.rings.finite_rings - sage: p._factor_of_degree(1) # optional - sage.rings.finite_rings + sage: S. = PowerSeriesRing(GF(5)) + sage: R. = S[] + sage: p = x^2 + y + x*y^2 + sage: p._factor_of_degree(1) (1 + O(x^20))*y + x^2 + x^5 + 2*x^8 + 4*x^14 + 2*x^17 + 2*x^20 + O(x^22) AUTHOR: @@ -1337,30 +1354,31 @@ def factor_of_slope(self, slope=None): EXAMPLES:: - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics - sage: f.newton_slopes() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5) + sage: R. = K[] + sage: K = Qp(5) + sage: R. = K[] + sage: f = 5 + 3*t + t^4 + 25*t^10 + sage: f.newton_slopes() [1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3] - sage: g = f.factor_of_slope(0) # optional - sage.rings.padics - sage: g.newton_slopes() # optional - sage.rings.padics + sage: g = f.factor_of_slope(0) # needs sage.rings.padics + sage: g.newton_slopes() # needs sage.rings.padics [0, 0, 0] - sage: (f % g).is_zero() # optional - sage.rings.padics + sage: (f % g).is_zero() # needs sage.rings.padics True - sage: h = f.factor_of_slope() # optional - sage.rings.padics - sage: h.newton_slopes() # optional - sage.rings.padics + sage: h = f.factor_of_slope() # needs sage.rings.padics + sage: h.newton_slopes() # needs sage.rings.padics [1] - sage: (f % h).is_zero() # optional - sage.rings.padics + sage: (f % h).is_zero() # needs sage.rings.padics True If ``slope`` is not a slope of ``self``, the corresponding factor is `1`:: - sage: f.factor_of_slope(-1) # optional - sage.rings.padics + sage: f.factor_of_slope(-1) # needs sage.rings.padics 1 + O(5^20) AUTHOR: @@ -1406,18 +1424,19 @@ def slope_factorization(self): EXAMPLES:: - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: K = Qp(5) # optional - sage.rings.padics - sage: R. = K[] # optional - sage.rings.padics - sage: f = 5 + 3*t + t^4 + 25*t^10 # optional - sage.rings.padics - sage: f.newton_slopes() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5) + sage: R. = K[] + sage: K = Qp(5) + sage: R. = K[] + sage: f = 5 + 3*t + t^4 + 25*t^10 + sage: f.newton_slopes() [1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3] - sage: F = f.slope_factorization() # optional - sage.rings.padics - sage: F.prod() == f # optional - sage.rings.padics + sage: F = f.slope_factorization() # needs sage.rings.padics + sage: F.prod() == f # needs sage.rings.padics True - sage: for (f,_) in F: # optional - sage.rings.padics + sage: for (f,_) in F: # needs sage.rings.padics ....: print(f.newton_slopes()) [-1/3, -1/3, -1/3, -1/3, -1/3, -1/3] [0, 0, 0] @@ -1425,10 +1444,10 @@ def slope_factorization(self): TESTS:: - sage: S. = PowerSeriesRing(GF(5)) # optional - sage.rings.finite_rings - sage: R. = S[] # optional - sage.rings.finite_rings - sage: p = x^2 + y + x*y^2 # optional - sage.rings.finite_rings - sage: p.slope_factorization() # optional - sage.rings.finite_rings + sage: S. = PowerSeriesRing(GF(5)) + sage: R. = S[] + sage: p = x^2 + y + x*y^2 + sage: p.slope_factorization() # needs sage.geometry.polyhedron (x) * ((x + O(x^22))*y + 1 + 4*x^3 + 4*x^6 + 3*x^9 + x^15 + 3*x^18 + O(x^21)) * ((x^-1 + O(x^20))*y + x + x^4 + 2*x^7 + 4*x^13 + 2*x^16 + 2*x^19 + O(x^22)) @@ -1483,11 +1502,12 @@ def _roots(self, secure, minval, hint): TESTS:: - sage: R = Zp(2) # optional - sage.rings.padics - sage: S. = R[] # optional - sage.rings.padics - sage: P = (x-1) * (x-2) * (x-4) * (x-8) * (x-16) # optional - sage.rings.padics - sage: Q = P^2 # optional - sage.rings.padics - sage: Q.roots(algorithm="sage") # indirect doctest # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R = Zp(2) + sage: S. = R[] + sage: P = (x-1) * (x-2) * (x-4) * (x-8) * (x-16) + sage: Q = P^2 + sage: Q.roots(algorithm="sage") # indirect doctest [(2^4 + O(2^14), 2), (2^3 + O(2^13), 2), (2^2 + O(2^12), 2), @@ -1591,9 +1611,11 @@ class Polynomial_generic_sparse_cdvf(Polynomial_generic_sparse_cdv, Polynomial_g # XXX: Ensures that the generic polynomials implemented in Sage via PARI # # until at least until 4.5.0 unpickle correctly as polynomials implemented # # via FLINT. # -from sage.misc.persist import register_unpickle_override -from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint - -register_unpickle_override( - 'sage.rings.polynomial.polynomial_element_generic', - 'Polynomial_rational_dense', Polynomial_rational_flint) +try: + from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint +except ImportError: + pass +else: + from sage.misc.persist import register_unpickle_override + register_unpickle_override('sage.rings.polynomial.polynomial_element_generic', + 'Polynomial_rational_dense', Polynomial_rational_flint) diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index fd03ece69d6..57468e3510f 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -536,30 +536,30 @@ def small_roots(self, X=None, beta=1.0, epsilon=None, **kwds): sage: length = 512 sage: hidden = 110 sage: p = next_prime(2^int(round(length/2))) - sage: q = next_prime( round(pi.n()*p) ) - sage: N = p*q + sage: q = next_prime(round(pi.n()*p)) # needs sage.symbolic + sage: N = p*q # needs sage.symbolic Now we disturb the low 110 bits of `q`:: - sage: qbar = q + ZZ.random_element(0,2^hidden-1) + sage: qbar = q + ZZ.random_element(0, 2^hidden - 1) # needs sage.symbolic And try to recover `q` from it:: - sage: F. = PolynomialRing(Zmod(N), implementation='NTL') - sage: f = x - qbar + sage: F. = PolynomialRing(Zmod(N), implementation='NTL') # needs sage.symbolic + sage: f = x - qbar # needs sage.symbolic We know that the error is `\le 2^{\text{hidden}}-1` and that the modulus we are looking for is `\ge \sqrt{N}`:: sage: from sage.misc.verbose import set_verbose sage: set_verbose(2) - sage: d = f.small_roots(X=2^hidden-1, beta=0.5)[0] # time random + sage: d = f.small_roots(X=2^hidden-1, beta=0.5)[0] # time random # needs sage.symbolic verbose 2 () m = 4 verbose 2 () t = 4 verbose 2 () X = 1298074214633706907132624082305023 verbose 1 () LLL of 8x8 matrix (algorithm fpLLL:wrapper) verbose 1 () LLL finished (time = 0.006998) - sage: q == qbar - d + sage: q == qbar - d # needs sage.symbolic True REFERENCES: @@ -1061,8 +1061,8 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): TESTS:: - sage: y = var("y") - sage: f._derivative(y) + sage: y = var("y") # needs sage.symbolic + sage: f._derivative(y) # needs sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -1619,8 +1619,8 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): TESTS:: - sage: y = var("y") - sage: f._derivative(y) + sage: y = var("y") # needs sage.symbolic + sage: f._derivative(y) # needs sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y diff --git a/src/sage/rings/polynomial/polynomial_number_field.pyx b/src/sage/rings/polynomial/polynomial_number_field.pyx index a5e7a245574..96f1c002e99 100644 --- a/src/sage/rings/polynomial/polynomial_number_field.pyx +++ b/src/sage/rings/polynomial/polynomial_number_field.pyx @@ -30,34 +30,36 @@ operations with them:: Polynomials are aware of embeddings of the underlying field:: + sage: # needs sage.rings.padics sage: x = polygen(ZZ, 'x') - sage: Q7 = Qp(7) # optional - sage.rings.padics - sage: r1 = Q7(3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 # optional - sage.rings.padics + sage: Q7 = Qp(7) + sage: r1 = Q7(3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 ....: + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 ....: + 4*7^18 + 6*7^19) - sage: N. = NumberField(x^2 - 2, embedding=r1) # optional - sage.rings.padics - sage: K. = N[] # optional - sage.rings.padics - sage: f = t^3 - 2*t + 1 # optional - sage.rings.padics - sage: f(r1) # optional - sage.rings.padics + sage: N. = NumberField(x^2 - 2, embedding=r1) + sage: K. = N[] + sage: f = t^3 - 2*t + 1 + sage: f(r1) 1 + O(7^20) We can also construct polynomials over relative number fields:: - sage: N. = QQ[I, sqrt(2)] # optional - sage.symbolic - sage: K. = N[] # optional - sage.symbolic - sage: f = x - s2 # optional - sage.symbolic - sage: g = x^3 - 2*i*x^2 + s2*x # optional - sage.symbolic - sage: f * (x + s2) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: N. = QQ[I, sqrt(2)] + sage: K. = N[] + sage: f = x - s2 + sage: g = x^3 - 2*i*x^2 + s2*x + sage: f * (x + s2) x^2 - 2 - sage: f + g # optional - sage.symbolic + sage: f + g x^3 - 2*I*x^2 + (sqrt2 + 1)*x - sqrt2 - sage: g // f # optional - sage.symbolic + sage: g // f x^2 + (-2*I + sqrt2)*x - 2*sqrt2*I + sqrt2 + 2 - sage: g % f # optional - sage.symbolic + sage: g % f -4*I + 2*sqrt2 + 2 - sage: factor(i*x^4 - 2*i*x^2 + 9*i) # optional - sage.symbolic + sage: factor(i*x^4 - 2*i*x^2 + 9*i) (I) * (x - I + sqrt2) * (x + I - sqrt2) * (x - I - sqrt2) * (x + I + sqrt2) - sage: gcd(f, x - i) # optional - sage.symbolic + sage: gcd(f, x - i) 1 """ @@ -222,18 +224,18 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): - ``parent`` -- polynomial ring in which to construct the element. - - ``x`` -- (default: None) an object representing the + - ``x`` -- (default: ``None``) an object representing the polynomial, e.g. a list of coefficients. See :meth:`sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field.__init__` for more details. - - ``check`` -- boolean (default: True) if True, make sure that + - ``check`` -- boolean (default: ``True``) if ``True``, make sure that the coefficients of the polynomial are in the base ring. - - ``is_gen`` -- boolean (default: False) if True, ``x`` is the + - ``is_gen`` -- boolean (default: ``False``) if ``True``, ``x`` is the distinguished generator of the polynomial ring. - - ``construct`` -- (default: False) boolean, unused. + - ``construct`` -- (default: ``False``) boolean, unused. EXAMPLES:: @@ -260,19 +262,20 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): OUTPUT: - - The monic gcd of ``self`` and ``other``. + The monic gcd of ``self`` and ``other``. See :meth:`Polynomial_absolute_number_field_dense.gcd` for more details. EXAMPLES:: - sage: N = QQ[sqrt(2), sqrt(3)] # optional - sage.symbolic - sage: s2, s3 = N.gens() # optional - sage.symbolic - sage: x = polygen(N) # optional - sage.symbolic - sage: f = x^4 - 5*x^2 + 6 # optional - sage.symbolic - sage: g = x^3 + (-2*s2 + s3)*x^2 + (-2*s3*s2 + 2)*x + 2*s3 # optional - sage.symbolic - sage: gcd(f, g) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: N = QQ[sqrt(2), sqrt(3)] + sage: s2, s3 = N.gens() + sage: x = polygen(N) + sage: f = x^4 - 5*x^2 + 6 + sage: g = x^3 + (-2*s2 + s3)*x^2 + (-2*s3*s2 + 2)*x + 2*s3 + sage: gcd(f, g) x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2 sage: f.gcd(g) x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2 @@ -305,6 +308,7 @@ class Polynomial_relative_number_field_dense(Polynomial_generic_dense_field): Test for hardcoded variables:: + sage: # needs sage.symbolic sage: R = N['sqrt2sqrt3'] sage: x = R.gen() sage: f = x^2 - 2 diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 85b8d380d8c..3e59e6efb31 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -1,22 +1,23 @@ -# -*- coding: utf-8 -*- +# sage.doctest: needs sage.libs.pari """ Quotients of Univariate Polynomial Rings EXAMPLES:: sage: R. = QQ[] - sage: S = R.quotient(x**3 - 3*x + 1, 'alpha') # optional - sage.libs.pari - sage: S.gen()**2 in S # optional - sage.libs.pari + sage: S = R.quotient(x**3 - 3*x + 1, 'alpha') + sage: S.gen()**2 in S True - sage: x in S # optional - sage.libs.pari + sage: x in S True - sage: S.gen() in R # optional - sage.libs.pari + sage: S.gen() in R False - sage: 1 in S # optional - sage.libs.pari + sage: 1 in S True TESTS:: + sage: # needs sage.libs.flint sage: Pol. = CBF[] sage: Quo. = Pol.quotient(y^3) sage: CBF.zero()*y @@ -39,7 +40,6 @@ from . import polynomial_element import sage.rings.rational_field -import sage.rings.complex_mpfr from sage.rings.ring import Field, IntegralDomain, CommutativeRing @@ -81,25 +81,25 @@ class PolynomialQuotientRingFactory(UniqueFactory): sage: Z = IntegerRing() sage: R = PolynomialRing(Z, 'x'); x = R.gen() - sage: S = R.quotient(x^3 + 7, 'a'); a = S.gen() # optional - sage.libs.pari - sage: S # optional - sage.libs.pari + sage: S = R.quotient(x^3 + 7, 'a'); a = S.gen() + sage: S Univariate Quotient Polynomial Ring in a over Integer Ring with modulus x^3 + 7 - sage: a^3 # optional - sage.libs.pari + sage: a^3 -7 - sage: S.is_field() # optional - sage.libs.pari + sage: S.is_field() False - sage: a in S # optional - sage.libs.pari + sage: a in S True - sage: x in S # optional - sage.libs.pari + sage: x in S True - sage: a in R # optional - sage.libs.pari + sage: a in R False - sage: S.polynomial_ring() # optional - sage.libs.pari + sage: S.polynomial_ring() Univariate Polynomial Ring in x over Integer Ring - sage: S.modulus() # optional - sage.libs.pari + sage: S.modulus() x^3 + 7 - sage: S.degree() # optional - sage.libs.pari + sage: S.degree() 3 We create the "iterated" polynomial ring quotient @@ -110,16 +110,17 @@ class PolynomialQuotientRingFactory(UniqueFactory): :: - sage: A. = PolynomialRing(GF(2)); A # optional - sage.rings.finite_rings + sage: # needs sage.libs.ntl + sage: A. = PolynomialRing(GF(2)); A Univariate Polynomial Ring in y over Finite Field of size 2 (using GF2X) - sage: B = A.quotient(y^2 + y + 1, 'y2'); B # optional - sage.rings.finite_rings + sage: B = A.quotient(y^2 + y + 1, 'y2'); B Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 with modulus y^2 + y + 1 - sage: C = PolynomialRing(B, 'x'); x = C.gen(); C # optional - sage.rings.finite_rings + sage: C = PolynomialRing(B, 'x'); x = C.gen(); C Univariate Polynomial Ring in x over Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 with modulus y^2 + y + 1 - sage: R = C.quotient(x^3 - 5); R # optional - sage.rings.finite_rings + sage: R = C.quotient(x^3 - 5); R Univariate Quotient Polynomial Ring in xbar over Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2 with modulus y^2 + y + 1 @@ -129,22 +130,21 @@ class PolynomialQuotientRingFactory(UniqueFactory): polynomial ring over `\QQ`:: sage: R = PolynomialRing(RationalField(), 'x'); x = R.gen() - sage: S = R.quotient(x^3 + 2*x - 5, 'a') # optional - sage.libs.pari - sage: S # optional - sage.libs.pari + sage: S = R.quotient(x^3 + 2*x - 5, 'a'); S Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^3 + 2*x - 5 - sage: S.is_field() # optional - sage.libs.pari + sage: S.is_field() True - sage: S.degree() # optional - sage.libs.pari + sage: S.degree() 3 There are conversion functions for easily going back and forth between quotients of polynomial rings over `\QQ` and number fields:: - sage: K = S.number_field(); K # optional - sage.libs.pari sage.rings.number_field + sage: K = S.number_field(); K # needs sage.rings.number_field Number Field in a with defining polynomial x^3 + 2*x - 5 - sage: K.polynomial_quotient_ring() # optional - sage.libs.pari sage.rings.number_field + sage: K.polynomial_quotient_ring() # needs sage.rings.number_field Univariate Quotient Polynomial Ring in a over Rational Field with modulus x^3 + 2*x - 5 @@ -163,14 +163,14 @@ class PolynomialQuotientRingFactory(UniqueFactory): sage: R. = PolynomialRing(IntegerRing()) sage: f = x^2 + 1 - sage: R.quotient(f) # optional - sage.libs.pari + sage: R.quotient(f) Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 This shows that the issue at :trac:`5482` is solved:: sage: R. = PolynomialRing(QQ) sage: f = x^2 - 1 - sage: R.quotient_by_principal_ideal(f) # optional - sage.libs.pari + sage: R.quotient_by_principal_ideal(f) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 """ @@ -195,19 +195,19 @@ def create_key(self, ring, polynomial, names=None): Consequently, you get two distinct objects:: - sage: S = PolynomialQuotientRing(R, x + 1); S # optional - sage.libs.pari + sage: S = PolynomialQuotientRing(R, x + 1); S Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x + 1 - sage: T = PolynomialQuotientRing(R, 2*x + 2); T # optional - sage.libs.pari + sage: T = PolynomialQuotientRing(R, 2*x + 2); T Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus 2*x + 2 - sage: S is T # optional - sage.libs.pari + sage: S is T False - sage: S == T # optional - sage.libs.pari + sage: S == T False In most applications this will not be a concern since the calling code takes care of normalizing the generators:: - sage: R.quo(x + 1) is R.quo(2*x + 2) # optional - sage.libs.pari + sage: R.quo(x + 1) is R.quo(2*x + 2) True """ @@ -236,7 +236,7 @@ def create_object(self, version, key): EXAMPLES:: sage: R. = QQ[] - sage: PolynomialQuotientRing.create_object((8, 0, 0), # optional - sage.libs.pari + sage: PolynomialQuotientRing.create_object((8, 0, 0), ....: (R, x^2 - 1, ('xbar'))) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1 @@ -292,19 +292,19 @@ class PolynomialQuotientRing_generic(QuotientRing_generic): :: sage: R. = PolynomialRing(ZZ) - sage: S = R.quo(x^2 - 4) # optional - sage.libs.pari - sage: f = S.hom([2]) # optional - sage.libs.pari - sage: f # optional - sage.libs.pari + sage: S = R.quo(x^2 - 4) + sage: f = S.hom([2]) + sage: f Ring morphism: From: Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 - 4 To: Integer Ring Defn: xbar |--> 2 - sage: f(x) # optional - sage.libs.pari + sage: f(x) 2 - sage: f(x^2 - 4) # optional - sage.libs.pari + sage: f(x^2 - 4) 0 - sage: f(x^2) # optional - sage.libs.pari + sage: f(x^2) 4 TESTS: @@ -320,8 +320,8 @@ class of the quotient ring and its newly created elements. Thus, in order to document that this works fine, we go into some detail:: sage: P. = QQ[] - sage: Q = P.quotient(x^2 + 2) # optional - sage.libs.pari - sage: Q.category() # optional - sage.libs.pari + sage: Q = P.quotient(x^2 + 2) + sage: Q.category() Category of commutative no zero divisors quotients of algebras over (number fields and quotient fields and metric spaces) @@ -330,24 +330,24 @@ class of the quotient ring and its newly created elements. class of the category, and store the current class of the quotient ring:: - sage: isinstance(Q.an_element(), Q.element_class) # optional - sage.libs.pari + sage: isinstance(Q.an_element(), Q.element_class) True - sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] # optional - sage.libs.pari + sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] ['cartesian_product', 'inverse', 'inverse_of_unit', 'is_idempotent', 'is_one', 'is_unit', 'lift', 'powers'] - sage: first_class = Q.__class__ # optional - sage.libs.pari + sage: first_class = Q.__class__ We try to find out whether `Q` is a field. Indeed it is, and thus its category, including its class and element class, is changed accordingly:: - sage: Q in Fields() # optional - sage.libs.pari + sage: Q in Fields() True - sage: Q.category() # optional - sage.libs.pari + sage: Q.category() Category of commutative division no zero divisors quotients of algebras over (number fields and quotient fields and metric spaces) - sage: first_class == Q.__class__ # optional - sage.libs.pari + sage: first_class == Q.__class__ False - sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] # optional - sage.libs.pari + sage: [s for s in dir(Q.category().element_class) if not s.startswith('_')] ['cartesian_product', 'euclidean_degree', 'factor', @@ -371,22 +371,22 @@ class of the category, and store the current class of the quotient new methods from the category of fields, thanks to :meth:`Element.__getattr__`:: - sage: e = Q.an_element() # optional - sage.libs.pari - sage: isinstance(e, Q.element_class) # optional - sage.libs.pari + sage: e = Q.an_element() + sage: isinstance(e, Q.element_class) False - sage: e.gcd(e + 1) # optional - sage.libs.pari + sage: e.gcd(e + 1) 1 The test suite passes. However, we have to skip the test for its elements, since `an_element` has been cached in the call above and its class does not match the new category's element class anymore:: - sage: TestSuite(Q).run(skip=['_test_elements']) # optional - sage.libs.pari + sage: TestSuite(Q).run(skip=['_test_elements']) # needs sage.rings.number_field Newly created elements are fine, though, and their test suite passes:: - sage: TestSuite(Q(x)).run() # optional - sage.libs.pari - sage: isinstance(Q(x), Q.element_class) # optional - sage.libs.pari + sage: TestSuite(Q(x)).run() + sage: isinstance(Q(x), Q.element_class) True """ Element = PolynomialQuotientRingElement @@ -396,18 +396,18 @@ def __init__(self, ring, polynomial, name=None, category=None): TESTS:: sage: R. = PolynomialRing(ZZ) - sage: S = R.quo(x^2 - 4) # optional - sage.libs.pari + sage: S = R.quo(x^2 - 4) sage: from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic - sage: S == PolynomialQuotientRing_generic(R, x^2 - 4, 'xbar') # optional - sage.libs.pari + sage: S == PolynomialQuotientRing_generic(R, x^2 - 4, 'xbar') True Check that :trac:`26161` has been resolved:: - sage: R. = GF(2)[] # optional - sage.rings.finite_rings - sage: S = R.quo(x) # optional - sage.rings.finite_rings - sage: S in FiniteFields() # optional - sage.rings.finite_rings + sage: R. = GF(2)[] + sage: S = R.quo(x) # needs sage.rings.finite_rings + sage: S in FiniteFields() # needs sage.rings.finite_rings True - sage: type(S).mro() # optional - sage.rings.finite_rings + sage: type(S).mro() # needs sage.rings.finite_rings [, ... , @@ -453,18 +453,18 @@ def _element_constructor_(self, x): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^3 - 3*x + 1) # optional - sage.libs.pari - sage: S(x) # optional - sage.libs.pari + sage: S. = R.quotient(x^3 - 3*x + 1) + sage: S(x) alpha - sage: S(x^3) # optional - sage.libs.pari + sage: S(x^3) 3*alpha - 1 - sage: S([1,2]) # optional - sage.libs.pari + sage: S([1,2]) 2*alpha + 1 - sage: S([1,2,3,4,5]) # optional - sage.libs.pari + sage: S([1,2,3,4,5]) 18*alpha^2 + 9*alpha - 3 - sage: S(S.gen()+1) # optional - sage.libs.pari + sage: S(S.gen()+1) alpha + 1 - sage: S(S.gen()^10+1) # optional - sage.libs.pari + sage: S(S.gen()^10+1) 90*alpha^2 - 109*alpha + 28 TESTS: @@ -473,54 +473,54 @@ def _element_constructor_(self, x): This was fixed in :trac:`8800`:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari - sage: Q = P.quo([(x^2+1)^2]) # optional - sage.libs.pari - sage: Q1.has_coerce_map_from(Q) # optional - sage.libs.pari + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) + sage: Q = P.quo([(x^2+1)^2]) + sage: Q1.has_coerce_map_from(Q) False - sage: Q1(Q.gen()) # optional - sage.libs.pari + sage: Q1(Q.gen()) xbar Here we test against several issues discussed in :trac:`8992`:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari - sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) # optional - sage.libs.pari - sage: p = Q1.gen() + Q2.gen() # optional - sage.libs.pari - sage: p # optional - sage.libs.pari + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) + sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) + sage: p = Q1.gen() + Q2.gen() + sage: p 2*xbar - sage: p.parent() # optional - sage.libs.pari + sage: p.parent() Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^4 + 2*x^2 + 1 - sage: p.parent()('xbar') # optional - sage.libs.pari + sage: p.parent()('xbar') xbar Note that the result of string conversion has the correct parent, even when the given string suggests an element of the cover ring or the base ring:: - sage: a = Q1('x'); a # optional - sage.libs.pari + sage: a = Q1('x'); a xbar - sage: a.parent() is Q1 # optional - sage.libs.pari + sage: a.parent() is Q1 True - sage: b = Q1('1'); b # optional - sage.libs.pari + sage: b = Q1('1'); b 1 - sage: b.parent() is Q1 # optional - sage.libs.pari + sage: b.parent() is Q1 True Conversion may lift an element of one quotient ring to the base ring of another quotient ring:: - sage: R. = P[] # optional - sage.libs.pari - sage: Q3 = R.quo([(y^2+1)]) # optional - sage.libs.pari - sage: Q3(Q1.gen()) # optional - sage.libs.pari + sage: R. = P[] + sage: Q3 = R.quo([(y^2+1)]) + sage: Q3(Q1.gen()) x - sage: Q3.has_coerce_map_from(Q1) # optional - sage.libs.pari + sage: Q3.has_coerce_map_from(Q1) False String conversion takes into account both the generators of the quotient ring and its base ring:: - sage: Q3('x*ybar^2') # optional - sage.libs.pari + sage: Q3('x*ybar^2') -x """ @@ -562,25 +562,25 @@ def _coerce_map_from_(self, R): TESTS:: - sage: P5. = GF(5)[] # optional - sage.rings.finite_rings - sage: Q = P5.quo([(x^2+1)^2]) # optional - sage.rings.finite_rings + sage: P5. = GF(5)[] + sage: Q = P5.quo([(x^2+1)^2]) sage: P. = ZZ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari - sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) # optional - sage.libs.pari - sage: Q.has_coerce_map_from(Q1) #indirect doctest # optional - sage.libs.pari sage.rings.finite_rings + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) + sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)]) + sage: Q.has_coerce_map_from(Q1) #indirect doctest True - sage: Q1.has_coerce_map_from(Q) # optional - sage.libs.pari sage.rings.finite_rings + sage: Q1.has_coerce_map_from(Q) False - sage: Q1.has_coerce_map_from(Q2) # optional - sage.libs.pari sage.rings.finite_rings + sage: Q1.has_coerce_map_from(Q2) False The following tests against a bug fixed in :trac:`8992`:: sage: P. = QQ[] - sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) # optional - sage.libs.pari + sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)]) sage: R. = P[] - sage: Q2 = R.quo([(y^2 + 1)]) # optional - sage.libs.pari - sage: Q2.has_coerce_map_from(Q1) # optional - sage.libs.pari + sage: Q2 = R.quo([(y^2 + 1)]) + sage: Q2.has_coerce_map_from(Q1) False """ @@ -600,16 +600,17 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): """ EXAMPLES:: + sage: # needs sage.rings.number_field sage: T. = ZZ[] - sage: K. = NumberField(t^2 + 1) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient(x^2 - i) # optional - sage.rings.number_field - sage: Q8. = CyclotomicField(8) # optional - sage.rings.number_field - sage: S._is_valid_homomorphism_(Q8, [z]) # no coercion from K to Q8 # optional - sage.rings.number_field + sage: K. = NumberField(t^2 + 1) + sage: R. = K[] + sage: S. = R.quotient(x^2 - i) + sage: Q8. = CyclotomicField(8) + sage: S._is_valid_homomorphism_(Q8, [z]) # no coercion from K to Q8 False - sage: S._is_valid_homomorphism_(Q8, [z], K.hom([z^2])) # optional - sage.rings.number_field + sage: S._is_valid_homomorphism_(Q8, [z], K.hom([z^2])) True - sage: S._is_valid_homomorphism_(Q8, [1/z], K.hom([z^-2])) # optional - sage.rings.number_field + sage: S._is_valid_homomorphism_(Q8, [1/z], K.hom([z^-2])) True """ if base_map is None and not codomain.has_coerce_map_from(self.base_ring()): @@ -659,12 +660,12 @@ def lift(self, x): EXAMPLES:: sage: P. = QQ[] - sage: Q = P.quotient(x^2 + 2) # optional - sage.libs.pari - sage: Q.lift(Q.0^3) # optional - sage.libs.pari + sage: Q = P.quotient(x^2 + 2) + sage: Q.lift(Q.0^3) -2*x - sage: Q(-2*x) # optional - sage.libs.pari + sage: Q(-2*x) -2*xbar - sage: Q.0^3 # optional - sage.libs.pari + sage: Q.0^3 -2*xbar """ @@ -680,14 +681,14 @@ def __eq__(self, other): sage: Ry. = PolynomialRing(QQ) sage: Rx == Ry False - sage: Qx = Rx.quotient(x^2 + 1) # optional - sage.libs.pari - sage: Qy = Ry.quotient(y^2 + 1) # optional - sage.libs.pari - sage: Qx == Qy # optional - sage.libs.pari + sage: Qx = Rx.quotient(x^2 + 1) + sage: Qy = Ry.quotient(y^2 + 1) + sage: Qx == Qy False - sage: Qx == Qx # optional - sage.libs.pari + sage: Qx == Qx True - sage: Qz = Rx.quotient(x^2 + 1) # optional - sage.libs.pari - sage: Qz == Qx # optional - sage.libs.pari + sage: Qz = Rx.quotient(x^2 + 1) + sage: Qz == Qx True """ if not isinstance(other, PolynomialQuotientRing_generic): @@ -705,14 +706,14 @@ def __ne__(self, other): sage: Ry. = PolynomialRing(QQ) sage: Rx != Ry True - sage: Qx = Rx.quotient(x^2 + 1) # optional - sage.libs.pari - sage: Qy = Ry.quotient(y^2 + 1) # optional - sage.libs.pari - sage: Qx != Qy # optional - sage.libs.pari + sage: Qx = Rx.quotient(x^2 + 1) + sage: Qy = Ry.quotient(y^2 + 1) + sage: Qx != Qy True - sage: Qx != Qx # optional - sage.libs.pari + sage: Qx != Qx False - sage: Qz = Rx.quotient(x^2 + 1) # optional - sage.libs.pari - sage: Qz != Qx # optional - sage.libs.pari + sage: Qz = Rx.quotient(x^2 + 1) + sage: Qz != Qx False """ return not (self == other) @@ -727,14 +728,14 @@ def __hash__(self): sage: Ry. = PolynomialRing(QQ) sage: hash(Rx) == hash(Ry) False - sage: Qx = Rx.quotient(x^2 + 1) # optional - sage.libs.pari - sage: Qy = Ry.quotient(y^2 + 1) # optional - sage.libs.pari - sage: hash(Qx) == hash(Qy) # optional - sage.libs.pari + sage: Qx = Rx.quotient(x^2 + 1) + sage: Qy = Ry.quotient(y^2 + 1) + sage: hash(Qx) == hash(Qy) False - sage: hash(Qx) == hash(Qx) # optional - sage.libs.pari + sage: hash(Qx) == hash(Qx) True - sage: Qz = Rx.quotient(x^2 + 1) # optional - sage.libs.pari - sage: hash(Qz) == hash(Qx) # optional - sage.libs.pari + sage: Qz = Rx.quotient(x^2 + 1) + sage: hash(Qz) == hash(Qx) True """ return hash((self.polynomial_ring(), self.modulus())) @@ -746,8 +747,8 @@ def _singular_init_(self, S=None): TESTS:: sage: P. = QQ[] - sage: Q = P.quo([(x^2 + 1)]) # optional - sage.libs.pari - sage: singular(Q) # indirect doctest # optional - sage.libs.pari + sage: Q = P.quo([(x^2 + 1)]) + sage: singular(Q) # indirect doctest # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -756,7 +757,7 @@ def _singular_init_(self, S=None): // block 2 : ordering C // quotient ring from ideal _[1]=xbar^2+1 - sage: singular(Q.gen()) # optional - sage.libs.pari + sage: singular(Q.gen()) # needs sage.libs.singular xbar """ @@ -781,14 +782,14 @@ def construction(self): EXAMPLES:: sage: P. = ZZ[] - sage: Q = P.quo(5 + t^2) # optional - sage.libs.pari - sage: F, R = Q.construction() # optional - sage.libs.pari - sage: F(R) == Q # optional - sage.libs.pari + sage: Q = P.quo(5 + t^2) + sage: F, R = Q.construction() + sage: F(R) == Q True - sage: P. = GF(3)[] # optional - sage.rings.finite_rings - sage: Q = P.quo([2 + t^2]) # optional - sage.rings.finite_rings - sage: F, R = Q.construction() # optional - sage.rings.finite_rings - sage: F(R) == Q # optional - sage.rings.finite_rings + sage: P. = GF(3)[] + sage: Q = P.quo([2 + t^2]) + sage: F, R = Q.construction() + sage: F(R) == Q True AUTHOR: @@ -817,8 +818,8 @@ def base_ring(self): :: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quo(z^3 + z^2 + z + 1) # optional - sage.libs.pari - sage: S.base_ring() # optional - sage.libs.pari + sage: S. = R.quo(z^3 + z^2 + z + 1) + sage: S.base_ring() Integer Ring Next we make a polynomial quotient ring over `S` and ask @@ -826,9 +827,9 @@ def base_ring(self): :: - sage: T. = PolynomialRing(S) # optional - sage.libs.pari - sage: W = T.quotient(t^99 + 99) # optional - sage.libs.pari - sage: W.base_ring() # optional - sage.libs.pari + sage: T. = PolynomialRing(S) + sage: W = T.quotient(t^99 + 99) + sage: W.base_ring() Univariate Quotient Polynomial Ring in beta over Integer Ring with modulus z^3 + z^2 + z + 1 """ @@ -845,22 +846,23 @@ def cardinality(self): sage: R. = ZZ[] sage: R.quo(1).cardinality() 1 - sage: R.quo(x^3 - 2).cardinality() # optional - sage.libs.pari + sage: R.quo(x^3 - 2).cardinality() +Infinity sage: R.quo(1).order() 1 - sage: R.quo(x^3 - 2).order() # optional - sage.libs.pari + sage: R.quo(x^3 - 2).order() +Infinity :: - sage: R. = GF(9, 'a')[] # optional - sage.rings.finite_rings - sage: R.quo(2*x^3 + x + 1).cardinality() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(9, 'a')[] + sage: R.quo(2*x^3 + x + 1).cardinality() 729 - sage: GF(9, 'a').extension(2*x^3 + x + 1).cardinality() # optional - sage.rings.finite_rings + sage: GF(9, 'a').extension(2*x^3 + x + 1).cardinality() 729 - sage: R.quo(2).cardinality() # optional - sage.rings.finite_rings + sage: R.quo(2).cardinality() 1 TESTS:: @@ -894,21 +896,21 @@ def is_finite(self): sage: R. = ZZ[] sage: R.quo(1).is_finite() True - sage: R.quo(x^3 - 2).is_finite() # optional - sage.libs.pari + sage: R.quo(x^3 - 2).is_finite() False :: - sage: R. = GF(9, 'a')[] # optional - sage.rings.finite_rings - sage: R.quo(2*x^3 + x + 1).is_finite() # optional - sage.rings.finite_rings + sage: R. = GF(9, 'a')[] # needs sage.rings.finite_rings + sage: R.quo(2*x^3 + x + 1).is_finite() # needs sage.rings.finite_rings True - sage: R.quo(2).is_finite() # optional - sage.rings.finite_rings + sage: R.quo(2).is_finite() # needs sage.rings.finite_rings True :: - sage: P. = GF(2)[] # optional - sage.rings.finite_rings - sage: P.quotient(v^2 - v).is_finite() # optional - sage.rings.finite_rings + sage: P. = GF(2)[] + sage: P.quotient(v^2 - v).is_finite() True """ f = self.modulus() @@ -924,9 +926,9 @@ def __iter__(self): r""" EXAMPLES:: - sage: R. = GF(3)[] # optional - sage.rings.finite_rings - sage: Q = R.quo(x^3 - x^2 - x - 1) # optional - sage.rings.finite_rings - sage: list(Q) # optional - sage.rings.finite_rings + sage: R. = GF(3)[] + sage: Q = R.quo(x^3 - x^2 - x - 1) + sage: list(Q) [0, 1, 2, @@ -937,7 +939,7 @@ def __iter__(self): ... 2*xbar^2 + 2*xbar + 1, 2*xbar^2 + 2*xbar + 2] - sage: len(_) == Q.cardinality() == 27 # optional - sage.rings.finite_rings + sage: len(_) == Q.cardinality() == 27 True """ if not self.is_finite(): @@ -958,12 +960,12 @@ def characteristic(self): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quo(z - 19) # optional - sage.libs.pari - sage: S.characteristic() # optional - sage.libs.pari + sage: S. = R.quo(z - 19) + sage: S.characteristic() 0 - sage: R. = PolynomialRing(GF(9, 'a')) # optional - sage.rings.finite_rings - sage: S = R.quotient(x^3 + 1) # optional - sage.rings.finite_rings - sage: S.characteristic() # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(9, 'a')) # needs sage.rings.finite_rings + sage: S = R.quotient(x^3 + 1) # needs sage.rings.finite_rings + sage: S.characteristic() # needs sage.rings.finite_rings 3 """ return self.base_ring().characteristic() @@ -975,9 +977,9 @@ def degree(self): EXAMPLES:: - sage: R. = PolynomialRing(GF(3)) # optional - sage.rings.finite_rings - sage: S = R.quotient(x^2005 + 1) # optional - sage.rings.finite_rings - sage: S.degree() # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(3)) + sage: S = R.quotient(x^2005 + 1) + sage: S.degree() 2005 """ return self.modulus().degree() @@ -991,11 +993,11 @@ def discriminant(self, v=None): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^3 + x^2 + x + 1) # optional - sage.libs.pari - sage: S.discriminant() # optional - sage.libs.pari + sage: S = R.quotient(x^3 + x^2 + x + 1) + sage: S.discriminant() -16 - sage: S = R.quotient((x + 1) * (x + 1)) # optional - sage.libs.pari - sage: S.discriminant() # optional - sage.libs.pari + sage: S = R.quotient((x + 1) * (x + 1)) + sage: S.discriminant() 0 The discriminant of the quotient polynomial ring need not equal the @@ -1003,10 +1005,10 @@ def discriminant(self, v=None): discriminant of a number field is by definition the discriminant of the ring of integers of the number field:: - sage: S = R.quotient(x^2 - 8) # optional - sage.libs.pari - sage: S.number_field().discriminant() # optional - sage.libs.pari + sage: S = R.quotient(x^2 - 8) + sage: S.number_field().discriminant() # needs sage.rings.number_field 8 - sage: S.discriminant() # optional - sage.libs.pari + sage: S.discriminant() 32 """ return self.modulus().discriminant() @@ -1019,8 +1021,8 @@ class of the image of the generator of the polynomial ring. EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^2 - 8, 'gamma') # optional - sage.libs.pari - sage: S.gen() # optional - sage.libs.pari + sage: S = R.quotient(x^2 - 8, 'gamma') + sage: S.gen() gamma """ if n != 0: @@ -1038,28 +1040,29 @@ def is_field(self, proof=True): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S = R.quo(z^2 - 2) # optional - sage.libs.pari - sage: S.is_field() # optional - sage.libs.pari + sage: S = R.quo(z^2 - 2) + sage: S.is_field() False sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^2 - 2) # optional - sage.libs.pari - sage: S.is_field() # optional - sage.libs.pari + sage: S = R.quotient(x^2 - 2) + sage: S.is_field() True If proof is ``True``, requires the ``is_irreducible`` method of the modulus to be implemented:: - sage: R1. = Qp(2)[] # optional - sage.rings.padics - sage: F1 = R1.quotient_ring(x^2 + x + 1) # optional - sage.rings.padics - sage: R2. = F1[] # optional - sage.rings.padics - sage: F2 = R2.quotient_ring(x^2 + x + 1) # optional - sage.rings.padics - sage: F2.is_field() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R1. = Qp(2)[] + sage: F1 = R1.quotient_ring(x^2 + x + 1) + sage: R2. = F1[] + sage: F2 = R2.quotient_ring(x^2 + x + 1) + sage: F2.is_field() Traceback (most recent call last): ... NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in xbar over 2-adic Field with capped relative precision 20 with modulus (1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring - sage: F2.is_field(proof = False) # optional - sage.rings.padics + sage: F2.is_field(proof = False) False """ @@ -1084,21 +1087,21 @@ def is_integral_domain(self, proof=True): EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S = R.quotient(z^2 - z) # optional - sage.libs.pari - sage: S.is_integral_domain() # optional - sage.libs.pari + sage: S = R.quotient(z^2 - z) + sage: S.is_integral_domain() False - sage: T = R.quotient(z^2 + 1) # optional - sage.libs.pari - sage: T.is_integral_domain() # optional - sage.libs.pari + sage: T = R.quotient(z^2 + 1) + sage: T.is_integral_domain() True sage: U = R.quotient(-1) sage: U.is_integral_domain() False sage: R2. = PolynomialRing(R) - sage: S2 = R2.quotient(z^2 - y^3) # optional - sage.libs.pari - sage: S2.is_integral_domain() # optional - sage.libs.pari + sage: S2 = R2.quotient(z^2 - y^3) + sage: S2.is_integral_domain() # needs sage.libs.singular True - sage: S3 = R2.quotient(z^2 - 2*y*z + y^2) # optional - sage.libs.pari - sage: S3.is_integral_domain() # optional - sage.libs.pari + sage: S3 = R2.quotient(z^2 - 2*y*z + y^2) + sage: S3.is_integral_domain() # needs sage.libs.singular False sage: R. = PolynomialRing(ZZ.quotient(4)) @@ -1112,15 +1115,16 @@ def is_integral_domain(self, proof=True): domain, even though the base ring is integral and the modulus is irreducible:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: B = ZZ.extension(x^2 - 5, 'a') # optional - sage.rings.number_field - sage: R. = PolynomialRing(B) # optional - sage.rings.number_field - sage: S = R.quotient(y^2 - y - 1) # optional - sage.libs.pari sage.rings.number_field - sage: S.is_integral_domain() # optional - sage.libs.pari sage.rings.number_field + sage: B = ZZ.extension(x^2 - 5, 'a') + sage: R. = PolynomialRing(B) + sage: S = R.quotient(y^2 - y - 1) + sage: S.is_integral_domain() Traceback (most recent call last): ... NotImplementedError - sage: S.is_integral_domain(proof=False) # optional - sage.libs.pari sage.rings.number_field + sage: S.is_integral_domain(proof=False) False The reason that the modulus y^2 - y - 1 is not prime is that it @@ -1169,11 +1173,11 @@ def krull_dimension(self): EXAMPLES:: sage: x = polygen(ZZ, 'x') - sage: R = PolynomialRing(ZZ, 'x').quotient(x**6 - 1) # optional - sage.libs.pari - sage: R.krull_dimension() # optional - sage.libs.pari + sage: R = PolynomialRing(ZZ, 'x').quotient(x**6 - 1) + sage: R.krull_dimension() 1 - sage: R = PolynomialRing(ZZ, 'x').quotient(1) # optional - sage.libs.pari - sage: R.krull_dimension() # optional - sage.libs.pari + sage: R = PolynomialRing(ZZ, 'x').quotient(1) + sage: R.krull_dimension() -1 """ if self.is_zero(): @@ -1186,9 +1190,9 @@ def modulus(self): EXAMPLES:: - sage: R. = PolynomialRing(GF(3)) # optional - sage.rings.finite_rings - sage: S = R.quotient(x^2 - 2) # optional - sage.rings.finite_rings - sage: S.modulus() # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(3)) + sage: S = R.quotient(x^2 - 2) + sage: S.modulus() x^2 + 1 """ return self.__polynomial @@ -1204,7 +1208,8 @@ def ngens(self): sage: S. = PolynomialRing(R) sage: T. = S.quotient(y + x) sage: T - Univariate Quotient Polynomial Ring in z over Univariate Polynomial Ring in x over Rational Field with modulus y + x + Univariate Quotient Polynomial Ring in z over + Univariate Polynomial Ring in x over Rational Field with modulus y + x sage: T.ngens() 1 """ @@ -1217,12 +1222,13 @@ def number_field(self): EXAMPLES:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^29 - 17*x - 1) # optional - sage.libs.pari - sage: K = S.number_field(); K # optional - sage.libs.pari sage.rings.number_field + sage: S. = R.quotient(x^29 - 17*x - 1) + sage: K = S.number_field(); K Number Field in alpha with defining polynomial x^29 - 17*x - 1 - sage: alpha = K.gen() # optional - sage.libs.pari sage.rings.number_field - sage: alpha^29 # optional - sage.libs.pari sage.rings.number_field + sage: alpha = K.gen() + sage: alpha^29 17*alpha + 1 """ if self.characteristic() != 0: @@ -1240,8 +1246,8 @@ def polynomial_ring(self): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: S = R.quotient(x^2 - 2) # optional - sage.libs.pari - sage: S.polynomial_ring() # optional - sage.libs.pari + sage: S = R.quotient(x^2 - 2) + sage: S.polynomial_ring() Univariate Polynomial Ring in x over Rational Field """ return self.__ring @@ -1264,10 +1270,11 @@ def random_element(self, *args, **kwds): EXAMPLES:: - sage: F1. = GF(2^7) # optional - sage.rings.finite_rings - sage: P1. = F1[] # optional - sage.rings.finite_rings - sage: F2 = F1.extension(x^2 + x + 1, 'u') # optional - sage.rings.finite_rings - sage: F2.random_element().parent() is F2 # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F1. = GF(2^7) + sage: P1. = F1[] + sage: F2 = F1.extension(x^2 + x + 1, 'u') + sage: F2.random_element().parent() is F2 True """ return self(self.polynomial_ring().random_element( @@ -1283,22 +1290,23 @@ def _S_decomposition(self, S): EXAMPLES:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field - sage: fields, isos, iso_classes = S._S_decomposition(tuple(K.primes_above(3))) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) + sage: fields, isos, iso_classes = S._S_decomposition(tuple(K.primes_above(3))) Representatives of the number fields up to isomorphism that occur in the decomposition:: - sage: fields # optional - sage.rings.number_field + sage: fields # needs sage.rings.number_field [Number Field in x0 with defining polynomial x^2 + 23 over its base field, Number Field in x1 with defining polynomial x^2 + 31 over its base field] In this case, the isomorphisms of these representatives to the components are the identity maps:: - sage: isos # optional - sage.rings.number_field + sage: isos # needs sage.rings.number_field [(Ring endomorphism of Number Field in y0 with defining polynomial x^4 + 56*x^2 + 324 Defn: y0 |--> y0, 0), @@ -1309,9 +1317,9 @@ def _S_decomposition(self, S): There are four primes above 3 in the first component and two in the second component:: - sage: len(iso_classes[0][1]) # optional - sage.rings.number_field + sage: len(iso_classes[0][1]) # needs sage.rings.number_field 4 - sage: len(iso_classes[1][1]) # optional - sage.rings.number_field + sage: len(iso_classes[1][1]) # needs sage.rings.number_field 2 """ from sage.rings.number_field.number_field_base import NumberField @@ -1390,43 +1398,46 @@ def S_class_group(self, S, proof=True): A trivial algebra over `\QQ(\sqrt{-5})` has the same class group as its base:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient(x) # optional - sage.rings.number_field - sage: S.S_class_group([]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: S. = R.quotient(x) + sage: S.S_class_group([]) [((2, -a + 1), 2)] When we include the prime `(2, -a+1)`, the `S`-class group becomes trivial:: - sage: S.S_class_group([K.ideal(2, -a+1)]) # optional - sage.rings.number_field + sage: S.S_class_group([K.ideal(2, -a+1)]) # needs sage.rings.number_field [] Here is an example where the base and the extension both contribute to the class group:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: K.class_group() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: K.class_group() Class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient(x^2 + 23) # optional - sage.rings.number_field - sage: S.S_class_group([]) # optional - sage.rings.number_field + sage: R. = K[] + sage: S. = R.quotient(x^2 + 23) + sage: S.S_class_group([]) [((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)] - sage: S.S_class_group([K.ideal(3, a-1)]) # optional - sage.rings.number_field + sage: S.S_class_group([K.ideal(3, a-1)]) [] - sage: S.S_class_group([K.ideal(2, a+1)]) # optional - sage.rings.number_field + sage: S.S_class_group([K.ideal(2, a+1)]) [] - sage: S.S_class_group([K.ideal(a)]) # optional - sage.rings.number_field + sage: S.S_class_group([K.ideal(a)]) [((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)] Now we take an example over a nontrivial base with two factors, each contributing to the class group:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field - sage: S.S_class_group([]) # representation varies, not tested # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) + sage: S.S_class_group([]) # not tested [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, @@ -1447,7 +1458,7 @@ def S_class_group(self, S, proof=True): `x^2 + 31` from 12 to 2, i.e. we lose a generator of order 6 (this was fixed in :trac:`14489`):: - sage: S.S_class_group([K.ideal(a)]) # representation varies, not tested # optional - sage.rings.number_field + sage: S.S_class_group([K.ideal(a)]) # representation varies # not tested, needs sage.rings.number_field [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, -1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8), @@ -1459,21 +1470,23 @@ def S_class_group(self, S, proof=True): Note that all the returned values live where we expect them to:: - sage: CG = S.S_class_group([]) # optional - sage.rings.number_field - sage: type(CG[0][0][1]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: CG = S.S_class_group([]) + sage: type(CG[0][0][1]) - sage: type(CG[0][1]) # optional - sage.rings.number_field + sage: type(CG[0][1]) TESTS: We verify the above test, where the representation depends on the PARI version:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field - sage: C = S.S_class_group([]) # optional - sage.rings.number_field - sage: C[:2] # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) + sage: C = S.S_class_group([]) + sage: C[:2] [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, @@ -1484,21 +1497,21 @@ def S_class_group(self, S, proof=True): -1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16, 1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8), 6)] - sage: C[2][1] # optional - sage.rings.number_field + sage: C[2][1] 2 - sage: gens = C[2][0] # optional - sage.rings.number_field - sage: expected_gens = ( # optional - sage.rings.number_field + sage: gens = C[2][0] + sage: expected_gens = ( ....: -5/4*xbar^2 - 115/4, ....: 1/4*a*xbar^2 + 23/4*a, ....: -1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16, ....: 1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a) - sage: gens[0] == expected_gens[0] # optional - sage.rings.number_field + sage: gens[0] == expected_gens[0] True - sage: gens[1] in (expected_gens[1], expected_gens[1]/2 + expected_gens[0]/2) # optional - sage.rings.number_field + sage: gens[1] in (expected_gens[1], expected_gens[1]/2 + expected_gens[0]/2) True - sage: gens[2] in (expected_gens[2], expected_gens[2] + expected_gens[0]/2) # optional - sage.rings.number_field + sage: gens[2] in (expected_gens[2], expected_gens[2] + expected_gens[0]/2) True - sage: gens[3] in (expected_gens[3], expected_gens[3] + expected_gens[0]/2) # optional - sage.rings.number_field + sage: gens[3] in (expected_gens[3], expected_gens[3] + expected_gens[0]/2) True """ fields, isos, iso_classes = self._S_decomposition(tuple(S)) @@ -1553,49 +1566,53 @@ def class_group(self, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-3) # optional - sage.rings.number_field - sage: K.class_group() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-3) + sage: K.class_group() Class group of order 1 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I sage: x = polygen(QQ, 'x') - sage: K. = QQ['x'].quotient(x^2 + 3) # optional - sage.libs.pari sage.rings.number_field - sage: K.class_group() # optional - sage.libs.pari sage.rings.number_field + sage: K. = QQ['x'].quotient(x^2 + 3) + sage: K.class_group() [] A trivial algebra over `\QQ(\sqrt{-5})` has the same class group as its base:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient(x) # optional - sage.rings.number_field - sage: S.class_group() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: S. = R.quotient(x) + sage: S.class_group() [((2, -a + 1), 2)] The same algebra constructed in a different way:: sage: x = polygen(ZZ, 'x') - sage: K. = QQ['x'].quotient(x^2 + 5) # optional - sage.libs.pari - sage: K.class_group(()) # optional - sage.libs.pari + sage: K. = QQ['x'].quotient(x^2 + 5) + sage: K.class_group(()) # needs sage.rings.number_field [((2, a + 1), 2)] Here is an example where the base and the extension both contribute to the class group:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: K.class_group() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: K.class_group() Class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient(x^2 + 23) # optional - sage.rings.number_field - sage: S.class_group() # optional - sage.rings.number_field + sage: R. = K[] + sage: S. = R.quotient(x^2 + 23) + sage: S.class_group() [((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)] Here is an example of a product of number fields, both of which contribute to the class group:: - sage: R. = QQ[] # optional - sage.rings.number_field - sage: S. = R.quotient((x^2 + 23) * (x^2 + 47)) # optional - sage.rings.number_field - sage: S.class_group() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = QQ[] + sage: S. = R.quotient((x^2 + 23) * (x^2 + 47)) + sage: S.class_group() [((1/12*xbar^2 + 47/12, 1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48), 3), @@ -1606,10 +1623,11 @@ def class_group(self, proof=True): Now we take an example over a nontrivial base with two factors, each contributing to the class group:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) # optional - sage.rings.number_field - sage: S.class_group() # representation varies, not tested # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: S. = R.quotient((x^2 + 23) * (x^2 + 31)) + sage: S.class_group() # not tested [((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8, 1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16, @@ -1628,10 +1646,11 @@ def class_group(self, proof=True): Note that all the returned values live where we expect them to:: - sage: CG = S.class_group() # optional - sage.rings.number_field - sage: type(CG[0][0][1]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: CG = S.class_group() + sage: type(CG[0][0][1]) - sage: type(CG[0][1]) # optional - sage.rings.number_field + sage: type(CG[0][1]) """ @@ -1657,40 +1676,43 @@ def S_units(self, S, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-3) # optional - sage.rings.number_field - sage: K.unit_group() # optional - sage.rings.number_field + sage: K. = QuadraticField(-3) # needs sage.rings.number_field + sage: K.unit_group() # needs sage.rings.number_field Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = QQ['x'].quotient(x^2 + 3) # optional - sage.libs.pari - sage: u, o = K.S_units([])[0]; o # optional - sage.libs.pari + sage: K. = QQ['x'].quotient(x^2 + 3) + sage: u, o = K.S_units([])[0]; o 6 - sage: 2*u - 1 in {a, -a} # optional - sage.libs.pari + sage: 2*u - 1 in {a, -a} True - sage: u^6 # optional - sage.libs.pari + sage: u^6 1 - sage: u^3 # optional - sage.libs.pari + sage: u^3 -1 - sage: 2*u^2 + 1 in {a, -a} # optional - sage.libs.pari + sage: 2*u^2 + 1 in {a, -a} True :: - sage: K. = QuadraticField(-3) # optional - sage.rings.number_field - sage: y = polygen(K) # optional - sage.rings.number_field - sage: L. = K['y'].quotient(y^3 + 5); L # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-3) + sage: y = polygen(K) + sage: L. = K['y'].quotient(y^3 + 5); L Univariate Quotient Polynomial Ring in b over Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I with modulus y^3 + 5 - sage: [u for u, o in L.S_units([]) if o is Infinity] # optional - sage.rings.number_field + sage: [u for u, o in L.S_units([]) if o is Infinity] [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] - sage: [u for u, o in L.S_units([K.ideal(1/2*a - 3/2)]) # optional - sage.rings.number_field + sage: [u for u, o in L.S_units([K.ideal(1/2*a - 3/2)]) ....: if o is Infinity] [(-1/6*a - 1/2)*b^2 + (1/3*a - 1)*b + 4/3*a, (-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] - sage: [u for u, o in L.S_units([K.ideal(2)]) if o is Infinity] # optional - sage.rings.number_field + sage: [u for u, o in L.S_units([K.ideal(2)]) if o is Infinity] [(1/2*a - 1/2)*b^2 + (a + 1)*b + 3, (1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a + 1/2, (1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a - 1/2, @@ -1699,12 +1721,13 @@ def S_units(self, S, proof=True): Note that all the returned values live where we expect them to:: - sage: U = L.S_units([]) # optional - sage.rings.number_field - sage: type(U[0][0]) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: U = L.S_units([]) + sage: type(U[0][0]) - sage: type(U[0][1]) # optional - sage.rings.number_field + sage: type(U[0][1]) - sage: type(U[1][1]) # optional - sage.rings.number_field + sage: type(U[1][1]) """ @@ -1748,56 +1771,60 @@ def units(self, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-3) # optional - sage.rings.number_field - sage: K.unit_group() # optional - sage.rings.number_field + sage: K. = QuadraticField(-3) # needs sage.rings.number_field + sage: K.unit_group() # needs sage.rings.number_field Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I + + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = QQ['x'].quotient(x^2 + 3) # optional - sage.libs.pari - sage: u = K.units()[0][0] # optional - sage.libs.pari - sage: 2*u - 1 in {a, -a} # optional - sage.libs.pari + sage: K. = QQ['x'].quotient(x^2 + 3) + sage: u = K.units()[0][0] + sage: 2*u - 1 in {a, -a} True - sage: u^6 # optional - sage.libs.pari + sage: u^6 1 - sage: u^3 # optional - sage.libs.pari + sage: u^3 -1 - sage: 2*u^2 + 1 in {a, -a} # optional - sage.libs.pari + sage: 2*u^2 + 1 in {a, -a} True sage: x = polygen(ZZ, 'x') - sage: K. = QQ['x'].quotient(x^2 + 5) # optional - sage.libs.pari - sage: K.units(()) # optional - sage.libs.pari + sage: K. = QQ['x'].quotient(x^2 + 5) + sage: K.units(()) [(-1, 2)] :: - sage: K. = QuadraticField(-3) # optional - sage.rings.number_field - sage: y = polygen(K) # optional - sage.rings.number_field - sage: L. = K['y'].quotient(y^3 + 5); L # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-3) + sage: y = polygen(K) + sage: L. = K['y'].quotient(y^3 + 5); L Univariate Quotient Polynomial Ring in b over Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I with modulus y^3 + 5 - sage: [u for u, o in L.units() if o is Infinity] # optional - sage.rings.number_field + sage: [u for u, o in L.units() if o is Infinity] [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] - sage: L. = K.extension(y^3 + 5) # optional - sage.rings.number_field - sage: L.unit_group() # optional - sage.rings.number_field + sage: L. = K.extension(y^3 + 5) + sage: L.unit_group() Unit group with structure C6 x Z x Z of Number Field in b with defining polynomial x^3 + 5 over its base field - sage: L.unit_group().gens() # abstract generators # optional - sage.rings.number_field + sage: L.unit_group().gens() # abstract generators (u0, u1, u2) - sage: L.unit_group().gens_values()[1:] # optional - sage.rings.number_field + sage: L.unit_group().gens_values()[1:] [(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2, 2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2] Note that all the returned values live where we expect them to:: - sage: L. = K['y'].quotient(y^3 + 5) # optional - sage.libs.pari - sage: U = L.units() # optional - sage.libs.pari - sage: type(U[0][0]) # optional - sage.libs.pari + sage: # needs sage.rings.number_field + sage: L. = K['y'].quotient(y^3 + 5) + sage: U = L.units() + sage: type(U[0][0]) - sage: type(U[0][1]) # optional - sage.libs.pari + sage: type(U[0][1]) - sage: type(U[1][1]) # optional - sage.libs.pari + sage: type(U[1][1]) """ @@ -1826,22 +1853,23 @@ def selmer_generators(self, S, m, proof=True): EXAMPLES:: - sage: K. = QuadraticField(-5) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: D. = R.quotient(x) # optional - sage.rings.number_field - sage: D.selmer_generators((), 2) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-5) + sage: R. = K[] + sage: D. = R.quotient(x) + sage: D.selmer_generators((), 2) [-1, 2] - sage: D.selmer_generators([K.ideal(2, -a + 1)], 2) # optional - sage.rings.number_field + sage: D.selmer_generators([K.ideal(2, -a + 1)], 2) [2, -1] - sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2) # optional - sage.rings.number_field + sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2) [2, a + 1, -1] - sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4) # optional - sage.rings.number_field + sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4) [2, a + 1, -1] - sage: D.selmer_generators([K.ideal(2, -a + 1)], 3) # optional - sage.rings.number_field + sage: D.selmer_generators([K.ideal(2, -a + 1)], 3) [2] - sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3) # optional - sage.rings.number_field + sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3) [2, a + 1] - sage: D.selmer_generators([K.ideal(2, -a + 1), # optional - sage.rings.number_field + sage: D.selmer_generators([K.ideal(2, -a + 1), ....: K.ideal(3, a + 1), ....: K.ideal(a)], 3) [2, a + 1, -a] @@ -1878,13 +1906,14 @@ def _factor_multivariate_polynomial(self, f, proof=True): TESTS:: - sage: k. = GF(4) # optional - sage.rings.finite_rings - sage: R. = k[] # optional - sage.rings.finite_rings - sage: l. = k.extension(b^2 + b + a) # optional - sage.rings.finite_rings - sage: K. = FunctionField(l) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: F = t * x # optional - sage.rings.finite_rings - sage: F.factor(proof=False) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(4) + sage: R. = k[] + sage: l. = k.extension(b^2 + b + a) + sage: K. = FunctionField(l) + sage: R. = K[] + sage: F = t * x + sage: F.factor(proof=False) (x) * t """ @@ -1905,17 +1934,18 @@ def _factor_univariate_polynomial(self, f): TESTS:: - sage: K = GF(2) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: L. = K.extension(x^2 + x + 1) # optional - sage.rings.finite_rings - sage: R. = L[] # optional - sage.rings.finite_rings - sage: M. = L.extension(y^2 + y + x) # optional - sage.rings.finite_rings - sage: R. = M[] # optional - sage.rings.finite_rings - sage: R(y).factor() # indirect doctest # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K = GF(2) + sage: R. = K[] + sage: L. = K.extension(x^2 + x + 1) + sage: R. = L[] + sage: M. = L.extension(y^2 + y + x) + sage: R. = M[] + sage: R(y).factor() # indirect doctest y - sage: (T^2 + T + x).factor() # indirect doctest # optional - sage.rings.finite_rings + sage: (T^2 + T + x).factor() # indirect doctest (T + y) * (T + y + 1) - sage: (y*T^2 + y*T + y*x).factor() # indirect doctest # optional - sage.rings.finite_rings + sage: (y*T^2 + y*T + y*x).factor() # indirect doctest (y) * (T + y) * (T + y + 1) """ @@ -1956,36 +1986,37 @@ def _isomorphic_ring(self): EXAMPLES:: - sage: K. = GF(4) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: L. = K.extension(b^2 + b + a); L # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(4) + sage: R. = K[] + sage: L. = K.extension(b^2 + b + a); L Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^2 with modulus b^2 + b + a - sage: from_M, to_M, M = L._isomorphic_ring(); M # optional - sage.rings.finite_rings + sage: from_M, to_M, M = L._isomorphic_ring(); M Finite Field in z4 of size 2^4 - sage: R. = L[] # optional - sage.rings.finite_rings - sage: M. = L.extension(c^2 + b*c + b); M # optional - sage.rings.finite_rings + sage: R. = L[] # needs sage.rings.finite_rings + sage: M. = L.extension(c^2 + b*c + b); M # needs sage.rings.finite_rings Univariate Quotient Polynomial Ring in c over Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^2 with modulus b^2 + b + a with modulus c^2 + b*c + b - sage: from_N, to_N, N = M._isomorphic_ring(); N # optional - sage.rings.finite_rings + sage: from_N, to_N, N = M._isomorphic_ring(); N # needs sage.rings.finite_rings Finite Field in z8 of size 2^8 sage: R. = QQ[] - sage: K = R.quo(x^2 + 1) # optional - sage.libs.pari - sage: from_L, to_L, L = K._isomorphic_ring() # optional - sage.libs.pari sage.rings.number_field - sage: L # optional - sage.libs.pari sage.rings.number_field + sage: K = R.quo(x^2 + 1) + sage: from_L, to_L, L = K._isomorphic_ring() # needs sage.rings.number_field + sage: L # needs sage.rings.number_field Number Field in xbar with defining polynomial x^2 + 1 TESTS: Verify that this works for trivial extensions:: - sage: K. = GF(4) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: from_L, to_L, L = R.quo(b)._isomorphic_ring(); L # optional - sage.rings.finite_rings + sage: K. = GF(4) # needs sage.rings.finite_rings + sage: R. = K[] # needs sage.rings.finite_rings + sage: from_L, to_L, L = R.quo(b)._isomorphic_ring(); L # needs sage.rings.finite_rings Finite Field in a of size 2^2 """ @@ -2102,13 +2133,14 @@ def _test_isomorphic_ring(self, **options): TESTS:: - sage: K. = GF(4) # optional - sage.rings.finite_rings - sage: R. = K[] # optional - sage.rings.finite_rings - sage: L. = K.extension(b^2 + b + a) # optional - sage.rings.finite_rings - sage: L._test_isomorphic_ring() # optional - sage.rings.finite_rings - sage: R. = L[] # optional - sage.rings.finite_rings - sage: M. = L.extension(c^2 + b*c + b) # optional - sage.rings.finite_rings - sage: M._test_isomorphic_ring() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(4) + sage: R. = K[] + sage: L. = K.extension(b^2 + b + a) + sage: L._test_isomorphic_ring() + sage: R. = L[] + sage: M. = L.extension(c^2 + b*c + b) + sage: M._test_isomorphic_ring() """ tester = self._tester(**options) @@ -2146,7 +2178,7 @@ class PolynomialQuotientRing_coercion(DefaultConvertMap_unique): sage: R. = ZZ[] sage: S. = QQ[] - sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)); f # optional - sage.libs.pari + sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)); f Coercion map: From: Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 @@ -2156,17 +2188,17 @@ class PolynomialQuotientRing_coercion(DefaultConvertMap_unique): TESTS:: sage: from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_coercion - sage: isinstance(f, PolynomialQuotientRing_coercion) # optional - sage.libs.pari + sage: isinstance(f, PolynomialQuotientRing_coercion) True - sage: TestSuite(f).run(skip=['_test_pickling']) # optional - sage.libs.pari + sage: TestSuite(f).run(skip=['_test_pickling']) Pickling works:: - sage: g = loads(dumps(f)); g # optional - sage.libs.pari + sage: g = loads(dumps(f)); g Coercion map: From: Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 To: Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 - sage: f == g # optional - sage.libs.pari + sage: f == g True """ @@ -2182,8 +2214,8 @@ def is_injective(self): sage: R. = ZZ[] sage: S. = QQ[] - sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)) # optional - sage.libs.pari - sage: f.is_injective() # optional - sage.libs.pari + sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)) + sage: f.is_injective() True """ @@ -2206,18 +2238,19 @@ def is_surjective(self): domain:: sage: R. = ZZ[] - sage: f = R.quo(x).coerce_map_from(R.quo(x^2)) # optional - sage.libs.pari - sage: f.is_surjective() # optional - sage.libs.pari + sage: f = R.quo(x).coerce_map_from(R.quo(x^2)) + sage: f.is_surjective() True If the modulus of the domain and the codomain is the same, then the map is surjective iff the underlying map on the constants is:: - sage: A. = ZqCA(9) # optional - sage.rings.padics - sage: R. = A[] # optional - sage.rings.padics - sage: S. = A.fraction_field()[] # optional - sage.rings.padics - sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2)) # optional - sage.rings.padics - sage: f.is_surjective() # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: A. = ZqCA(9) + sage: R. = A[] + sage: S. = A.fraction_field()[] + sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2)) + sage: f.is_surjective() False """ @@ -2236,11 +2269,11 @@ def _richcmp_(self, other, op): sage: R. = ZZ[] sage: S. = ZZ[] - sage: f = S.quo(x).coerce_map_from(R.quo(x^2)) # optional - sage.libs.pari - sage: g = S.quo(x).coerce_map_from(R.quo(x^3)) # optional - sage.libs.pari - sage: f == g # optional - sage.libs.pari + sage: f = S.quo(x).coerce_map_from(R.quo(x^2)) + sage: g = S.quo(x).coerce_map_from(R.quo(x^3)) + sage: f == g False - sage: f == f # optional - sage.libs.pari + sage: f == f True """ @@ -2254,13 +2287,13 @@ class PolynomialQuotientRing_domain(PolynomialQuotientRing_generic, IntegralDoma EXAMPLES:: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quotient(x^2 + 1) # optional - sage.libs.pari - sage: S # optional - sage.libs.pari + sage: S. = R.quotient(x^2 + 1) + sage: S Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 - sage: loads(S.dumps()) == S # optional - sage.libs.pari + sage: loads(S.dumps()) == S True - sage: loads(xbar.dumps()) == xbar # optional - sage.libs.pari + sage: loads(xbar.dumps()) == xbar True """ def __init__(self, ring, polynomial, name=None, category=None): @@ -2270,21 +2303,21 @@ def __init__(self, ring, polynomial, name=None, category=None): TESTS:: sage: R. = PolynomialRing(ZZ) - sage: S. = R.quotient(x^2 + 1) # optional - sage.libs.pari - sage: TestSuite(S).run() # optional - sage.libs.pari + sage: S. = R.quotient(x^2 + 1) + sage: TestSuite(S).run() Check that :trac:`17450` is fixed:: - sage: S in IntegralDomains() # optional - sage.libs.pari + sage: S in IntegralDomains() True Check that :trac:`29017` is fixed:: sage: R. = ZZ[] - sage: Q = R.quo(x - 1) # optional - sage.libs.pari - sage: H = R.Hom(Q) # optional - sage.libs.pari - sage: h = R.hom(Q) # optional - sage.libs.pari - sage: h.parent() is H # optional - sage.libs.pari + sage: Q = R.quo(x - 1) + sage: H = R.Hom(Q) + sage: h = R.hom(Q) + sage: h.parent() is H True """ category = CommutativeAlgebras(ring.base_ring().category()).Quotients().NoZeroDivisors().or_subcategory(category) @@ -2308,22 +2341,23 @@ def field_extension(self, names): EXAMPLES:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(Rationals()) - sage: S. = R.quotient(x^3 - 2) # optional - sage.libs.pari - sage: F., f, g = S.field_extension() # optional - sage.libs.pari sage.rings.number_field - sage: F # optional - sage.libs.pari sage.rings.number_field + sage: S. = R.quotient(x^3 - 2) + sage: F., f, g = S.field_extension() + sage: F Number Field in b with defining polynomial x^3 - 2 - sage: a = F.gen() # optional - sage.libs.pari sage.rings.number_field - sage: f(alpha) # optional - sage.libs.pari sage.rings.number_field + sage: a = F.gen() + sage: f(alpha) b - sage: g(a) # optional - sage.libs.pari sage.rings.number_field + sage: g(a) alpha Note that the parent ring must be an integral domain:: - sage: R. = GF(25, 'f25')['x'] # optional - sage.rings.finite_rings - sage: S. = R.quo(x^3 - 2) # optional - sage.rings.finite_rings - sage: F, g, h = S.field_extension('b') # optional - sage.rings.finite_rings + sage: R. = GF(25, 'f25')['x'] # needs sage.rings.finite_rings + sage: S. = R.quo(x^3 - 2) # needs sage.rings.finite_rings + sage: F, g, h = S.field_extension('b') # needs sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension' @@ -2331,21 +2365,23 @@ def field_extension(self, names): Over a finite field, the corresponding field extension is not a number field:: - sage: R. = GF(25, 'a')['x'] # optional - sage.rings.finite_rings - sage: S. = R.quo(x^3 + 2*x + 1) # optional - sage.rings.finite_rings - sage: F, g, h = S.field_extension('b') # optional - sage.rings.finite_rings - sage: h(F.0^2 + 3) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(25, 'a')['x'] + sage: S. = R.quo(x^3 + 2*x + 1) + sage: F, g, h = S.field_extension('b') + sage: h(F.0^2 + 3) a^2 + 3 - sage: g(x^2 + 2) # optional - sage.rings.finite_rings + sage: g(x^2 + 2) b^2 + 2 We do an example involving a relative number field:: + sage: # needs sage.rings.number_field sage: R. = QQ['x'] - sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: S. = K['X'] # optional - sage.rings.number_field - sage: Q. = S.quo(X^3 + 2*X + 1) # optional - sage.rings.number_field - sage: Q.field_extension('b') # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 2) + sage: S. = K['X'] + sage: Q. = S.quo(X^3 + 2*X + 1) + sage: Q.field_extension('b') (Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field, ... Defn: b |--> b, Relative number field morphism: From: Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field @@ -2357,20 +2393,21 @@ def field_extension(self, names): :: + sage: # needs sage.rings.number_field sage: R. = QQ['x'] - sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: S. = K['X'] # optional - sage.rings.number_field - sage: f = (X+a)^3 + 2*(X+a) + 1 # optional - sage.rings.number_field - sage: f # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 2) + sage: S. = K['X'] + sage: f = (X+a)^3 + 2*(X+a) + 1 + sage: f X^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3 - sage: Q. = S.quo(f) # optional - sage.rings.number_field - sage: F., g, h = Q.field_extension() # optional - sage.rings.number_field - sage: c = g(z) # optional - sage.rings.number_field - sage: f(c) # optional - sage.rings.number_field + sage: Q. = S.quo(f) + sage: F., g, h = Q.field_extension() + sage: c = g(z) + sage: f(c) 0 - sage: h(g(z)) # optional - sage.rings.number_field + sage: h(g(z)) z - sage: g(h(w)) # optional - sage.rings.number_field + sage: g(h(w)) w AUTHORS: @@ -2387,14 +2424,15 @@ class PolynomialQuotientRing_field(PolynomialQuotientRing_domain, Field): """ EXAMPLES:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) - sage: S. = R.quotient(x^2 + 1) # optional - sage.rings.number_field - sage: S # optional - sage.rings.number_field + sage: S. = R.quotient(x^2 + 1) + sage: S Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 - sage: loads(S.dumps()) == S # optional - sage.rings.number_field + sage: loads(S.dumps()) == S True - sage: loads(xbar.dumps()) == xbar # optional - sage.rings.number_field + sage: loads(xbar.dumps()) == xbar True """ def __init__(self, ring, polynomial, name=None, category=None): @@ -2413,17 +2451,19 @@ def complex_embeddings(self, prec=53): EXAMPLES:: + sage: # needs sage.rings.number_field sage: R. = QQ[] sage: f = x^5 + x + 17 - sage: k = R.quotient(f) # optional - sage.rings.number_field - sage: v = k.complex_embeddings(100) # optional - sage.rings.number_field - sage: [phi(k.0^2) for phi in v] # optional - sage.rings.number_field + sage: k = R.quotient(f) + sage: v = k.complex_embeddings(100) + sage: [phi(k.0^2) for phi in v] [2.9757207403766761469671194565, -2.4088994371613850098316292196 + 1.9025410530350528612407363802*I, -2.4088994371613850098316292196 - 1.9025410530350528612407363802*I, 0.92103906697304693634806949137 - 3.0755331188457794473265418086*I, 0.92103906697304693634806949137 + 3.0755331188457794473265418086*I] """ - CC = sage.rings.complex_mpfr.ComplexField(prec) + from sage.rings.complex_mpfr import ComplexField + CC = ComplexField(prec) v = self.modulus().roots(multiplicities=False, ring=CC) return [self.hom([a], check=False) for a in v] diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py index 7dd4e836be1..2f7d825dbf8 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring_element.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring_element.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.libs.pari r""" Elements of Quotients of Univariate Polynomial Rings @@ -8,8 +8,8 @@ :: sage: R. = ZZ[] - sage: S. = R.quotient(x^3 + 3*x - 1) # optional - sage.libs.pari - sage: 2 * a^3 # optional - sage.libs.pari + sage: S. = R.quotient(x^3 + 3*x - 1) + sage: 2 * a^3 -6*a + 2 Next we make a univariate polynomial ring over @@ -17,24 +17,24 @@ :: - sage: S1. = S[] # optional - sage.libs.pari + sage: S1. = S[] And, we quotient out that by `y^2 + a`. :: - sage: T. = S1.quotient(y^2 + a) # optional - sage.libs.pari + sage: T. = S1.quotient(y^2 + a) In the quotient `z^2` is `-a`. :: - sage: z^2 # optional - sage.libs.pari + sage: z^2 -a And since `a^3 = -3x + 1`, we have:: - sage: z^6 # optional - sage.libs.pari + sage: z^6 3*a - 1 :: @@ -100,9 +100,9 @@ class PolynomialQuotientRingElement(polynomial_singular_interface.Polynomial_sin sage: Q. = P.quo([(x^2 + 1)]) sage: xi^2 -1 - sage: singular(xi) + sage: singular(xi) # needs sage.libs.singular xi - sage: (singular(xi)*singular(xi)).NF('std(0)') + sage: (singular(xi)*singular(xi)).NF('std(0)') # needs sage.libs.singular -1 """ @@ -161,16 +161,17 @@ def _im_gens_(self, codomain, im_gens, base_map=None): EXAMPLES:: + sage: # needs sage.rings.number_field sage: Zx. = ZZ[] - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: cc = K.hom([-i]) # optional - sage.rings.number_field - sage: S. = K[] # optional - sage.rings.number_field - sage: Q. = S.quotient(y^2*(y-1)*(y-i)) # optional - sage.rings.number_field - sage: T. = S.quotient(y*(y+1)) # optional - sage.rings.number_field - sage: phi = Q.hom([t+1], base_map=cc) # optional - sage.rings.number_field - sage: phi(q) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) + sage: cc = K.hom([-i]) + sage: S. = K[] + sage: Q. = S.quotient(y^2*(y-1)*(y-i)) + sage: T. = S.quotient(y*(y+1)) + sage: phi = Q.hom([t+1], base_map=cc) + sage: phi(q) t + 1 - sage: phi(i*q) # optional - sage.rings.number_field + sage: phi(i*q) -i*t - i """ return self._polynomial._im_gens_(codomain, im_gens, base_map=base_map) @@ -468,52 +469,56 @@ def field_extension(self, names): EXAMPLES:: + sage: # needs sage.rings.number_field sage: R. = PolynomialRing(QQ) sage: S. = R.quotient(x^3 - 2) - sage: F., f, g = alpha.field_extension() # optional - sage.rings.number_field - sage: F # optional - sage.rings.number_field + sage: F., f, g = alpha.field_extension() + sage: F Number Field in a with defining polynomial x^3 - 2 - sage: a = F.gen() # optional - sage.rings.number_field - sage: f(alpha) # optional - sage.rings.number_field + sage: a = F.gen() + sage: f(alpha) a - sage: g(a) # optional - sage.rings.number_field + sage: g(a) alpha Over a finite field, the corresponding field extension is not a number field:: - sage: R. = GF(25,'b')['x'] # optional - sage.rings.finite_rings - sage: S. = R.quo(x^3 + 2*x + 1) # optional - sage.rings.finite_rings - sage: F., g, h = a.field_extension() # optional - sage.rings.finite_rings - sage: h(b^2 + 3) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(25,'b')['x'] + sage: S. = R.quo(x^3 + 2*x + 1) + sage: F., g, h = a.field_extension() + sage: h(b^2 + 3) a^2 + 3 - sage: g(x^2 + 2) # optional - sage.rings.finite_rings + sage: g(x^2 + 2) b^2 + 2 We do an example involving a relative number field:: + sage: # needs sage.rings.number_field sage: R. = QQ['x'] - sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: S. = K['X'] # optional - sage.rings.number_field - sage: Q. = S.quo(X^3 + 2*X + 1) # optional - sage.rings.number_field - sage: F, g, h = b.field_extension('c') # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 2) + sage: S. = K['X'] + sage: Q. = S.quo(X^3 + 2*X + 1) + sage: F, g, h = b.field_extension('c') Another more awkward example:: + sage: # needs sage.rings.number_field sage: R. = QQ['x'] - sage: K. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: S. = K['X'] # optional - sage.rings.number_field - sage: f = (X+a)^3 + 2*(X+a) + 1 # optional - sage.rings.number_field - sage: f # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 2) + sage: S. = K['X'] + sage: f = (X+a)^3 + 2*(X+a) + 1 + sage: f X^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3 - sage: Q. = S.quo(f) # optional - sage.rings.number_field - sage: F., g, h = z.field_extension() # optional - sage.rings.number_field - sage: c = g(z) # optional - sage.rings.number_field - sage: f(c) # optional - sage.rings.number_field + sage: Q. = S.quo(f) + sage: F., g, h = z.field_extension() + sage: c = g(z) + sage: f(c) 0 - sage: h(g(z)) # optional - sage.rings.number_field + sage: h(g(z)) z - sage: g(h(w)) # optional - sage.rings.number_field + sage: g(h(w)) w AUTHORS: @@ -703,28 +708,30 @@ def minpoly(self): polynomial of a finite-field element over an intermediate extension, rather than the absolute minimal polynomial over the prime field:: - sage: F2. = GF((431,2), modulus=[1,0,1]) # optional - sage.rings.finite_rings - sage: F6. = F2.extension(3) # optional - sage.rings.finite_rings - sage: (u + 1).minpoly() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F2. = GF((431,2), modulus=[1,0,1]) + sage: F6. = F2.extension(3) + sage: (u + 1).minpoly() x^6 + 425*x^5 + 19*x^4 + 125*x^3 + 189*x^2 + 239*x + 302 - sage: ext = F6.over(F2) # optional - sage.rings.finite_rings - sage: ext(u + 1).minpoly() # indirect doctest # optional - sage.rings.finite_rings + sage: ext = F6.over(F2) + sage: ext(u + 1).minpoly() # indirect doctest x^3 + (396*i + 428)*x^2 + (80*i + 39)*x + 9*i + 178 TESTS: We make sure that the previous example works on random examples:: + sage: # needs sage.rings.finite_rings sage: p = random_prime(50) - sage: K. = GF((p, randrange(1,20))) # optional - sage.rings.finite_rings - sage: L. = K.extension(randrange(2,20)) # optional - sage.rings.finite_rings - sage: LK = L.over(K) # optional - sage.rings.finite_rings - sage: a = L.random_element() # optional - sage.rings.finite_rings - sage: poly = LK(a).minpoly() # indirect doctest # optional - sage.rings.finite_rings - sage: poly(a) # optional - sage.rings.finite_rings + sage: K. = GF((p, randrange(1,20))) + sage: L. = K.extension(randrange(2,20)) + sage: LK = L.over(K) + sage: a = L.random_element() + sage: poly = LK(a).minpoly() # indirect doctest + sage: poly(a) 0 - sage: abs_deg = a.minpoly().degree() # optional - sage.rings.finite_rings - sage: poly.degree() == abs_deg // gcd(abs_deg, K.degree()) # optional - sage.rings.finite_rings + sage: abs_deg = a.minpoly().degree() + sage: poly.degree() == abs_deg // gcd(abs_deg, K.degree()) True """ poly = self.lift() @@ -772,14 +779,15 @@ def rational_reconstruction(self, *args, **kwargs): EXAMPLES:: - sage: R. = GF(65537)[] # optional - sage.rings.finite_rings - sage: m = (x^11 + 25345*x^10 + 10956*x^9 + 13873*x^8 + 23962*x^7 # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF(65537)[] + sage: m = (x^11 + 25345*x^10 + 10956*x^9 + 13873*x^8 + 23962*x^7 ....: + 17496*x^6 + 30348*x^5 + 7440*x^4 + 65438*x^3 + 7676*x^2 ....: + 54266*x + 47805) - sage: f = (20437*x^10 + 62630*x^9 + 63241*x^8 + 12820*x^7 + 42171*x^6 # optional - sage.rings.finite_rings + sage: f = (20437*x^10 + 62630*x^9 + 63241*x^8 + 12820*x^7 + 42171*x^6 ....: + 63091*x^5 + 15288*x^4 + 32516*x^3 + 2181*x^2 + 45236*x + 2447) - sage: f_mod_m = R.quotient(m)(f) # optional - sage.rings.finite_rings - sage: f_mod_m.rational_reconstruction() # optional - sage.rings.finite_rings + sage: f_mod_m = R.quotient(m)(f) + sage: f_mod_m.rational_reconstruction() (51388*x^5 + 29141*x^4 + 59341*x^3 + 7034*x^2 + 14152*x + 23746, x^5 + 15208*x^4 + 19504*x^3 + 20457*x^2 + 11180*x + 28352) """ diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index 8dbe789a410..d0dd15522e9 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -1506,8 +1506,8 @@ cdef class Polynomial_rational_flint(Polynomial): Check that :trac:`28187` is fixed:: - sage: x = var("x") - sage: f._derivative(x) + sage: x = var("x") # needs sage.symbolic + sage: f._derivative(x) # needs sage.symbolic 4*x^3 - 1 """ cdef Polynomial_rational_flint der diff --git a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx index 094aa2a3623..fbe96d186c5 100644 --- a/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +++ b/src/sage/rings/polynomial/polynomial_real_mpfr_dense.pyx @@ -6,19 +6,20 @@ TESTS: Check that operations with numpy elements work well (see :trac:`18076` and :trac:`8426`):: - sage: import numpy # optional - numpy + sage: # needs numpy + sage: import numpy sage: x = polygen(RR) - sage: x * numpy.int32('1') # optional - numpy + sage: x * numpy.int32('1') x - sage: numpy.int32('1') * x # optional - numpy + sage: numpy.int32('1') * x x - sage: x * numpy.int64('1') # optional - numpy + sage: x * numpy.int64('1') x - sage: numpy.int64('1') * x # optional - numpy + sage: numpy.int64('1') * x x - sage: x * numpy.float32('1.5') # optional - numpy + sage: x * numpy.float32('1.5') 1.50000000000000*x - sage: numpy.float32('1.5') * x # optional - numpy + sage: numpy.float32('1.5') * x 1.50000000000000*x """ @@ -39,7 +40,11 @@ from sage.structure.element cimport parent from sage.structure.element import coerce_binop from sage.libs.mpfr cimport * -from sage.libs.pari.all import pari_gen +try: + from sage.libs.pari.all import pari_gen +except ImportError: + pari_gen = () + cdef class PolynomialRealDense(Polynomial): r""" @@ -72,7 +77,7 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense - sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) # optional - sage.symbolic + sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) # needs sage.symbolic 3.14159265358979*x^4 + 4.00000000000000*x^3 + 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 sage: PolynomialRealDense(RR['x'], None) 0 @@ -81,13 +86,13 @@ cdef class PolynomialRealDense(Polynomial): Check that errors and interrupts are handled properly (see :trac:`10100`):: - sage: a = var('a') # optional - sage.symbolic - sage: PolynomialRealDense(RR['x'], [1,a]) # optional - sage.symbolic + sage: a = var('a') # needs sage.symbolic + sage: PolynomialRealDense(RR['x'], [1,a]) # needs sage.symbolic Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value - sage: R. = SR[] # optional - sage.symbolic - sage: (x-a).change_ring(RR) # optional - sage.symbolic + sage: R. = SR[] # needs sage.symbolic + sage: (x-a).change_ring(RR) # needs sage.symbolic Traceback (most recent call last): ... TypeError: cannot evaluate symbolic expression to a numeric value @@ -96,9 +101,9 @@ cdef class PolynomialRealDense(Polynomial): Test that we don't clean up uninitialized coefficients (:trac:`9826`):: - sage: k. = GF(7^3) # optional - sage.rings.finite_rings - sage: P. = PolynomialRing(k) # optional - sage.rings.finite_rings - sage: (a*x).complex_roots() # optional - sage.rings.finite_rings + sage: k. = GF(7^3) # needs sage.rings.finite_rings + sage: P. = PolynomialRing(k) # needs sage.rings.finite_rings + sage: (a*x).complex_roots() # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to convert 'a' to a real number @@ -514,16 +519,16 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense - sage: f = PolynomialRealDense(RR['x'], [pi, 0, 2, 1]) # optional - sage.symbolic - sage: f.derivative() # optional - sage.symbolic + sage: f = PolynomialRealDense(RR['x'], [pi, 0, 2, 1]) # needs sage.symbolic + sage: f.derivative() # needs sage.symbolic 3.00000000000000*x^2 + 4.00000000000000*x TESTS:: - sage: x, y = var('x,y') # optional - sage.symbolic - sage: f.derivative(x) # optional - sage.symbolic + sage: x, y = var('x,y') # needs sage.symbolic + sage: f.derivative(x) # needs sage.symbolic 3.00000000000000*x^2 + 4.00000000000000*x - sage: f.derivative(y) # optional - sage.symbolic + sage: f.derivative(y) # needs sage.symbolic Traceback (most recent call last): ... ValueError: cannot differentiate with respect to y @@ -542,8 +547,8 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense - sage: f = PolynomialRealDense(RR['x'], [3, pi, 1]) # optional - sage.symbolic - sage: f.integral() # optional - sage.symbolic + sage: f = PolynomialRealDense(RR['x'], [3, pi, 1]) # needs sage.symbolic + sage: f.integral() # needs sage.symbolic 0.333333333333333*x^3 + 1.57079632679490*x^2 + 3.00000000000000*x """ cdef mpfr_rnd_t rnd = self._base_ring.rnd @@ -567,19 +572,20 @@ cdef class PolynomialRealDense(Polynomial): EXAMPLES:: - sage: f = RR['x']([-3, pi, 0, 1]) # optional - sage.symbolic - sage: f.reverse() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: f = RR['x']([-3, pi, 0, 1]) + sage: f.reverse() -3.00000000000000*x^3 + 3.14159265358979*x^2 + 1.00000000000000 - sage: f.reverse(2) # optional - sage.symbolic + sage: f.reverse(2) -3.00000000000000*x^2 + 3.14159265358979*x - sage: f.reverse(5) # optional - sage.symbolic + sage: f.reverse(5) -3.00000000000000*x^5 + 3.14159265358979*x^4 + x^2 TESTS: We check that this implementation is compatible with the generic one:: - sage: all(f.reverse(d) == Polynomial.reverse(f, d) # optional - sage.symbolic + sage: all(f.reverse(d) == Polynomial.reverse(f, d) # needs sage.symbolic ....: for d in [None, 0, 1, 2, 3, 4, 5]) True """ @@ -619,10 +625,11 @@ cdef class PolynomialRealDense(Polynomial): sage: fg.quo_rem(g) (x^2 - 2.00000000000000, 0) + sage: # needs sage.symbolic sage: f = PolynomialRealDense(RR['x'], range(5)) - sage: g = PolynomialRealDense(RR['x'], [pi,3000,4]) # optional - sage.symbolic - sage: q, r = f.quo_rem(g) # optional - sage.symbolic - sage: g*q + r == f # optional - sage.symbolic + sage: g = PolynomialRealDense(RR['x'], [pi,3000,4]) + sage: q, r = f.quo_rem(g) + sage: g*q + r == f True TESTS: @@ -681,7 +688,7 @@ cdef class PolynomialRealDense(Polynomial): 2.00000000000000 sage: f(RealField(10)(2)) 2.0 - sage: f(pi) # optional - sage.symbolic + sage: f(pi) # needs sage.symbolic 1.00000000000000*pi^2 - 2.00000000000000 diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 5e4a52943fc..968330c9288 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -89,7 +89,6 @@ different base rings. In that situation, coercion works by means of the :func:`~sage.categories.pushout.pushout` formalism:: - sage: # needs sage.rings.finite_rings sage: R. = PolynomialRing(GF(5), sparse=True) sage: S. = PolynomialRing(ZZ) sage: R.has_coerce_map_from(S) @@ -108,7 +107,7 @@ to the default FLINT implementation, but not vice versa:: sage: R. = PolynomialRing(ZZ, implementation='NTL') # needs sage.libs.ntl - sage: S. = PolynomialRing(ZZ, implementation='FLINT') # needs sage.libs.flint + sage: S. = PolynomialRing(ZZ, implementation='FLINT') sage: (S.0 + R.0).parent() is S # needs sage.libs.flint sage.libs.ntl True sage: (R.0 + S.0).parent() is S # needs sage.libs.flint sage.libs.ntl @@ -151,13 +150,17 @@ import sage.rings.ring as ring from sage.structure.element import is_RingElement -import sage.rings.polynomial.polynomial_element_generic as polynomial_element_generic import sage.rings.rational_field as rational_field from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from sage.rings.number_field.number_field_base import NumberField -from sage.libs.pari.all import pari_gen + +try: + from sage.libs.pari.all import pari_gen +except ImportError: + pari_gen = () + from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category import sage.misc.latex as latex @@ -168,15 +171,12 @@ import sage.rings.abc from sage.rings.fraction_field_element import FractionFieldElement from sage.rings.finite_rings.element_base import FiniteRingElement -from .polynomial_real_mpfr_dense import PolynomialRealDense -from .polynomial_integer_dense_flint import Polynomial_integer_dense_flint from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular +from sage.rings.power_series_ring_element import PowerSeries _CommutativeRings = categories.commutative_rings.CommutativeRings() -from . import cyclotomic - import sage.interfaces.abc @@ -212,11 +212,12 @@ def is_PolynomialRing(x): :: - sage: R. = PolynomialRing(ZZ, implementation="singular"); R # needs sage.libs.singular + sage: # needs sage.libs.singular + sage: R. = PolynomialRing(ZZ, implementation="singular"); R Multivariate Polynomial Ring in w over Integer Ring - sage: is_PolynomialRing(R) # needs sage.libs.singular + sage: is_PolynomialRing(R) False - sage: type(R) # needs sage.libs.singular + sage: type(R) """ return isinstance(x, PolynomialRing_general) @@ -245,7 +246,7 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, and Category of commutative algebras over (euclidean domains and infinite enumerated sets and metric spaces) and Category of infinite sets - sage: category(GF(7)['x']) # needs sage.rings.finite_rings + sage: category(GF(7)['x']) Join of Category of euclidean domains and Category of commutative algebras over (finite enumerated fields and subquotients of monoids and quotients of semigroups) and Category of infinite sets @@ -270,13 +271,13 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: Zmod(1)['x'].is_finite() True - sage: GF(7)['x'].is_finite() # needs sage.rings.finite_rings + sage: GF(7)['x'].is_finite() False sage: Zmod(1)['x']['y'].is_finite() True - sage: GF(7)['x']['y'].is_finite() # needs sage.rings.finite_rings + sage: GF(7)['x']['y'].is_finite() False """ @@ -292,10 +293,11 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, self._polynomial_class = element_class else: if sparse: - self._polynomial_class = polynomial_element_generic.Polynomial_generic_sparse + from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse + self._polynomial_class = Polynomial_generic_sparse else: - from sage.rings.polynomial import polynomial_element - self._polynomial_class = polynomial_element.Polynomial_generic_dense + from sage.rings.polynomial.polynomial_element import Polynomial_generic_dense + self._polynomial_class = Polynomial_generic_dense self.Element = self._polynomial_class self.__cyclopoly_cache = {} self._has_singular = False @@ -379,16 +381,17 @@ def _element_constructor_(self, x=None, check=True, is_gen=False, This shows that the issue at :trac:`4106` is fixed:: - sage: x = var('x') # needs sage.symbolic + sage: # needs sage.symbolic + sage: x = var('x') sage: R = IntegerModRing(4) - sage: S = R['x'] # needs sage.symbolic - sage: S(x) # needs sage.symbolic + sage: S = R['x'] + sage: S(x) x Throw a TypeError if any of the coefficients cannot be coerced into the base ring (:trac:`6777`):: - sage: RealField(300)['x']( [ 1, ComplexField(300).gen(), 0 ]) + sage: RealField(300)['x']( [ 1, ComplexField(300).gen(), 0 ]) # needs sage.rings.real_mpfr Traceback (most recent call last): ... TypeError: unable to convert '1.00...00*I' to a real number @@ -466,7 +469,7 @@ def _element_constructor_(self, x=None, check=True, is_gen=False, return self(x.polynomial()) except AttributeError: pass - elif isinstance(x, sage.rings.power_series_ring_element.PowerSeries): + elif isinstance(x, PowerSeries): x = x.truncate() return C(self, x, check, is_gen, construct=construct, **kwds) @@ -657,6 +660,7 @@ def completion(self, p=None, prec=20, extras=None): sage: 1 / g 1 - x + O(x^20) + sage: # needs sage.combinat sage: PP = P.completion(x, prec=oo); PP Lazy Taylor Series Ring in x over Rational Field sage: g = 1 / PP(f); g @@ -697,7 +701,7 @@ def _coerce_map_from_base_ring(self): Polynomial base injection morphism: From: Rational Field To: Univariate Polynomial Ring in x over Rational Field - sage: R.coerce_map_from(GF(7)) # needs sage.rings.finite_rings + sage: R.coerce_map_from(GF(7)) """ from .polynomial_element import PolynomialBaseringInjection @@ -765,6 +769,7 @@ def _coerce_map_from_(self, P): Over the integers, there is a coercion from the NTL and generic implementation to the default FLINT implementation:: + sage: del R, S # clear values from doctests above sage: R = PolynomialRing(ZZ, 't', implementation="NTL") # needs sage.libs.ntl sage: S = PolynomialRing(ZZ, 't', implementation="FLINT") # needs sage.libs.flint sage: T = PolynomialRing(ZZ, 't', implementation="generic") @@ -816,6 +821,10 @@ def _coerce_map_from_(self, P): elif base_ring is ZZ: # Over ZZ, only allow coercion from any ZZ['x'] # implementation to the default FLINT implementation + try: + from .polynomial_integer_dense_flint import Polynomial_integer_dense_flint + except ImportError: + return None if self.element_class is not Polynomial_integer_dense_flint: return None # Other rings: always allow coercion @@ -875,7 +884,7 @@ def _magma_init_(self, magma): sage: k. = GF(9) # needs sage.rings.finite_rings sage: R. = k[] # needs sage.rings.finite_rings - sage: magma(a^2*x^3 + (a+1)*x + a) # optional - magma, needs sage.rings.finite_rings + sage: magma(a^2*x^3 + (a+1)*x + a) # optional - magma # needs sage.rings.finite_rings a^2*x^3 + a^2*x + a """ B = magma(self.base_ring()) @@ -927,11 +936,11 @@ def _sage_input_(self, sib, coerced): EXAMPLES:: - sage: sage_input(GF(5)['x']['y'], verify=True) # needs sage.rings.finite_rings + sage: sage_input(GF(5)['x']['y'], verify=True) # Verified GF(5)['x']['y'] - sage: from sage.misc.sage_input import SageInputBuilder # needs sage.rings.finite_rings - sage: ZZ['z']._sage_input_(SageInputBuilder(), False) # needs sage.rings.finite_rings + sage: from sage.misc.sage_input import SageInputBuilder + sage: ZZ['z']._sage_input_(SageInputBuilder(), False) {constr_parent: {subscr: {atomic:ZZ}[{atomic:'z'}]} with gens: ('z',)} """ base = sib(self.base_ring()) @@ -970,7 +979,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): EXAMPLES:: sage: R. = QQ[] - sage: R._is_valid_homomorphism_(GF(7), [5]) # needs sage.rings.finite_rings + sage: R._is_valid_homomorphism_(GF(7), [5]) False sage: R._is_valid_homomorphism_(Qp(7), [5]) # needs sage.rings.padics True @@ -1023,6 +1032,7 @@ def base_extend(self, R): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: R. = RR[]; R Univariate Polynomial Ring in x over Real Field with 53 bits of precision sage: R.base_extend(CC) @@ -1171,22 +1181,22 @@ def cyclotomic_polynomial(self, n): EXAMPLES:: sage: R = ZZ['x'] - sage: R.cyclotomic_polynomial(8) # needs sage.libs.pari + sage: R.cyclotomic_polynomial(8) x^4 + 1 - sage: R.cyclotomic_polynomial(12) # needs sage.libs.pari + sage: R.cyclotomic_polynomial(12) x^4 - x^2 + 1 - sage: S = PolynomialRing(FiniteField(7), 'x') # needs sage.rings.finite_rings - sage: S.cyclotomic_polynomial(12) # needs sage.rings.finite_rings + sage: S = PolynomialRing(FiniteField(7), 'x') + sage: S.cyclotomic_polynomial(12) x^4 + 6*x^2 + 1 - sage: S.cyclotomic_polynomial(1) # needs sage.rings.finite_rings + sage: S.cyclotomic_polynomial(1) x + 6 TESTS: Make sure it agrees with other systems for the trivial case:: - sage: ZZ['x'].cyclotomic_polynomial(1) # needs sage.libs.pari + sage: ZZ['x'].cyclotomic_polynomial(1) x - 1 sage: gp('polcyclo(1)') # needs sage.libs.pari x - 1 @@ -1196,7 +1206,8 @@ def cyclotomic_polynomial(self, n): elif n == 1: return self.gen() - 1 else: - return self(cyclotomic.cyclotomic_coeffs(n), check=True) + from .cyclotomic import cyclotomic_coeffs + return self(cyclotomic_coeffs(n), check=True) @cached_method def gen(self, n=0): @@ -1255,10 +1266,11 @@ def is_exact(self): def is_field(self, proof=True): """ - Return False, since polynomial rings are never fields. + Return ``False``, since polynomial rings are never fields. EXAMPLES:: + sage: # needs sage.libs.ntl sage: R. = Integers(2)[]; R Univariate Polynomial Ring in z over Ring of integers modulo 2 (using GF2X) sage: R.is_field() @@ -1401,13 +1413,13 @@ def random_element(self, degree=(-1,2), *args, **kwds): Check that :trac:`16682` is fixed:: - sage: R = PolynomialRing(GF(2), 'z') # needs sage.rings.finite_rings - sage: for _ in range(100): # needs sage.rings.finite_rings + sage: R = PolynomialRing(GF(2), 'z') + sage: for _ in range(100): ....: d = randint(-1,20) ....: P = R.random_element(degree=d) ....: assert P.degree() == d, "problem with {} which has not degree {}".format(P,d) - sage: R.random_element(degree=-2) # needs sage.rings.finite_rings + sage: R.random_element(degree=-2) Traceback (most recent call last): ... ValueError: degree should be an integer greater or equal than -1 @@ -1515,9 +1527,13 @@ def _Karatsuba_threshold(self): base_ring = self.base_ring() if is_PolynomialRing(base_ring): return 0 - from sage.matrix.matrix_space import MatrixSpace - if isinstance(base_ring, MatrixSpace): - return 0 + try: + from sage.matrix.matrix_space import MatrixSpace + except ImportError: + pass + else: + if isinstance(base_ring, MatrixSpace): + return 0 from sage.rings.fraction_field import FractionField_generic if isinstance(base_ring, FractionField_generic): return 1 << 60 @@ -1578,7 +1594,6 @@ def polynomials( self, of_degree=None, max_degree=None ): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: P = PolynomialRing(GF(3), 'y') sage: for p in P.polynomials(of_degree=2): print(p) y^2 @@ -1740,9 +1755,9 @@ def quotient_by_principal_ideal(self, f, names=None, **kwds): Quotienting by the zero ideal returns ``self`` (:trac:`5978`):: sage: R = QQ['x'] - sage: R.quotient_by_principal_ideal(R.zero_ideal()) is R # needs sage.libs.pari + sage: R.quotient_by_principal_ideal(R.zero_ideal()) is R True - sage: R.quotient_by_principal_ideal(0) is R # needs sage.libs.pari + sage: R.quotient_by_principal_ideal(0) is R True """ from sage.rings.ideal import Ideal @@ -1760,9 +1775,9 @@ def weyl_algebra(self): EXAMPLES:: sage: R = QQ['x'] - sage: W = R.weyl_algebra(); W # needs sage.combinat sage.modules + sage: W = R.weyl_algebra(); W # needs sage.modules Differential Weyl algebra of polynomials in x over Rational Field - sage: W.polynomial_ring() == R # needs sage.combinat sage.modules + sage: W.polynomial_ring() == R # needs sage.modules True """ from sage.algebras.weyl_algebra import DifferentialWeylAlgebra @@ -2016,11 +2031,12 @@ def construction(self): sage: functor.implementation is None True - sage: R = PRing(ZZ, 'x', implementation='NTL'); R # needs sage.libs.ntl + sage: # needs sage.libs.ntl + sage: R = PRing(ZZ, 'x', implementation='NTL'); R Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: functor, arg = R.construction(); functor, arg # needs sage.libs.ntl + sage: functor, arg = R.construction(); functor, arg (Poly[x], Integer Ring) - sage: functor.implementation # needs sage.libs.ntl + sage: functor.implementation 'NTL' """ implementation = None @@ -2051,22 +2067,23 @@ def __init__(self, base_ring, name="x", sparse=False, implementation=None, Sparse Univariate Polynomial Ring in x over Rational Field sage: type(R.gen()) - sage: R = PRing(CC, 'x'); R + sage: R = PRing(CC, 'x'); R # needs sage.rings.real_mpfr Univariate Polynomial Ring in x over Complex Field with 53 bits of precision - sage: type(R.gen()) + sage: type(R.gen()) # needs sage.rings.real_mpfr Demonstrate that :trac:`8762` is fixed:: sage: R. = PolynomialRing(GF(next_prime(10^20)), sparse=True) # needs sage.rings.finite_rings - sage: x^(10^20) # this should be fast # needs sage.rings.finite_rings + sage: x^(10^20) # this should be fast # needs sage.rings.finite_rings x^100000000000000000000 """ def _element_class(): if element_class: return element_class if sparse: - return polynomial_element_generic.Polynomial_generic_sparse_field + from sage.rings.polynomial.polynomial_element_generic import Polynomial_generic_sparse_field + return Polynomial_generic_sparse_field if isinstance(base_ring, rational_field.RationalField): try: from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint @@ -2105,8 +2122,8 @@ def _ideal_class_(self, n=0): EXAMPLES:: - sage: R. = GF(5)[] # needs sage.rings.finite_rings - sage: R._ideal_class_() # needs sage.rings.finite_rings + sage: R. = GF(5)[] + sage: R._ideal_class_() """ from sage.rings.polynomial.ideal import Ideal_1poly_field @@ -2281,9 +2298,10 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r -17/42*x^2 - 83/42*x + 53/7, -23/84*x^3 - 11/84*x^2 + 13/7*x + 1] - sage: R = PolynomialRing(GF(2**3, 'a'), 'x') # needs sage.rings.finite_rings - sage: a = R.base_ring().gen() # needs sage.rings.finite_rings - sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)], # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R = PolynomialRing(GF(2**3, 'a'), 'x') + sage: a = R.base_ring().gen() + sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)], ....: algorithm="neville") [a^2 + a + 1, x + a + 1, a^2*x^2 + a^2*x + a^2] @@ -2343,10 +2361,10 @@ def lagrange_polynomial(self, points, algorithm="divided_difference", previous_r Check that base fields of positive characteristic are treated correctly (see :trac:`9787`):: - sage: R. = GF(101)[] # needs sage.rings.finite_rings - sage: R.lagrange_polynomial([[1, 0], [2, 0]]) # needs sage.rings.finite_rings + sage: R. = GF(101)[] + sage: R.lagrange_polynomial([[1, 0], [2, 0]]) 0 - sage: R.lagrange_polynomial([[1, 0], [2, 0], [3, 0]]) # needs sage.rings.finite_rings + sage: R.lagrange_polynomial([[1, 0], [2, 0], [3, 0]]) 0 """ # Perhaps we should be slightly stricter on the input and use @@ -2432,8 +2450,8 @@ def fraction_field(self): EXAMPLES:: - sage: R. = GF(5)[] # needs sage.rings.finite_rings - sage: R.fraction_field() # needs sage.rings.finite_rings + sage: R. = GF(5)[] + sage: R.fraction_field() Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5 @@ -2459,9 +2477,13 @@ def fraction_field(self): R = self.base_ring() p = R.characteristic() if p != 0 and R.is_prime_field(): - from sage.rings.fraction_field_FpT import FpT - if 2 < p and p < FpT.INTEGER_LIMIT: - return FpT(self) + try: + from sage.rings.fraction_field_FpT import FpT + except ImportError: + pass + else: + if 2 < p and p < FpT.INTEGER_LIMIT: + return FpT(self) from sage.rings.fraction_field import FractionField_1poly_field return FractionField_1poly_field(self) @@ -2485,8 +2507,8 @@ def __init__(self, base_ring, name="x", element_class=None, implementation=None) sage: type(R(0)) - sage: S = PolynomialRing_dense_finite_field(GF(25, 'a'), implementation='NTL') # needs sage.rings.finite_rings - sage: type(S(0)) # needs sage.rings.finite_rings + sage: S = PolynomialRing_dense_finite_field(GF(25, 'a'), implementation='NTL') # needs sage.libs.ntl sage.rings.finite_rings + sage: type(S(0)) # needs sage.libs.ntl sage.rings.finite_rings sage: S = PolynomialRing_dense_finite_field(GF(64), implementation='superfast') # needs sage.rings.finite_rings @@ -2863,10 +2885,10 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=False, algor Check that :trac:`23639` is fixed:: - sage: R = GF(3)['x']['y'] # needs sage.rings.finite_rings - sage: R.one().roots(multiplicities=False) # needs sage.rings.finite_rings + sage: R = GF(3)['x']['y'] + sage: R.one().roots(multiplicities=False) [] - sage: R.zero().roots(multiplicities=False) # needs sage.rings.finite_rings + sage: R.zero().roots(multiplicities=False) Traceback (most recent call last): ... ArithmeticError: roots of 0 are not defined @@ -2911,7 +2933,8 @@ def __init__(self, base_ring, name=None, sparse=False, implementation=None, sage: isinstance(S, PolynomialRing_cdvr) False - sage: S. = Zp(5)[] # needs sage.rings.padics + sage: # needs sage.rings.padics + sage: S. = Zp(5)[] sage: isinstance(S, PolynomialRing_cdvr) True """ @@ -3121,7 +3144,7 @@ def __init__(self, base_ring, name=None, element_class=None, sage: type(R.gen()) # needs sage.libs.ntl - sage: R = PRing(Zmod(2**63*3), 'x', implementation='FLINT') # needs sage.libs.flint + sage: R = PRing(Zmod(2**63*3), 'x', implementation='FLINT') Traceback (most recent call last): ... ValueError: FLINT does not support modulus 27670116110564327424 @@ -3231,7 +3254,7 @@ def residue_field(self, ideal, names=None): EXAMPLES:: - sage: # needs sage.rings.finite_rings + sage: # needs sage.libs.ntl sage: R. = GF(2)[] sage: k. = R.residue_field(t^3 + t + 1); k Residue field in a @@ -3255,15 +3278,16 @@ def residue_field(self, ideal, names=None): Non-maximal ideals are not accepted:: - sage: R.residue_field(t^2 + 1) # needs sage.rings.finite_rings + sage: # needs sage.libs.ntl + sage: R.residue_field(t^2 + 1) Traceback (most recent call last): ... ArithmeticError: ideal is not maximal - sage: R.residue_field(0) # needs sage.rings.finite_rings + sage: R.residue_field(0) Traceback (most recent call last): ... ArithmeticError: ideal is not maximal - sage: R.residue_field(1) # needs sage.rings.finite_rings + sage: R.residue_field(1) Traceback (most recent call last): ... ArithmeticError: ideal is not maximal @@ -3281,35 +3305,37 @@ def __init__(self, base_ring, name="x", implementation=None, element_class=None, """ TESTS:: - sage: P = GF(2)['x']; P # needs sage.rings.finite_rings + sage: P = GF(2)['x']; P # needs sage.libs.ntl Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: type(P.gen()) # needs sage.rings.finite_rings + sage: type(P.gen()) # needs sage.libs.ntl - sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_p # needs sage.rings.finite_rings - sage: P = PolynomialRing_dense_mod_p(GF(5), 'x'); P # needs sage.rings.finite_rings + sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_dense_mod_p + sage: P = PolynomialRing_dense_mod_p(GF(5), 'x'); P Univariate Polynomial Ring in x over Finite Field of size 5 - sage: type(P.gen()) # needs sage.rings.finite_rings + sage: type(P.gen()) # needs sage.libs.flint - sage: P = PolynomialRing_dense_mod_p(GF(5), 'x', implementation='NTL'); P # needs sage.rings.finite_rings + sage: # needs sage.libs.ntl + sage: P = PolynomialRing_dense_mod_p(GF(5), 'x', implementation='NTL'); P Univariate Polynomial Ring in x over Finite Field of size 5 (using NTL) - sage: type(P.gen()) # needs sage.rings.finite_rings + sage: type(P.gen()) - sage: P = PolynomialRing_dense_mod_p(GF(9223372036854775837), 'x'); P # needs sage.rings.finite_rings + sage: P = PolynomialRing_dense_mod_p(GF(9223372036854775837), 'x'); P # needs sage.libs.ntl sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 9223372036854775837 (using NTL) - sage: type(P.gen()) # needs sage.rings.finite_rings + sage: type(P.gen()) # needs sage.libs.ntl sage.rings.finite_rings This caching bug was fixed in :trac:`24264`:: + sage: # needs sage.rings.finite_rings sage: p = 2^64 + 13 - sage: A = GF(p^2) # needs sage.rings.finite_rings - sage: B = GF(p^3) # needs sage.rings.finite_rings - sage: R = A.modulus().parent() # needs sage.rings.finite_rings - sage: S = B.modulus().parent() # needs sage.rings.finite_rings - sage: R is S # needs sage.rings.finite_rings + sage: A = GF(p^2) + sage: B = GF(p^3) + sage: R = A.modulus().parent() + sage: S = B.modulus().parent() + sage: R is S True """ if element_class is None: @@ -3351,19 +3377,20 @@ def _implementation_names_impl(implementation, base_ring, sparse): """ TESTS:: - sage: # needs sage.rings.finite_rings + sage: # needs sage.libs.ntl sage: PolynomialRing(GF(2), 'x', implementation="GF2X") Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) sage: PolynomialRing(GF(2), 'x', implementation="NTL") Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) sage: PolynomialRing(GF(2), 'x', implementation=None) Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) - sage: PolynomialRing(GF(2), 'x', implementation="FLINT") - Univariate Polynomial Ring in x over Finite Field of size 2 sage: PolynomialRing(GF(3), 'x', implementation="GF2X") Traceback (most recent call last): ... ValueError: GF2X only supports modulus 2 + + sage: PolynomialRing(GF(2), 'x', implementation="FLINT") # needs sage.libs.flint + Univariate Polynomial Ring in x over Finite Field of size 2 """ if sparse: return NotImplemented @@ -3474,9 +3501,6 @@ def irreducible_element(self, n, algorithm=None): from sage.libs.pari.all import pari from sage.rings.finite_rings.conway_polynomials import (conway_polynomial, exists_conway_polynomial) - from .polynomial_gf2x import (GF2X_BuildIrred_list, - GF2X_BuildSparseIrred_list, - GF2X_BuildRandomIrred_list) p = self.characteristic() n = int(n) @@ -3489,7 +3513,12 @@ def irreducible_element(self, n, algorithm=None): elif exists_conway_polynomial(p, n): algorithm = "conway" elif p == 2: - algorithm = "minimal_weight" + try: + from .polynomial_gf2x import GF2X_BuildSparseIrred_list + except ImportError: + algorithm = "adleman-lenstra" + else: + algorithm = "minimal_weight" else: algorithm = "adleman-lenstra" elif algorithm == "primitive": @@ -3504,6 +3533,7 @@ def irreducible_element(self, n, algorithm=None): return self(conway_polynomial(p, n)) elif algorithm == "first_lexicographic": if p == 2: + from .polynomial_gf2x import GF2X_BuildIrred_list return self(GF2X_BuildIrred_list(n)) else: # Fallback to PolynomialRing_dense_finite_field.irreducible_element @@ -3512,11 +3542,13 @@ def irreducible_element(self, n, algorithm=None): return self(pari(p).ffinit(n).ffgen().ffprimroot().charpoly()) elif algorithm == "minimal_weight": if p == 2: + from .polynomial_gf2x import GF2X_BuildSparseIrred_list return self(GF2X_BuildSparseIrred_list(n)) else: raise NotImplementedError("'minimal_weight' option only implemented for p = 2") elif algorithm == "random": if p == 2: + from .polynomial_gf2x import GF2X_BuildRandomIrred_list return self(GF2X_BuildRandomIrred_list(n)) else: pass diff --git a/src/sage/rings/polynomial/polynomial_ring_constructor.py b/src/sage/rings/polynomial/polynomial_ring_constructor.py index 08968a5795b..acaea2e3a16 100644 --- a/src/sage/rings/polynomial/polynomial_ring_constructor.py +++ b/src/sage/rings/polynomial/polynomial_ring_constructor.py @@ -22,7 +22,15 @@ # **************************************************************************** from sage.structure.category_object import normalize_names import sage.rings.ring as ring -import sage.rings.padics.padic_base_leaves as padic_base_leaves + +try: + import sage.rings.padics.padic_base_leaves as padic_base_leaves +except ImportError: + class padic_base_leaves: + pAdicFieldCappedRelative = () + pAdicRingCappedRelative = () + pAdicRingCappedAbsolute = () + pAdicRingFixedMod = () import sage.rings.abc from sage.rings.integer import Integer @@ -144,7 +152,7 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R. = PolynomialRing(QQ, sparse=True); R Sparse Univariate Polynomial Ring in abc over Rational Field - sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); R # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); R Univariate Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 @@ -180,32 +188,32 @@ def PolynomialRing(base_ring, *args, **kwds): like 2^1000000 * x^1000000 in FLINT may be unwise. :: - sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL # optional - sage.libs.ntl + sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL # needs sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT # optional - sage.libs.flint + sage: ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT # needs sage.libs.flint Univariate Polynomial Ring in x over Integer Ring - sage: ZxFLINT is ZZ['x'] # optional - sage.libs.flint + sage: ZxFLINT is ZZ['x'] # needs sage.libs.flint True - sage: ZxFLINT is PolynomialRing(ZZ, 'x') # optional - sage.libs.flint + sage: ZxFLINT is PolynomialRing(ZZ, 'x') # needs sage.libs.flint True - sage: xNTL = ZxNTL.gen() # optional - sage.libs.ntl - sage: xFLINT = ZxFLINT.gen() # optional - sage.libs.flint - sage: xNTL.parent() # optional - sage.libs.ntl + sage: xNTL = ZxNTL.gen() # needs sage.libs.ntl + sage: xFLINT = ZxFLINT.gen() # needs sage.libs.flint + sage: xNTL.parent() # needs sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring (using NTL) - sage: xFLINT.parent() # optional - sage.libs.flint + sage: xFLINT.parent() # needs sage.libs.flint Univariate Polynomial Ring in x over Integer Ring There is a coercion from the non-default to the default implementation, so the values can be mixed in a single expression:: - sage: (xNTL + xFLINT^2) # optional - sage.libs.flint sage.libs.ntl + sage: (xNTL + xFLINT^2) # needs sage.libs.flint sage.libs.ntl x^2 + x The result of such an expression will use the default, i.e., the FLINT implementation:: - sage: (xNTL + xFLINT^2).parent() # optional - sage.libs.flint sage.libs.ntl + sage: (xNTL + xFLINT^2).parent() # needs sage.libs.flint sage.libs.ntl Univariate Polynomial Ring in x over Integer Ring The generic implementation uses neither NTL nor FLINT:: @@ -260,9 +268,9 @@ def PolynomialRing(base_ring, *args, **kwds): The Singular implementation always returns a multivariate ring, even for 1 variable:: - sage: PolynomialRing(QQ, "x", implementation="singular") # optional - sage.libs.singular + sage: PolynomialRing(QQ, "x", implementation="singular") # needs sage.libs.singular Multivariate Polynomial Ring in x over Rational Field - sage: P. = PolynomialRing(QQ, implementation="singular"); P # optional - sage.libs.singular + sage: P. = PolynomialRing(QQ, implementation="singular"); P # needs sage.libs.singular Multivariate Polynomial Ring in x over Rational Field **3. PolynomialRing(base_ring, n, names, ...)** (where the arguments @@ -279,7 +287,7 @@ def PolynomialRing(base_ring, *args, **kwds): sage: PolynomialRing(QQ, 2, 'alpha0') Multivariate Polynomial Ring in alpha00, alpha01 over Rational Field - sage: PolynomialRing(GF(7), 'y', 5) # optional - sage.rings.finite_rings + sage: PolynomialRing(GF(7), 'y', 5) Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7 sage: PolynomialRing(QQ, 'y', 3, sparse=True) @@ -299,7 +307,7 @@ def PolynomialRing(base_ring, *args, **kwds): example, here is a ring with generators labeled by the primes less than 100:: - sage: R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R # optional - sage.libs.pari + sage: R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R # needs sage.libs.pari Multivariate Polynomial Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 over Integer Ring @@ -308,10 +316,10 @@ def PolynomialRing(base_ring, *args, **kwds): :meth:`~sage.structure.category_object.CategoryObject.inject_variables` method, all those variable names are available for interactive use:: - sage: R.inject_variables() # optional - sage.libs.pari + sage: R.inject_variables() # needs sage.libs.pari Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97 - sage: (x2 + x41 + x71)^2 # optional - sage.libs.pari + sage: (x2 + x41 + x71)^2 # needs sage.libs.pari x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2 **4. PolynomialRing(base_ring, n, ..., var_array=var_array, ...)** @@ -347,6 +355,7 @@ def PolynomialRing(base_ring, *args, **kwds): You can alternatively create a polynomial ring over a ring `R` with square brackets:: + sage: # needs sage.rings.real_mpfr sage: RR["x"] Univariate Polynomial Ring in x over Real Field with 53 bits of precision sage: RR["x,y"] @@ -399,9 +408,9 @@ def PolynomialRing(base_ring, *args, **kwds): Check uniqueness if the same implementation is used for different values of the ``"implementation"`` keyword:: - sage: R = PolynomialRing(QQbar, 'j', implementation="generic") - sage: S = PolynomialRing(QQbar, 'j', implementation=None) - sage: R is S + sage: R = PolynomialRing(QQbar, 'j', implementation="generic") # needs sage.rings.number_field + sage: S = PolynomialRing(QQbar, 'j', implementation=None) # needs sage.rings.number_field + sage: R is S # needs sage.rings.number_field True sage: R = PolynomialRing(ZZ['t'], 'j', implementation="generic") @@ -409,11 +418,13 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R is S True + sage: # needs sage.rings.number_field sage: R = PolynomialRing(QQbar, 'j,k', implementation="generic") sage: S = PolynomialRing(QQbar, 'j,k', implementation=None) sage: R is S True + sage: # needs sage.libs.singular sage: R = PolynomialRing(ZZ, 'j,k', implementation="singular") sage: S = PolynomialRing(ZZ, 'j,k', implementation=None) sage: R is S @@ -426,14 +437,14 @@ def PolynomialRing(base_ring, *args, **kwds): The generic implementation is different in some cases:: - sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) - sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) # optional - sage.rings.finite_rings + sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) - sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) + sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) # needs sage.libs.singular - sage: S = PolynomialRing(ZZ, 'x,y'); TestSuite(S).run(skip='_test_elements'); type(S) + sage: S = PolynomialRing(ZZ, 'x,y'); TestSuite(S).run(skip='_test_elements'); type(S) # needs sage.libs.singular Sparse univariate polynomials only support a generic @@ -441,7 +452,7 @@ def PolynomialRing(base_ring, *args, **kwds): sage: R = PolynomialRing(ZZ, 'j', sparse=True); TestSuite(R).run(); type(R) - sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) # needs sage.rings.finite_rings If the requested implementation is not known or not supported for @@ -451,7 +462,7 @@ def PolynomialRing(base_ring, *args, **kwds): Traceback (most recent call last): ... ValueError: unknown implementation 'Foo' for dense polynomial rings over Integer Ring - sage: R. = PolynomialRing(GF(2), implementation='GF2X', sparse=True) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(2), implementation='GF2X', sparse=True) Traceback (most recent call last): ... ValueError: unknown implementation 'GF2X' for sparse polynomial rings over Finite Field of size 2 @@ -459,7 +470,7 @@ def PolynomialRing(base_ring, *args, **kwds): Traceback (most recent call last): ... ValueError: unknown implementation 'FLINT' for multivariate polynomial rings - sage: R. = PolynomialRing(QQbar, implementation="whatever") + sage: R. = PolynomialRing(QQbar, implementation="whatever") # needs sage.rings.number_field Traceback (most recent call last): ... ValueError: unknown implementation 'whatever' for dense polynomial rings over Algebraic Field @@ -471,7 +482,7 @@ def PolynomialRing(base_ring, *args, **kwds): Traceback (most recent call last): ... ValueError: unknown implementation 'whatever' for multivariate polynomial rings - sage: PolynomialRing(RR, name="x", implementation="singular") + sage: PolynomialRing(RR, name="x", implementation="singular") # needs sage.libs.singular Traceback (most recent call last): ... NotImplementedError: polynomials over Real Field with 53 bits of precision are not supported in Singular @@ -486,18 +497,20 @@ def PolynomialRing(base_ring, *args, **kwds): We verify that :trac:`13187` is fixed:: - sage: var('t') + sage: var('t') # needs sage.symbolic t - sage: PolynomialRing(ZZ, name=t) == PolynomialRing(ZZ, name='t') + sage: PolynomialRing(ZZ, name=t) == PolynomialRing(ZZ, name='t') # needs sage.symbolic True We verify that polynomials with interval coefficients from :trac:`7712` and :trac:`13760` are fixed:: + sage: # needs sage.rings.real_interval_field sage: P. = PolynomialRing(RealIntervalField(2)) sage: TestSuite(P).run(skip=['_test_elements', '_test_elements_eq_transitive']) sage: Q. = PolynomialRing(P) - sage: TestSuite(Q).run(skip=['_test_additive_associativity', '_test_associativity', '_test_distributivity', '_test_prod']) + sage: TestSuite(Q).run(skip=['_test_additive_associativity', '_test_associativity', + ....: '_test_distributivity', '_test_prod']) sage: C = (y-x)^3 sage: C(y/2) 1.?*y^3 @@ -563,7 +576,7 @@ def PolynomialRing(base_ring, *args, **kwds): We run the testsuite for various polynomial rings, skipping tests that currently fail:: - sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); TestSuite(R).run(); R # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(PolynomialRing(GF(7),'k')); TestSuite(R).run(); R Univariate Polynomial Ring in w over Univariate Polynomial Ring in k over Finite Field of size 7 sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); TestSuite(ZxNTL).run(skip='_test_pickling'); ZxNTL Univariate Polynomial Ring in x over Integer Ring (using NTL) @@ -579,23 +592,24 @@ def PolynomialRing(base_ring, *args, **kwds): Multivariate Polynomial Ring in x, y, z over Rational Field sage: Q0 = PolynomialRing(QQ,[]); TestSuite(Q0).run(skip=['_test_elements', '_test_elements_eq_transitive', '_test_gcd_vs_xgcd', '_test_quo_rem']); Q0 Multivariate Polynomial Ring in no variables over Rational Field - sage: P. = PolynomialRing(QQ, implementation="singular"); TestSuite(P).run(skip=['_test_construction', '_test_elements', '_test_euclidean_degree', '_test_quo_rem']); P + sage: P. = PolynomialRing(QQ, implementation="singular"); TestSuite(P).run(skip=['_test_construction', '_test_elements', # needs sage.libs.singular + ....: '_test_euclidean_degree', '_test_quo_rem']); P Multivariate Polynomial Ring in x over Rational Field sage: Q1 = PolynomialRing(QQ,"x",1); TestSuite(Q1).run(skip=['_test_construction', '_test_elements', '_test_euclidean_degree', '_test_quo_rem']); Q1 Multivariate Polynomial Ring in x over Rational Field sage: Q0 = PolynomialRing(QQ,"x",0); TestSuite(Q0).run(skip=['_test_elements', '_test_elements_eq_transitive', '_test_gcd_vs_xgcd', '_test_quo_rem']); Q0 Multivariate Polynomial Ring in no variables over Rational Field - sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(2), 'j', implementation="generic"); TestSuite(R).run(skip=['_test_construction', '_test_pickling']); type(R) - sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) # optional - sage.rings.finite_rings + sage: S = PolynomialRing(GF(2), 'j'); TestSuite(S).run(); type(S) sage: R = PolynomialRing(ZZ, 'x,y', implementation="generic"); TestSuite(R).run(skip=['_test_elements', '_test_elements_eq_transitive']); type(R) - sage: S = PolynomialRing(ZZ, 'x,y'); TestSuite(S).run(skip='_test_elements'); type(S) + sage: S = PolynomialRing(ZZ, 'x,y'); TestSuite(S).run(skip='_test_elements'); type(S) # needs sage.libs.singular sage: R = PolynomialRing(ZZ, 'j', sparse=True); TestSuite(R).run(); type(R) - sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(49), 'j', sparse=True); TestSuite(R).run(); type(R) # needs sage.rings.finite_rings sage: P. = PolynomialRing(RealIntervalField(2)) sage: TestSuite(P).run(skip=['_test_elements', '_test_elements_eq_transitive']) @@ -942,42 +956,42 @@ def BooleanPolynomialRing_constructor(n=None, names=None, order="lex"): EXAMPLES:: - sage: R. = BooleanPolynomialRing(); R # indirect doctest # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: R. = BooleanPolynomialRing(); R # indirect doctest Boolean PolynomialRing in x, y, z - - sage: p = x*y + x*z + y*z # optional - sage.rings.polynomial.pbori - sage: x*p # optional - sage.rings.polynomial.pbori + sage: p = x*y + x*z + y*z + sage: x*p x*y*z + x*y + x*z - - sage: R.term_order() # optional - sage.rings.polynomial.pbori + sage: R.term_order() Lexicographic term order - sage: R = BooleanPolynomialRing(5, 'x', order='deglex(3),deglex(2)') # optional - sage.rings.polynomial.pbori - sage: R.term_order() # optional - sage.rings.polynomial.pbori + sage: R = BooleanPolynomialRing(5, 'x', order='deglex(3),deglex(2)') # needs sage.rings.polynomial.pbori + sage: R.term_order() # needs sage.rings.polynomial.pbori Block term order with blocks: (Degree lexicographic term order of length 3, Degree lexicographic term order of length 2) - sage: R = BooleanPolynomialRing(3, 'x', order='degneglex') # optional - sage.rings.polynomial.pbori - sage: R.term_order() # optional - sage.rings.polynomial.pbori + sage: R = BooleanPolynomialRing(3, 'x', order='degneglex') # needs sage.rings.polynomial.pbori + sage: R.term_order() # needs sage.rings.polynomial.pbori Degree negative lexicographic term order - sage: BooleanPolynomialRing(names=('x','y')) # optional - sage.rings.polynomial.pbori + sage: BooleanPolynomialRing(names=('x','y')) # needs sage.rings.polynomial.pbori Boolean PolynomialRing in x, y - sage: BooleanPolynomialRing(names='x,y') # optional - sage.rings.polynomial.pbori + sage: BooleanPolynomialRing(names='x,y') # needs sage.rings.polynomial.pbori Boolean PolynomialRing in x, y TESTS:: - sage: P. = BooleanPolynomialRing(2, order='deglex') # optional - sage.rings.polynomial.pbori - sage: x > y # optional - sage.rings.polynomial.pbori + sage: P. = BooleanPolynomialRing(2, order='deglex') # needs sage.rings.polynomial.pbori + sage: x > y # needs sage.rings.polynomial.pbori True - sage: P. = BooleanPolynomialRing(4, order='deglex(2),deglex(2)') # optional - sage.rings.polynomial.pbori - sage: x0 > x1 # optional - sage.rings.polynomial.pbori + sage: # needs sage.rings.polynomial.pbori + sage: P. = BooleanPolynomialRing(4, order='deglex(2),deglex(2)') + sage: x0 > x1 True - sage: x2 > x3 # optional - sage.rings.polynomial.pbori + sage: x2 > x3 True """ if isinstance(n, str): diff --git a/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx b/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx index 4b55fa8c778..7e3e27dd520 100644 --- a/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx +++ b/src/sage/rings/polynomial/polynomial_ring_homomorphism.pyx @@ -55,7 +55,7 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: g = QQ.hom(RR) sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) sage: G(A.gen()^1000000) - 1.00000000000000*x^1000000 + 1.0...*x^1000000 """ P = self.codomain() @@ -73,18 +73,19 @@ cdef class PolynomialRingHomomorphism_from_base(RingHomomorphism_from_base): sage: from sage.rings.polynomial.polynomial_ring_homomorphism import PolynomialRingHomomorphism_from_base sage: R. = ZZ[] - sage: S = GF(5)['x'] # optional - sage.rings.finite_rings - sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings - sage: F = PolynomialRingHomomorphism_from_base(R.Hom(S), f) # optional - sage.rings.finite_rings - sage: F(2 * x, check=True) # optional - sage.rings.finite_rings + sage: S = GF(5)['x'] + sage: f = ZZ.hom(GF(5)) + sage: F = PolynomialRingHomomorphism_from_base(R.Hom(S), f) + sage: F(2 * x, check=True) 2*x - sage: k = GF(49, 'z') # optional - sage.rings.finite_rings - sage: A = PolynomialRing(GF(7), 'x', sparse=True) # optional - sage.rings.finite_rings - sage: B = PolynomialRing(k, 'x', sparse=True) # optional - sage.rings.finite_rings - sage: g = GF(7).hom(k) # optional - sage.rings.finite_rings - sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) # optional - sage.rings.finite_rings - sage: G(A.gen()^1000000, True, construct=False) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k = GF(49, 'z') + sage: A = PolynomialRing(GF(7), 'x', sparse=True) + sage: B = PolynomialRing(k, 'x', sparse=True) + sage: g = GF(7).hom(k) + sage: G = PolynomialRingHomomorphism_from_base(A.Hom(B), g) + sage: G(A.gen()^1000000, True, construct=False) x^1000000 """ diff --git a/src/sage/rings/polynomial/polynomial_singular_interface.py b/src/sage/rings/polynomial/polynomial_singular_interface.py index d725046ccdf..257eaf4c267 100644 --- a/src/sage/rings/polynomial/polynomial_singular_interface.py +++ b/src/sage/rings/polynomial/polynomial_singular_interface.py @@ -10,11 +10,11 @@ TESTS:: - sage: R = PolynomialRing(GF(2**8,'a'), 10, 'x', order='invlex') # optional - sage.rings.finite_rings - sage: R == loads(dumps(R)) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(2**8,'a'), 10, 'x', order='invlex') # needs sage.rings.finite_rings + sage: R == loads(dumps(R)) # needs sage.rings.finite_rings True - sage: P. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings - sage: f = (a^3 + 2*b^2*a)^7; f # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(7), 2) + sage: f = (a^3 + 2*b^2*a)^7; f a^21 + 2*a^7*b^14 """ @@ -41,7 +41,11 @@ import sage.rings.abc import sage.rings.number_field as number_field -from sage.interfaces.singular import singular +try: + from sage.interfaces.singular import singular +except ImportError: + singular = None + from sage.rings.rational_field import is_RationalField from sage.rings.function_field.function_field_rational import RationalFunctionField from sage.rings.finite_rings.finite_field_base import FiniteField @@ -61,7 +65,7 @@ def _do_singular_init_(singular, base_ring, char, _vars, order): TESTS:: sage: from sage.rings.polynomial.polynomial_singular_interface import _do_singular_init_ - sage: _do_singular_init_(singular, ZZ, 0, 'X', 'dp') # optional - sage.libs.singular + sage: _do_singular_init_(singular, ZZ, 0, 'X', 'dp') # needs sage.libs.singular (polynomial ring, over a domain, global ordering // coefficients: ZZ // number of vars : 1 @@ -163,7 +167,7 @@ def _do_singular_init_(singular, base_ring, char, _vars, order): return singular(f"std(ideal({base_ring.__minpoly}))", type='qring'), None - elif isinstance(base_ring, sage.rings.function_field.function_field_rational.RationalFunctionField) \ + elif isinstance(base_ring, RationalFunctionField) \ and base_ring.constant_field().is_prime_field(): gen = str(base_ring.gen()) return make_ring(f"({base_ring.characteristic()},{gen})"), None @@ -194,8 +198,8 @@ def _singular_(self, singular=singular): EXAMPLES:: - sage: R. = PolynomialRing(CC) - sage: singular(R) + sage: R. = PolynomialRing(CC) # needs sage.rings.real_mpfr + sage: singular(R) # needs sage.libs.singular sage.rings.real_mpfr polynomial ring, over a field, global ordering // coefficients: real[I](complex:15 digits, additional 0 digits)/(I^2+1) // number of vars : 2 @@ -203,8 +207,8 @@ def _singular_(self, singular=singular): // : names x y // block 2 : ordering C - sage: R. = PolynomialRing(RealField(100)) - sage: singular(R) + sage: R. = PolynomialRing(RealField(100)) # needs sage.rings.real_mpfr + sage: singular(R) # needs sage.libs.singular sage.rings.real_mpfr polynomial ring, over a field, global ordering // coefficients: Float() // number of vars : 2 @@ -213,8 +217,8 @@ def _singular_(self, singular=singular): // block 2 : ordering C sage: w = polygen(ZZ, 'w') - sage: R. = PolynomialRing(NumberField(w^2 + 1, 's')) # optional - sage.rings.number_field - sage: singular(R) # optional - sage.rings.number_field + sage: R. = PolynomialRing(NumberField(w^2 + 1, 's')) # needs sage.rings.number_field + sage: singular(R) # needs sage.libs.singular sage.rings.number_field polynomial ring, over a field, global ordering // coefficients: QQ[s]/(s^2+1) // number of vars : 1 @@ -222,8 +226,8 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: R = PolynomialRing(GF(127), 'x', implementation="singular") # optional - sage.rings.finite_rings - sage: singular(R) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(127), 'x', implementation="singular") # needs sage.libs.singular + sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 1 @@ -231,8 +235,8 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: R = PolynomialRing(QQ, 'x', implementation="singular") - sage: singular(R) + sage: R = PolynomialRing(QQ, 'x', implementation="singular") # needs sage.libs.singular + sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -241,7 +245,7 @@ def _singular_(self, singular=singular): // block 2 : ordering C sage: R = PolynomialRing(QQ,'x') - sage: singular(R) + sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -249,8 +253,8 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: R = PolynomialRing(GF(127), 'x') # optional - sage.rings.finite_rings - sage: singular(R) # optional - sage.rings.finite_rings + sage: R = PolynomialRing(GF(127), 'x') + sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 1 @@ -259,7 +263,7 @@ def _singular_(self, singular=singular): // block 2 : ordering C sage: R = Frac(ZZ['a,b'])['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ(a, b) // number of vars : 2 @@ -269,7 +273,7 @@ def _singular_(self, singular=singular): sage: R = IntegerModRing(1024)['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.libs.singular polynomial ring, over a ring (with zero-divisors), global ordering // coefficients: ZZ/(2^10) // number of vars : 2 @@ -278,7 +282,7 @@ def _singular_(self, singular=singular): // block 2 : ordering C sage: R = IntegerModRing(15)['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.libs.singular polynomial ring, over a ring (with zero-divisors), global ordering // coefficients: ZZ/...(15) // number of vars : 2 @@ -287,7 +291,7 @@ def _singular_(self, singular=singular): // block 2 : ordering C sage: R = ZZ['x,y'] - sage: singular(R) + sage: singular(R) # needs sage.libs.singular polynomial ring, over a domain, global ordering // coefficients: ZZ // number of vars : 2 @@ -296,7 +300,7 @@ def _singular_(self, singular=singular): // block 2 : ordering C sage: R = ZZ['x'] - sage: singular(R) + sage: singular(R) # needs sage.libs.singular polynomial ring, over a domain, global ordering // coefficients: ZZ // number of vars : 1 @@ -304,11 +308,12 @@ def _singular_(self, singular=singular): // : names x // block 2 : ordering C - sage: k. = FiniteField(25) # optional - sage.rings.finite_rings - sage: R = k['x'] # optional - sage.rings.finite_rings - sage: K = R.fraction_field() # optional - sage.rings.finite_rings - sage: S = K['y'] # optional - sage.rings.finite_rings - sage: singular(S) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = FiniteField(25) + sage: R = k['x'] + sage: K = R.fraction_field() + sage: S = K['y'] + sage: singular(S) # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: ZZ/5(x) // number of vars : 2 @@ -349,7 +354,7 @@ def _singular_init_(self, singular=singular): EXAMPLES:: - sage: PolynomialRing(QQ,'u_ba')._singular_init_() # optional - sage.libs.singular + sage: PolynomialRing(QQ,'u_ba')._singular_init_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 @@ -399,23 +404,25 @@ def can_convert_to_singular(R): Avoid non absolute number fields (see :trac:`23535`):: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField([x^2 - 2, x^2 - 5]) # optional - sage.rings.number_field - sage: can_convert_to_singular(K['s,t']) # optional - sage.rings.number_field + sage: K. = NumberField([x^2 - 2, x^2 - 5]) # needs sage.rings.number_field + sage: can_convert_to_singular(K['s,t']) # needs sage.rings.number_field False Check for :trac:`33319`:: - sage: R. = GF((2^31-1)^3)[] # optional - sage.rings.finite_rings - sage: R._has_singular # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: R. = GF((2^31-1)^3)[] + sage: R._has_singular True - sage: R. = GF((2^31+11)^2)[] # optional - sage.rings.finite_rings - sage: R._has_singular # optional - sage.rings.finite_rings + sage: R. = GF((2^31+11)^2)[] + sage: R._has_singular False - sage: R. = GF(10^20 - 11)[] # optional - sage.rings.finite_rings - sage: R._has_singular # optional - sage.rings.finite_rings + sage: R. = GF(10^20 - 11)[] + sage: R._has_singular True - sage: R. = Zmod(10^20 + 1)[] # optional - sage.libs.pari - sage: R._has_singular # optional - sage.libs.pari + + sage: R. = Zmod(10^20 + 1)[] + sage: R._has_singular True """ if R.ngens() == 0: @@ -470,25 +477,27 @@ def _singular_func(self, singular=singular): EXAMPLES:: - sage: P. = PolynomialRing(GF(7), 2) # optional - sage.rings.finite_rings - sage: f = (a^3 + 2*b^2*a)^7; f # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: P. = PolynomialRing(GF(7), 2) + sage: f = (a^3 + 2*b^2*a)^7; f a^21 + 2*a^7*b^14 - sage: h = f._singular_(); h # optional - sage.rings.finite_rings + sage: h = f._singular_(); h a^21+2*a^7*b^14 - sage: P(h) # optional - sage.rings.finite_rings + sage: P(h) a^21 + 2*a^7*b^14 - sage: P(h^20) == f^20 # optional - sage.rings.finite_rings + sage: P(h^20) == f^20 True - sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings - sage: f = (x^3 + 2*x^2*x)^7 # optional - sage.rings.finite_rings - sage: f # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular + sage: R. = PolynomialRing(GF(7)) + sage: f = (x^3 + 2*x^2*x)^7 + sage: f 3*x^21 - sage: h = f._singular_(); h # optional - sage.rings.finite_rings + sage: h = f._singular_(); h 3*x^21 - sage: R(h) # optional - sage.rings.finite_rings + sage: R(h) 3*x^21 - sage: R(h^20) == f^20 # optional - sage.rings.finite_rings + sage: R(h^20) == f^20 True """ self.parent()._singular_(singular).set_ring() # this is expensive diff --git a/src/sage/rings/polynomial/polynomial_template.pxi b/src/sage/rings/polynomial/polynomial_template.pxi index 7419e9ebb4a..ada39527536 100644 --- a/src/sage/rings/polynomial/polynomial_template.pxi +++ b/src/sage/rings/polynomial/polynomial_template.pxi @@ -214,6 +214,7 @@ cdef class Polynomial_template(Polynomial): The following has been a problem in a preliminary version of :trac:`12313`:: + sage: # needs sage.rings.finite_rings sage: K. = GF(4) sage: P. = K[] sage: del P @@ -778,7 +779,7 @@ cdef class Polynomial_template(Polynomial): sage: P. = PolynomialRing(GF(7)) sage: f = 3*x^2 + 2*x + 5 - sage: singular(f) + sage: singular(f) # needs sage.libs.singular 3*x^2+2*x-2 """ self.parent()._singular_(singular).set_ring() # this is expensive diff --git a/src/sage/rings/polynomial/polynomial_zz_pex.pyx b/src/sage/rings/polynomial/polynomial_zz_pex.pyx index ca5d32e2903..d7d8473b563 100644 --- a/src/sage/rings/polynomial/polynomial_zz_pex.pyx +++ b/src/sage/rings/polynomial/polynomial_zz_pex.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.ntl sage.rings.finite_rings +# sage.doctest: needs sage.libs.ntl sage.rings.finite_rings # distutils: libraries = NTL_LIBRARIES gmp # distutils: extra_compile_args = NTL_CFLAGS # distutils: include_dirs = NTL_INCDIR @@ -237,7 +237,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): sage: F. = GF(4) sage: P. = F[] sage: p = y^4 + x*y^3 + y^2 + (x + 1)*y + x + 1 - sage: SR(p) # optional - sage.symbolic + sage: SR(p) # needs sage.symbolic Traceback (most recent call last): ... TypeError: positive characteristic not allowed in symbolic computations diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index 55363a1c00c..4b5ebac6d8e 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -435,7 +435,7 @@ dr_cache = {} cdef class interval_bernstein_polynomial_integer(interval_bernstein_polynomial): """ - This is the subclass of interval_bernstein_polynomial where + This is the subclass of :class:`interval_bernstein_polynomial` where polynomial coefficients are represented using integers. In this integer representation, each coefficient is represented by @@ -443,8 +443,8 @@ cdef class interval_bernstein_polynomial_integer(interval_bernstein_polynomial): E (which is a machine integer). These represent the coefficients A*2^n <= c < (A+E)*2^n. - (Note that mk_ibpi is a simple helper function for creating - elements of interval_bernstein_polynomial_integer in doctests.) + (Note that :func:`mk_ibpi is a simple helper` function for creating + elements of :class:`interval_bernstein_polynomial_integer` in doctests.) EXAMPLES:: @@ -455,11 +455,13 @@ cdef class interval_bernstein_polynomial_integer(interval_bernstein_polynomial): sage: bp.variations() (0, 0) - sage: bp = mk_ibpi([-3, -1, 1, -1, -3, -1], lower=1, upper=5/4, usign=1, error=2, scale_log2=-3, level=2, slope_err=RIF(pi)); print(bp) + sage: bp = mk_ibpi([-3, -1, 1, -1, -3, -1], lower=1, upper=5/4, usign=1, # needs sage.symbolic + ....: error=2, scale_log2=-3, level=2, slope_err=RIF(pi)); print(bp) degree 5 IBP with 2-bit coefficients - sage: bp - - sage: bp.variations() + sage: bp # needs sage.symbolic + + sage: bp.variations() # needs sage.symbolic (3, 3) """ @@ -1330,7 +1332,7 @@ def intvec_to_doublevec(Vector_integer_dense b, long err): cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): """ - This is the subclass of interval_bernstein_polynomial where + This is the subclass of :class:`interval_bernstein_polynomial` where polynomial coefficients are represented using floating-point numbers. In the floating-point representation, each coefficient is represented @@ -1341,8 +1343,8 @@ cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): Note that we always have E1 <= 0 <= E2. Also, each floating-point coefficient has absolute value less than one. - (Note that mk_ibpf is a simple helper function for creating - elements of interval_bernstein_polynomial_float in doctests.) + (Note that :func:`mk_ibpf` is a simple helper function for creating + elements of :class:`interval_bernstein_polynomial_float` in doctests.) EXAMPLES:: @@ -1353,11 +1355,14 @@ cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): sage: bp.variations() (0, 0) - sage: bp = mk_ibpf([-0.3, -0.1, 0.1, -0.1, -0.3, -0.1], lower=1, upper=5/4, usign=1, pos_err=0.2, scale_log2=-3, level=2, slope_err=RIF(pi)); print(bp) + sage: bp = mk_ibpf([-0.3, -0.1, 0.1, -0.1, -0.3, -0.1], # needs sage.symbolic + ....: lower=1, upper=5/4, usign=1, pos_err=0.2, + ....: scale_log2=-3, level=2, slope_err=RIF(pi)); print(bp) degree 5 IBP with floating-point coefficients - sage: bp - - sage: bp.variations() + sage: bp # needs sage.symbolic + + sage: bp.variations() # needs sage.symbolic (3, 3) """ @@ -1560,13 +1565,13 @@ cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): INPUT: - - ``mid`` -- where to split the Bernstein basis region; 0 < mid < 1 - - ``msign`` -- default 0 (unknown); the sign of this polynomial at mid + - ``mid`` -- where to split the Bernstein basis region; ``0 < mid < 1`` + - ``msign`` -- default 0 (unknown); the sign of this polynomial at ``mid`` OUTPUT: - ``bp1``, ``bp2`` -- the new interval Bernstein polynomials - - ``ok`` -- a boolean; True if the sign of the original polynomial at mid is known + - ``ok`` -- a boolean; ``True`` if the sign of the original polynomial at ``mid`` is known EXAMPLES:: @@ -1679,7 +1684,7 @@ cdef class interval_bernstein_polynomial_float(interval_bernstein_polynomial): def mk_ibpf(coeffs, lower=0, upper=1, lsign=0, usign=0, neg_err=0, pos_err=0, scale_log2=0, level=0, slope_err=RIF(0)): """ - A simple wrapper for creating interval_bernstein_polynomial_float + A simple wrapper for creating :class:`interval_bernstein_polynomial_float` objects with coercions, defaults, etc. For use in doctests. diff --git a/src/sage/rings/polynomial/refine_root.pyx b/src/sage/rings/polynomial/refine_root.pyx index 082bf810881..32a9ce8c8e4 100644 --- a/src/sage/rings/polynomial/refine_root.pyx +++ b/src/sage/rings/polynomial/refine_root.pyx @@ -38,6 +38,7 @@ def refine_root(ip, ipd, irt, fld): EXAMPLES:: + sage: # needs sage.symbolic sage: from sage.rings.polynomial.refine_root import refine_root sage: x = polygen(ZZ) sage: p = x^9 - 1 diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx index dea7f1ea027..6ab57e1f7c5 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_order.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.rings.finite_rings +# sage.doctest: needs sage.rings.finite_rings r""" Univariate dense skew polynomials over a field with a finite order automorphism diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index 9f499430d59..2ae48556880 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -116,12 +116,13 @@ def _minimal_vanishing_polynomial(R, eval_pts): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.skew_polynomial_ring import _minimal_vanishing_polynomial - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob] # optional - sage.rings.finite_rings - sage: eval_pts = [1, t, t^2] # optional - sage.rings.finite_rings - sage: b = _minimal_vanishing_polynomial(S, eval_pts); b # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob] + sage: eval_pts = [1, t, t^2] + sage: b = _minimal_vanishing_polynomial(S, eval_pts); b doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/13215 for details. @@ -171,24 +172,25 @@ def _lagrange_polynomial(R, eval_pts, values): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.rings.polynomial.skew_polynomial_ring import _lagrange_polynomial - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: eval_pts = [t , t^2] # optional - sage.rings.finite_rings - sage: values = [3*t^2 + 4*t + 4, 4*t] # optional - sage.rings.finite_rings - sage: d = _lagrange_polynomial(S, eval_pts, values); d # optional - sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: eval_pts = [t , t^2] + sage: values = [3*t^2 + 4*t + 4, 4*t] + sage: d = _lagrange_polynomial(S, eval_pts, values); d x + t - sage: d.multi_point_evaluation(eval_pts) == values # optional - sage.rings.finite_rings + sage: d.multi_point_evaluation(eval_pts) == values True The following restrictions are impossible to satisfy because the evaluation points are linearly dependent over the fixed field of the twisting morphism, and the corresponding values do not match:: - sage: eval_pts = [t, 2*t] # optional - sage.rings.finite_rings - sage: values = [1, 3] # optional - sage.rings.finite_rings - sage: _lagrange_polynomial(S, eval_pts, values) # optional - sage.rings.finite_rings + sage: eval_pts = [t, 2*t] # needs sage.rings.finite_rings + sage: values = [1, 3] + sage: _lagrange_polynomial(S, eval_pts, values) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the given evaluation points are linearly dependent over the fixed field of the twisting morphism, @@ -275,26 +277,27 @@ def minimal_vanishing_polynomial(self, eval_pts): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: eval_pts = [1, t, t^2] # optional - sage.rings.finite_rings - sage: b = S.minimal_vanishing_polynomial(eval_pts); b # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: eval_pts = [1, t, t^2] + sage: b = S.minimal_vanishing_polynomial(eval_pts); b x^3 + 4 The minimal vanishing polynomial evaluates to 0 at each of the evaluation points:: - sage: eval = b.multi_point_evaluation(eval_pts); eval # optional - sage.rings.finite_rings + sage: eval = b.multi_point_evaluation(eval_pts); eval # needs sage.rings.finite_rings [0, 0, 0] If the evaluation points are linearly dependent over the fixed field of the twisting morphism, then the returned polynomial has lower degree than the number of evaluation points:: - sage: S.minimal_vanishing_polynomial([t]) # optional - sage.rings.finite_rings + sage: S.minimal_vanishing_polynomial([t]) # needs sage.rings.finite_rings x + 3*t^2 + 3*t - sage: S.minimal_vanishing_polynomial([t, 3*t]) # optional - sage.rings.finite_rings + sage: S.minimal_vanishing_polynomial([t, 3*t]) # needs sage.rings.finite_rings x + 3*t^2 + 3*t """ return _minimal_vanishing_polynomial(_base_ring_to_fraction_field(self), eval_pts) @@ -328,11 +331,12 @@ def lagrange_polynomial(self, points): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - sage: points = [(t, 3*t^2 + 4*t + 4), (t^2, 4*t)] # optional - sage.rings.finite_rings - sage: d = S.lagrange_polynomial(points); d # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: points = [(t, 3*t^2 + 4*t + 4), (t^2, 4*t)] + sage: d = S.lagrange_polynomial(points); d x + t sage: R. = ZZ[] @@ -379,12 +383,13 @@ class SectionSkewPolynomialCenterInjection(Section): TESTS:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: sigma = iota.section() # optional - sage.rings.finite_rings - sage: TestSuite(sigma).run(skip=['_test_category']) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) + sage: sigma = iota.section() + sage: TestSuite(sigma).run(skip=['_test_category']) """ def _call_(self, x): r""" @@ -392,14 +397,15 @@ def _call_(self, x): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: sigma = iota.section() # optional - sage.rings.finite_rings - sage: sigma(x^3) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) + sage: sigma = iota.section() + sage: sigma(x^3) z - sage: sigma(x^2) # optional - sage.rings.finite_rings + sage: sigma(x^2) Traceback (most recent call last): ... ValueError: x^2 is not in the center @@ -426,18 +432,20 @@ def _richcmp_(self, right, op): TESTS:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: sigma = iota.section() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) + sage: sigma = iota.section() - sage: s = loads(dumps(sigma)) # optional - sage.rings.finite_rings - sage: s == sigma # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: s = loads(dumps(sigma)) + sage: s == sigma True - sage: s != sigma # optional - sage.rings.finite_rings + sage: s != sigma False - sage: s is sigma # optional - sage.rings.finite_rings + sage: s is sigma False """ if op == op_EQ: @@ -454,11 +462,12 @@ class SkewPolynomialCenterInjection(RingHomomorphism): TESTS:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: TestSuite(iota).run(skip=['_test_category']) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) + sage: TestSuite(iota).run(skip=['_test_category']) """ def __init__(self, domain, codomain, embed, order): r""" @@ -466,10 +475,11 @@ def __init__(self, domain, codomain, embed, order): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: S.convert_map_from(Z) # indirect doctest # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: S.convert_map_from(Z) # indirect doctest Embedding of the center of Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 into this ring """ RingHomomorphism.__init__(self, Hom(domain, codomain)) @@ -484,13 +494,14 @@ def _repr_(self): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: iota # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) + sage: iota Embedding of the center of Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 into this ring - sage: iota._repr_() # optional - sage.rings.finite_rings + sage: iota._repr_() 'Embedding of the center of Ore Polynomial Ring in x over Finite Field in a of size 5^3 twisted by a |--> a^5 into this ring' """ return "Embedding of the center of %s into this ring" % self._codomain @@ -501,12 +512,13 @@ def _call_(self, x): TESTS:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z. = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z. = S.center() + sage: iota = S.convert_map_from(Z) - sage: iota(z) # optional - sage.rings.finite_rings + sage: iota(z) # needs sage.rings.finite_rings x^3 """ k = self._codomain.base_ring() @@ -522,17 +534,19 @@ def _richcmp_(self, right, op): TESTS:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) - sage: i = loads(dumps(iota)) # optional - sage.rings.finite_rings - sage: i == iota # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: i = loads(dumps(iota)) + sage: i == iota True - sage: i != iota # optional - sage.rings.finite_rings + sage: i != iota False - sage: i is iota # optional - sage.rings.finite_rings + sage: i is iota False """ if op == op_EQ: @@ -547,12 +561,13 @@ def section(self): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) # optional - sage.rings.finite_rings - sage: Z = S.center() # optional - sage.rings.finite_rings - sage: iota = S.convert_map_from(Z) # optional - sage.rings.finite_rings - sage: sigma = iota.section() # optional - sage.rings.finite_rings - sage: sigma(x^3) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: S. = SkewPolynomialRing(k, k.frobenius_endomorphism()) + sage: Z = S.center() + sage: iota = S.convert_map_from(Z) + sage: sigma = iota.section() + sage: sigma(x^3) z """ return self._section @@ -574,26 +589,28 @@ def __init__(self, base_ring, morphism, derivation, name, sparse, category=None) TESTS:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob]; S # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob]; S Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - sage: S.category() # optional - sage.rings.finite_rings + sage: S.category() Category of algebras over Finite Field in t of size 5^3 - sage: TestSuite(S).run() # optional - sage.rings.finite_rings + sage: TestSuite(S).run() # needs sage.rings.finite_rings We check that a call to the method :meth:`sage.rings.polynomial.skew_polynomial_finite_order.SkewPolynomial_finite_order.is_central` does not affect the behaviour of default central variable names:: - sage: k. = GF(7^4) # optional - sage.rings.finite_rings - sage: phi = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', phi] # optional - sage.rings.finite_rings - sage: (x^4).is_central() # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(7^4) + sage: phi = k.frobenius_endomorphism() + sage: S. = k['x', phi] + sage: (x^4).is_central() True - sage: Z. = S.center() # optional - sage.rings.finite_rings - sage: S.center() is Z # optional - sage.rings.finite_rings + sage: Z. = S.center() + sage: S.center() is Z True """ if self.Element is None: @@ -639,57 +656,57 @@ def center(self, name=None, names=None, default=False): EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x',Frob]; S # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(5^3) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x',Frob]; S Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - - sage: Z = S.center(); Z # optional - sage.rings.finite_rings + sage: Z = S.center(); Z Univariate Polynomial Ring in z over Finite Field of size 5 - sage: Z.gen() # optional - sage.rings.finite_rings + sage: Z.gen() z We can pass in another variable name:: - sage: S.center(name='y') # optional - sage.rings.finite_rings + sage: S.center(name='y') # needs sage.rings.finite_rings Univariate Polynomial Ring in y over Finite Field of size 5 or use the bracket notation:: - sage: Zy. = S.center(); Zy # optional - sage.rings.finite_rings + sage: Zy. = S.center(); Zy # needs sage.rings.finite_rings Univariate Polynomial Ring in y over Finite Field of size 5 - sage: y.parent() is Zy # optional - sage.rings.finite_rings + sage: y.parent() is Zy # needs sage.rings.finite_rings True A coercion map from the center to the skew polynomial ring is set:: - sage: S.has_coerce_map_from(Zy) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: S.has_coerce_map_from(Zy) True - - sage: P = y + x; P # optional - sage.rings.finite_rings + sage: P = y + x; P x^3 + x - sage: P.parent() # optional - sage.rings.finite_rings + sage: P.parent() Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 - sage: P.parent() is S # optional - sage.rings.finite_rings + sage: P.parent() is S True together with a conversion map in the reverse direction:: - sage: Zy(x^6 + 2*x^3 + 3) # optional - sage.rings.finite_rings + sage: Zy(x^6 + 2*x^3 + 3) # needs sage.rings.finite_rings y^2 + 2*y + 3 - sage: Zy(x^2) # optional - sage.rings.finite_rings + sage: Zy(x^2) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: x^2 is not in the center Two different skew polynomial rings can share the same center:: - sage: S1. = k['x1', Frob] # optional - sage.rings.finite_rings - sage: S2. = k['x2', Frob] # optional - sage.rings.finite_rings - sage: S1.center() is S2.center() # optional - sage.rings.finite_rings + sage: S1. = k['x1', Frob] # needs sage.rings.finite_rings + sage: S2. = k['x2', Frob] # needs sage.rings.finite_rings + sage: S1.center() is S2.center() # needs sage.rings.finite_rings True .. RUBRIC:: About the default name of the central variable @@ -699,32 +716,33 @@ def center(self, name=None, names=None, default=False): However, a variable name is given the first time this method is called, the given name become the default for the next calls:: - sage: K. = GF(11^3) # optional - sage.rings.finite_rings - sage: phi = K.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: A. = K['X', phi] # optional - sage.rings.finite_rings - - sage: C. = A.center() # first call # optional - sage.rings.finite_rings - sage: C # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: K. = GF(11^3) + sage: phi = K.frobenius_endomorphism() + sage: A. = K['X', phi] + sage: C. = A.center() # first call + sage: C Univariate Polynomial Ring in u over Finite Field of size 11 - sage: A.center() # second call: the variable name is still u # optional - sage.rings.finite_rings + sage: A.center() # second call: the variable name is still u Univariate Polynomial Ring in u over Finite Field of size 11 - sage: A.center() is C # optional - sage.rings.finite_rings + sage: A.center() is C True We can update the default variable name by passing in the argument ``default=True``:: - sage: D. = A.center(default=True) # optional - sage.rings.finite_rings - sage: D # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: D. = A.center(default=True) + sage: D Univariate Polynomial Ring in v over Finite Field of size 11 - sage: A.center() # optional - sage.rings.finite_rings + sage: A.center() Univariate Polynomial Ring in v over Finite Field of size 11 - sage: A.center() is D # optional - sage.rings.finite_rings + sage: A.center() is D True TESTS:: - sage: C. = S.center() # optional - sage.rings.finite_rings + sage: C. = S.center() # needs sage.rings.finite_rings Traceback (most recent call last): ... IndexError: the number of names must equal the number of generators @@ -796,9 +814,9 @@ def __init__(self, base_ring, morphism, derivation, names, sparse, category=None EXAMPLES:: - sage: k. = GF(5^3) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: T. = k['x', Frob]; T # optional - sage.rings.finite_rings + sage: k. = GF(5^3) # needs sage.rings.finite_rings + sage: Frob = k.frobenius_endomorphism() # needs sage.rings.finite_rings + sage: T. = k['x', Frob]; T # needs sage.rings.finite_rings Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5 """ if self.Element is None: @@ -823,21 +841,22 @@ def _new_retraction_map(self, seed=None): TESTS:: - sage: k. = GF(11^4) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - - sage: S._new_retraction_map() # optional - sage.rings.finite_rings - sage: S._matrix_retraction # random # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(11^4) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: S._new_retraction_map() + sage: S._matrix_retraction # random [ 9 4 10 4] We can specify a seed:: - sage: S._new_retraction_map(seed=a) # optional - sage.rings.finite_rings - sage: S._matrix_retraction # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: S._new_retraction_map(seed=a) + sage: S._matrix_retraction [ 0 6 3 10] - sage: S._new_retraction_map(seed=a) # optional - sage.rings.finite_rings - sage: S._matrix_retraction # optional - sage.rings.finite_rings + sage: S._new_retraction_map(seed=a) + sage: S._matrix_retraction [ 0 6 3 10] """ k = self.base_ring() @@ -875,27 +894,27 @@ def _retraction(self, x, newmap=False, seed=None): TESTS:: - sage: k. = GF(11^4) # optional - sage.rings.finite_rings - sage: Frob = k.frobenius_endomorphism() # optional - sage.rings.finite_rings - sage: S. = k['x', Frob] # optional - sage.rings.finite_rings - - sage: S._retraction(a) # random # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = GF(11^4) + sage: Frob = k.frobenius_endomorphism() + sage: S. = k['x', Frob] + sage: S._retraction(a) # random 6 Note that a retraction map has been automatically created:: - sage: S._matrix_retraction # random # optional - sage.rings.finite_rings + sage: S._matrix_retraction # random # needs sage.rings.finite_rings [ 0 6 3 10] If we call again the method :meth:`_retraction`, the same retraction map is used:: - sage: S._retraction(a) # random # optional - sage.rings.finite_rings + sage: S._retraction(a) # random # needs sage.rings.finite_rings 6 We can specify a seed:: - sage: S._retraction(a^2, seed=a) # random # optional - sage.rings.finite_rings + sage: S._retraction(a^2, seed=a) # random # needs sage.rings.finite_rings 10 """ # Better to return the retraction map but more difficult diff --git a/src/sage/rings/polynomial/symmetric_ideal.py b/src/sage/rings/polynomial/symmetric_ideal.py index 4905e5d87a6..84138cd8975 100644 --- a/src/sage/rings/polynomial/symmetric_ideal.py +++ b/src/sage/rings/polynomial/symmetric_ideal.py @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.singular """ Symmetric Ideals of Infinite Polynomial Rings @@ -23,13 +24,14 @@ Note that ``I`` is not a symmetric Groebner basis:: - sage: G = R * I.groebner_basis() # optional - sage.combinat - sage: G # optional - sage.combinat + sage: # needs sage.combinat + sage: G = R * I.groebner_basis() + sage: G Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) of Infinite polynomial ring in x over Rational Field - sage: Q = R.quotient(G) # optional - sage.combinat - sage: p = x[3]*x[1] + x[2]^2 + 3 # optional - sage.combinat - sage: Q(p) # optional - sage.combinat + sage: Q = R.quotient(G) + sage: p = x[3]*x[1] + x[2]^2 + 3 + sage: Q(p) -2*x_1 + 3 By the second generator of ``G``, variable `x_n` is equal to `x_1` for @@ -37,7 +39,7 @@ equal to `x_1` in ``Q``. Indeed, we have :: - sage: Q(p)*x[2] == Q(p)*x[1]*x[3]*x[5] # optional - sage.combinat + sage: Q(p)*x[2] == Q(p)*x[1]*x[3]*x[5] # needs sage.combinat True """ @@ -118,7 +120,7 @@ class SymmetricIdeal(Ideal_generic): The default ordering is lexicographic. We now compute a Groebner basis:: - sage: J = I.groebner_basis(); J # about 3 seconds # optional - sage.combinat + sage: J = I.groebner_basis(); J # about 3 seconds # needs sage.combinat [x_1*y_2*y_1 + 2*x_1*y_2, x_2*y_2*y_1 + 2*x_2*y_1, x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1] @@ -127,17 +129,18 @@ class SymmetricIdeal(Ideal_generic): four elements. Ideal membership in ``I`` can now be tested by commuting symmetric reduction modulo ``J``:: - sage: I.reduce(J) # optional - sage.combinat + sage: I.reduce(J) # needs sage.combinat Symmetric Ideal (0) of Infinite polynomial ring in x, y over Rational Field The Groebner basis is not point-wise invariant under permutation:: - sage: P = Permutation([2, 1]) # optional - sage.combinat - sage: J[2] # optional - sage.combinat + sage: # needs sage.combinat + sage: P = Permutation([2, 1]) + sage: J[2] x_2*x_1*y_1^2 + 2*x_2*x_1*y_1 - sage: J[2]^P # optional - sage.combinat + sage: J[2]^P x_2*x_1*y_2^2 + 2*x_2*x_1*y_2 - sage: J[2]^P in J # optional - sage.combinat + sage: J[2]^P in J False However, any element of ``J`` has symmetric reduction zero even @@ -145,13 +148,13 @@ class SymmetricIdeal(Ideal_generic): permutations involve higher variable indices than the ones occurring in ``J``:: - sage: [[(p^P).reduce(J) for p in J] for P in Permutations(3)] # optional - sage.combinat + sage: [[(p^P).reduce(J) for p in J] for P in Permutations(3)] # needs sage.combinat [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] Since ``I`` is not a Groebner basis, it is no surprise that it cannot detect ideal membership:: - sage: [p.reduce(I) for p in J] # optional - sage.combinat + sage: [p.reduce(I) for p in J] # needs sage.combinat [0, x_2*y_2*y_1 + 2*x_2*y_1, x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1] Note that we give no guarantee that the computation of a symmetric @@ -164,13 +167,13 @@ class SymmetricIdeal(Ideal_generic): :: sage: I = X * (x[1]) - sage: I * I # optional - sage.combinat + sage: I * I # needs sage.combinat Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I^3 # optional - sage.combinat + sage: I^3 # needs sage.combinat Symmetric Ideal (x_1^3, x_2*x_1^2, x_2^2*x_1, x_3*x_2*x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I * I == X * (x[1]^2) # optional - sage.combinat + sage: I * I == X * (x[1]^2) # needs sage.combinat False """ @@ -235,11 +238,11 @@ def _contains_(self, p): sage: R. = InfinitePolynomialRing(QQ) sage: I = R.ideal([x[1]*x[2] + x[3]]) - sage: I = R * I.groebner_basis() # optional - sage.combinat - sage: I # optional - sage.combinat + sage: I = R * I.groebner_basis() # needs sage.combinat + sage: I # needs sage.combinat Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) of Infinite polynomial ring in x over Rational Field - sage: x[2]^2 + x[3] in I # indirect doctest # optional - sage.combinat + sage: x[2]^2 + x[3] in I # indirect doctest # needs sage.combinat True """ try: @@ -260,7 +263,7 @@ def __mul__(self, other): sage: X. = InfinitePolynomialRing(QQ) sage: I = X * (x[1]) - sage: I*I # indirect doctest # optional - sage.combinat + sage: I*I # indirect doctest # needs sage.combinat Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x over Rational Field """ @@ -300,7 +303,7 @@ def __pow__(self, n): sage: X. = InfinitePolynomialRing(QQ) sage: I = X * (x[1]) - sage: I^2 # indirect doctest # optional - sage.combinat + sage: I^2 # indirect doctest # needs sage.combinat Symmetric Ideal (x_1^2, x_2*x_1) of Infinite polynomial ring in x over Rational Field """ @@ -329,20 +332,20 @@ def is_maximal(self): sage: R. = InfinitePolynomialRing(QQ) sage: I = R.ideal([x[1] + y[2], x[2] - y[1]]) - sage: I = R * I.groebner_basis(); I # optional - sage.combinat + sage: I = R * I.groebner_basis(); I # needs sage.combinat Symmetric Ideal (y_1, x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I = R.ideal([x[1] + y[2], x[2] - y[1]]) # optional - sage.combinat - sage: I.is_maximal() # optional - sage.combinat + sage: I = R.ideal([x[1] + y[2], x[2] - y[1]]) # needs sage.combinat + sage: I.is_maximal() # needs sage.combinat False The preceding answer is wrong, since it is not the case that ``I`` is given by a symmetric Groebner basis:: - sage: I = R * I.groebner_basis(); I # optional - sage.combinat + sage: I = R * I.groebner_basis(); I # needs sage.combinat Symmetric Ideal (y_1, x_1) of Infinite polynomial ring in x, y over Rational Field - sage: I.is_maximal() # optional - sage.combinat + sage: I.is_maximal() # needs sage.combinat True """ @@ -398,7 +401,7 @@ def reduce(self, I, tailreduce=False): reduction by ``x[2]^2*y[1]`` works, since one can change variable index 1 into 2 and 2 into 3:: - sage: I.reduce([x[2]^2*y[1]]) # optional - sage.combinat + sage: I.reduce([x[2]^2*y[1]]) # needs sage.combinat Symmetric Ideal (y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field @@ -410,7 +413,7 @@ def reduce(self, I, tailreduce=False): sage: I.reduce(J) Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) of Infinite polynomial ring in x, y over Rational Field - sage: I.reduce(J, tailreduce=True) # optional - sage.combinat + sage: I.reduce(J, tailreduce=True) # needs sage.combinat Symmetric Ideal (x_3^2*y_1) of Infinite polynomial ring in x, y over Rational Field @@ -455,13 +458,13 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None sage: X. = InfinitePolynomialRing(QQ) sage: I = X * (x[1] + x[2], x[1]*x[2]) - sage: I.interreduction() + sage: I.interreduction() # needs sage.combinat Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field Here, we show the ``report`` option:: - sage: I.interreduction(report=True) # optional - sage.combinat + sage: I.interreduction(report=True) # needs sage.combinat Symmetric interreduction [1/2] > [2/2] :> @@ -480,18 +483,19 @@ def interreduction(self, tailreduce=True, sorted=False, report=None, RStrat=None Last, we demonstrate the use of the optional parameter ``RStrat``:: sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy - sage: R = SymmetricReductionStrategy(X) - sage: R - Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field - sage: I.interreduction(RStrat=R) # optional - sage.combinat + sage: R = SymmetricReductionStrategy(X); R + Symmetric Reduction Strategy in + Infinite polynomial ring in x over Rational Field + sage: I.interreduction(RStrat=R) # needs sage.combinat Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field - sage: R - Symmetric Reduction Strategy in Infinite polynomial ring in x over Rational Field, modulo + sage: R # needs sage.combinat + Symmetric Reduction Strategy in + Infinite polynomial ring in x over Rational Field, modulo x_1^2, x_2 + x_1 sage: R = SymmetricReductionStrategy(X, [x[1]^2]) - sage: I.interreduction(RStrat=R) + sage: I.interreduction(RStrat=R) # needs sage.combinat Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational Field """ @@ -573,7 +577,7 @@ def interreduced_basis(self): sage: X. = InfinitePolynomialRing(QQ) sage: I = X * (x[1] + x[2], x[1]*x[2]) - sage: I.interreduced_basis() # optional - sage.combinat + sage: I.interreduced_basis() # needs sage.combinat [-x_1^2, x_2 + x_1] """ @@ -620,12 +624,12 @@ def symmetrisation(self, N=None, tailreduce=False, report=None, use_full_group=F sage: X. = InfinitePolynomialRing(QQ) sage: I = X * (x[1] + x[2], x[1]*x[2]) - sage: I.symmetrisation() # optional - sage.combinat + sage: I.symmetrisation() # needs sage.combinat Symmetric Ideal (-x_1^2, x_2 + x_1) of Infinite polynomial ring in x over Rational Field - sage: I.symmetrisation(N=3) # optional - sage.combinat + sage: I.symmetrisation(N=3) # needs sage.combinat Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field - sage: I.symmetrisation(N=3, use_full_group=True) # optional - sage.combinat + sage: I.symmetrisation(N=3, use_full_group=True) # needs sage.combinat Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field """ @@ -680,7 +684,7 @@ def symmetric_basis(self): sage: X. = InfinitePolynomialRing(QQ) sage: I = X * (x[1] + x[2], x[1]*x[2]) - sage: I.symmetric_basis() # optional - sage.combinat + sage: I.symmetric_basis() # needs sage.combinat [x_1^2, x_2 + x_1] """ @@ -807,10 +811,10 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= sage: X. = InfinitePolynomialRing(QQ) sage: I1 = X * (x[1] + x[2], x[1]*x[2]) - sage: I1.groebner_basis() # optional - sage.combinat + sage: I1.groebner_basis() # needs sage.combinat [x_1] sage: I2 = X * (y[1]^2*y[3] + y[1]*x[3]) - sage: I2.groebner_basis() # optional - sage.combinat + sage: I2.groebner_basis() # needs sage.combinat [x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2] Note that a symmetric Groebner basis of a principal ideal is @@ -820,13 +824,13 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= and Hillar, the result is the same, but the computation takes much longer:: - sage: I2.groebner_basis(use_full_group=True) # optional - sage.combinat + sage: I2.groebner_basis(use_full_group=True) # needs sage.combinat [x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2] Last, we demonstrate how the report on the progress of computations looks like:: - sage: I1.groebner_basis(report=True, reduced=True) # optional - sage.combinat + sage: I1.groebner_basis(report=True, reduced=True) # needs sage.combinat Symmetric interreduction [1/2] > [2/2] :> @@ -899,7 +903,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= sage: R. = InfinitePolynomialRing(ZZ) sage: I = R * [x[1] + x[2], y[1]] - sage: I.groebner_basis() # optional - sage.combinat + sage: I.groebner_basis() # needs sage.combinat Traceback (most recent call last): ... TypeError: The base ring (= Integer Ring) must be a field @@ -908,19 +912,19 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= In an earlier version, the following examples failed:: - sage: X. = InfinitePolynomialRing(GF(5), order='degrevlex') # optional - sage.rings.finite_rings + sage: X. = InfinitePolynomialRing(GF(5), order='degrevlex') sage: I = ['-2*y_0^2 + 2*z_0^2 + 1', ....: '-y_0^2 + 2*y_0*z_0 - 2*z_0^2 - 2*z_0 - 1', ....: 'y_0*z_0 + 2*z_0^2 - 2*z_0 - 1', ....: 'y_0^2 + 2*y_0*z_0 - 2*z_0^2 + 2*z_0 - 2', ....: '-y_0^2 - 2*y_0*z_0 - z_0^2 + y_0 - 1'] * X - sage: I.groebner_basis() # optional - sage.combinat sage.rings.finite_rings + sage: I.groebner_basis() # needs sage.combinat [1] - sage: Y. = InfinitePolynomialRing(GF(3), order='degrevlex', # optional - sage.rings.finite_rings + sage: Y. = InfinitePolynomialRing(GF(3), order='degrevlex', ....: implementation='sparse') sage: I = ['-y_3'] * Y - sage: I.groebner_basis() # optional - sage.combinat sage.rings.finite_rings + sage: I.groebner_basis() # needs sage.combinat [y_1] """ diff --git a/src/sage/rings/polynomial/symmetric_reduction.pyx b/src/sage/rings/polynomial/symmetric_reduction.pyx index 4e5c8b6cf35..6cc00047de8 100644 --- a/src/sage/rings/polynomial/symmetric_reduction.pyx +++ b/src/sage/rings/polynomial/symmetric_reduction.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.libs.singular r""" Symmetric Reduction of Infinite Polynomials @@ -79,15 +80,15 @@ change variable index 1 into 2 and 2 into 3. So, we add this to Infinite polynomial ring in x, y over Rational Field, modulo x_2*y_1^2, x_1*y_2^2 - sage: S.reduce(p) # optional - sage.combinat + sage: S.reduce(p) # needs sage.combinat y_3*y_1 The next example shows that tail reduction is not done, unless it is explicitly advised:: - sage: S.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # optional - sage.combinat + sage: S.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # needs sage.combinat x_3 + 2*x_2*y_1^2 + 3*x_1*y_2^2 - sage: S.tailreduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # optional - sage.combinat + sage: S.tailreduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # needs sage.combinat x_3 However, it is possible to ask for tailreduction already when the @@ -100,7 +101,7 @@ Symmetric Reduction Strategy is created:: x_2*y_1^2, x_1*y_2^2 with tailreduction - sage: S2.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # optional - sage.combinat + sage: S2.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1]) # needs sage.combinat x_3 """ @@ -145,7 +146,7 @@ cdef class SymmetricReductionStrategy: sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]], good_input=True) sage: S.reduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) y_3 + 3*y_2^2*y_1 + 2*y_2*y_1^2 - sage: S.tailreduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) # optional - sage.combinat + sage: S.tailreduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1]) # needs sage.combinat y_3 """ @@ -439,8 +440,8 @@ cdef class SymmetricReductionStrategy: Note that the first added polynomial will be simplified when adding a suitable second polynomial:: - sage: S.add_generator(x[2] + x[1]) # optional - sage.combinat - sage: S # optional - sage.combinat + sage: S.add_generator(x[2] + x[1]) # needs sage.combinat + sage: S # needs sage.combinat Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo y_3, @@ -450,17 +451,18 @@ cdef class SymmetricReductionStrategy: polynomial. This can be avoided by specifying the optional parameter 'good_input':: - sage: S.add_generator(y[2] + y[1]*x[2]) # optional - sage.combinat - sage: S # optional - sage.combinat + sage: # needs sage.combinat + sage: S.add_generator(y[2] + y[1]*x[2]) + sage: S Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo y_3, x_1*y_1 - y_2, x_2 + x_1 - sage: S.reduce(x[3] + x[2]) # optional - sage.combinat + sage: S.reduce(x[3] + x[2]) -2*x_1 - sage: S.add_generator(x[3] + x[2], good_input=True) # optional - sage.combinat - sage: S # optional - sage.combinat + sage: S.add_generator(x[3] + x[2], good_input=True) + sage: S Symmetric Reduction Strategy in Infinite polynomial ring in x, y over Rational Field, modulo y_3, @@ -637,7 +639,7 @@ cdef class SymmetricReductionStrategy: sage: S = SymmetricReductionStrategy(X, [y[3]]) sage: S.reduce(y[4]*x[1] + y[1]*x[4]) x_4*y_1 + x_1*y_4 - sage: S.tailreduce(y[4]*x[1] + y[1]*x[4]) # optional - sage.combinat + sage: S.tailreduce(y[4]*x[1] + y[1]*x[4]) # needs sage.combinat x_4*y_1 Last, we demonstrate the 'report' option:: @@ -651,7 +653,7 @@ cdef class SymmetricReductionStrategy: y_3 + y_2, x_2 + y_1, x_1*y_2 + y_4 + y_1^2 - sage: S.tailreduce(x[3] + x[1]*y[3] + x[1]*y[1], report=True) # optional - sage.combinat + sage: S.tailreduce(x[3] + x[1]*y[3] + x[1]*y[1], report=True) # needs sage.combinat T[3]:::> T[3]:> x_1*y_1 - y_2 + y_1^2 - y_1 diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index 39c103e215d..a3321cf1bb2 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -272,22 +272,23 @@ EXAMPLES:: - sage: m = matrix(2, [2,3,0,1]); m # optional - sage.modules + sage: # needs sage.modules + sage: m = matrix(2, [2,3,0,1]); m [2 3] [0 1] - sage: T = TermOrder(m); T # optional - sage.modules + sage: T = TermOrder(m); T Matrix term order with matrix [2 3] [0 1] - sage: P. = PolynomialRing(QQ, 2, order=T) # optional - sage.modules - sage: P # optional - sage.modules + sage: P. = PolynomialRing(QQ, 2, order=T) + sage: P Multivariate Polynomial Ring in a, b over Rational Field - sage: a > b # optional - sage.modules + sage: a > b False - sage: a^3 < b^2 # optional - sage.modules + sage: a^3 < b^2 True - sage: S = TermOrder('M(2,3,0,1)') # optional - sage.modules - sage: T == S # optional - sage.modules + sage: S = TermOrder('M(2,3,0,1)') + sage: T == S True Additionally all these monomial orders may be combined to product or block @@ -657,7 +658,7 @@ def __init__(self, name='lex', n=0, force=False): sage: T = TermOrder('degrevlex') sage: R. = PolynomialRing(QQ, order=T) - sage: R._singular_() # optional - sage.libs.singular + sage: R._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 3 @@ -673,7 +674,7 @@ def __init__(self, name='lex', n=0, force=False): sage: S = R.change_ring(order=T2) sage: S == T False - sage: S._singular_() # optional - sage.libs.singular + sage: S._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 3 @@ -683,11 +684,11 @@ def __init__(self, name='lex', n=0, force=False): Check that :trac:`29635` is fixed:: - sage: T = PolynomialRing(GF(101^5), 'u,v,w', # optional - sage.rings.finite_rings + sage: T = PolynomialRing(GF(101^5), 'u,v,w', # needs sage.rings.finite_rings ....: order=TermOrder('degneglex')).term_order() - sage: T.singular_str() # optional - sage.rings.finite_rings + sage: T.singular_str() # needs sage.rings.finite_rings '(a(1:3),ls(3))' - sage: (T + T).singular_str() # optional - sage.rings.finite_rings + sage: (T + T).singular_str() # needs sage.rings.finite_rings '(a(1:3),ls(3),a(1:3),ls(3))' """ if isinstance(name, TermOrder): @@ -930,10 +931,10 @@ def sortkey_matrix(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') # optional - sage.rings.number_field - sage: y > x^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') # needs sage.rings.number_field + sage: y > x^2 # indirect doctest # needs sage.rings.number_field True - sage: y > x^3 # optional - sage.rings.number_field + sage: y > x^3 # needs sage.rings.number_field False """ return tuple(sum(l * r for l, r in zip(row, f)) @@ -950,10 +951,10 @@ def sortkey_lex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='lex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='lex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field True - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field True """ return f @@ -969,10 +970,10 @@ def sortkey_invlex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='invlex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='invlex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field False - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field True """ return f.reversed() @@ -988,10 +989,10 @@ def sortkey_deglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='deglex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='deglex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field False - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field True """ @@ -1008,10 +1009,10 @@ def sortkey_degrevlex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='degrevlex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='degrevlex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field False - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field True """ @@ -1030,10 +1031,10 @@ def sortkey_neglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='neglex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='neglex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field False - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field False """ return tuple(-v for v in f) @@ -1049,10 +1050,10 @@ def sortkey_negdegrevlex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='negdegrevlex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='negdegrevlex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field True - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field False """ return (-sum(f.nonzero_values(sort=False)), @@ -1069,10 +1070,10 @@ def sortkey_negdeglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='negdeglex') # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='negdeglex') # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field True - sage: x > 1 # optional - sage.rings.number_field + sage: x > 1 # needs sage.rings.number_field False """ return (-sum(f.nonzero_values(sort=False)), f) @@ -1088,10 +1089,10 @@ def sortkey_degneglex(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='degneglex') # optional - sage.rings.number_field - sage: x*y > y*z # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='degneglex') # needs sage.rings.number_field + sage: x*y > y*z # indirect doctest # needs sage.rings.number_field False - sage: x*y > x # optional - sage.rings.number_field + sage: x*y > x # needs sage.rings.number_field True """ return (sum(f.nonzero_values(sort=False)), tuple(-v for v in f)) @@ -1108,10 +1109,10 @@ def sortkey_wdegrevlex(self, f): EXAMPLES:: sage: t = TermOrder('wdegrevlex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order=t) # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field False - sage: x^2 > y^3 # optional - sage.rings.number_field + sage: x^2 > y^3 # needs sage.rings.number_field True """ return (sum(l * r for (l, r) in zip(f, self._weights)), @@ -1129,10 +1130,10 @@ def sortkey_wdeglex(self, f): EXAMPLES:: sage: t = TermOrder('wdeglex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order=t) # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field False - sage: x > y # optional - sage.rings.number_field + sage: x > y # needs sage.rings.number_field True """ return (sum(l * r for (l, r) in zip(f, self._weights)), f) @@ -1149,10 +1150,10 @@ def sortkey_negwdeglex(self, f): EXAMPLES:: sage: t = TermOrder('negwdeglex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order=t) # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field True - sage: x^2 > y^3 # optional - sage.rings.number_field + sage: x^2 > y^3 # needs sage.rings.number_field True """ return (-sum(l * r for (l, r) in zip(f, self._weights)), f) @@ -1169,10 +1170,10 @@ def sortkey_negwdegrevlex(self, f): EXAMPLES:: sage: t = TermOrder('negwdegrevlex',(3,2)) - sage: P. = PolynomialRing(QQbar, 2, order=t) # optional - sage.rings.number_field - sage: x > y^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order=t) # needs sage.rings.number_field + sage: x > y^2 # indirect doctest # needs sage.rings.number_field True - sage: x^2 > y^3 # optional - sage.rings.number_field + sage: x^2 > y^3 # needs sage.rings.number_field True """ return (-sum(l * r for (l, r) in zip(f, self._weights)), @@ -1189,19 +1190,19 @@ def sortkey_block(self, f): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 6, # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 6, # needs sage.rings.number_field ....: order='degrevlex(3),degrevlex(3)') - sage: a > c^4 # indirect doctest # optional - sage.rings.number_field + sage: a > c^4 # indirect doctest # needs sage.rings.number_field False - sage: a > e^4 # optional - sage.rings.number_field + sage: a > e^4 # needs sage.rings.number_field True TESTS: Check that the issue in :trac:`27139` is fixed:: - sage: R. = PolynomialRing(AA, order='lex(2),lex(2)') # optional - sage.rings.number_field - sage: x > y # optional - sage.rings.number_field + sage: R. = PolynomialRing(AA, order='lex(2),lex(2)') # needs sage.rings.number_field + sage: x > y # needs sage.rings.number_field True """ key = tuple() @@ -1225,10 +1226,10 @@ def greater_tuple_matrix(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') # optional - sage.rings.number_field - sage: y > x^2 # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 2, order='m(1,3,1,0)') # needs sage.rings.number_field + sage: y > x^2 # indirect doctest # needs sage.rings.number_field True - sage: y > x^3 # optional - sage.rings.number_field + sage: y > x^3 # needs sage.rings.number_field False """ for row in self._matrix: @@ -1254,8 +1255,8 @@ def greater_tuple_lex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='lex') # optional - sage.rings.number_field - sage: f = x + y^2; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='lex') # needs sage.rings.number_field + sage: f = x + y^2; f.lm() # indirect doctest # needs sage.rings.number_field x This method is called by the lm/lc/lt methods of @@ -1276,10 +1277,10 @@ def greater_tuple_invlex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='invlex') # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='invlex') # needs sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # needs sage.rings.number_field y - sage: f = y + x^2; f.lm() # optional - sage.rings.number_field + sage: f = y + x^2; f.lm() # needs sage.rings.number_field y This method is called by the lm/lc/lt methods of @@ -1300,10 +1301,10 @@ def greater_tuple_deglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='deglex') # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='deglex') # needs sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # needs sage.rings.number_field x - sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field + sage: f = x + y^2*z; f.lm() # needs sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1326,10 +1327,10 @@ def greater_tuple_degrevlex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='degrevlex') # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='degrevlex') # needs sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # needs sage.rings.number_field x - sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field + sage: f = x + y^2*z; f.lm() # needs sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1352,12 +1353,13 @@ def greater_tuple_negdegrevlex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='negdegrevlex') # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='negdegrevlex') + sage: f = x + y; f.lm() # indirect doctest x - sage: f = x + x^2; f.lm() # optional - sage.rings.number_field + sage: f = x + x^2; f.lm() x - sage: f = x^2*y*z^2 + x*y^3*z; f.lm() # optional - sage.rings.number_field + sage: f = x^2*y*z^2 + x*y^3*z; f.lm() x*y^3*z This method is called by the lm/lc/lt methods of @@ -1380,12 +1382,13 @@ def greater_tuple_negdeglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='negdeglex') # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='negdeglex') + sage: f = x + y; f.lm() # indirect doctest x - sage: f = x + x^2; f.lm() # optional - sage.rings.number_field + sage: f = x + x^2; f.lm() x - sage: f = x^2*y*z^2 + x*y^3*z; f.lm() # optional - sage.rings.number_field + sage: f = x^2*y*z^2 + x*y^3*z; f.lm() x^2*y*z^2 This method is called by the lm/lc/lt methods of @@ -1408,10 +1411,10 @@ def greater_tuple_degneglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 3, order='degneglex') # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order='degneglex') # needs sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # needs sage.rings.number_field y - sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field + sage: f = x + y^2*z; f.lm() # needs sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1437,11 +1440,11 @@ def greater_tuple_neglex(self,f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 6, # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 6, # needs sage.rings.number_field ....: order='degrevlex(3),degrevlex(3)') - sage: f = a + c^4; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: f = a + c^4; f.lm() # indirect doctest # needs sage.rings.number_field c^4 - sage: g = a + e^4; g.lm() # optional - sage.rings.number_field + sage: g = a + e^4; g.lm() # needs sage.rings.number_field a """ return (f < g) and f or g @@ -1460,10 +1463,10 @@ def greater_tuple_wdeglex(self,f,g): EXAMPLES:: sage: t = TermOrder('wdeglex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order=t) # needs sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # needs sage.rings.number_field y - sage: f = x*y + z; f.lm() # optional - sage.rings.number_field + sage: f = x*y + z; f.lm() # needs sage.rings.number_field x*y This method is called by the lm/lc/lt methods of @@ -1487,10 +1490,10 @@ def greater_tuple_wdegrevlex(self,f,g): EXAMPLES:: sage: t = TermOrder('wdegrevlex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order=t) # needs sage.rings.number_field + sage: f = x + y; f.lm() # indirect doctest # needs sage.rings.number_field y - sage: f = x + y^2*z; f.lm() # optional - sage.rings.number_field + sage: f = x + y^2*z; f.lm() # needs sage.rings.number_field y^2*z This method is called by the lm/lc/lt methods of @@ -1513,13 +1516,14 @@ def greater_tuple_negwdeglex(self,f,g): EXAMPLES:: + sage: # needs sage.rings.number_field sage: t = TermOrder('negwdeglex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order=t) + sage: f = x + y; f.lm() # indirect doctest x - sage: f = x + x^2; f.lm() # optional - sage.rings.number_field + sage: f = x + x^2; f.lm() x - sage: f = x^3 + z; f.lm() # optional - sage.rings.number_field + sage: f = x^3 + z; f.lm() x^3 This method is called by the lm/lc/lt methods of @@ -1542,13 +1546,14 @@ def greater_tuple_negwdegrevlex(self,f,g): EXAMPLES:: + sage: # needs sage.rings.number_field sage: t = TermOrder('negwdegrevlex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, 3, order=t) # optional - sage.rings.number_field - sage: f = x + y; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 3, order=t) + sage: f = x + y; f.lm() # indirect doctest x - sage: f = x + x^2; f.lm() # optional - sage.rings.number_field + sage: f = x + x^2; f.lm() x - sage: f = x^3 + z; f.lm() # optional - sage.rings.number_field + sage: f = x^3 + z; f.lm() x^3 This method is called by the lm/lc/lt methods of @@ -1574,11 +1579,11 @@ def greater_tuple_block(self, f,g): EXAMPLES:: - sage: P. = PolynomialRing(QQbar, 6, # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, 6, # needs sage.rings.number_field ....: order='degrevlex(3),degrevlex(3)') - sage: f = a + c^4; f.lm() # indirect doctest # optional - sage.rings.number_field + sage: f = a + c^4; f.lm() # indirect doctest # needs sage.rings.number_field c^4 - sage: g = a + e^4; g.lm() # optional - sage.rings.number_field + sage: g = a + e^4; g.lm() # needs sage.rings.number_field a """ n = 0 @@ -1605,8 +1610,8 @@ def tuple_weight(self, f): EXAMPLES:: sage: t = TermOrder('wdeglex',(1,2,3)) - sage: P. = PolynomialRing(QQbar, order=t) # optional - sage.rings.number_field - sage: P.term_order().tuple_weight([3,2,1]) # optional - sage.rings.number_field + sage: P. = PolynomialRing(QQbar, order=t) # needs sage.rings.number_field + sage: P.term_order().tuple_weight([3,2,1]) # needs sage.rings.number_field 10 """ return sum(l*r for (l,r) in zip(f,self._weights)) @@ -1651,12 +1656,12 @@ def singular_str(self): EXAMPLES:: - sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), 10, names='x', ....: order='lex(3),deglex(5),lex(2)') - sage: T = P.term_order() # optional - sage.rings.finite_rings - sage: T.singular_str() # optional - sage.rings.finite_rings + sage: T = P.term_order() + sage: T.singular_str() '(lp(3),Dp(5),lp(2))' - sage: P._singular_() # optional - sage.rings.finite_rings + sage: P._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: ZZ/127 // number of vars : 10 @@ -1682,7 +1687,7 @@ def singular_str(self): sage: T = P.term_order() sage: T.singular_str() '(a(1:2),ls(2),a(1:2),ls(2))' - sage: P._singular_() # optional - sage.libs.singular + sage: P._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1704,7 +1709,7 @@ def singular_str(self): sage: T = TermOrder("degneglex", 2) + TermOrder("degneglex", 2) sage: T._singular_ringorder_column = 0 sage: P = PolynomialRing(QQ, 4, names='x', order=T) - sage: P._singular_() # optional - sage.libs.singular + sage: P._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1722,7 +1727,7 @@ def singular_str(self): sage: T._singular_ringorder_column = 1 sage: P = PolynomialRing(QQ, 4, names='y', order=T) - sage: P._singular_() # optional - sage.libs.singular + sage: P._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1740,7 +1745,7 @@ def singular_str(self): sage: T._singular_ringorder_column = 2 sage: P = PolynomialRing(QQ, 4, names='z', order=T) - sage: P._singular_() # optional - sage.libs.singular + sage: P._singular_() # needs sage.libs.singular polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -1779,20 +1784,20 @@ def singular_moreblocks(self): EXAMPLES:: - sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), 10, names='x', ....: order='lex(3),deglex(5),lex(2)') - sage: T = P.term_order() # optional - sage.rings.finite_rings - sage: T.singular_moreblocks() # optional - sage.rings.finite_rings + sage: T = P.term_order() + sage: T.singular_moreblocks() 0 - sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), 10, names='x', ....: order='lex(3),degneglex(5),lex(2)') - sage: T = P.term_order() # optional - sage.rings.finite_rings - sage: T.singular_moreblocks() # optional - sage.rings.finite_rings + sage: T = P.term_order() + sage: T.singular_moreblocks() 1 - sage: P = PolynomialRing(GF(127), 10, names='x', # optional - sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), 10, names='x', ....: order='degneglex(5),degneglex(5)') - sage: T = P.term_order() # optional - sage.rings.finite_rings - sage: T.singular_moreblocks() # optional - sage.rings.finite_rings + sage: T = P.term_order() + sage: T.singular_moreblocks() 2 TESTS: @@ -1822,12 +1827,11 @@ def macaulay2_str(self): EXAMPLES:: - sage: P = PolynomialRing(GF(127), 8, names='x', # optional - sage.rings.finite_rings - ....: order='degrevlex(3),lex(5)') - sage: T = P.term_order() # optional - sage.rings.finite_rings - sage: T.macaulay2_str() # optional - sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), 8, names='x', order='degrevlex(3),lex(5)') + sage: T = P.term_order() + sage: T.macaulay2_str() '{GRevLex => 3,Lex => 5}' - sage: P._macaulay2_().options()['MonomialOrder'] # optional - macaulay2 # optional - sage.rings.finite_rings + sage: P._macaulay2_().options()['MonomialOrder'] # optional - macaulay2 {MonomialSize => 16 } {GRevLex => {1, 1, 1}} {Lex => 5 } @@ -1843,16 +1847,16 @@ def magma_str(self): EXAMPLES:: - sage: P = PolynomialRing(GF(127), 10, names='x', order='degrevlex') # optional - sage.rings.finite_rings - sage: magma(P) # optional - magma # optional - sage.rings.finite_rings + sage: P = PolynomialRing(GF(127), 10, names='x', order='degrevlex') + sage: magma(P) # optional - magma Polynomial ring of rank 10 over GF(127) Order: Graded Reverse Lexicographical Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 :: - sage: T = P.term_order() # optional - sage.rings.finite_rings - sage: T.magma_str() # optional - sage.rings.finite_rings + sage: T = P.term_order() + sage: T.magma_str() '"grevlex"' """ return self._magma_str @@ -1884,8 +1888,8 @@ def matrix(self): EXAMPLES:: - sage: t = TermOrder("M(1,2,0,1)") # optional - sage.modules - sage: t.matrix() # optional - sage.modules + sage: t = TermOrder("M(1,2,0,1)") # needs sage.modules + sage: t.matrix() # needs sage.modules [1 2] [0 1] @@ -2165,9 +2169,9 @@ def termorder_from_singular(S): EXAMPLES:: sage: from sage.rings.polynomial.term_order import termorder_from_singular - sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)') # optional - sage.libs.singular + sage: singular.eval('ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp)') # needs sage.libs.singular '' - sage: termorder_from_singular(singular) # optional - sage.libs.singular + sage: termorder_from_singular(singular) # needs sage.libs.singular Block term order with blocks: (Matrix term order with matrix [1 2] @@ -2179,7 +2183,8 @@ def termorder_from_singular(S): This information is reflected in ``_singular_ringorder_column`` attribute of the term order. :: - sage: singular.ring(0, '(x,y,z,w)', '(C,dp(2),lp(2))') # optional - sage.libs.singular + sage: # needs sage.libs.singular + sage: singular.ring(0, '(x,y,z,w)', '(C,dp(2),lp(2))') polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -2188,15 +2193,16 @@ def termorder_from_singular(S): // : names x y // block 3 : ordering lp // : names z w - sage: T = termorder_from_singular(singular) # optional - sage.libs.singular - sage: T # optional - sage.libs.singular + sage: T = termorder_from_singular(singular) + sage: T Block term order with blocks: (Degree reverse lexicographic term order of length 2, Lexicographic term order of length 2) - sage: T._singular_ringorder_column # optional - sage.libs.singular + sage: T._singular_ringorder_column 0 - sage: singular.ring(0, '(x,y,z,w)', '(c,dp(2),lp(2))') # optional - sage.libs.singular + sage: # needs sage.libs.singular + sage: singular.ring(0, '(x,y,z,w)', '(c,dp(2),lp(2))') polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 4 @@ -2205,12 +2211,12 @@ def termorder_from_singular(S): // : names x y // block 3 : ordering lp // : names z w - sage: T = termorder_from_singular(singular) # optional - sage.libs.singular - sage: T # optional - sage.libs.singular + sage: T = termorder_from_singular(singular) + sage: T Block term order with blocks: (Degree reverse lexicographic term order of length 2, Lexicographic term order of length 2) - sage: T._singular_ringorder_column # optional - sage.libs.singular + sage: T._singular_ringorder_column 1 TESTS: @@ -2218,16 +2224,17 @@ def termorder_from_singular(S): Check that ``degneglex`` term orders are converted correctly (:trac:`29635`):: - sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:4),ls(4))') # optional - sage.libs.singular - sage: termorder_from_singular(singular).singular_str() # optional - sage.libs.singular + sage: # needs sage.libs.singular + sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:4),ls(4))') + sage: termorder_from_singular(singular).singular_str() '(a(1:4),ls(4))' - sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),a(1:2),ls(2))') # optional - sage.libs.singular - sage: termorder_from_singular(singular).singular_str() # optional - sage.libs.singular + sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),a(1:2),ls(2))') + sage: termorder_from_singular(singular).singular_str() '(a(1:2),ls(2),a(1:2),ls(2))' - sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),C,a(1:2),ls(2))') # optional - sage.libs.singular - sage: termorder_from_singular(singular).singular_str() # optional - sage.libs.singular + sage: _ = singular.ring(0, '(x,y,z,w)', '(a(1:2),ls(2),C,a(1:2),ls(2))') + sage: termorder_from_singular(singular).singular_str() '(a(1:2),ls(2),C,a(1:2),ls(2))' - sage: PolynomialRing(QQ, 'x,y', order='degneglex')('x^2')._singular_().sage() # optional - sage.libs.singular + sage: PolynomialRing(QQ, 'x,y', order='degneglex')('x^2')._singular_().sage() x^2 """ from sage.rings.integer_ring import ZZ diff --git a/src/sage/rings/polynomial/toy_buchberger.py b/src/sage/rings/polynomial/toy_buchberger.py index c70cf1f90aa..4edd2491b6d 100644 --- a/src/sage/rings/polynomial/toy_buchberger.py +++ b/src/sage/rings/polynomial/toy_buchberger.py @@ -23,41 +23,42 @@ Consider Katsura-6 with respect to a ``degrevlex`` ordering. :: + sage: # needs sage.libs.singular sage.rings.finite_rings sage: from sage.rings.polynomial.toy_buchberger import * - sage: P. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P, 6) # optional - sage.rings.finite_rings - - sage: g1 = buchberger(I) # optional - sage.rings.finite_rings - sage: g2 = buchberger_improved(I) # optional - sage.rings.finite_rings - sage: g3 = I.groebner_basis() # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(32003)) + sage: I = sage.rings.ideal.Katsura(P, 6) + sage: g1 = buchberger(I) + sage: g2 = buchberger_improved(I) + sage: g3 = I.groebner_basis() All algorithms actually compute a Groebner basis:: - sage: Ideal(g1).basis_is_groebner() # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings + sage: Ideal(g1).basis_is_groebner() True - sage: Ideal(g2).basis_is_groebner() # optional - sage.rings.finite_rings + sage: Ideal(g2).basis_is_groebner() True - sage: Ideal(g3).basis_is_groebner() # optional - sage.rings.finite_rings + sage: Ideal(g3).basis_is_groebner() True The results are correct:: - sage: Ideal(g1) == Ideal(g2) == Ideal(g3) # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings + sage: Ideal(g1) == Ideal(g2) == Ideal(g3) True If ``get_verbose()`` is `\ge 1`, a protocol is provided:: + sage: # needs sage.libs.singular sage.rings.finite_rings sage: from sage.misc.verbose import set_verbose sage: set_verbose(1) - sage: P. = PolynomialRing(GF(127)) # optional - sage.rings.finite_rings - sage: I = sage.rings.ideal.Katsura(P) # optional - sage.rings.finite_rings + sage: P. = PolynomialRing(GF(127)) + sage: I = sage.rings.ideal.Katsura(P) // sage... ideal - - sage: I # optional - sage.rings.finite_rings + sage: I Ideal (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b) of Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 - - sage: buchberger(I) # random # optional - sage.rings.finite_rings + sage: buchberger(I) # random (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a) => -2*b^2 - 6*b*c - 6*c^2 + b + 2*c G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c]) @@ -118,17 +119,19 @@ The original Buchberger algorithm performs 15 useless reductions to zero for this example:: - sage: gb = buchberger(I) # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings + sage: gb = buchberger(I) ... 15 reductions to zero. The 'improved' Buchberger algorithm in contrast only performs 1 reduction to zero:: - sage: gb = buchberger_improved(I) # optional - sage.rings.finite_rings + sage: # needs sage.libs.singular sage.rings.finite_rings + sage: gb = buchberger_improved(I) ... 1 reductions to zero. - sage: sorted(gb) # optional - sage.rings.finite_rings + sage: sorted(gb) [a + 2*b + 2*c - 1, b*c + 52*c^2 + 38*b + 25*c, b^2 - 26*c^2 - 51*b + 51*c, c^3 + 22*c^2 - 55*b + 49*c] @@ -193,10 +196,10 @@ def buchberger(F): sage: R. = PolynomialRing(QQ) sage: I = R.ideal([x^2 - z - 1, z^2 - y - 1, x*y^2 - x - 1]) sage: set_verbose(0) - sage: gb = buchberger(I) # optional - sage.libs.singular - sage: gb.is_groebner() # optional - sage.libs.singular + sage: gb = buchberger(I) # needs sage.libs.singular + sage: gb.is_groebner() # needs sage.libs.singular True - sage: gb.ideal() == I # optional - sage.libs.singular + sage: gb.ideal() == I # needs sage.libs.singular True """ G = set(F.gens()) @@ -251,7 +254,7 @@ def buchberger_improved(F): sage: from sage.rings.polynomial.toy_buchberger import buchberger_improved sage: R. = PolynomialRing(QQ) sage: set_verbose(0) - sage: sorted(buchberger_improved(R.ideal([x^4 - y - z, x*y*z - 1]))) # optional - sage.libs.singular + sage: sorted(buchberger_improved(R.ideal([x^4 - y - z, x*y*z - 1]))) # needs sage.libs.singular [x*y*z - 1, x^3 - y^2*z - y*z^2, y^3*z^2 + y^2*z^3 - x^2] """ F = inter_reduction(F.gens()) @@ -421,10 +424,10 @@ def inter_reduction(Q): :: sage: P. = QQ[] - sage: reduced = inter_reduction(set([x^2 - 5*y^2, x^3])) # optional - sage.libs.singular - sage: reduced == set([x*y^2, x^2 - 5*y^2]) # optional - sage.libs.singular + sage: reduced = inter_reduction(set([x^2 - 5*y^2, x^3])) # needs sage.libs.singular + sage: reduced == set([x*y^2, x^2 - 5*y^2]) # needs sage.libs.singular True - sage: reduced == inter_reduction(set([2*(x^2 - 5*y^2), x^3])) # optional - sage.libs.singular + sage: reduced == inter_reduction(set([2*(x^2 - 5*y^2), x^3])) # needs sage.libs.singular True """ if not Q: diff --git a/src/sage/rings/polynomial/toy_d_basis.py b/src/sage/rings/polynomial/toy_d_basis.py index 660922aaf64..393eb0452b2 100644 --- a/src/sage/rings/polynomial/toy_d_basis.py +++ b/src/sage/rings/polynomial/toy_d_basis.py @@ -25,7 +25,7 @@ sage: fx = f.derivative(x) sage: fy = f.derivative(y) sage: I = B.ideal([B(f), B(fx), B(fy)]) - sage: I.groebner_basis() # optional - sage.libs.singular + sage: I.groebner_basis() # needs sage.libs.singular [1] Since the output is 1, we know that there are no generic @@ -102,7 +102,7 @@ sage: I.change_ring(P.change_ring(GF(103))).groebner_basis() [z - 18, y + 8, x + 39] - sage: I.change_ring( P.change_ring(GF(27173681))).groebner_basis() + sage: I.change_ring( P.change_ring(GF(27173681))).groebner_basis() # needs sage.libs.pari [z + 10380032, y + 3186055, x - 536027] Of course, modulo any other prime the Groebner basis is trivial so diff --git a/src/sage/rings/polynomial/toy_variety.py b/src/sage/rings/polynomial/toy_variety.py index 16ccfb6cf8c..5b51dc5eb00 100644 --- a/src/sage/rings/polynomial/toy_variety.py +++ b/src/sage/rings/polynomial/toy_variety.py @@ -100,7 +100,7 @@ def coefficient_matrix(polys): sage: from sage.rings.polynomial.toy_variety import coefficient_matrix sage: R. = PolynomialRing(QQ) - sage: coefficient_matrix([x^2 + 1, y^2 + 1, x*y + 1]) # optional - sage.modules + sage: coefficient_matrix([x^2 + 1, y^2 + 1, x*y + 1]) # needs sage.modules [1 0 0 1] [0 0 1 1] [0 1 0 1] @@ -159,12 +159,12 @@ def is_linearly_dependent(polys) -> bool: sage: R. = PolynomialRing(QQ) sage: B = [x^2 + 1, y^2 + 1, x*y + 1] sage: p = 3*B[0] - 2*B[1] + B[2] - sage: is_linearly_dependent(B + [p]) # optional - sage.modules + sage: is_linearly_dependent(B + [p]) # needs sage.modules True - sage: p = x*B[0] # optional - sage.modules - sage: is_linearly_dependent(B + [p]) # optional - sage.modules + sage: p = x*B[0] + sage: is_linearly_dependent(B + [p]) # needs sage.modules False - sage: is_linearly_dependent([]) # optional - sage.modules + sage: is_linearly_dependent([]) # needs sage.modules False """ if not polys: @@ -203,11 +203,12 @@ def linear_representation(p, polys): EXAMPLES:: + sage: # needs sage.modules sage.rings.finite_rings sage: from sage.rings.polynomial.toy_variety import linear_representation - sage: R. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings - sage: B = [x^2 + 1, y^2 + 1, x*y + 1] # optional - sage.rings.finite_rings - sage: p = 3*B[0] - 2*B[1] + B[2] # optional - sage.rings.finite_rings - sage: linear_representation(p, B) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(32003)) + sage: B = [x^2 + 1, y^2 + 1, x*y + 1] + sage: p = 3*B[0] - 2*B[1] + B[2] + sage: linear_representation(p, B) [3, 32001, 1] """ from sage.matrix.constructor import diagonal_matrix @@ -240,15 +241,16 @@ def triangular_factorization(B, n=-1): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.misc.verbose import set_verbose sage: set_verbose(0) sage: from sage.rings.polynomial.toy_variety import triangular_factorization - sage: R. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings - sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 # optional - sage.rings.finite_rings - sage: p2 = z^2 - z # optional - sage.rings.finite_rings - sage: p3 = (x-2)^2*(y-1)^3 # optional - sage.rings.finite_rings - sage: I = R.ideal(p1,p2,p3) # optional - sage.rings.finite_rings - sage: triangular_factorization(I.groebner_basis()) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(32003)) + sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 + sage: p2 = z^2 - z + sage: p3 = (x-2)^2*(y-1)^3 + sage: I = R.ideal(p1,p2,p3) + sage: triangular_factorization(I.groebner_basis()) # needs sage.libs.singular [[x^2 - 4*x + 4, y, z], [x^5 - 3*x^4 + 3*x^3 - x^2, y - 1, z], [x^2 - 4*x + 4, y, z - 1], @@ -314,15 +316,16 @@ def elim_pol(B, n=-1): EXAMPLES:: + sage: # needs sage.rings.finite_rings sage: from sage.misc.verbose import set_verbose sage: set_verbose(0) sage: from sage.rings.polynomial.toy_variety import elim_pol - sage: R. = PolynomialRing(GF(32003)) # optional - sage.rings.finite_rings - sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 # optional - sage.rings.finite_rings - sage: p2 = z^2 - z # optional - sage.rings.finite_rings - sage: p3 = (x-2)^2*(y-1)^3 # optional - sage.rings.finite_rings - sage: I = R.ideal(p1,p2,p3) # optional - sage.rings.finite_rings - sage: elim_pol(I.groebner_basis()) # optional - sage.rings.finite_rings + sage: R. = PolynomialRing(GF(32003)) + sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3 + sage: p2 = z^2 - z + sage: p3 = (x-2)^2*(y-1)^3 + sage: I = R.ideal(p1,p2,p3) + sage: elim_pol(I.groebner_basis()) # needs sage.libs.singular z^2 - z """ # type checking in a probably vain attempt to avoid stupid errors diff --git a/src/sage/rings/power_series_ring_element.pyx b/src/sage/rings/power_series_ring_element.pyx index 85ad48798eb..54314d538ed 100644 --- a/src/sage/rings/power_series_ring_element.pyx +++ b/src/sage/rings/power_series_ring_element.pyx @@ -101,7 +101,6 @@ from .infinity import infinity, is_Infinite from sage.rings.rational_field import QQ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -import sage.rings.polynomial.polynomial_element import sage.misc.misc import sage.arith.all as arith import sage.misc.latex @@ -112,9 +111,6 @@ from sage.categories.fields import Fields _Fields = Fields() from sage.misc.derivative import multi_derivative - -Polynomial = sage.rings.polynomial.polynomial_element.Polynomial_generic_dense - from sage.structure.element cimport AlgebraElement, RingElement from sage.structure.richcmp cimport richcmp