Skip to content

Add ABCs CommutativePolynomial, MPolynomial_libsingular, InfinitePolynomial; deprecate is_Polynomial, is_MPolynomial #35076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking β€œSign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
eb3a270
sage.structure.element: Add ABCs Polynomial, MPolynomial, use for isi…
mkoeppe Dec 6, 2022
6696f5c
Use ABC MPolynomial for isinstance testing
mkoeppe Dec 6, 2022
79f7e62
Fixups
mkoeppe Dec 6, 2022
ed050bb
sage.rings.polynomial: Make it a namespace package
mkoeppe Dec 6, 2022
0613280
sage.structure.element: Introduce common base class CommutativePolyno…
mkoeppe Jan 7, 2023
27e8889
sage.structure.element: Introduce ABC InfinitePolynomial
mkoeppe Jan 7, 2023
57228f5
src/sage/structure/element.pyx: Update hierarchy in documentation
mkoeppe Jan 7, 2023
95e0adc
src/sage/structure/element.pyx: Add unique-direct-subclass tests
mkoeppe Jan 7, 2023
1fd625c
src/sage/structure/element.pyx: Add unique-direct-subclass test for E…
mkoeppe Jan 7, 2023
960506b
InfinitePolynomial: Change from constructor function to base class wi…
mkoeppe Jan 18, 2023
fd54c82
Remove ABCs sage.structure.element.*Polynomial; introduce ABCs in sag…
mkoeppe Jan 18, 2023
538c2a7
Replace use of implementation class from multi_polynomial_libsingular…
mkoeppe Jan 23, 2023
0fcb6fb
src/sage/rings/polynomial/commutative_polynomial.pyx: Add doctests
mkoeppe Jan 23, 2023
6e2adaf
InfinitePolynomial: Move _lmul_, _rmul_ here from subclasses
mkoeppe Jan 25, 2023
cdab0df
InfinitePolynomial.__classcall_private__: Add doctest
mkoeppe Jan 25, 2023
f7e9f41
Merge tag '9.8' into t/32709/sage_structure_element__add_abcs_polynom…
mkoeppe Feb 11, 2023
e06e582
src/sage/rings/polynomial/infinite_polynomial_element.py: Use Infinit…
mkoeppe Feb 12, 2023
6b557c0
Merge tag '10.0.beta0' into t/32709/sage_structure_element__add_abcs_…
mkoeppe Feb 13, 2023
8f5b799
src/sage/combinat/schubert_polynomial.py: Use isinstance(..., Infinit…
mkoeppe Feb 13, 2023
2d32a2e
Merge branch 'develop' into t/32709/sage_structure_element__add_abcs_…
mkoeppe Feb 13, 2023
95b8793
Merge branch 'develop' into t/32709/sage_structure_element__add_abcs_…
mkoeppe Feb 14, 2023
488a8b1
Merge branch 'develop' into t/32709/sage_structure_element__add_abcs_…
mkoeppe Feb 19, 2023
ffb4647
src/sage/rings/polynomial/polynomial_element.pyx: Update doctest outp…
mkoeppe Feb 20, 2023
2993660
Merge remote-tracking branch 'upstream/develop' into t/32709/sage_str…
mkoeppe Mar 3, 2023
3b65350
src/sage/quadratic_forms/quadratic_form.py: Replace use of deprecated…
mkoeppe Mar 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/sage/algebras/fusion_rings/shm_managers.pyx
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions src/sage/combinat/kazhdan_lusztig.py
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
#*****************************************************************************


from sage.rings.polynomial.polynomial_element import is_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
@@ -76,7 +76,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"
11 changes: 5 additions & 6 deletions src/sage/combinat/schubert_polynomial.py
Original file line number Diff line number Diff line change
@@ -80,10 +80,9 @@
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 is_MPolynomial

from sage.rings.polynomial.multi_polynomial import MPolynomial
import sage.libs.symmetrica.all as symmetrica


@@ -150,7 +149,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
@@ -462,9 +461,9 @@ 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)
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(),
6 changes: 3 additions & 3 deletions src/sage/combinat/sf/sfa.py
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.polynomial_element import is_Polynomial
from sage.rings.polynomial.multi_polynomial import is_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
@@ -6409,7 +6409,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 isinstance(x, MPolynomial):
return all(c >= 0 for c in x.coefficients(sparse=False))
else:
return x >= 0
4 changes: 2 additions & 2 deletions src/sage/crypto/boolean_function.pyx
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.polynomial_element import Polynomial

from sage.misc.superseded import deprecated_function_alias

@@ -327,7 +327,7 @@ cdef class BooleanFunction(SageObject):
bitset_init(self._truth_table, <mp_bitcnt_t> (1<<self._nvariables))
bitset_zero(self._truth_table)

elif is_Polynomial(x):
elif isinstance(x, Polynomial):
K = x.base_ring()
if is_FiniteField(K) and K.characteristic() == 2:
self._nvariables = K.degree()
4 changes: 2 additions & 2 deletions src/sage/crypto/mq/rijndael_gf.py
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.multi_polynomial 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))
4 changes: 2 additions & 2 deletions src/sage/crypto/sbox.pyx
Original file line number Diff line number Diff line change
@@ -173,12 +173,12 @@ cdef class SBox(SageObject):
sage: S.output_size()
3
"""
from sage.rings.polynomial.polynomial_element import is_Polynomial
from sage.rings.polynomial.polynomial_element import Polynomial

if "S" in kwargs:
args = kwargs["S"]

if len(args) == 1 and is_Polynomial(args[0]):
if len(args) == 1 and isinstance(args[0], Polynomial):
# SBox defined via Univariate Polynomial, compute lookup table
# by evaluating the polynomial on every base_ring element
poly = args[0]
4 changes: 2 additions & 2 deletions src/sage/crypto/stream.py
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.polynomial_element import is_Polynomial
from sage.rings.polynomial.polynomial_element import Polynomial


IntegerModRing = IntegerModFactory("IntegerModRing")
@@ -73,7 +73,7 @@ def __call__(self, key):
if not isinstance(key, (list, tuple)) and len(key) == 2:
raise TypeError("Argument key (= %s) must be a list of tuple of length 2" % key)
poly, IS = key
if not is_Polynomial(poly):
if not isinstance(poly, Polynomial):
raise TypeError("poly (= %s) must be a polynomial." % poly)
if not isinstance(IS, (list, tuple)):
raise TypeError("IS (= %s) must be an initial in the key space." % IS)
8 changes: 4 additions & 4 deletions src/sage/groups/affine_gps/group_element.py
Original file line number Diff line number Diff line change
@@ -414,13 +414,13 @@ def __call__(self, v):
if v in parent.vector_space():
return self._A*v + self._b

from sage.rings.polynomial.polynomial_element import is_Polynomial
if is_Polynomial(v) and parent.degree() == 1:
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.rings.polynomial.multi_polynomial import is_MPolynomial
if is_MPolynomial(v) and parent.degree() == v.parent().ngens():
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
image_coords = self._A * vector(ring, ring.gens()) + self._b
8 changes: 4 additions & 4 deletions src/sage/groups/perm_gps/permgroup_element.pyx
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.polynomial_element import is_Polynomial
from sage.rings.polynomial.multi_polynomial import is_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
@@ -1225,12 +1225,12 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement):
"""
if not self_on_left:
left = x
if is_Polynomial(left):
if isinstance(left, Polynomial):
if self != 1:
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:
2 changes: 1 addition & 1 deletion src/sage/libs/symmetrica/sb.pxi
Original file line number Diff line number Diff line change
@@ -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")
6 changes: 3 additions & 3 deletions src/sage/libs/symmetrica/symmetrica.pxi
Original file line number Diff line number Diff line change
@@ -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

@@ -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
is_MPolynomial = sage.rings.polynomial.multi_polynomial_element.is_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
Original file line number Diff line number Diff line change
@@ -290,7 +290,7 @@
from .bundle_connection import BundleConnection
from .levi_civita_connection import LeviCivitaConnection
from sage.symbolic.expression import Expression
from sage.rings.polynomial.polynomial_element import is_Polynomial
from sage.rings.polynomial.polynomial_element import Polynomial
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing


@@ -795,7 +795,7 @@ def _element_constructor_(self, x, **kwargs):
Characteristic cohomology class pontr(TM) of the Tangent bundle
TM over the 8-dimensional differentiable manifold M
"""
if isinstance(x, (str, Expression)) or is_Polynomial(x):
if isinstance(x, (str, Expression)) or isinstance(x, Polynomial):
return self._build_element(x, **kwargs)

R = self.base_ring()
@@ -983,7 +983,7 @@ def _build_element(self, *args, **kwargs):
val = P(val.taylor(x, 0, pow_range))

# turn polynomial into a characteristic cohomology class via sequences
if is_Polynomial(val):
if isinstance(val, Polynomial):
if class_type is None:
raise TypeError(f'class_type must be stated if {val} '
f'is a polynomial')
4 changes: 2 additions & 2 deletions src/sage/modular/modsym/ambient.py
Original file line number Diff line number Diff line change
@@ -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.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
@@ -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)
4 changes: 2 additions & 2 deletions src/sage/quadratic_forms/binary_qf.py
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.multi_polynomial 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]]
4 changes: 2 additions & 2 deletions src/sage/quadratic_forms/constructions.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
##

from sage.rings.integer_ring import ZZ
from sage.rings.polynomial.polynomial_element import is_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

@@ -46,7 +46,7 @@ def BezoutianQuadraticForm(f, g):

"""
# Check that f and g are polynomials with a common base ring
if not is_Polynomial(f) or not is_Polynomial(g):
if not isinstance(f, Polynomial) or not isinstance(g, Polynomial):
raise TypeError("one of your inputs is not a polynomial")
if f.base_ring() != g.base_ring(): # TO DO: Change this to allow coercion!
raise TypeError("these polynomials are not defined over the same coefficient ring")
4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/element_ntl_gf2e.pyx
Original file line number Diff line number Diff line change
@@ -1004,8 +1004,8 @@ 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.rings.polynomial.polynomial_element import is_Polynomial
sage: is_Polynomial(e.polynomial())
sage: from sage.rings.polynomial.polynomial_element import Polynomial
sage: isinstance(e.polynomial(), Polynomial)
True

sage: e.polynomial('x')
4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/finite_field_base.pyx
Original file line number Diff line number Diff line change
@@ -1521,7 +1521,7 @@ cdef class FiniteField(Field):
True
"""
from .finite_field_constructor import GF
from sage.rings.polynomial.polynomial_element import is_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
@@ -1532,7 +1532,7 @@ cdef class FiniteField(Field):
E = GF((self.characteristic(), modulus), name=name, **kwds)
elif isinstance(modulus, (list, tuple)):
E = GF((self.characteristic(), len(modulus) - 1), name=name, modulus=modulus, **kwds)
elif is_Polynomial(modulus):
elif isinstance(modulus, Polynomial):
if modulus.change_ring(self).is_irreducible():
E = GF((self.characteristic(), modulus.degree()), name=name, modulus=modulus, **kwds)
else:
4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/finite_field_constructor.py
Original file line number Diff line number Diff line change
@@ -173,7 +173,7 @@

from collections import defaultdict
from sage.structure.category_object import normalize_names

from sage.rings.polynomial.polynomial_element import Polynomial
from sage.rings.integer import Integer

# the import below is just a redirection
@@ -641,7 +641,7 @@ def create_key_and_extra_args(self, order, name=None, modulus=None, names=None,
else:
self._modulus_cache[order][modulus] = modulus = R.irreducible_element(n, algorithm=modulus)
else:
if sage.rings.polynomial.polynomial_element.is_Polynomial(modulus):
if isinstance(modulus, Polynomial):
modulus = modulus.change_variable_name('x')
modulus = R(modulus).monic()

4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/finite_field_givaro.py
Original file line number Diff line number Diff line change
@@ -137,8 +137,8 @@ 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.rings.polynomial.polynomial_element import is_Polynomial
if not is_Polynomial(modulus):
from sage.rings.polynomial.polynomial_element import Polynomial
if not isinstance(modulus, Polynomial):
raise TypeError("modulus must be a polynomial")

self._cache = Cache_givaro(self, p, k, modulus, repr, cache)
4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/finite_field_ntl_gf2e.py
Original file line number Diff line number Diff line change
@@ -138,8 +138,8 @@ 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.rings.polynomial.polynomial_element import is_Polynomial
if not is_Polynomial(modulus):
from sage.rings.polynomial.polynomial_element import Polynomial
if not isinstance(modulus, Polynomial):
raise TypeError("modulus must be a polynomial")

self._cache = Cache_ntl_gf2e(self, k, modulus)
4 changes: 2 additions & 2 deletions src/sage/rings/finite_rings/residue_field.pyx
Original file line number Diff line number Diff line change
@@ -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.rings.polynomial.polynomial_element import is_Polynomial
from sage.rings.polynomial.polynomial_element import Polynomial

from sage.structure.factory import UniqueFactory
from sage.structure.element cimport parent
@@ -300,7 +300,7 @@ class ResidueFieldFactory(UniqueFactory):
p = p.parent().ring_of_integers().ideal(p)
else:
p = p.parent().ideal(p)
elif is_Polynomial(p):
elif isinstance(p, Polynomial):
p = p.parent().ideal(p)
#elif isinstance(p.parent(), FractionField_1poly_field):
# p = p.parent().ring_of_integers().ideal(p)
4 changes: 2 additions & 2 deletions src/sage/rings/function_field/function_field.py
Original file line number Diff line number Diff line change
@@ -1307,8 +1307,8 @@ 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.rings.polynomial.polynomial_element import is_Polynomial
if polynomial.parent().ngens()>1 or not is_Polynomial(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:
names = (polynomial.variable_name(), )
Loading