From eb3a270968597fcec607a9f1c5d8d2ca42725e88 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Dec 2022 22:14:24 -0800 Subject: [PATCH 01/19] sage.structure.element: Add ABCs Polynomial, MPolynomial, use for isinstance testing --- src/sage/combinat/kazhdan_lusztig.py | 4 ++-- src/sage/combinat/sf/sfa.py | 4 ++-- src/sage/crypto/boolean_function.pyx | 4 ++-- src/sage/crypto/sbox.pyx | 4 ++-- src/sage/crypto/stream.py | 4 ++-- src/sage/groups/affine_gps/group_element.py | 4 ++-- .../groups/perm_gps/permgroup_element.pyx | 4 ++-- .../characteristic_cohomology_class.py | 6 +++--- src/sage/quadratic_forms/constructions.py | 4 ++-- .../rings/finite_rings/element_ntl_gf2e.pyx | 2 +- .../rings/finite_rings/finite_field_base.pyx | 4 ++-- .../finite_rings/finite_field_constructor.py | 4 ++-- .../rings/finite_rings/finite_field_givaro.py | 4 ++-- .../finite_rings/finite_field_ntl_gf2e.py | 4 ++-- src/sage/rings/finite_rings/residue_field.pyx | 4 ++-- .../rings/function_field/function_field.py | 4 ++-- src/sage/rings/laurent_series_ring.py | 2 +- src/sage/rings/number_field/number_field.py | 6 +++--- src/sage/rings/padics/factory.py | 8 ++++---- .../rings/padics/padic_template_element.pxi | 4 ++-- .../rings/polynomial/multi_polynomial.pxd | 4 ++-- .../rings/polynomial/multi_polynomial.pyx | 2 +- .../polynomial_padic_capped_relative_dense.py | 2 +- .../rings/polynomial/polynomial_element.pxd | 5 +++-- .../rings/polynomial/polynomial_element.pyx | 12 +++++------ .../polynomial_integer_dense_ntl.pyx | 4 +--- src/sage/rings/qqbar.py | 4 ++-- .../schemes/berkovich/berkovich_cp_element.py | 6 +++--- src/sage/schemes/cyclic_covers/constructor.py | 4 ++-- .../elliptic_curves/ell_curve_isogeny.py | 4 ++-- .../hyperelliptic_curves/constructor.py | 4 ++-- .../hyperelliptic_curves/jacobian_homset.py | 8 ++++---- .../hyperelliptic_curves/monsky_washnitzer.py | 6 +++--- src/sage/structure/element.pxd | 6 ++++++ src/sage/structure/element.pyx | 20 +++++++++++++++++++ 35 files changed, 100 insertions(+), 75 deletions(-) diff --git a/src/sage/combinat/kazhdan_lusztig.py b/src/sage/combinat/kazhdan_lusztig.py index a8561253b28..75995aa34e4 100644 --- a/src/sage/combinat/kazhdan_lusztig.py +++ b/src/sage/combinat/kazhdan_lusztig.py @@ -20,7 +20,7 @@ #***************************************************************************** -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.misc.cachefunc import cached_method from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial from sage.structure.sage_object import SageObject @@ -75,7 +75,7 @@ def __init__(self, W, q, trace=False): self._trace = trace self._one = W.one() self._base_ring = q.parent() - if is_Polynomial(q): + if isinstance(q, Polynomial): self._base_ring_type = "polynomial" elif isinstance(q, LaurentPolynomial): self._base_ring_type = "laurent" diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 040dd78f4d3..8144233329e 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -217,7 +217,7 @@ from sage.rings.integer import Integer from sage.rings.infinity import infinity from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.rings.polynomial.multi_polynomial import is_MPolynomial from sage.combinat.partition import _Partitions, Partitions, Partitions_n, Partition from sage.categories.hopf_algebras import HopfAlgebras @@ -6404,7 +6404,7 @@ def _nonnegative_coefficients(x): sage: _nonnegative_coefficients(x^2-4) False """ - if is_Polynomial(x) or is_MPolynomial(x): + if isinstance(x, Polynomial) or is_MPolynomial(x): return all(c >= 0 for c in x.coefficients(sparse=False)) else: return x >= 0 diff --git a/src/sage/crypto/boolean_function.pyx b/src/sage/crypto/boolean_function.pyx index a9ea665475c..1358ae1b958 100644 --- a/src/sage/crypto/boolean_function.pyx +++ b/src/sage/crypto/boolean_function.pyx @@ -40,7 +40,7 @@ from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.polynomial.pbori.pbori import BooleanPolynomial from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.misc.superseded import deprecated_function_alias @@ -327,7 +327,7 @@ cdef class BooleanFunction(SageObject): bitset_init(self._truth_table, (1<1 or not is_Polynomial(polynomial): + from sage.structure.element import Polynomial + if polynomial.parent().ngens()>1 or not isinstance(polynomial, Polynomial): raise TypeError("polynomial must be univariate a polynomial") if names is None: names = (polynomial.variable_name(), ) diff --git a/src/sage/rings/laurent_series_ring.py b/src/sage/rings/laurent_series_ring.py index 9cad038840c..d3660288b4c 100644 --- a/src/sage/rings/laurent_series_ring.py +++ b/src/sage/rings/laurent_series_ring.py @@ -466,7 +466,7 @@ def _element_constructor_(self, x, n=0, prec=infinity): x^-3 """ from sage.rings.fraction_field_element import is_FractionFieldElement - from sage.rings.polynomial.polynomial_element import is_Polynomial + from sage.structure.element import Polynomial from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial from sage.structure.element import parent from sage.libs.pari.all import pari_gen diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index fbdd43dfabb..31572ab1c2e 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -114,7 +114,7 @@ import sage.interfaces.gap import sage.rings.complex_mpfr -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial import sage.rings.real_mpfr import sage.rings.real_mpfi import sage.rings.complex_double @@ -647,7 +647,7 @@ def create_key_and_extra_args(self, polynomial, name, check, embedding, latex_na raise TypeError("You must specify the name of the generator.") name = normalize_names(1, name) - if not is_Polynomial(polynomial): + if not isinstance(polynomial, Polynomial): try: polynomial = polynomial.polynomial(QQ) except (AttributeError, TypeError): @@ -868,7 +868,7 @@ def NumberFieldTower(polynomials, names, check=True, embeddings=None, latex_name f = polynomials[0] name = names[0] w = NumberFieldTower(polynomials[1:], names=names[1:], check=check, embeddings=embeddings[1:], latex_names=latex_names[1:], assume_disc_small=assume_disc_small, maximize_at_primes=maximize_at_primes, structures=structures[1:]) - var = f.variable_name() if is_Polynomial(f) else 'x' + var = f.variable_name() if isinstance(f, Polynomial) else 'x' R = w[var] # polynomial ring return w.extension(R(f), name, check=check, embedding=embeddings[0], structure=structures[0], latex_name=latex_names[0]) # currently, extension does not accept assume_disc_small, or maximize_at_primes diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index 044dcae0bed..72ee42a0e5b 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -35,7 +35,7 @@ from sage.rings.infinity import Infinity from sage.structure.factorization import Factorization from sage.rings.integer_ring import ZZ -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.structure.element import is_Element from .padic_base_leaves import (pAdicRingCappedRelative, pAdicRingCappedAbsolute, @@ -2535,7 +2535,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, if isinstance(names, (list, tuple)): names = names[0] from sage.structure.element import Expression - if not (modulus is None or is_Polynomial(modulus) or isinstance(modulus, Expression)): + if not (modulus is None or isinstance(modulus, Polynomial) or isinstance(modulus, Expression)): raise TypeError("modulus must be a polynomial") if names is not None and not isinstance(names, str): names = str(names) @@ -3278,7 +3278,7 @@ def create_key_and_extra_args(self, base, modulus, prec = None, print_mode = Non raise ValueError("symbolic expression must be in only one variable") exact_modulus = modulus.polynomial(base.exact_field()) approx_modulus = modulus.polynomial(base) - elif is_Polynomial(modulus): + elif isinstance(modulus, Polynomial): if modulus.parent().ngens() != 1: raise ValueError("must use univariate polynomial") exact_modulus = modulus.change_ring(base.exact_field()) @@ -3381,7 +3381,7 @@ def create_object(self, version, key, approx_modulus=None, shift_seed=None): from sage.structure.element import Expression if isinstance(premodulus, Expression): exact_modulus = premodulus.polynomial(base.exact_field()) - elif is_Polynomial(premodulus): + elif isinstance(premodulus, Polynomial): exact_modulus = premodulus.change_ring(base.exact_field()) show_prec = None else: diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi index fed8ac89f81..f3aa97e879b 100644 --- a/src/sage/rings/padics/padic_template_element.pxi +++ b/src/sage/rings/padics/padic_template_element.pxi @@ -36,7 +36,7 @@ from sage.rings.infinity import infinity from sage.rings.rational import Rational from sage.rings.padics.precision_error import PrecisionError from sage.rings.padics.misc import trim_zeros -from sage.structure.element import canonical_coercion +from sage.structure.element import canonical_coercion, Polynomial import itertools cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) - 1 @@ -156,7 +156,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): x = x + [k.prime_subfield().zero()] * (k.degree() - len(x)) elif isinstance(x, (Integer, Rational, list, tuple)): pass - elif sage.rings.polynomial.polynomial_element.is_Polynomial(x) and x.variable_name() == self.parent().variable_name(): + elif isinstance(x, Polynomial) and x.variable_name() == self.parent().variable_name(): x = x.list() else: x = Rational(x) diff --git a/src/sage/rings/polynomial/multi_polynomial.pxd b/src/sage/rings/polynomial/multi_polynomial.pxd index 44fdf3edfc4..fd947a33bb2 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pxd +++ b/src/sage/rings/polynomial/multi_polynomial.pxd @@ -1,6 +1,6 @@ -from sage.structure.element cimport CommutativeRingElement +from sage.structure.element cimport MPolynomial as MPolynomial_base -cdef class MPolynomial(CommutativeRingElement): +cdef class MPolynomial(MPolynomial_base): cdef long _hash_c(self) except -1 cpdef _mod_(self, right) cpdef dict _mpoly_dict_recursive(self, tuple vars=*, base_ring=*) diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 49e4c52d365..57d95361ddd 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -30,7 +30,7 @@ from sage.rings.real_mpfr import RealField_class,RealField from sage.rings.polynomial.polydict cimport ETuple from sage.rings.polynomial.polynomial_element cimport Polynomial -cdef class MPolynomial(CommutativeRingElement): +cdef class MPolynomial(MPolynomial_base): #################### # Some standard conversions diff --git a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py index 64e1f6368b6..35fe90dd8f8 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py @@ -661,7 +661,7 @@ def rshift_coeffs(self, shift, no_list=False): return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly // fdiv, 0, [0 if a <= shift else a - shift for a in self._relprecs], False, None, None), construct=True) # def __floordiv__(self, right): - # if is_Polynomial(right) and right.is_constant() and right[0] in self.base_ring(): + # if isinstance(right, Polynomial) and right.is_constant() and right[0] in self.base_ring(): # d = self.base_ring()(right[0]) # elif (right in self.base_ring()): # d = self.base_ring()(right) diff --git a/src/sage/rings/polynomial/polynomial_element.pxd b/src/sage/rings/polynomial/polynomial_element.pxd index 1ba103329c3..cafc17eab3f 100644 --- a/src/sage/rings/polynomial/polynomial_element.pxd +++ b/src/sage/rings/polynomial/polynomial_element.pxd @@ -1,11 +1,12 @@ -from sage.structure.element import Element, CommutativeAlgebraElement +from sage.structure.element import Element from sage.structure.element cimport Element, CommutativeAlgebraElement, ModuleElement +from sage.structure.element cimport Polynomial as Polynomial_base from sage.structure.parent cimport Parent from sage.rings.integer cimport Integer from .polynomial_compiled cimport CompiledPolynomialFunction -cdef class Polynomial(CommutativeAlgebraElement): +cdef class Polynomial(Polynomial_base): cdef Polynomial _new_generic(self, list coeffs) cdef char _is_gen cdef CompiledPolynomialFunction _compiled diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index d2649163d48..a0c5fd2e84f 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -149,14 +149,14 @@ cpdef is_Polynomial(f): EXAMPLES:: - sage: from sage.rings.polynomial.polynomial_element import is_Polynomial + sage: from sage.structure.element import Polynomial sage: R. = ZZ[] - sage: is_Polynomial(x^3 + x + 1) + sage: isinstance(x^3 + x + 1, Polynomial) True sage: S. = R[] sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x - sage: is_Polynomial(f) + sage: isinstance(f, Polynomial) True However this function does not return True for genuine multivariate @@ -166,13 +166,13 @@ cpdef is_Polynomial(f): sage: R. = QQ[] sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x - sage: is_Polynomial(f) + sage: isinstance(f, Polynomial) False sage: var('x,y') (x, y) sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x - sage: is_Polynomial(f) + sage: isinstance(f, Polynomial) False """ return isinstance(f, Polynomial) @@ -182,7 +182,7 @@ from .polynomial_compiled cimport CompiledPolynomialFunction from sage.rings.polynomial.polydict cimport ETuple -cdef class Polynomial(CommutativeAlgebraElement): +cdef class Polynomial(Polynomial_base): """ A polynomial. diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx index 41ddaa92e51..7a84cb86f05 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @@ -51,8 +51,6 @@ from sage.rings.integer_ring import IntegerRing from sage.rings.integer_ring cimport IntegerRing_class ZZ_sage = IntegerRing() -from sage.rings.polynomial.polynomial_element import is_Polynomial - from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.rings.integer_ring import ZZ @@ -757,7 +755,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): sage: g // f x - 6 """ - if is_Polynomial(right) and right.is_constant() and right[0] in ZZ: + if isinstance(right, Polynomial) and right.is_constant() and right[0] in ZZ: d = ZZ(right[0]) return self.parent()([c // d for c in self.list()], construct=True) elif (right in self.parent().base_ring()): diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index e0aeed19815..90b8645ab82 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -573,7 +573,7 @@ from sage.rings.complex_interval_field import ComplexIntervalField from sage.rings.complex_interval import is_ComplexIntervalFieldElement from sage.rings.polynomial.all import PolynomialRing -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.number_field.number_field import NumberField, GaussianField, CyclotomicField @@ -6676,7 +6676,7 @@ def __init__(self, poly): sage: type(P) # indirect doctest """ - if not is_Polynomial(poly): + if not isinstance(poly, Polynomial): raise ValueError("Trying to create AlgebraicPolynomialTracker on non-Polynomial") B = poly.base_ring() diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index b8cc1887957..57968823ec9 100644 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -83,7 +83,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= Type I point centered at 4 + O(5^20) """ from sage.rings.function_field.element import is_FunctionFieldElement - from sage.rings.polynomial.polynomial_element import is_Polynomial + from sage.structure.element import Polynomial from sage.rings.fraction_field_element import FractionFieldElement_1poly_field self._type = None @@ -117,9 +117,9 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= raise TypeError('center was %s, a multivariable polynomial' % center) # check if the radius and the center are functions - center_func_check = is_FunctionFieldElement(center) or is_Polynomial(center) or\ + center_func_check = is_FunctionFieldElement(center) or isinstance(center, Polynomial) or\ isinstance(center, FractionFieldElement_1poly_field) or isinstance(center, Expression) - radius_func_check = is_FunctionFieldElement(radius) or is_Polynomial(radius) or\ + radius_func_check = is_FunctionFieldElement(radius) or isinstance(radius, Polynomial) or\ isinstance(radius, FractionFieldElement_1poly_field) or isinstance(radius, Expression) if center_func_check: diff --git a/src/sage/schemes/cyclic_covers/constructor.py b/src/sage/schemes/cyclic_covers/constructor.py index 0966b0793d5..a67a17a2f17 100644 --- a/src/sage/schemes/cyclic_covers/constructor.py +++ b/src/sage/schemes/cyclic_covers/constructor.py @@ -8,7 +8,7 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.schemes.affine.affine_space import AffineSpace from .cycliccover_generic import CyclicCover_generic @@ -100,7 +100,7 @@ def CyclicCover(r, f, names=None, check_smooth=True): """ - if not is_Polynomial(f): + if not isinstance(f, Polynomial): raise TypeError("Arguments f (= %s) must be a polynomial" % (f,)) P = f.parent() f = P(f) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index fe80879bc15..4bc0825a35a 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -86,7 +86,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer import Integer from sage.rings.laurent_series_ring import LaurentSeriesRing -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.rings.fraction_field import FractionField from sage.schemes.elliptic_curves.all import EllipticCurve @@ -159,7 +159,7 @@ def _isogeny_determine_algorithm(E, kernel): kernel = [kernel] kernel_is_list = True - if is_Polynomial(kernel) or (kernel_is_list and kernel[0] in E.base_ring()): + if isinstance(kernel, Polynomial) or (kernel_is_list and kernel[0] in E.base_ring()): return "kohel" if kernel_is_list and kernel[0] in E: diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index 54556e08755..49ff0254cd1 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -25,7 +25,7 @@ import sage.rings.abc from sage.rings.rational_field import is_RationalField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.structure.dynamic_class import dynamic_class @@ -197,7 +197,7 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): # F is the discriminant; use this for the type check # rather than f and h, one of which might be constant. F = h**2 + 4*f - if not is_Polynomial(F): + if not isinstance(F, Polynomial): raise TypeError("Arguments f (= %s) and h (= %s) must be polynomials" % (f, h)) P = F.parent() f = P(f) diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py index f7b0a1f67f0..9fc24367211 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py @@ -49,7 +49,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer_ring import ZZ from sage.rings.integer import is_Integer, Integer -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.schemes.generic.homset import SchemeHomset_points from sage.schemes.generic.morphism import is_SchemeMorphism @@ -138,15 +138,15 @@ def __call__(self, P): P1 = R(P1) P2 = R(P2) return JacobianMorphism_divisor_class_field(self, (P1, P2)) - if is_Integer(P1) and is_Polynomial(P2): + if is_Integer(P1) and isinstance(P2, Polynomial): R = PolynomialRing(self.value_ring(), 'x') P1 = R(P1) return JacobianMorphism_divisor_class_field(self, (P1, P2)) - if is_Integer(P2) and is_Polynomial(P1): + if is_Integer(P2) and isinstance(P1, Polynomial): R = PolynomialRing(self.value_ring(), 'x') P2 = R(P2) return JacobianMorphism_divisor_class_field(self, (P1, P2)) - if is_Polynomial(P1) and is_Polynomial(P2): + if isinstance(P1, Polynomial) and isinstance(P2, Polynomial): return JacobianMorphism_divisor_class_field(self, tuple(P)) if is_SchemeMorphism(P1) and is_SchemeMorphism(P2): return self(P1) - self(P2) diff --git a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py index b1f10eb1344..40bb62aae0d 100644 --- a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +++ b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py @@ -64,7 +64,7 @@ from sage.rings.infinity import Infinity from sage.rings.laurent_series_ring import is_LaurentSeriesRing from sage.rings.padics.all import pAdicField -from sage.rings.polynomial.polynomial_element import is_Polynomial +from sage.structure.element import Polynomial from sage.rings.ring import CommutativeAlgebra from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve @@ -489,7 +489,7 @@ def __init__(self, Q, laurent_series=False): ... ArithmeticError: 2 and 3 must be invertible in the coefficient ring (=Ring of integers modulo 10) of Q """ - if not is_Polynomial(Q): + if not isinstance(Q, Polynomial): raise TypeError("Q (=%s) must be a polynomial" % Q) if Q.degree() != 3 or not Q[2].is_zero(): @@ -2389,7 +2389,7 @@ def __init__(self, Q, R=None, invert_y=True): Q = C.hyperelliptic_polynomials()[0].change_ring(R) self._curve = C - if is_Polynomial(Q): + if isinstance(Q, Polynomial): self._Q = Q.change_ring(R) self._coeffs = self._Q.coefficients(sparse=False) if self._coeffs.pop() != 1: diff --git a/src/sage/structure/element.pxd b/src/sage/structure/element.pxd index 5c6e295a4b8..d6de9b9d2d3 100644 --- a/src/sage/structure/element.pxd +++ b/src/sage/structure/element.pxd @@ -239,6 +239,12 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): cdef class Expression(CommutativeRingElement): pass +cdef class Polynomial(CommutativeAlgebraElement): + pass + +cdef class MPolynomial(CommutativeAlgebraElement): + pass + cdef class InfinityElement(RingElement): pass diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index e9430f0b086..eb694681249 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4291,6 +4291,26 @@ def is_CommutativeAlgebraElement(x): cdef class CommutativeAlgebraElement(CommutativeRingElement): pass + ############################################## + +cdef class Polynomial(CommutativeAlgebraElement): + r""" + Abstract base class for :class:`~sage.rings.polynomial.polynomial_element.Polynomial` + """ + + pass + + ############################################## + +cdef class MPolynomial(CommutativeAlgebraElement): + r""" + Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial` + """ + + pass + + ############################################## + def is_InfinityElement(x): """ Return ``True`` if x is of type InfinityElement. From 6696f5c470b690f528a3b869bd9ae482e91b1e37 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Dec 2022 23:27:41 -0800 Subject: [PATCH 02/19] Use ABC MPolynomial for isinstance testing --- src/sage/combinat/schubert_polynomial.py | 6 +++--- src/sage/combinat/sf/sfa.py | 4 ++-- src/sage/crypto/mq/rijndael_gf.py | 4 ++-- src/sage/groups/affine_gps/group_element.py | 4 ++-- src/sage/groups/perm_gps/permgroup_element.pyx | 4 ++-- src/sage/libs/symmetrica/sb.pxi | 2 +- src/sage/modular/modsym/ambient.py | 4 ++-- src/sage/quadratic_forms/binary_qf.py | 4 ++-- src/sage/rings/finite_rings/element_ntl_gf2e.pyx | 2 +- src/sage/rings/laurent_series_ring.py | 5 ++--- src/sage/rings/polynomial/infinite_polynomial_element.py | 4 ++-- src/sage/rings/polynomial/multi_polynomial_element.py | 5 +---- src/sage/schemes/berkovich/berkovich_cp_element.py | 4 ++-- src/sage/schemes/curves/constructor.py | 4 ++-- src/sage/schemes/elliptic_curves/constructor.py | 4 ++-- src/sage/schemes/elliptic_curves/jacobian.py | 4 ++-- src/sage/schemes/generic/hypersurface.py | 6 +++--- src/sage/schemes/plane_conics/constructor.py | 4 ++-- src/sage/schemes/plane_quartics/quartic_constructor.py | 4 ++-- 19 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/sage/combinat/schubert_polynomial.py b/src/sage/combinat/schubert_polynomial.py index 07d679ac65d..070e1b1e5bf 100644 --- a/src/sage/combinat/schubert_polynomial.py +++ b/src/sage/combinat/schubert_polynomial.py @@ -78,7 +78,7 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.multi_polynomial import is_MPolynomial +from sage.structure.element import MPolynomial from sage.combinat.permutation import Permutations, Permutation import sage.libs.symmetrica.all as symmetrica from sage.misc.cachefunc import cached_method @@ -147,7 +147,7 @@ def expand(self): x0 """ p = symmetrica.t_SCHUBERT_POLYNOM(self) - if not is_MPolynomial(p): + if not isinstance(p, MPolynomial): R = PolynomialRing(self.parent().base_ring(), 1, 'x0') p = R(p) return p @@ -439,7 +439,7 @@ def _element_constructor_(self, x): elif isinstance(x, Permutation): perm = x.remove_extra_fixed_points() return self._from_dict({perm: self.base_ring().one()}) - elif is_MPolynomial(x): + elif isinstance(x, MPolynomial): return symmetrica.t_POLYNOM_SCHUBERT(x) else: raise TypeError diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 8144233329e..cefc2d7f473 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -218,7 +218,7 @@ from sage.rings.infinity import infinity from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.structure.element import Polynomial -from sage.rings.polynomial.multi_polynomial import is_MPolynomial +from sage.structure.element import MPolynomial from sage.combinat.partition import _Partitions, Partitions, Partitions_n, Partition from sage.categories.hopf_algebras import HopfAlgebras from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis @@ -6404,7 +6404,7 @@ def _nonnegative_coefficients(x): sage: _nonnegative_coefficients(x^2-4) False """ - if isinstance(x, Polynomial) or is_MPolynomial(x): + if isinstance(x, Polynomial) or isinstance(x, MPolynomial): return all(c >= 0 for c in x.coefficients(sparse=False)) else: return x >= 0 diff --git a/src/sage/crypto/mq/rijndael_gf.py b/src/sage/crypto/mq/rijndael_gf.py index 154c84d146c..30160378077 100644 --- a/src/sage/crypto/mq/rijndael_gf.py +++ b/src/sage/crypto/mq/rijndael_gf.py @@ -1549,9 +1549,9 @@ def compose(self, f, g, algorithm='encrypt', f_attr=None, g_attr=None): if not isinstance(f, RijndaelGF.Round_Component_Poly_Constr): msg = "keyword 'f' must be a Round_Component_Poly_Constr" raise TypeError(msg) - from sage.rings.polynomial.multi_polynomial import is_MPolynomial + from sage.structure.element import MPolynomial if not isinstance(g, RijndaelGF.Round_Component_Poly_Constr) and \ - not is_MPolynomial(g): + not isinstance(g, MPolynomial): msg = ("keyword 'g' must be a Round_Component_Poly_Constr or a " "polynomial over {0}") raise TypeError(msg.format(self._F)) diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index fe691151cf3..3ad22c1d96b 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -419,8 +419,8 @@ def __call__(self, v): ring = v.parent() return ring([self._A[0,0], self._b[0]]) - from sage.rings.polynomial.multi_polynomial import is_MPolynomial - if is_MPolynomial(v) and parent.degree() == v.parent().ngens(): + from sage.structure.element import MPolynomial + if isinstance(v, MPolynomial) and parent.degree() == v.parent().ngens(): ring = v.parent() from sage.modules.free_module_element import vector image_coords = self._A * vector(ring, ring.gens()) + self._b diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index 90ed0e7d6b3..b06873b7f3d 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -115,7 +115,7 @@ from cypari2.gen cimport Gen from sage.ext.stdsage cimport HAS_DICTIONARY from sage.rings.all import ZZ, Integer from sage.structure.element import Polynomial -from sage.rings.polynomial.multi_polynomial import is_MPolynomial +from sage.structure.element import MPolynomial from sage.structure.element import is_Matrix from sage.matrix.all import MatrixSpace from sage.sets.finite_enumerated_set import FiniteEnumeratedSet @@ -1230,7 +1230,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): raise ValueError("%s does not act on %s" % (self, left.parent())) return left - elif is_MPolynomial(left): + elif isinstance(left, MPolynomial): R = left.parent() vars = R.gens() try: diff --git a/src/sage/libs/symmetrica/sb.pxi b/src/sage/libs/symmetrica/sb.pxi index e61fc08fb98..54ba66ecb06 100644 --- a/src/sage/libs/symmetrica/sb.pxi +++ b/src/sage/libs/symmetrica/sb.pxi @@ -111,7 +111,7 @@ def t_POLYNOM_SCHUBERT_symmetrica(a): cdef OP ca = callocobject(), cres = callocobject() - if not is_MPolynomial(a): + if not isinstance(a, MPolynomial): freeall(ca) freeall(cres) raise TypeError("a (= %s) must be a multivariate polynomial") diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index 627f1c567e7..53393317183 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -95,7 +95,7 @@ class ``ModularSymbolsAmbient``, derived from from sage.modules.free_module_element import FreeModuleElement from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.rings.polynomial.multi_polynomial import is_MPolynomial +from sage.structure.element import MPolynomial from sage.rings.rational_field import QQ from sage.rings.ring import Ring from sage.structure.factorization import Factorization @@ -474,7 +474,7 @@ def _element_constructor_(self, x, computed_with_hecke=False): return sum([c*self(y) for c, y in x], self(0)) elif isinstance(x, list): - if len(x) == 3 and is_MPolynomial(x[0]): + if len(x) == 3 and isinstance(x[0], MPolynomial): return self.modular_symbol_sum(x) else: return self.modular_symbol(x) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index cfa3ada73ef..727077a7197 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -130,14 +130,14 @@ def __init__(self, a, b=None, c=None): sage: BinaryQF(0) 0 """ - from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial + from sage.structure.element import MPolynomial if b is None and c is None: if (isinstance(a, (list, tuple)) and len(a) == 3): a, b, c = a elif a == 0: a = b = c = 0 - elif (is_MPolynomial(a) and a.is_homogeneous() and a.base_ring() == ZZ + elif (isinstance(a, MPolynomial) and a.is_homogeneous() and a.base_ring() == ZZ and a.degree() == 2 and a.parent().ngens() == 2): x, y = a.parent().gens() a, b, c = [a.monomial_coefficient(mon) for mon in [x**2, x*y, y**2]] diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index fee9990e573..38b1aaf2ce7 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -1005,7 +1005,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1 sage: from sage.structure.element import Polynomial - sage: is_Polynomial(e.polynomial()) + sage: isinstance(e.polynomial(), Polynomial) True sage: e.polynomial('x') diff --git a/src/sage/rings/laurent_series_ring.py b/src/sage/rings/laurent_series_ring.py index d3660288b4c..37b0455928d 100644 --- a/src/sage/rings/laurent_series_ring.py +++ b/src/sage/rings/laurent_series_ring.py @@ -466,8 +466,7 @@ def _element_constructor_(self, x, n=0, prec=infinity): x^-3 """ from sage.rings.fraction_field_element import is_FractionFieldElement - from sage.structure.element import Polynomial - from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial + from sage.structure.element import Polynomial, MPolynomial from sage.structure.element import parent from sage.libs.pari.all import pari_gen @@ -500,7 +499,7 @@ def _element_constructor_(self, x, n=0, prec=infinity): return (self(self.polynomial_ring()(x)) << n).add_bigoh(prec) elif (is_FractionFieldElement(x) and (x.base_ring() is self.base_ring() or x.base_ring() == self.base_ring()) - and (is_Polynomial(x.numerator()) or is_MPolynomial(x.numerator()))): + and isinstance(x.numerator(), (Polynomial, MPolynomial))): x = self(x.numerator()) / self(x.denominator()) return (x << n).add_bigoh(prec) return self.element_class(self, x, n).add_bigoh(prec) diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index ac21b71553f..aacddf7a040 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -94,7 +94,7 @@ from sage.structure.element import RingElement from sage.structure.richcmp import richcmp from sage.misc.cachefunc import cached_method -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.structure.element import MPolynomial import copy @@ -249,7 +249,7 @@ def __init__(self, A, p): # the wrong ring and we get here without going through # _element_constructor_. See trac 22514 for examples. # So a little extra checking is done here. - if not is_MPolynomial(p) or p.base_ring() is not A.base_ring(): + if not isinstance(p, MPolynomial) or p.base_ring() is not A.base_ring(): # coerce to a convenient multivariate polynomial ring p = A._minP(p) diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 702bf9af7eb..d96e9bfb9cc 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -61,7 +61,7 @@ from sage.structure.factorization import Factorization from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr from sage.structure.sequence import Sequence -from .multi_polynomial import MPolynomial +from .multi_polynomial import MPolynomial, is_MPolynomial from sage.categories.morphism import Morphism from sage.misc.lazy_attribute import lazy_attribute @@ -71,9 +71,6 @@ from sage.categories.number_fields import NumberFields from sage.rings.real_mpfr import RealField -def is_MPolynomial(x): - return isinstance(x, MPolynomial) - class MPolynomial_element(MPolynomial): def __init__(self, parent, x): diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index 57968823ec9..d496d0543b6 100644 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -109,8 +109,8 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= # is_FunctionFieldElement calls .parent elif hasattr(center, "parent") and hasattr(radius, 'parent'): - from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial - if is_MPolynomial(center): + from sage.structure.element import MPolynomial + if isinstance(center, MPolynomial): try: center = center.univariate_polynomial() except AttributeError: diff --git a/src/sage/schemes/curves/constructor.py b/src/sage/schemes/curves/constructor.py index fc3d174de59..a388e660fef 100644 --- a/src/sage/schemes/curves/constructor.py +++ b/src/sage/schemes/curves/constructor.py @@ -36,7 +36,7 @@ from sage.categories.fields import Fields -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.structure.element import MPolynomial from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.finite_rings.finite_field_constructor import is_FiniteField @@ -239,7 +239,7 @@ def Curve(F, A=None): else: A = ProjectiveSpace(P.ngens()-1, P.base_ring(), names=P.variable_names()) A._coordinate_ring = P - elif is_MPolynomial(F): # define a plane curve + elif isinstance(F, MPolynomial): # define a plane curve P = F.parent() k = F.base_ring() diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 1ecdc082cd5..ff59b42bfe9 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -29,7 +29,7 @@ from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.number_field.number_field import is_NumberField -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.structure.element import MPolynomial from sage.rings.ring import is_Ring from sage.categories.fields import Fields @@ -420,7 +420,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, if isinstance(parent(x), sage.rings.abc.SymbolicRing): x = x._polynomial_(rings.QQ['x', 'y']) - if is_MPolynomial(x): + if isinstance(x, MPolynomial): if y is None: x = coefficients_from_Weierstrass_polynomial(x) else: diff --git a/src/sage/schemes/elliptic_curves/jacobian.py b/src/sage/schemes/elliptic_curves/jacobian.py index b6983ab75f7..dc09a18096e 100644 --- a/src/sage/schemes/elliptic_curves/jacobian.py +++ b/src/sage/schemes/elliptic_curves/jacobian.py @@ -104,8 +104,8 @@ def Jacobian(X, **kwds): pass morphism = kwds.pop('morphism', False) - from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial - if is_MPolynomial(X): + from sage.structure.element import MPolynomial + if isinstance(X, MPolynomial): if morphism: from sage.schemes.curves.constructor import Curve return Jacobian_of_equation(X, curve=Curve(X), **kwds) diff --git a/src/sage/schemes/generic/hypersurface.py b/src/sage/schemes/generic/hypersurface.py index 12138d596af..58f8ed517fd 100644 --- a/src/sage/schemes/generic/hypersurface.py +++ b/src/sage/schemes/generic/hypersurface.py @@ -18,7 +18,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.structure.element import MPolynomial from sage.schemes.affine.affine_subscheme import AlgebraicScheme_subscheme_affine from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective @@ -92,7 +92,7 @@ def __init__(self, poly, ambient=None): sage: H == loads(dumps(H)) True """ - if not is_MPolynomial(poly): + if not isinstance(poly, MPolynomial): raise TypeError("Defining polynomial (=%s) must be a multivariate polynomial."%poly) if not poly.is_homogeneous(): raise TypeError("Defining polynomial (=%s) must be homogeneous."%poly) @@ -177,7 +177,7 @@ def __init__(self, poly, ambient=None): sage: H == loads(dumps(H)) True """ - if not is_MPolynomial(poly): + if not isinstance(poly, MPolynomial): raise TypeError("Defining polynomial (= %s) must be a multivariate polynomial"%poly) if ambient is None: R = poly.parent() diff --git a/src/sage/schemes/plane_conics/constructor.py b/src/sage/schemes/plane_conics/constructor.py index a2a14190087..c1c24049dfe 100644 --- a/src/sage/schemes/plane_conics/constructor.py +++ b/src/sage/schemes/plane_conics/constructor.py @@ -32,7 +32,7 @@ from sage.rings.ring import IntegralDomain from sage.rings.rational_field import is_RationalField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.structure.element import MPolynomial from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.fraction_field import is_FractionField @@ -204,7 +204,7 @@ def Conic(base_field, F=None, names=None, unique=True): temp_ring = PolynomialRing(F.base_ring(), 3, names) F = vector(temp_ring.gens()) * F * vector(temp_ring.gens()) - if not is_MPolynomial(F): + if not isinstance(F, MPolynomial): raise TypeError("F (=%s) must be a three-variable polynomial or " "a sequence of points or coefficients" % F) diff --git a/src/sage/schemes/plane_quartics/quartic_constructor.py b/src/sage/schemes/plane_quartics/quartic_constructor.py index a0b5ce3c93a..53f1494abf0 100644 --- a/src/sage/schemes/plane_quartics/quartic_constructor.py +++ b/src/sage/schemes/plane_quartics/quartic_constructor.py @@ -9,7 +9,7 @@ #***************************************************************************** from sage.schemes.projective.projective_space import is_ProjectiveSpace, ProjectiveSpace -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.structure.element import MPolynomial from .quartic_generic import QuarticCurve_generic @@ -50,7 +50,7 @@ def QuarticCurve(F, PP=None, check=False): ValueError: Argument F (=x^4 + y^4) must be a polynomial in 3 variables """ - if not is_MPolynomial(F): + if not isinstance(F, MPolynomial): raise ValueError(f"Argument F (={F}) must be a multivariate polynomial") P = F.parent() if not P.ngens() == 3: From 79f7e62da9a4d9170c383da70a727302a4340e83 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Dec 2022 00:13:37 -0800 Subject: [PATCH 03/19] Fixups --- src/sage/libs/symmetrica/symmetrica.pxi | 4 ++-- src/sage/rings/polynomial/multi_polynomial.pyx | 3 +++ .../rings/polynomial/polynomial_element.pyx | 17 ++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/sage/libs/symmetrica/symmetrica.pxi b/src/sage/libs/symmetrica/symmetrica.pxi index 7244b7e9655..06330bffbd4 100644 --- a/src/sage/libs/symmetrica/symmetrica.pxi +++ b/src/sage/libs/symmetrica/symmetrica.pxi @@ -401,7 +401,7 @@ cdef void late_import(): SymmetricFunctions, \ sqrt, \ builtinlist, \ - MPolynomialRing_base, is_MPolynomial,\ + MPolynomialRing_base, MPolynomial,\ SchubertPolynomialRing, SchubertPolynomial_class,\ two, fifteen, thirty, zero, sage_maxint @@ -454,7 +454,7 @@ cdef void late_import(): import sage.rings.polynomial.multi_polynomial_ring MPolynomialRing_base = sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_base import sage.rings.polynomial.multi_polynomial_element - is_MPolynomial = sage.rings.polynomial.multi_polynomial_element.is_MPolynomial + MPolynomial = sage.structure.element.MPolynomial import sage.combinat.schubert_polynomial SchubertPolynomialRing = sage.combinat.schubert_polynomial.SchubertPolynomialRing diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index 57d95361ddd..f798a67aa41 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -18,6 +18,9 @@ from sage.misc.derivative import multi_derivative from sage.misc.misc_c import prod def is_MPolynomial(x): + from sage.misc.superseded import deprecation + deprecation(32709, "the function is_MPolynomial is deprecated; use isinstance(x, sage.structure.element.MPolynomial) instead") + return isinstance(x, MPolynomial) from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index a0c5fd2e84f..5cff2e446a4 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -143,20 +143,24 @@ cpdef is_Polynomial(f): """ Return True if f is of type univariate polynomial. + This function is deprecated. + INPUT: - ``f`` -- an object EXAMPLES:: - sage: from sage.structure.element import Polynomial + sage: from sage.rings.polynomial.polynomial_element import is_Polynomial sage: R. = ZZ[] - sage: isinstance(x^3 + x + 1, Polynomial) + sage: is_Polynomial(x^3 + x + 1) + doctest:...: DeprecationWarning: the function is_Polynomial is deprecated; use isinstance(x, sage.structure.element.Polynomial) instead + See https://trac.sagemath.org/32709 for details. True sage: S. = R[] sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x - sage: isinstance(f, Polynomial) + sage: is_Polynomial(f) True However this function does not return True for genuine multivariate @@ -166,15 +170,18 @@ cpdef is_Polynomial(f): sage: R. = QQ[] sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x - sage: isinstance(f, Polynomial) + sage: is_Polynomial(f) False sage: var('x,y') (x, y) sage: f = y^3 + x*y -3*x; f y^3 + x*y - 3*x - sage: isinstance(f, Polynomial) + sage: is_Polynomial(f) False """ + from sage.misc.superseded import deprecation + deprecation(32709, "the function is_Polynomial is deprecated; use isinstance(x, sage.structure.element.Polynomial) instead") + return isinstance(f, Polynomial) from .polynomial_compiled cimport CompiledPolynomialFunction From ed050bbe039dc694cab318b9b3e6e4cf0c7e0e0f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Dec 2022 00:28:48 -0800 Subject: [PATCH 04/19] sage.rings.polynomial: Make it a namespace package --- src/sage/rings/polynomial/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/sage/rings/polynomial/__init__.py diff --git a/src/sage/rings/polynomial/__init__.py b/src/sage/rings/polynomial/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 From 0613280e8b65291b76fd7d440ba16db3f055b5c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Jan 2023 16:47:29 -0800 Subject: [PATCH 05/19] sage.structure.element: Introduce common base class CommutativePolynomial for ABCs Polynomial, MPolynomial --- src/sage/structure/element.pxd | 7 +++++-- src/sage/structure/element.pyx | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/sage/structure/element.pxd b/src/sage/structure/element.pxd index d6de9b9d2d3..d0a574a95a1 100644 --- a/src/sage/structure/element.pxd +++ b/src/sage/structure/element.pxd @@ -239,10 +239,13 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): cdef class Expression(CommutativeRingElement): pass -cdef class Polynomial(CommutativeAlgebraElement): +cdef class CommutativePolynomial(CommutativeAlgebraElement): pass -cdef class MPolynomial(CommutativeAlgebraElement): +cdef class Polynomial(CommutativePolynomial): + pass + +cdef class MPolynomial(CommutativePolynomial): pass cdef class InfinityElement(RingElement): diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index eb694681249..3c80f65040d 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4293,7 +4293,16 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): ############################################## -cdef class Polynomial(CommutativeAlgebraElement): +cdef class CommutativePolynomial(CommutativeAlgebraElement): + r""" + Abstract base class, common base for :class:`Polynomial` and :class:`MPolynomial` + """ + + pass + + ############################################## + +cdef class Polynomial(CommutativePolynomial): r""" Abstract base class for :class:`~sage.rings.polynomial.polynomial_element.Polynomial` """ @@ -4302,7 +4311,7 @@ cdef class Polynomial(CommutativeAlgebraElement): ############################################## -cdef class MPolynomial(CommutativeAlgebraElement): +cdef class MPolynomial(CommutativePolynomial): r""" Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial` """ From 27e888972fb6df6db5fd28ea8a1a5c276417796c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Jan 2023 17:02:09 -0800 Subject: [PATCH 06/19] sage.structure.element: Introduce ABC InfinitePolynomial --- .../polynomial/infinite_polynomial_element.py | 5 ++--- src/sage/structure/element.pyx | 14 +++++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index aacddf7a040..38c97fd3cf3 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -91,10 +91,9 @@ from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer -from sage.structure.element import RingElement from sage.structure.richcmp import richcmp from sage.misc.cachefunc import cached_method -from sage.structure.element import MPolynomial +from sage.structure.element import RingElement, MPolynomial, InfinitePolynomial as InfinitePolynomial_base import copy @@ -206,7 +205,7 @@ def InfinitePolynomial(A, p): return InfinitePolynomial_sparse(A, p) -class InfinitePolynomial_sparse(RingElement): +class InfinitePolynomial_sparse(InfinitePolynomial_base): """ Element of a sparse Polynomial Ring with a Countably Infinite Number of Variables. diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 3c80f65040d..f0e9a802bf5 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4295,7 +4295,10 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): cdef class CommutativePolynomial(CommutativeAlgebraElement): r""" - Abstract base class, common base for :class:`Polynomial` and :class:`MPolynomial` + Abstract base class for commutative polynomials in any number of variables + + It is a common base for :class:`Polynomial`, :class:`MPolynomial`, and + :class:`InfinitePolynomial`. """ pass @@ -4320,6 +4323,15 @@ cdef class MPolynomial(CommutativePolynomial): ############################################## +cdef class InfinitePolynomial(CommutativePolynomial): + r""" + Abstract base class for :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse` + """ + + pass + + ############################################## + def is_InfinityElement(x): """ Return ``True`` if x is of type InfinityElement. From 57228f59679e4b9d90d3b3071618cd6bdadc744d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Jan 2023 18:05:38 -0800 Subject: [PATCH 07/19] src/sage/structure/element.pyx: Update hierarchy in documentation --- src/sage/structure/element.pyx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index f0e9a802bf5..bcecea4f589 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -47,6 +47,10 @@ abstract base classes. EuclideanDomainElement FieldElement CommutativeAlgebraElement + CommutativePolynomial + Polynomial + MPolynomial + InfinitePolynomial Expression AlgebraElement Matrix From 95e0adc1e4fae31a9e0fc2243bc599ea26f9f024 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Jan 2023 19:18:46 -0800 Subject: [PATCH 08/19] src/sage/structure/element.pyx: Add unique-direct-subclass tests --- src/sage/structure/element.pyx | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index bcecea4f589..9099451b0d6 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4312,6 +4312,23 @@ cdef class CommutativePolynomial(CommutativeAlgebraElement): cdef class Polynomial(CommutativePolynomial): r""" Abstract base class for :class:`~sage.rings.polynomial.polynomial_element.Polynomial` + + This class is defined for the purpose of :func:`isinstance` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: R1. = QQ[] + sage: isinstance(x, sage.structure.element.Polynomial) + True + sage: R2. = QQ[] + sage: isinstance(y, sage.structure.element.Polynomial) + False + + By design, there is a unique direct subclass:: + + sage: len(sage.structure.element.Polynomial.__subclasses__()) <= 1 + True """ pass @@ -4321,6 +4338,23 @@ cdef class Polynomial(CommutativePolynomial): cdef class MPolynomial(CommutativePolynomial): r""" Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial` + + This class is defined for the purpose of :func:`isinstance` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: R1. = QQ[] + sage: isinstance(x, sage.structure.element.MPolynomial) + False + sage: R2. = QQ[] + sage: isinstance(y, sage.structure.element.MPolynomial) + True + + By design, there is a unique direct subclass:: + + sage: len(sage.structure.element.MPolynomial.__subclasses__()) <= 1 + True """ pass From 1fd625cddc8bb0e5cdafd8f08612ce886aaa5b7e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Jan 2023 19:47:04 -0800 Subject: [PATCH 09/19] src/sage/structure/element.pyx: Add unique-direct-subclass test for Expression --- src/sage/structure/element.pyx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 9099451b0d6..bad783a11b4 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -3357,6 +3357,19 @@ cdef class Expression(CommutativeRingElement): r""" Abstract base class for :class:`~sage.symbolic.expression.Expression`. + + This class is defined for the purpose of :func:`isinstance` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(SR.var('y'), sage.structure.element.Expression) # optional - sage.symbolic + True + + By design, there is a unique direct subclass:: + + sage: len(sage.structure.element.Expression.__subclasses__()) <= 1 + True """ pass From 960506b6bf0939bbefa17702d794f91ccafb4282 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 17 Jan 2023 18:58:14 -0800 Subject: [PATCH 10/19] InfinitePolynomial: Change from constructor function to base class with __classcall__ --- .../polynomial/infinite_polynomial_element.py | 819 +++++++++--------- src/sage/structure/element.pyx | 16 +- 2 files changed, 426 insertions(+), 409 deletions(-) diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index 38c97fd3cf3..dd87d6e9c05 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -93,11 +93,12 @@ from sage.rings.integer import Integer from sage.structure.richcmp import richcmp from sage.misc.cachefunc import cached_method +from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.structure.element import RingElement, MPolynomial, InfinitePolynomial as InfinitePolynomial_base import copy -def InfinitePolynomial(A, p): +class InfinitePolynomial(InfinitePolynomial_base, metaclass=InheritComparisonClasscallMetaclass): """ Create an element of a Polynomial Ring with a Countably Infinite Number of Variables. @@ -163,73 +164,50 @@ def InfinitePolynomial(A, p): alpha_2^2 + alpha_1^2 """ - from sage.structure.element import parent - if hasattr(A, '_P'): - if parent(p) is A._P or (A._P.base_ring().has_coerce_map_from(parent(p))): - return InfinitePolynomial_dense(A, p) - # MPolynomialRing_polydict is crab. So, in that case, use sage_eval - from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - if isinstance(A._P, MPolynomialRing_polydict): - from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering - from sage.misc.sage_eval import sage_eval - p = sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict())) - return InfinitePolynomial_dense(A, p) - else: - # Now there remains to fight the oddities and bugs of libsingular. - PP = p.parent() - if A._P.has_coerce_map_from(PP): - if A._P.ngens() == PP.ngens(): # coercion is sometimes by position! - f = PP.hom(PP.variable_names(), A._P) - try: - return InfinitePolynomial_dense(A, f(p)) - except (ValueError, TypeError): - # last desperate attempt: String conversion - from sage.misc.sage_eval import sage_eval - from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering - # the base ring may be a function field, therefore - # we need GenDictWithBasering - return InfinitePolynomial_dense(A, sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict()))) - return InfinitePolynomial_dense(A, A._P(p)) - # there is no coercion, so, we set up a name-preserving map. - SV = set(repr(x) for x in p.variables()) - f = PP.hom([x if x in SV else 0 for x in PP.variable_names()], A._P) - try: - return InfinitePolynomial_dense(A, f(p)) - except (ValueError, TypeError): - # last desperate attempt: String conversion - from sage.misc.sage_eval import sage_eval - from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering - # the base ring may be a function field, therefore - # we need GenDictWithBasering - return InfinitePolynomial_dense(A, sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict()))) - return InfinitePolynomial_sparse(A, p) - - -class InfinitePolynomial_sparse(InfinitePolynomial_base): - """ - Element of a sparse Polynomial Ring with a Countably Infinite Number of Variables. - - INPUT: - - - ``A`` -- an Infinite Polynomial Ring in sparse implementation - - ``p`` -- a *classical* polynomial that can be interpreted in ``A``. - - Of course, one should not directly invoke this class, but rather - construct elements of ``A`` in the usual way. - EXAMPLES:: - - sage: A. = QQ[] - sage: B. = InfinitePolynomialRing(A,implementation='sparse') - sage: p = a*b[100] + 1/2*c[4] - sage: p - a*b_100 + 1/2*c_4 - sage: p.parent() - Infinite polynomial ring in b, c over Univariate Polynomial Ring in a over Rational Field - sage: p.polynomial().parent() - Multivariate Polynomial Ring in b_100, b_0, c_4, c_0 over Univariate Polynomial Ring in a over Rational Field + @staticmethod + def __classcall_private__(cls, A, p): + from sage.structure.element import parent + if hasattr(A, '_P'): + if parent(p) is A._P or (A._P.base_ring().has_coerce_map_from(parent(p))): + return InfinitePolynomial_dense(A, p) + # MPolynomialRing_polydict is crab. So, in that case, use sage_eval + from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict + if isinstance(A._P, MPolynomialRing_polydict): + from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering + from sage.misc.sage_eval import sage_eval + p = sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict())) + return InfinitePolynomial_dense(A, p) + else: + # Now there remains to fight the oddities and bugs of libsingular. + PP = p.parent() + if A._P.has_coerce_map_from(PP): + if A._P.ngens() == PP.ngens(): # coercion is sometimes by position! + f = PP.hom(PP.variable_names(), A._P) + try: + return InfinitePolynomial_dense(A, f(p)) + except (ValueError, TypeError): + # last desperate attempt: String conversion + from sage.misc.sage_eval import sage_eval + from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering + # the base ring may be a function field, therefore + # we need GenDictWithBasering + return InfinitePolynomial_dense(A, sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict()))) + return InfinitePolynomial_dense(A, A._P(p)) + # there is no coercion, so, we set up a name-preserving map. + SV = set(repr(x) for x in p.variables()) + f = PP.hom([x if x in SV else 0 for x in PP.variable_names()], A._P) + try: + return InfinitePolynomial_dense(A, f(p)) + except (ValueError, TypeError): + # last desperate attempt: String conversion + from sage.misc.sage_eval import sage_eval + from sage.rings.polynomial.infinite_polynomial_ring import GenDictWithBasering + # the base ring may be a function field, therefore + # we need GenDictWithBasering + return InfinitePolynomial_dense(A, sage_eval(repr(p), GenDictWithBasering(A._P, A._P.gens_dict()))) + return InfinitePolynomial_sparse(A, p) - """ # Construction and other basic methods # We assume that p is good input. Type checking etc. is now done # in the _element_constructor_ of the parent. @@ -299,56 +277,6 @@ def polynomial(self): """ return self._p - def __call__(self, *args, **kwargs): - """ - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(QQ,implementation='sparse') - sage: a = x[0] + x[1] - sage: a(x_0=2,x_1=x[1]) - x_1 + 2 - sage: _.parent() - Infinite polynomial ring in x over Rational Field - sage: a(x_1=3) - x_0 + 3 - sage: _.parent() - Infinite polynomial ring in x over Rational Field - sage: a(x_1=x[100]) - x_100 + x_0 - - """ - # Replace any InfinitePolynomials by their underlying polynomials - if hasattr(self._p, 'variables'): - V = [str(x) for x in self._p.variables()] - else: - V = [] - for kw in kwargs: - value = kwargs[kw] - if isinstance(value, InfinitePolynomial_sparse): - kwargs[kw] = value._p - V.append(kw) - if hasattr(value._p, 'variables'): - V.extend([str(x) for x in value._p.variables()]) - args = list(args) - for i, arg in enumerate(args): - if isinstance(arg, InfinitePolynomial_sparse): - args[i] = arg._p - if hasattr(arg._p, 'variables'): - V.extend([str(x) for x in arg._p.variables()]) - V = list(set(V)) - V.sort(key=self.parent().varname_key, reverse=True) - if V: - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(self._p.base_ring(), V, order=self.parent()._order) - else: - return self - res = R(self._p)(*args, **kwargs) - try: - from sage.misc.sage_eval import sage_eval - return sage_eval(repr(res), self.parent().gens_dict()) - except Exception: - return res - def _getAttributeNames(self): """ This method implements tab completion, see :trac:`6854`. @@ -550,101 +478,6 @@ def max_index(self): """ return max([Integer(str(X).split('_')[1]) for X in self.variables()]+[-1]) - # Basic arithmetics - def _add_(self, x): - """ - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(QQ) - sage: x[1] + x[2] # indirect doctest - x_2 + x_1 - - Check adding from a different parent:: - - sage: Y. = PolynomialRing(QQ) - sage: x[0] - x_0 - 0 - """ - # One may need a new parent for self._p and x._p - try: - return InfinitePolynomial_sparse(self.parent(), self._p + x._p) - except Exception: - pass - # We can now assume that self._p and x._p actually are polynomials, - # hence, their parent is not simply the underlying ring. - VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names()))) - VarList.sort(key=self.parent().varname_key, reverse=True) - if VarList: - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) - else: - R = self._p.base_ring() - return InfinitePolynomial_sparse(self.parent(), R(self._p) + R(x._p)) - - def _mul_(self, x): - """ - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(ZZ) - sage: x[2]*x[1] # indirect doctest - x_2*x_1 - - """ - try: - return InfinitePolynomial_sparse(self.parent(), self._p * x._p) - except Exception: - pass - # We can now assume that self._p and x._p actually are polynomials, - # hence, their parent is not just the underlying ring. - VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names()))) - VarList.sort(key=self.parent().varname_key, reverse=True) - if VarList: - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) - else: - R = self._p.base_ring() - return InfinitePolynomial_sparse(self.parent(), R(self._p) * R(x._p)) - - def gcd(self, x): - """ - computes the greatest common divisor - - EXAMPLES:: - - sage: R.=InfinitePolynomialRing(QQ) - sage: p1=x[0]+x[1]**2 - sage: gcd(p1,p1+3) - 1 - sage: gcd(p1,p1)==p1 - True - """ - P = self.parent() - self._p = P._P(self._p) - x._p = P._P(x._p) - return InfinitePolynomial_sparse(self.parent(), self._p.gcd(x._p)) - - def _rmul_(self, left): - """ - TESTS:: - - sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') - sage: R.from_base_ring(4) # indirect doctest - 4 - - """ - return InfinitePolynomial_sparse(self.parent(), left * self._p) - - def _lmul_(self, right): - """ - TESTS:: - - sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') - sage: alpha[3]*4 # indirect doctest - 4*alpha_3 - - """ - return InfinitePolynomial_sparse(self.parent(), self._p * right) - def _div_(self, x): r""" Division of Infinite Polynomials. @@ -719,213 +552,52 @@ def _floordiv_(self, x): R = self._p.base_ring() return InfinitePolynomial_sparse(self.parent(), R(self._p) // R(x._p)) - def _sub_(self, x): + @cached_method + def lm(self): """ + The leading monomial of ``self``. + EXAMPLES:: - sage: X. = InfinitePolynomialRing(QQ) - sage: x[2] - x[1] # indirect doctest - x_2 - x_1 + sage: X. = InfinitePolynomialRing(QQ) + sage: p = 2*x[10]*y[30]+x[10]*y[1]^3*x[1]^2 + sage: p.lm() + x_10*x_1^2*y_1^3 """ - try: - return InfinitePolynomial_sparse(self.parent(), self._p - x._p) - except Exception: - pass - # We can now assume that self._p and x._p actually are polynomials, - # hence, their parent is not just the underlying ring. - VarList = list(set(self._p.parent().variable_names()).union(x._p.parent().variable_names())) - VarList.sort(key=self.parent().varname_key, reverse=True) - if VarList: - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) - else: - R = self._p.base_ring() - return InfinitePolynomial_sparse(self.parent(), R(self._p) - R(x._p)) + if hasattr(self._p, 'lm'): + return InfinitePolynomial(self.parent(), self._p.lm()) + if self._p == 0: + return self + if hasattr(self._p, 'variable_name'): # if it is univariate + return InfinitePolynomial(self.parent(), + self._p.parent().gen() ** max(self._p.exponents())) + return self # if it is scalar - def __pow__(self, n): + @cached_method + def lc(self): """ - Exponentiation by an integer, or action by a callable object - - NOTE: - - The callable object must accept non-negative integers as input - and return non-negative integers. Typical use case is a - permutation, that will result in the corresponding permutation - of variables. + The coefficient of the leading term of ``self``. EXAMPLES:: - 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))) - sage: p^P # indirect doctest - x_10*y_1 + 2*x_2*y_4 + sage: X. = InfinitePolynomialRing(QQ) + sage: p = 2*x[10]*y[30]+3*x[10]*y[1]^3*x[1]^2 + sage: p.lc() + 3 """ - P = self.parent() - if callable(n): - if (self._p.parent() == self._p.base_ring()): - return self - if not (hasattr(self._p, 'variables') and self._p.variables()): - return self - if hasattr(n, 'to_cycles') and hasattr(n, '__len__'): # duck typing Permutation - # auxiliary function, necessary since n(m) raises an error if m>len(n) - l = len(n) + if hasattr(self._p, 'lc'): + return self._p.lc() + if hasattr(self._p, 'variable_name'): # univariate case + return self._p.leading_coefficient() + # scalar case + return self._p - def p(m): - return n(m) if 0 < m <= l else m - else: # Permutation group element - p = n - - def q(s): return s[0]+'_'+str(p(ZZ(s[1]))) - newVars = [q(X.split('_')) for X in self._p.parent().variable_names()] - if not newVars: - return self - copyVars = copy.copy(newVars) - newVars = list(set(list(self._p.parent().variable_names())+newVars)) - newVars.sort(key=self.parent().varname_key, reverse=True) - if newVars == list(self._p.parent().variable_names()): - newR = self._p.parent() - else: - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - newR = PolynomialRing(self._p.base_ring(), newVars, order=P._order) - mapR = self._p.parent().hom(copyVars, newR) - return InfinitePolynomial_sparse(self.parent(), mapR(self._p)) - return InfinitePolynomial_sparse(self.parent(), self._p**n) - - # Basic tools for Buchberger algorithm: - # order, leading term/monomial, symmetric cancellation order - - def _richcmp_(self, x, op): - r""" - Comparison of Infinite Polynomials. - - NOTE: - - Let x and y be generators of the parent of self. We only consider - monomial orderings in which x[m] > y[n] iff x appears earlier in the - list of generators than y, or x==y and m>n - - Under this restriction, the monomial ordering can be 'lex' (default), - 'degrevlex' or 'deglex'. - - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(QQ, implementation='sparse') - sage: a = x[10]^3 - sage: b = x[1] + x[2] - sage: c = x[1] + x[2] - sage: d = y[1] + x[2] - sage: a == a # indirect doctest - True - sage: b == c # indirect doctest - True - sage: a == b # indirect doctest - False - sage: c > d # indirect doctest - True - - TESTS: - - A classical and an infinite sparse polynomial ring. Note that - the Sage coercion system allows comparison only if a common - parent for the two rings can be constructed. This is why we - have to have the order 'degrevlex':: - - sage: X. = InfinitePolynomialRing(ZZ,order='degrevlex', implementation='sparse') - sage: Y. = QQ[] - sage: x[3] == x_3 # indirect doctest - True - - Two infinite polynomial rings in different implementation and - order:: - - sage: Y = InfinitePolynomialRing(QQ,['x','y'],order='deglex',implementation='dense') - sage: x[2] == Y(x[2]) # indirect doctest - True - - An example in which a previous version had failed:: - - 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 # indirect doctest - False - - """ - # We can assume that self.parent() is x.parent(), - # but of course the underlying polynomial rings - # may be widely different, and the sage coercion - # system can't guess what order we want. - from sage.structure.element import parent - R1 = parent(self._p) - R2 = parent(x._p) - if (hasattr(R1, 'has_coerce_map_from') and R1.has_coerce_map_from(R2)) or (hasattr(R2, 'has_coerce_map_from') and R2.has_coerce_map_from(R1)): - return richcmp(self._p, x._p, op) - VarList = list(set(self._p.parent().variable_names()).union(x._p.parent().variable_names())) - VarList.sort(key=self.parent().varname_key, reverse=True) - if VarList: - from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) - else: - R = self._p.base_ring() - if (self._p.parent() is self._p.base_ring()) or not self._p.parent().gens(): - fself = self._p.base_ring() - else: - fself = self._p.parent().hom(self._p.parent().variable_names(), R) - if (x._p.parent() is x._p.base_ring()) or not x._p.parent().gens(): - fx = x._p.base_ring() - else: - fx = x._p.parent().hom(x._p.parent().variable_names(), R) - return richcmp(fself(self._p), fx(x._p), op) - - @cached_method - def lm(self): - """ - The leading monomial of ``self``. - - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(QQ) - sage: p = 2*x[10]*y[30]+x[10]*y[1]^3*x[1]^2 - sage: p.lm() - x_10*x_1^2*y_1^3 - - """ - if hasattr(self._p, 'lm'): - return InfinitePolynomial(self.parent(), self._p.lm()) - if self._p == 0: - return self - if hasattr(self._p, 'variable_name'): # if it is univariate - return InfinitePolynomial(self.parent(), - self._p.parent().gen() ** max(self._p.exponents())) - return self # if it is scalar - - @cached_method - def lc(self): - """ - The coefficient of the leading term of ``self``. - - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(QQ) - sage: p = 2*x[10]*y[30]+3*x[10]*y[1]^3*x[1]^2 - sage: p.lc() - 3 - - """ - if hasattr(self._p, 'lc'): - return self._p.lc() - if hasattr(self._p, 'variable_name'): # univariate case - return self._p.leading_coefficient() - # scalar case - return self._p - - @cached_method - def lt(self): - """ - The leading term (= product of coefficient and monomial) of ``self``. + @cached_method + def lt(self): + """ + The leading term (= product of coefficient and monomial) of ``self``. EXAMPLES:: @@ -1377,8 +1049,341 @@ def __iter__(self): self.__class__(self.parent(), monomial)) for coefficient, monomial in self._p) + def gcd(self, x): + """ + computes the greatest common divisor + + EXAMPLES:: + + sage: R.=InfinitePolynomialRing(QQ) + sage: p1=x[0]+x[1]**2 + sage: gcd(p1,p1+3) + 1 + sage: gcd(p1,p1)==p1 + True + """ + P = self.parent() + self._p = P._P(self._p) + x._p = P._P(x._p) + return self.__class__.__base__(self.parent(), self._p.gcd(x._p)) + + +class InfinitePolynomial_sparse(InfinitePolynomial): + """ + Element of a sparse Polynomial Ring with a Countably Infinite Number of Variables. + + INPUT: + + - ``A`` -- an Infinite Polynomial Ring in sparse implementation + - ``p`` -- a *classical* polynomial that can be interpreted in ``A``. + + Of course, one should not directly invoke this class, but rather + construct elements of ``A`` in the usual way. + + EXAMPLES:: + + sage: A. = QQ[] + sage: B. = InfinitePolynomialRing(A,implementation='sparse') + sage: p = a*b[100] + 1/2*c[4] + sage: p + a*b_100 + 1/2*c_4 + sage: p.parent() + Infinite polynomial ring in b, c over Univariate Polynomial Ring in a over Rational Field + sage: p.polynomial().parent() + Multivariate Polynomial Ring in b_100, b_0, c_4, c_0 over Univariate Polynomial Ring in a over Rational Field -class InfinitePolynomial_dense(InfinitePolynomial_sparse): + """ + + def __call__(self, *args, **kwargs): + """ + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ,implementation='sparse') + sage: a = x[0] + x[1] + sage: a(x_0=2,x_1=x[1]) + x_1 + 2 + sage: _.parent() + Infinite polynomial ring in x over Rational Field + sage: a(x_1=3) + x_0 + 3 + sage: _.parent() + Infinite polynomial ring in x over Rational Field + sage: a(x_1=x[100]) + x_100 + x_0 + + """ + # Replace any InfinitePolynomials by their underlying polynomials + if hasattr(self._p, 'variables'): + V = [str(x) for x in self._p.variables()] + else: + V = [] + for kw in kwargs: + value = kwargs[kw] + if isinstance(value, InfinitePolynomial_sparse): + kwargs[kw] = value._p + V.append(kw) + if hasattr(value._p, 'variables'): + V.extend([str(x) for x in value._p.variables()]) + args = list(args) + for i, arg in enumerate(args): + if isinstance(arg, InfinitePolynomial_sparse): + args[i] = arg._p + if hasattr(arg._p, 'variables'): + V.extend([str(x) for x in arg._p.variables()]) + V = list(set(V)) + V.sort(key=self.parent().varname_key, reverse=True) + if V: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self._p.base_ring(), V, order=self.parent()._order) + else: + return self + res = R(self._p)(*args, **kwargs) + try: + from sage.misc.sage_eval import sage_eval + return sage_eval(repr(res), self.parent().gens_dict()) + except Exception: + return res + + # Basic arithmetics + def _add_(self, x): + """ + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ) + sage: x[1] + x[2] # indirect doctest + x_2 + x_1 + + Check adding from a different parent:: + + sage: Y. = PolynomialRing(QQ) + sage: x[0] - x_0 + 0 + """ + # One may need a new parent for self._p and x._p + try: + return InfinitePolynomial_sparse(self.parent(), self._p + x._p) + except Exception: + pass + # We can now assume that self._p and x._p actually are polynomials, + # hence, their parent is not simply the underlying ring. + VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names()))) + VarList.sort(key=self.parent().varname_key, reverse=True) + if VarList: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) + else: + R = self._p.base_ring() + return InfinitePolynomial_sparse(self.parent(), R(self._p) + R(x._p)) + + def _mul_(self, x): + """ + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(ZZ) + sage: x[2]*x[1] # indirect doctest + x_2*x_1 + + """ + try: + return InfinitePolynomial_sparse(self.parent(), self._p * x._p) + except Exception: + pass + # We can now assume that self._p and x._p actually are polynomials, + # hence, their parent is not just the underlying ring. + VarList = list(set(self._p.parent().variable_names()).union(set(x._p.parent().variable_names()))) + VarList.sort(key=self.parent().varname_key, reverse=True) + if VarList: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) + else: + R = self._p.base_ring() + return InfinitePolynomial_sparse(self.parent(), R(self._p) * R(x._p)) + + def _rmul_(self, left): + """ + TESTS:: + + sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: R.from_base_ring(4) # indirect doctest + 4 + + """ + return InfinitePolynomial_sparse(self.parent(), left * self._p) + + def _lmul_(self, right): + """ + TESTS:: + + sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: alpha[3]*4 # indirect doctest + 4*alpha_3 + + """ + return InfinitePolynomial_sparse(self.parent(), self._p * right) + + def _sub_(self, x): + """ + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ) + sage: x[2] - x[1] # indirect doctest + x_2 - x_1 + + """ + try: + return InfinitePolynomial_sparse(self.parent(), self._p - x._p) + except Exception: + pass + # We can now assume that self._p and x._p actually are polynomials, + # hence, their parent is not just the underlying ring. + VarList = list(set(self._p.parent().variable_names()).union(x._p.parent().variable_names())) + VarList.sort(key=self.parent().varname_key, reverse=True) + if VarList: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) + else: + R = self._p.base_ring() + return InfinitePolynomial_sparse(self.parent(), R(self._p) - R(x._p)) + + def __pow__(self, n): + """ + Exponentiation by an integer, or action by a callable object + + NOTE: + + The callable object must accept non-negative integers as input + and return non-negative integers. Typical use case is a + permutation, that will result in the corresponding permutation + of variables. + + EXAMPLES:: + + 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))) + sage: p^P # indirect doctest + x_10*y_1 + 2*x_2*y_4 + + """ + P = self.parent() + if callable(n): + if (self._p.parent() == self._p.base_ring()): + return self + if not (hasattr(self._p, 'variables') and self._p.variables()): + return self + if hasattr(n, 'to_cycles') and hasattr(n, '__len__'): # duck typing Permutation + # auxiliary function, necessary since n(m) raises an error if m>len(n) + l = len(n) + + def p(m): + return n(m) if 0 < m <= l else m + else: # Permutation group element + p = n + + def q(s): return s[0]+'_'+str(p(ZZ(s[1]))) + newVars = [q(X.split('_')) for X in self._p.parent().variable_names()] + if not newVars: + return self + copyVars = copy.copy(newVars) + newVars = list(set(list(self._p.parent().variable_names())+newVars)) + newVars.sort(key=self.parent().varname_key, reverse=True) + if newVars == list(self._p.parent().variable_names()): + newR = self._p.parent() + else: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + newR = PolynomialRing(self._p.base_ring(), newVars, order=P._order) + mapR = self._p.parent().hom(copyVars, newR) + return InfinitePolynomial_sparse(self.parent(), mapR(self._p)) + return InfinitePolynomial_sparse(self.parent(), self._p**n) + + # Basic tools for Buchberger algorithm: + # order, leading term/monomial, symmetric cancellation order + + def _richcmp_(self, x, op): + r""" + Comparison of Infinite Polynomials. + + NOTE: + + Let x and y be generators of the parent of self. We only consider + monomial orderings in which x[m] > y[n] iff x appears earlier in the + list of generators than y, or x==y and m>n + + Under this restriction, the monomial ordering can be 'lex' (default), + 'degrevlex' or 'deglex'. + + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: a = x[10]^3 + sage: b = x[1] + x[2] + sage: c = x[1] + x[2] + sage: d = y[1] + x[2] + sage: a == a # indirect doctest + True + sage: b == c # indirect doctest + True + sage: a == b # indirect doctest + False + sage: c > d # indirect doctest + True + + TESTS: + + A classical and an infinite sparse polynomial ring. Note that + the Sage coercion system allows comparison only if a common + parent for the two rings can be constructed. This is why we + have to have the order 'degrevlex':: + + sage: X. = InfinitePolynomialRing(ZZ,order='degrevlex', implementation='sparse') + sage: Y. = QQ[] + sage: x[3] == x_3 # indirect doctest + True + + Two infinite polynomial rings in different implementation and + order:: + + sage: Y = InfinitePolynomialRing(QQ,['x','y'],order='deglex',implementation='dense') + sage: x[2] == Y(x[2]) # indirect doctest + True + + An example in which a previous version had failed:: + + 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 # indirect doctest + False + + """ + # We can assume that self.parent() is x.parent(), + # but of course the underlying polynomial rings + # may be widely different, and the sage coercion + # system can't guess what order we want. + from sage.structure.element import parent + R1 = parent(self._p) + R2 = parent(x._p) + if (hasattr(R1, 'has_coerce_map_from') and R1.has_coerce_map_from(R2)) or (hasattr(R2, 'has_coerce_map_from') and R2.has_coerce_map_from(R1)): + return richcmp(self._p, x._p, op) + VarList = list(set(self._p.parent().variable_names()).union(x._p.parent().variable_names())) + VarList.sort(key=self.parent().varname_key, reverse=True) + if VarList: + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order) + else: + R = self._p.base_ring() + if (self._p.parent() is self._p.base_ring()) or not self._p.parent().gens(): + fself = self._p.base_ring() + else: + fself = self._p.parent().hom(self._p.parent().variable_names(), R) + if (x._p.parent() is x._p.base_ring()) or not x._p.parent().gens(): + fx = x._p.base_ring() + else: + fx = x._p.parent().hom(x._p.parent().variable_names(), R) + return richcmp(fself(self._p), fx(x._p), op) + + +class InfinitePolynomial_dense(InfinitePolynomial): """ Element of a dense Polynomial Ring with a Countably Infinite Number of Variables. @@ -1394,8 +1399,6 @@ class InfinitePolynomial_dense(InfinitePolynomial_sparse): :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse`. See there for a description of the methods. """ - # Construction and other basic methods -## def __init__(self, A, p): # is inherited from the dense implementation def __call__(self, *args, **kwargs): """ diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index bad783a11b4..6c4bff702e4 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -4376,7 +4376,21 @@ cdef class MPolynomial(CommutativePolynomial): cdef class InfinitePolynomial(CommutativePolynomial): r""" - Abstract base class for :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse` + Abstract base class for :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial` + + This class is defined for the purpose of :func:`isinstance` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: X. = InfinitePolynomialRing(QQ) + sage: isinstance(x[0], sage.structure.element.InfinitePolynomial) + True + + By design, there is a unique direct subclass:: + + sage: len(sage.structure.element.InfinitePolynomial.__subclasses__()) <= 1 + True """ pass From fd54c82b627c8d2f2bdd2cf0f73583bc7bdf8156 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 17 Jan 2023 23:40:11 -0800 Subject: [PATCH 11/19] Remove ABCs sage.structure.element.*Polynomial; introduce ABCs in sage.rings.polynomial --- src/sage/combinat/kazhdan_lusztig.py | 2 +- src/sage/combinat/schubert_polynomial.py | 2 +- src/sage/combinat/sf/sfa.py | 4 +- src/sage/crypto/boolean_function.pyx | 2 +- src/sage/crypto/mq/rijndael_gf.py | 2 +- src/sage/crypto/sbox.pyx | 2 +- src/sage/crypto/stream.py | 2 +- src/sage/groups/affine_gps/group_element.py | 4 +- .../groups/perm_gps/permgroup_element.pyx | 4 +- src/sage/libs/symmetrica/symmetrica.pxi | 4 +- .../characteristic_cohomology_class.py | 2 +- src/sage/modular/modsym/ambient.py | 2 +- src/sage/quadratic_forms/binary_qf.py | 2 +- src/sage/quadratic_forms/constructions.py | 2 +- .../rings/finite_rings/element_ntl_gf2e.pyx | 2 +- .../rings/finite_rings/finite_field_base.pyx | 2 +- .../finite_rings/finite_field_constructor.py | 2 +- .../rings/finite_rings/finite_field_givaro.py | 2 +- .../finite_rings/finite_field_ntl_gf2e.py | 2 +- src/sage/rings/finite_rings/residue_field.pyx | 2 +- .../rings/function_field/function_field.py | 2 +- src/sage/rings/laurent_series_ring.py | 3 +- src/sage/rings/number_field/number_field.py | 2 +- src/sage/rings/padics/factory.py | 2 +- .../rings/padics/padic_template_element.pxi | 3 +- .../polynomial/commutative_polynomial.pxd | 5 + .../polynomial/commutative_polynomial.pyx | 10 ++ .../polynomial/infinite_polynomial_element.py | 6 +- .../rings/polynomial/multi_polynomial.pxd | 8 +- .../rings/polynomial/multi_polynomial.pyx | 25 ++++- .../multi_polynomial_libsingular.pxd | 4 +- .../multi_polynomial_libsingular.pyx | 2 +- .../rings/polynomial/polynomial_element.pxd | 4 +- .../rings/polynomial/polynomial_element.pyx | 2 +- src/sage/rings/qqbar.py | 2 +- .../schemes/berkovich/berkovich_cp_element.py | 4 +- src/sage/schemes/curves/constructor.py | 2 +- src/sage/schemes/cyclic_covers/constructor.py | 2 +- .../schemes/elliptic_curves/constructor.py | 2 +- .../elliptic_curves/ell_curve_isogeny.py | 2 +- src/sage/schemes/elliptic_curves/jacobian.py | 2 +- src/sage/schemes/generic/hypersurface.py | 2 +- .../hyperelliptic_curves/constructor.py | 2 +- .../hyperelliptic_curves/jacobian_homset.py | 2 +- .../hyperelliptic_curves/monsky_washnitzer.py | 2 +- src/sage/schemes/plane_conics/constructor.py | 2 +- .../plane_quartics/quartic_constructor.py | 2 +- src/sage/structure/element.pxd | 9 -- src/sage/structure/element.pyx | 91 ------------------- 49 files changed, 100 insertions(+), 154 deletions(-) create mode 100644 src/sage/rings/polynomial/commutative_polynomial.pxd create mode 100644 src/sage/rings/polynomial/commutative_polynomial.pyx diff --git a/src/sage/combinat/kazhdan_lusztig.py b/src/sage/combinat/kazhdan_lusztig.py index 75995aa34e4..c630e185c43 100644 --- a/src/sage/combinat/kazhdan_lusztig.py +++ b/src/sage/combinat/kazhdan_lusztig.py @@ -20,7 +20,7 @@ #***************************************************************************** -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.misc.cachefunc import cached_method from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial from sage.structure.sage_object import SageObject diff --git a/src/sage/combinat/schubert_polynomial.py b/src/sage/combinat/schubert_polynomial.py index 070e1b1e5bf..fdc81d19abc 100644 --- a/src/sage/combinat/schubert_polynomial.py +++ b/src/sage/combinat/schubert_polynomial.py @@ -78,7 +78,7 @@ from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.combinat.permutation import Permutations, Permutation import sage.libs.symmetrica.all as symmetrica from sage.misc.cachefunc import cached_method diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index cefc2d7f473..91091a48c1f 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -217,8 +217,8 @@ from sage.rings.integer import Integer from sage.rings.infinity import infinity from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.structure.element import Polynomial -from sage.structure.element import MPolynomial +from sage.rings.polynomial.polynomial_element import Polynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.combinat.partition import _Partitions, Partitions, Partitions_n, Partition from sage.categories.hopf_algebras import HopfAlgebras from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis diff --git a/src/sage/crypto/boolean_function.pyx b/src/sage/crypto/boolean_function.pyx index 1358ae1b958..cb251a4f03f 100644 --- a/src/sage/crypto/boolean_function.pyx +++ b/src/sage/crypto/boolean_function.pyx @@ -40,7 +40,7 @@ from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.polynomial.pbori.pbori import BooleanPolynomial from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.misc.superseded import deprecated_function_alias diff --git a/src/sage/crypto/mq/rijndael_gf.py b/src/sage/crypto/mq/rijndael_gf.py index 30160378077..fc3473d1b06 100644 --- a/src/sage/crypto/mq/rijndael_gf.py +++ b/src/sage/crypto/mq/rijndael_gf.py @@ -1549,7 +1549,7 @@ def compose(self, f, g, algorithm='encrypt', f_attr=None, g_attr=None): if not isinstance(f, RijndaelGF.Round_Component_Poly_Constr): msg = "keyword 'f' must be a Round_Component_Poly_Constr" raise TypeError(msg) - from sage.structure.element import MPolynomial + from sage.rings.polynomial.multi_polynomial import MPolynomial if not isinstance(g, RijndaelGF.Round_Component_Poly_Constr) and \ not isinstance(g, MPolynomial): msg = ("keyword 'g' must be a Round_Component_Poly_Constr or a " diff --git a/src/sage/crypto/sbox.pyx b/src/sage/crypto/sbox.pyx index 47d2f6c5e69..5c63e79bbac 100644 --- a/src/sage/crypto/sbox.pyx +++ b/src/sage/crypto/sbox.pyx @@ -173,7 +173,7 @@ cdef class SBox(SageObject): sage: S.output_size() 3 """ - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial if "S" in kwargs: args = kwargs["S"] diff --git a/src/sage/crypto/stream.py b/src/sage/crypto/stream.py index ab7c86b16a3..90e4a6f5133 100644 --- a/src/sage/crypto/stream.py +++ b/src/sage/crypto/stream.py @@ -20,7 +20,7 @@ from sage.arith.all import gcd, power_mod from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.rings.finite_rings.integer_mod_ring import IntegerModFactory -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial IntegerModRing = IntegerModFactory("IntegerModRing") diff --git a/src/sage/groups/affine_gps/group_element.py b/src/sage/groups/affine_gps/group_element.py index 3ad22c1d96b..127c1d33cb5 100644 --- a/src/sage/groups/affine_gps/group_element.py +++ b/src/sage/groups/affine_gps/group_element.py @@ -414,12 +414,12 @@ def __call__(self, v): if v in parent.vector_space(): return self._A*v + self._b - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial if isinstance(v, Polynomial) and parent.degree() == 1: ring = v.parent() return ring([self._A[0,0], self._b[0]]) - from sage.structure.element import MPolynomial + from sage.rings.polynomial.multi_polynomial import MPolynomial if isinstance(v, MPolynomial) and parent.degree() == v.parent().ngens(): ring = v.parent() from sage.modules.free_module_element import vector diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index b06873b7f3d..84907ab0c61 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -114,8 +114,8 @@ from cypari2.gen cimport Gen from sage.ext.stdsage cimport HAS_DICTIONARY from sage.rings.all import ZZ, Integer -from sage.structure.element import Polynomial -from sage.structure.element import MPolynomial +from sage.rings.polynomial.polynomial_element import Polynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.structure.element import is_Matrix from sage.matrix.all import MatrixSpace from sage.sets.finite_enumerated_set import FiniteEnumeratedSet diff --git a/src/sage/libs/symmetrica/symmetrica.pxi b/src/sage/libs/symmetrica/symmetrica.pxi index 06330bffbd4..95f9e52fbda 100644 --- a/src/sage/libs/symmetrica/symmetrica.pxi +++ b/src/sage/libs/symmetrica/symmetrica.pxi @@ -453,8 +453,8 @@ cdef void late_import(): import sage.rings.polynomial.multi_polynomial_ring MPolynomialRing_base = sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_base - import sage.rings.polynomial.multi_polynomial_element - MPolynomial = sage.structure.element.MPolynomial + import sage.rings.polynomial.multi_polynomial + MPolynomial = sage.rings.polynomial.multi_polynomial.MPolynomial import sage.combinat.schubert_polynomial SchubertPolynomialRing = sage.combinat.schubert_polynomial.SchubertPolynomialRing diff --git a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py index 144edfcd8f3..1af1c0c6d74 100644 --- a/src/sage/manifolds/differentiable/characteristic_cohomology_class.py +++ b/src/sage/manifolds/differentiable/characteristic_cohomology_class.py @@ -290,7 +290,7 @@ from .bundle_connection import BundleConnection from .levi_civita_connection import LeviCivitaConnection from sage.symbolic.expression import Expression -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing diff --git a/src/sage/modular/modsym/ambient.py b/src/sage/modular/modsym/ambient.py index 53393317183..e7ca7c669e2 100644 --- a/src/sage/modular/modsym/ambient.py +++ b/src/sage/modular/modsym/ambient.py @@ -95,7 +95,7 @@ class ``ModularSymbolsAmbient``, derived from from sage.modules.free_module_element import FreeModuleElement from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.rings.rational_field import QQ from sage.rings.ring import Ring from sage.structure.factorization import Factorization diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 727077a7197..cf0ac737f14 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -130,7 +130,7 @@ def __init__(self, a, b=None, c=None): sage: BinaryQF(0) 0 """ - from sage.structure.element import MPolynomial + from sage.rings.polynomial.multi_polynomial import MPolynomial if b is None and c is None: if (isinstance(a, (list, tuple)) and len(a) == 3): diff --git a/src/sage/quadratic_forms/constructions.py b/src/sage/quadratic_forms/constructions.py index 7d03d5e003d..43d3876f435 100644 --- a/src/sage/quadratic_forms/constructions.py +++ b/src/sage/quadratic_forms/constructions.py @@ -6,7 +6,7 @@ ## from sage.rings.integer_ring import ZZ -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.quadratic_forms.quadratic_form import QuadraticForm diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index 38b1aaf2ce7..16065f47966 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -1004,7 +1004,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): sage: e.polynomial() a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1 - sage: from sage.structure.element import Polynomial + sage: from sage.rings.polynomial.polynomial_element import Polynomial sage: isinstance(e.polynomial(), Polynomial) True diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 125fbf6770c..9927c9e534d 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1521,7 +1521,7 @@ cdef class FiniteField(Field): True """ from .finite_field_constructor import GF - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.integer import Integer if name is None and names is not None: name = names diff --git a/src/sage/rings/finite_rings/finite_field_constructor.py b/src/sage/rings/finite_rings/finite_field_constructor.py index 2f6a75b5abb..8b51fd37b2e 100644 --- a/src/sage/rings/finite_rings/finite_field_constructor.py +++ b/src/sage/rings/finite_rings/finite_field_constructor.py @@ -173,7 +173,7 @@ from collections import defaultdict from sage.structure.category_object import normalize_names -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.integer import Integer # the import below is just a redirection diff --git a/src/sage/rings/finite_rings/finite_field_givaro.py b/src/sage/rings/finite_rings/finite_field_givaro.py index acf64553f50..087db824de6 100644 --- a/src/sage/rings/finite_rings/finite_field_givaro.py +++ b/src/sage/rings/finite_rings/finite_field_givaro.py @@ -137,7 +137,7 @@ def __init__(self, q, name="a", modulus=None, repr="poly", cache=False): from .finite_field_constructor import GF FiniteField.__init__(self, GF(p), name, normalize=False) - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial if not isinstance(modulus, Polynomial): raise TypeError("modulus must be a polynomial") diff --git a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py index 1227d71ce67..e750f2fef5e 100644 --- a/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py +++ b/src/sage/rings/finite_rings/finite_field_ntl_gf2e.py @@ -138,7 +138,7 @@ def __init__(self, q, names="a", modulus=None, repr="poly"): raise ValueError("q must be a 2-power") FiniteField.__init__(self, GF2, names, normalize=True) - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial if not isinstance(modulus, Polynomial): raise TypeError("modulus must be a polynomial") diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index 83db0a58dca..225fafef0d3 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -170,7 +170,7 @@ from sage.rings.fraction_field import is_FractionField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.polynomial_ring import is_PolynomialRing -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.structure.factory import UniqueFactory from sage.structure.element cimport parent diff --git a/src/sage/rings/function_field/function_field.py b/src/sage/rings/function_field/function_field.py index e2f5aea7b83..06eb19905d8 100644 --- a/src/sage/rings/function_field/function_field.py +++ b/src/sage/rings/function_field/function_field.py @@ -1307,7 +1307,7 @@ def __init__(self, polynomial, names, category=None): TypeError: unable to evaluate 'x' in Fraction Field of Univariate Polynomial Ring in t over Rational Field """ - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial if polynomial.parent().ngens()>1 or not isinstance(polynomial, Polynomial): raise TypeError("polynomial must be univariate a polynomial") if names is None: diff --git a/src/sage/rings/laurent_series_ring.py b/src/sage/rings/laurent_series_ring.py index 37b0455928d..be921f22154 100644 --- a/src/sage/rings/laurent_series_ring.py +++ b/src/sage/rings/laurent_series_ring.py @@ -466,7 +466,8 @@ def _element_constructor_(self, x, n=0, prec=infinity): x^-3 """ from sage.rings.fraction_field_element import is_FractionFieldElement - from sage.structure.element import Polynomial, MPolynomial + from sage.rings.polynomial.polynomial_element import Polynomial + from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.structure.element import parent from sage.libs.pari.all import pari_gen diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 31572ab1c2e..1d3584ba3d1 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -114,7 +114,7 @@ import sage.interfaces.gap import sage.rings.complex_mpfr -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial import sage.rings.real_mpfr import sage.rings.real_mpfi import sage.rings.complex_double diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index 72ee42a0e5b..feb778b6a74 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -35,7 +35,7 @@ from sage.rings.infinity import Infinity from sage.structure.factorization import Factorization from sage.rings.integer_ring import ZZ -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.structure.element import is_Element from .padic_base_leaves import (pAdicRingCappedRelative, pAdicRingCappedAbsolute, diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi index f3aa97e879b..44b3e5ebf9e 100644 --- a/src/sage/rings/padics/padic_template_element.pxi +++ b/src/sage/rings/padics/padic_template_element.pxi @@ -36,7 +36,8 @@ from sage.rings.infinity import infinity from sage.rings.rational import Rational from sage.rings.padics.precision_error import PrecisionError from sage.rings.padics.misc import trim_zeros -from sage.structure.element import canonical_coercion, Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial +from sage.structure.element import canonical_coercion import itertools cdef long maxordp = (1L << (sizeof(long) * 8 - 2)) - 1 diff --git a/src/sage/rings/polynomial/commutative_polynomial.pxd b/src/sage/rings/polynomial/commutative_polynomial.pxd new file mode 100644 index 00000000000..c4a8956daa5 --- /dev/null +++ b/src/sage/rings/polynomial/commutative_polynomial.pxd @@ -0,0 +1,5 @@ +from sage.structure.element cimport CommutativeAlgebraElement + + +cdef class CommutativePolynomial(CommutativeAlgebraElement): + pass diff --git a/src/sage/rings/polynomial/commutative_polynomial.pyx b/src/sage/rings/polynomial/commutative_polynomial.pyx new file mode 100644 index 00000000000..9784f1586c9 --- /dev/null +++ b/src/sage/rings/polynomial/commutative_polynomial.pyx @@ -0,0 +1,10 @@ +cdef class CommutativePolynomial(CommutativeAlgebraElement): + r""" + Abstract base class for commutative polynomials in any number of variables + + It is a common base for :class:`~sage.rings.polynomial.polynomial_element.Polynomial`, + :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial`, and + :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial`. + """ + + pass diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index dd87d6e9c05..aa0d9da9884 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -94,11 +94,13 @@ from sage.structure.richcmp import richcmp from sage.misc.cachefunc import cached_method from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass -from sage.structure.element import RingElement, MPolynomial, InfinitePolynomial as InfinitePolynomial_base +from sage.structure.element import RingElement +from .commutative_polynomial import CommutativePolynomial +from .multi_polynomial import MPolynomial import copy -class InfinitePolynomial(InfinitePolynomial_base, metaclass=InheritComparisonClasscallMetaclass): +class InfinitePolynomial(CommutativePolynomial, metaclass=InheritComparisonClasscallMetaclass): """ Create an element of a Polynomial Ring with a Countably Infinite Number of Variables. diff --git a/src/sage/rings/polynomial/multi_polynomial.pxd b/src/sage/rings/polynomial/multi_polynomial.pxd index fd947a33bb2..5dc75e6bd3f 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pxd +++ b/src/sage/rings/polynomial/multi_polynomial.pxd @@ -1,7 +1,11 @@ -from sage.structure.element cimport MPolynomial as MPolynomial_base +from .commutative_polynomial cimport CommutativePolynomial -cdef class MPolynomial(MPolynomial_base): + +cdef class MPolynomial(CommutativePolynomial): cdef long _hash_c(self) except -1 cpdef _mod_(self, right) cpdef dict _mpoly_dict_recursive(self, tuple vars=*, base_ring=*) + +cdef class MPolynomial_libsingular(MPolynomial): + pass diff --git a/src/sage/rings/polynomial/multi_polynomial.pyx b/src/sage/rings/polynomial/multi_polynomial.pyx index f798a67aa41..65af5f4a1d6 100644 --- a/src/sage/rings/polynomial/multi_polynomial.pyx +++ b/src/sage/rings/polynomial/multi_polynomial.pyx @@ -33,7 +33,7 @@ from sage.rings.real_mpfr import RealField_class,RealField from sage.rings.polynomial.polydict cimport ETuple from sage.rings.polynomial.polynomial_element cimport Polynomial -cdef class MPolynomial(MPolynomial_base): +cdef class MPolynomial(CommutativePolynomial): #################### # Some standard conversions @@ -2623,3 +2623,26 @@ cdef remove_from_tuple(e, int ind): return w[0] else: return tuple(w) + + +cdef class MPolynomial_libsingular(MPolynomial): + r""" + Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular` + + This class is defined for the purpose of :func:`isinstance` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: R1. = QQ[] + sage: isinstance(x, sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular) + False + sage: R2. = QQ[] + sage: isinstance(y, sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular) + True + + By design, there is a unique direct subclass:: + + sage: len(sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular.__subclasses__()) <= 1 + True + """ diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd b/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd index f0518c93f9c..c9cec10e2bc 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pxd @@ -1,11 +1,11 @@ from sage.libs.singular.decl cimport poly, ring -from sage.rings.polynomial.multi_polynomial cimport MPolynomial +from sage.rings.polynomial.multi_polynomial cimport MPolynomial_libsingular as MPolynomial_libsingular_base from sage.rings.polynomial.multi_polynomial_ring_base cimport MPolynomialRing_base cdef class MPolynomialRing_libsingular -cdef class MPolynomial_libsingular(MPolynomial): +cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cdef poly *_poly cdef ring *_parent_ring cpdef _add_(self, other) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 6249cac4199..ca02ffbd791 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -1896,7 +1896,7 @@ def unpickle_MPolynomialRing_libsingular(base_ring, names, term_order): return _multi_variate(base_ring, tuple(names), None, term_order, None) -cdef class MPolynomial_libsingular(MPolynomial): +cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ A multivariate polynomial implemented using libSINGULAR. """ diff --git a/src/sage/rings/polynomial/polynomial_element.pxd b/src/sage/rings/polynomial/polynomial_element.pxd index cafc17eab3f..083f506b222 100644 --- a/src/sage/rings/polynomial/polynomial_element.pxd +++ b/src/sage/rings/polynomial/polynomial_element.pxd @@ -1,12 +1,12 @@ from sage.structure.element import Element from sage.structure.element cimport Element, CommutativeAlgebraElement, ModuleElement -from sage.structure.element cimport Polynomial as Polynomial_base from sage.structure.parent cimport Parent from sage.rings.integer cimport Integer +from .commutative_polynomial cimport CommutativePolynomial from .polynomial_compiled cimport CompiledPolynomialFunction -cdef class Polynomial(Polynomial_base): +cdef class Polynomial(CommutativePolynomial): cdef Polynomial _new_generic(self, list coeffs) cdef char _is_gen cdef CompiledPolynomialFunction _compiled diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 5cff2e446a4..cba9c0ee009 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -189,7 +189,7 @@ from .polynomial_compiled cimport CompiledPolynomialFunction from sage.rings.polynomial.polydict cimport ETuple -cdef class Polynomial(Polynomial_base): +cdef class Polynomial(CommutativePolynomial): """ A polynomial. diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index 90b8645ab82..d9c72b0b05d 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -573,7 +573,7 @@ from sage.rings.complex_interval_field import ComplexIntervalField from sage.rings.complex_interval import is_ComplexIntervalFieldElement from sage.rings.polynomial.all import PolynomialRing -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.number_field.number_field import NumberField, GaussianField, CyclotomicField diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index d496d0543b6..7c922fefb90 100644 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -83,7 +83,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= Type I point centered at 4 + O(5^20) """ from sage.rings.function_field.element import is_FunctionFieldElement - from sage.structure.element import Polynomial + from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.fraction_field_element import FractionFieldElement_1poly_field self._type = None @@ -109,7 +109,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= # is_FunctionFieldElement calls .parent elif hasattr(center, "parent") and hasattr(radius, 'parent'): - from sage.structure.element import MPolynomial + from sage.rings.polynomial.multi_polynomial import MPolynomial if isinstance(center, MPolynomial): try: center = center.univariate_polynomial() diff --git a/src/sage/schemes/curves/constructor.py b/src/sage/schemes/curves/constructor.py index a388e660fef..c3ff0fa9a42 100644 --- a/src/sage/schemes/curves/constructor.py +++ b/src/sage/schemes/curves/constructor.py @@ -36,7 +36,7 @@ from sage.categories.fields import Fields -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.finite_rings.finite_field_constructor import is_FiniteField diff --git a/src/sage/schemes/cyclic_covers/constructor.py b/src/sage/schemes/cyclic_covers/constructor.py index a67a17a2f17..32bdf239b99 100644 --- a/src/sage/schemes/cyclic_covers/constructor.py +++ b/src/sage/schemes/cyclic_covers/constructor.py @@ -8,7 +8,7 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.schemes.affine.affine_space import AffineSpace from .cycliccover_generic import CyclicCover_generic diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index ff59b42bfe9..d924bd8f45c 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -29,7 +29,7 @@ from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.number_field.number_field import is_NumberField -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.rings.ring import is_Ring from sage.categories.fields import Fields diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 4bc0825a35a..dd6d59f55b2 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -86,7 +86,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer import Integer from sage.rings.laurent_series_ring import LaurentSeriesRing -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.fraction_field import FractionField from sage.schemes.elliptic_curves.all import EllipticCurve diff --git a/src/sage/schemes/elliptic_curves/jacobian.py b/src/sage/schemes/elliptic_curves/jacobian.py index dc09a18096e..6cf48d0760a 100644 --- a/src/sage/schemes/elliptic_curves/jacobian.py +++ b/src/sage/schemes/elliptic_curves/jacobian.py @@ -104,7 +104,7 @@ def Jacobian(X, **kwds): pass morphism = kwds.pop('morphism', False) - from sage.structure.element import MPolynomial + from sage.rings.polynomial.multi_polynomial import MPolynomial if isinstance(X, MPolynomial): if morphism: from sage.schemes.curves.constructor import Curve diff --git a/src/sage/schemes/generic/hypersurface.py b/src/sage/schemes/generic/hypersurface.py index 58f8ed517fd..090ffacf59a 100644 --- a/src/sage/schemes/generic/hypersurface.py +++ b/src/sage/schemes/generic/hypersurface.py @@ -18,7 +18,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.schemes.affine.affine_subscheme import AlgebraicScheme_subscheme_affine from sage.schemes.projective.projective_subscheme import AlgebraicScheme_subscheme_projective diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index 49ff0254cd1..e73efa85558 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -25,7 +25,7 @@ import sage.rings.abc from sage.rings.rational_field import is_RationalField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.structure.dynamic_class import dynamic_class diff --git a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py index 9fc24367211..74cdccbaa49 100644 --- a/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py +++ b/src/sage/schemes/hyperelliptic_curves/jacobian_homset.py @@ -49,7 +49,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.integer_ring import ZZ from sage.rings.integer import is_Integer, Integer -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.schemes.generic.homset import SchemeHomset_points from sage.schemes.generic.morphism import is_SchemeMorphism diff --git a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py index 40bb62aae0d..3a60c34bf7d 100644 --- a/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +++ b/src/sage/schemes/hyperelliptic_curves/monsky_washnitzer.py @@ -64,7 +64,7 @@ from sage.rings.infinity import Infinity from sage.rings.laurent_series_ring import is_LaurentSeriesRing from sage.rings.padics.all import pAdicField -from sage.structure.element import Polynomial +from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.ring import CommutativeAlgebra from sage.schemes.elliptic_curves.constructor import EllipticCurve from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve diff --git a/src/sage/schemes/plane_conics/constructor.py b/src/sage/schemes/plane_conics/constructor.py index c1c24049dfe..abff2935854 100644 --- a/src/sage/schemes/plane_conics/constructor.py +++ b/src/sage/schemes/plane_conics/constructor.py @@ -32,7 +32,7 @@ from sage.rings.ring import IntegralDomain from sage.rings.rational_field import is_RationalField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing from sage.rings.fraction_field import is_FractionField diff --git a/src/sage/schemes/plane_quartics/quartic_constructor.py b/src/sage/schemes/plane_quartics/quartic_constructor.py index 53f1494abf0..274eaf049b6 100644 --- a/src/sage/schemes/plane_quartics/quartic_constructor.py +++ b/src/sage/schemes/plane_quartics/quartic_constructor.py @@ -9,7 +9,7 @@ #***************************************************************************** from sage.schemes.projective.projective_space import is_ProjectiveSpace, ProjectiveSpace -from sage.structure.element import MPolynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from .quartic_generic import QuarticCurve_generic diff --git a/src/sage/structure/element.pxd b/src/sage/structure/element.pxd index d0a574a95a1..5c6e295a4b8 100644 --- a/src/sage/structure/element.pxd +++ b/src/sage/structure/element.pxd @@ -239,15 +239,6 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): cdef class Expression(CommutativeRingElement): pass -cdef class CommutativePolynomial(CommutativeAlgebraElement): - pass - -cdef class Polynomial(CommutativePolynomial): - pass - -cdef class MPolynomial(CommutativePolynomial): - pass - cdef class InfinityElement(RingElement): pass diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 6c4bff702e4..de3783053dd 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -47,10 +47,6 @@ abstract base classes. EuclideanDomainElement FieldElement CommutativeAlgebraElement - CommutativePolynomial - Polynomial - MPolynomial - InfinitePolynomial Expression AlgebraElement Matrix @@ -4310,93 +4306,6 @@ cdef class CommutativeAlgebraElement(CommutativeRingElement): ############################################## -cdef class CommutativePolynomial(CommutativeAlgebraElement): - r""" - Abstract base class for commutative polynomials in any number of variables - - It is a common base for :class:`Polynomial`, :class:`MPolynomial`, and - :class:`InfinitePolynomial`. - """ - - pass - - ############################################## - -cdef class Polynomial(CommutativePolynomial): - r""" - Abstract base class for :class:`~sage.rings.polynomial.polynomial_element.Polynomial` - - This class is defined for the purpose of :func:`isinstance` tests. It should not be - instantiated. - - EXAMPLES:: - - sage: R1. = QQ[] - sage: isinstance(x, sage.structure.element.Polynomial) - True - sage: R2. = QQ[] - sage: isinstance(y, sage.structure.element.Polynomial) - False - - By design, there is a unique direct subclass:: - - sage: len(sage.structure.element.Polynomial.__subclasses__()) <= 1 - True - """ - - pass - - ############################################## - -cdef class MPolynomial(CommutativePolynomial): - r""" - Abstract base class for :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial` - - This class is defined for the purpose of :func:`isinstance` tests. It should not be - instantiated. - - EXAMPLES:: - - sage: R1. = QQ[] - sage: isinstance(x, sage.structure.element.MPolynomial) - False - sage: R2. = QQ[] - sage: isinstance(y, sage.structure.element.MPolynomial) - True - - By design, there is a unique direct subclass:: - - sage: len(sage.structure.element.MPolynomial.__subclasses__()) <= 1 - True - """ - - pass - - ############################################## - -cdef class InfinitePolynomial(CommutativePolynomial): - r""" - Abstract base class for :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial` - - This class is defined for the purpose of :func:`isinstance` tests. It should not be - instantiated. - - EXAMPLES:: - - sage: X. = InfinitePolynomialRing(QQ) - sage: isinstance(x[0], sage.structure.element.InfinitePolynomial) - True - - By design, there is a unique direct subclass:: - - sage: len(sage.structure.element.InfinitePolynomial.__subclasses__()) <= 1 - True - """ - - pass - - ############################################## - def is_InfinityElement(x): """ Return ``True`` if x is of type InfinityElement. From 538c2a7a6de1f5063993612926dc63268d38adc5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Jan 2023 17:15:56 -0800 Subject: [PATCH 12/19] Replace use of implementation class from multi_polynomial_libsingular in isinstance tests --- .../algebras/fusion_rings/shm_managers.pyx | 2 +- .../polynomial/infinite_polynomial_element.py | 2 +- .../polynomial/infinite_polynomial_ring.py | 99 ++++++++++--------- .../rings/polynomial/multi_polynomial_ring.py | 2 +- 4 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/sage/algebras/fusion_rings/shm_managers.pyx b/src/sage/algebras/fusion_rings/shm_managers.pyx index 91aba7ba59f..84c3bb22be4 100644 --- a/src/sage/algebras/fusion_rings/shm_managers.pyx +++ b/src/sage/algebras/fusion_rings/shm_managers.pyx @@ -22,7 +22,7 @@ from multiprocessing import shared_memory from sage.algebras.fusion_rings.poly_tup_engine cimport poly_to_tup, tup_fixes_sq, _flatten_coeffs from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational -from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular +from sage.rings.polynomial.multi_polynomial cimport MPolynomial_libsingular from sage.rings.polynomial.polydict cimport ETuple import numpy as np diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index aa0d9da9884..6437a28bb2f 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -695,7 +695,7 @@ def footprint(self): l = len(self.parent()._names) # get the pairs (shift,exponent) of the leading monomial, indexed by the variable names Vars = self._p.parent().variable_names() - from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomial_libsingular + from sage.rings.polynomial.multi_polynomial import MPolynomial_libsingular if isinstance(self._p, MPolynomial_libsingular): L = [(Vars[i].split('_'), e) for i, e in enumerate(self._p.lm().exponents(as_ETuples=False)[0]) if e] elif hasattr(self._p, 'lm'): diff --git a/src/sage/rings/polynomial/infinite_polynomial_ring.py b/src/sage/rings/polynomial/infinite_polynomial_ring.py index 1bc126c1e00..5dc44ec2c10 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_ring.py +++ b/src/sage/rings/polynomial/infinite_polynomial_ring.py @@ -936,7 +936,7 @@ def _element_constructor_(self, x): raise ValueError("cannot convert %s into an element of %s" % (x, self)) # direct conversion will only be used if the underlying polynomials are libsingular. - from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomial_libsingular, MPolynomialRing_libsingular + from sage.rings.polynomial.multi_polynomial import MPolynomial_libsingular # try interpretation in self._P, if we have a dense implementation if hasattr(self, '_P'): if x.parent() is self._P: @@ -945,36 +945,38 @@ def _element_constructor_(self, x): # that MPolynomialRing_polydict does not work in complicated settings. # So, if self._P is libsingular (and this will be the case in many # applications!), we do it "nicely". Otherwise, we have to use sage_eval. - if isinstance(x, MPolynomial_libsingular) and isinstance(self._P, MPolynomialRing_libsingular): - if xmaxind == -1: # Otherwise, x has been an InfinitePolynomial - # We infer the correct variable shift. - # Note: Since we are in the "libsingular" case, there are - # no further "variables" hidden in the base ring of x.parent() + if isinstance(x, MPolynomial_libsingular): + from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular + if isinstance(self._P, MPolynomialRing_libsingular): + if xmaxind == -1: # Otherwise, x has been an InfinitePolynomial + # We infer the correct variable shift. + # Note: Since we are in the "libsingular" case, there are + # no further "variables" hidden in the base ring of x.parent() + try: + VarList = [repr(v) for v in x.variables()] + # since interpretation in base ring + # was impossible, it *must* have + # variables + # This tests admissibility on the fly: + VarList.sort(key=self.varname_key, reverse=True) + except ValueError: + raise ValueError("cannot convert %s into an element of %s - variables are not admissible" % (x, self)) + xmaxind = max([int(v.split('_')[1]) for v in VarList]) try: - VarList = [repr(v) for v in x.variables()] - # since interpretation in base ring - # was impossible, it *must* have - # variables - # This tests admissibility on the fly: - VarList.sort(key=self.varname_key, reverse=True) - except ValueError: - raise ValueError("cannot convert %s into an element of %s - variables are not admissible" % (x, self)) - xmaxind = max([int(v.split('_')[1]) for v in VarList]) - try: - # Apparently, in libsingular, the polynomial conversion is not done by - # name but by position, if the number of variables in the parents coincide. - # So, we shift self._P to achieve xmaxind, and if the number of variables is - # the same then we shift further. We then *must* be - # able to convert x into self._P, or conversion to self is - # impossible (and will be done in InfinitePolynomial(...) - if self._max < xmaxind: - self.gen()[xmaxind] - if self._P.ngens() == x.parent().ngens(): - self.gen()[self._max + 1] - # conversion to self._P will be done in InfinitePolynomial.__init__ - return InfinitePolynomial(self, x) - except (ValueError, TypeError, NameError): - raise ValueError("cannot convert %s (from %s, but variables %s) into an element of %s - no conversion into underlying polynomial ring %s" % (x, x.parent(), x.variables(), self, self._P)) + # Apparently, in libsingular, the polynomial conversion is not done by + # name but by position, if the number of variables in the parents coincide. + # So, we shift self._P to achieve xmaxind, and if the number of variables is + # the same then we shift further. We then *must* be + # able to convert x into self._P, or conversion to self is + # impossible (and will be done in InfinitePolynomial(...) + if self._max < xmaxind: + self.gen()[xmaxind] + if self._P.ngens() == x.parent().ngens(): + self.gen()[self._max + 1] + # conversion to self._P will be done in InfinitePolynomial.__init__ + return InfinitePolynomial(self, x) + except (ValueError, TypeError, NameError): + raise ValueError("cannot convert %s (from %s, but variables %s) into an element of %s - no conversion into underlying polynomial ring %s" % (x, x.parent(), x.variables(), self, self._P)) # By now, x or self._P are not libsingular. Since MPolynomialRing_polydict # is too buggy, we use string evaluation try: @@ -1014,25 +1016,26 @@ def _element_constructor_(self, x): from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing R = PolynomialRing(self._base, VarList, order=self._order) - if isinstance(R, MPolynomialRing_libsingular) and isinstance(x, MPolynomial_libsingular): # everything else is so buggy that it's even not worth to try. - try: - # Problem: If there is only a partial overlap in the variables - # of x.parent() and R, then R(x) raises an error (which, I think, - # is a bug, since we talk here about conversion, not coercion). - # Hence, for being on the safe side, we coerce into a pushout ring: - x = R(1) * x - return InfinitePolynomial(self, x) - except Exception: - # OK, last resort, to be on the safe side + if isinstance(x, MPolynomial_libsingular): # everything else is so buggy that it's even not worth to try. + from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular + if isinstance(R, MPolynomialRing_libsingular): try: - return sage_eval(repr(x), self.gens_dict()) - except (ValueError, TypeError, NameError): - raise ValueError("cannot convert %s into an element of %s; conversion of the underlying polynomial failed" % (x, self)) - else: - try: - return sage_eval(repr(x), self.gens_dict()) - except (ValueError, TypeError, NameError): - raise ValueError("cannot convert %s into an element of %s" % (x, self)) + # Problem: If there is only a partial overlap in the variables + # of x.parent() and R, then R(x) raises an error (which, I think, + # is a bug, since we talk here about conversion, not coercion). + # Hence, for being on the safe side, we coerce into a pushout ring: + x = R(1) * x + return InfinitePolynomial(self, x) + except Exception: + # OK, last resort, to be on the safe side + try: + return sage_eval(repr(x), self.gens_dict()) + except (ValueError, TypeError, NameError): + raise ValueError("cannot convert %s into an element of %s; conversion of the underlying polynomial failed" % (x, self)) + try: + return sage_eval(repr(x), self.gens_dict()) + except (ValueError, TypeError, NameError): + raise ValueError("cannot convert %s into an element of %s" % (x, self)) def tensor_with_ring(self, R): """ diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index f0381318b30..64a49e97ca0 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -420,7 +420,7 @@ def __call__(self, x=0, check=True): except TypeError: pass - from .multi_polynomial_libsingular import MPolynomial_libsingular + from .multi_polynomial import MPolynomial_libsingular if isinstance(x, MPolynomial_polydict): P = x.parent() From 0fcb6fbbe723ba9c591f10766843c53918f3430c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 22 Jan 2023 17:22:25 -0800 Subject: [PATCH 13/19] src/sage/rings/polynomial/commutative_polynomial.pyx: Add doctests --- .../rings/polynomial/commutative_polynomial.pyx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sage/rings/polynomial/commutative_polynomial.pyx b/src/sage/rings/polynomial/commutative_polynomial.pyx index 9784f1586c9..dc9f2cab8b7 100644 --- a/src/sage/rings/polynomial/commutative_polynomial.pyx +++ b/src/sage/rings/polynomial/commutative_polynomial.pyx @@ -5,6 +5,19 @@ cdef class CommutativePolynomial(CommutativeAlgebraElement): It is a common base for :class:`~sage.rings.polynomial.polynomial_element.Polynomial`, :class:`~sage.rings.polynomial.multi_polynomial.MPolynomial`, and :class:`~sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial`. + + EXAMPLES:: + + sage: from sage.rings.polynomial.commutative_polynomial import CommutativePolynomial + sage: K. = PolynomialRing(QQ) + sage: isinstance(x, CommutativePolynomial) + True + sage: K. = PolynomialRing(QQ) + sage: isinstance(x, CommutativePolynomial) + True + sage: X. = InfinitePolynomialRing(ZZ, implementation='sparse') + sage: isinstance(x[2], CommutativePolynomial) + True """ pass From 6e2adaf291edc2c0d34ef390e08aa99cee32e6d0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 24 Jan 2023 18:49:59 -0800 Subject: [PATCH 14/19] InfinitePolynomial: Move _lmul_, _rmul_ here from subclasses --- .../polynomial/infinite_polynomial_element.py | 66 +++++++------------ 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index 6437a28bb2f..ab35e5f31d2 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -480,6 +480,28 @@ def max_index(self): """ return max([Integer(str(X).split('_')[1]) for X in self.variables()]+[-1]) + def _rmul_(self, left): + """ + TESTS:: + + sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: R.from_base_ring(4) # indirect doctest + 4 + + """ + return type(self)(self.parent(), left * self._p) + + def _lmul_(self, right): + """ + TESTS:: + + sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') + sage: alpha[3]*4 # indirect doctest + 4*alpha_3 + + """ + return type(self)(self.parent(), self._p * right) + def _div_(self, x): r""" Division of Infinite Polynomials. @@ -1201,28 +1223,6 @@ def _mul_(self, x): R = self._p.base_ring() return InfinitePolynomial_sparse(self.parent(), R(self._p) * R(x._p)) - def _rmul_(self, left): - """ - TESTS:: - - sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') - sage: R.from_base_ring(4) # indirect doctest - 4 - - """ - return InfinitePolynomial_sparse(self.parent(), left * self._p) - - def _lmul_(self, right): - """ - TESTS:: - - sage: R. = InfinitePolynomialRing(QQ, implementation='sparse') - sage: alpha[3]*4 # indirect doctest - 4*alpha_3 - - """ - return InfinitePolynomial_sparse(self.parent(), self._p * right) - def _sub_(self, x): """ EXAMPLES:: @@ -1508,28 +1508,6 @@ def _mul_(self, x): x._p = P._P(x._p) return InfinitePolynomial_dense(self.parent(), self._p * x._p) - def _rmul_(self, left): - """ - TESTS:: - - sage: R. = InfinitePolynomialRing(QQ) - sage: R.from_base_ring(4) # indirect doctest - 4 - - """ - return InfinitePolynomial_dense(self.parent(), left*self._p) - - def _lmul_(self, right): - """ - TESTS:: - - sage: R. = InfinitePolynomialRing(QQ) - sage: alpha[3]*4 # indirect doctest - 4*alpha_3 - - """ - return InfinitePolynomial_dense(self.parent(), self._p*right) - def _sub_(self, x): """ EXAMPLES:: From cdab0dfc716d77a0a0b2bef7f1779bc29a715385 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 24 Jan 2023 19:08:35 -0800 Subject: [PATCH 15/19] InfinitePolynomial.__classcall_private__: Add doctest --- .../polynomial/infinite_polynomial_element.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index ab35e5f31d2..859f9c407d5 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -169,6 +169,28 @@ class InfinitePolynomial(CommutativePolynomial, metaclass=InheritComparisonClass @staticmethod def __classcall_private__(cls, A, p): + r""" + TESTS:: + + sage: from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial + sage: X. = InfinitePolynomialRing(ZZ, implementation='sparse') + sage: xy = (x[0] + y[0]).polynomial() + sage: xy.parent() + Multivariate Polynomial Ring in x_1, x_0, y_1, y_0 over Integer Ring + sage: sparse_xy = InfinitePolynomial(X, xy); sparse_xy + x_0 + y_0 + sage: isinstance(sparse_xy, InfinitePolynomial) + True + sage: type(sparse_xy) + + sage: X. = InfinitePolynomialRing(ZZ, implementation='dense') + sage: dense_xy = InfinitePolynomial(X, xy); dense_xy + x_0 + y_0 + sage: isinstance(dense_xy, InfinitePolynomial) + True + sage: type(dense_xy) + + """ from sage.structure.element import parent if hasattr(A, '_P'): if parent(p) is A._P or (A._P.base_ring().has_coerce_map_from(parent(p))): From e06e5829216e6b4a68c92976c837901341c0a7d1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Feb 2023 14:01:51 -0800 Subject: [PATCH 16/19] src/sage/rings/polynomial/infinite_polynomial_element.py: Use InfinitePolynomial in isinstance tests, not InfinitePolynomial_sparse --- src/sage/rings/polynomial/infinite_polynomial_element.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/infinite_polynomial_element.py b/src/sage/rings/polynomial/infinite_polynomial_element.py index a56e4f1a1b4..b51ba3fe08a 100644 --- a/src/sage/rings/polynomial/infinite_polynomial_element.py +++ b/src/sage/rings/polynomial/infinite_polynomial_element.py @@ -1267,14 +1267,14 @@ def __call__(self, *args, **kwargs): V = [] for kw in kwargs: value = kwargs[kw] - if isinstance(value, InfinitePolynomial_sparse): + if isinstance(value, InfinitePolynomial): kwargs[kw] = value._p V.append(kw) if hasattr(value._p, 'variables'): V.extend([str(x) for x in value._p.variables()]) args = list(args) for i, arg in enumerate(args): - if isinstance(arg, InfinitePolynomial_sparse): + if isinstance(arg, InfinitePolynomial): args[i] = arg._p if hasattr(arg._p, 'variables'): V.extend([str(x) for x in arg._p.variables()]) @@ -1550,11 +1550,11 @@ def __call__(self, *args, **kwargs): # Replace any InfinitePolynomials by their underlying polynomials for kw in kwargs: value = kwargs[kw] - if isinstance(value, InfinitePolynomial_sparse): + if isinstance(value, InfinitePolynomial): kwargs[kw] = value._p args = list(args) for i, arg in enumerate(args): - if isinstance(arg, InfinitePolynomial_sparse): + if isinstance(arg, InfinitePolynomial): args[i] = arg._p self._p = self.parent().polynomial_ring()(self._p) res = self._p(*args, **kwargs) From 8f5b79901fa874f60f308b4ee93ac867de8fd784 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Feb 2023 20:47:15 -0800 Subject: [PATCH 17/19] src/sage/combinat/schubert_polynomial.py: Use isinstance(..., InfinitePolynomial) without _sparse --- src/sage/combinat/schubert_polynomial.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/schubert_polynomial.py b/src/sage/combinat/schubert_polynomial.py index 8650e599300..a0a682e985e 100644 --- a/src/sage/combinat/schubert_polynomial.py +++ b/src/sage/combinat/schubert_polynomial.py @@ -80,7 +80,7 @@ from sage.misc.cachefunc import cached_method from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ -from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial_sparse +from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.multi_polynomial import MPolynomial import sage.libs.symmetrica.all as symmetrica @@ -463,7 +463,7 @@ def _element_constructor_(self, x): return self._from_dict({perm: self.base_ring().one()}) elif isinstance(x, MPolynomial): return symmetrica.t_POLYNOM_SCHUBERT(x) - elif isinstance(x, InfinitePolynomial_sparse): + elif isinstance(x, InfinitePolynomial): R = x.polynomial().parent() # massage the term order to be what symmetrica expects S = PolynomialRing(R.base_ring(), From ffb4647de92cd6d489fa47d3e013298b6e3fa50d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 20 Feb 2023 09:29:53 -0800 Subject: [PATCH 18/19] src/sage/rings/polynomial/polynomial_element.pyx: Update doctest output (trac->github) --- src/sage/rings/polynomial/polynomial_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 2aae21a315e..0ca80d0ea49 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -155,7 +155,7 @@ cpdef is_Polynomial(f): sage: R. = ZZ[] sage: is_Polynomial(x^3 + x + 1) doctest:...: DeprecationWarning: the function is_Polynomial is deprecated; use isinstance(x, sage.structure.element.Polynomial) instead - See https://trac.sagemath.org/32709 for details. + See https://github.com/sagemath/sage/issues/32709 for details. True sage: S. = R[] sage: f = y^3 + x*y -3*x; f From 3b6535074e07af952be97afb1c5432ef41ba9dde Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 3 Mar 2023 09:05:20 -0800 Subject: [PATCH 19/19] src/sage/quadratic_forms/quadratic_form.py: Replace use of deprecated is_Polynomial, is_MPolynomial --- src/sage/quadratic_forms/quadratic_form.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index f53602f49f3..47f3d8be23e 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -32,8 +32,8 @@ from sage.rings.ring import is_Ring, PrincipalIdealDomain from sage.structure.element import is_Vector from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.polynomial.polynomial_element import is_Polynomial -from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial +from sage.rings.polynomial.polynomial_element import Polynomial +from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.modules.free_module_element import vector from sage.quadratic_forms.genera.genus import genera from sage.quadratic_forms.quadratic_form__evaluate import QFEvaluateVector, QFEvaluateMatrix @@ -576,9 +576,9 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ M_ring = M.base_ring() matrix_init_flag = True - elif is_Polynomial(R) or is_MPolynomial(R): + elif isinstance(R, (Polynomial, MPolynomial)): p = R - + if not p.is_zero() and not (p.is_homogeneous() and p.degree() == 2): raise ValueError("polynomial is neither zero nor homogeneous of degree 2")