Skip to content

Commit 33c99ab

Browse files
author
Release Manager
committed
gh-36127: Bandaid for polynomial evaluation There was a problem when evaluating polynomials: the following was failing ``` sage: x,y=polygens(QQ,'x,y') sage: t=PolynomialRing(x.parent(),'t').gen() sage: F=x*y*t sage: F(x=1) y*t ``` I propose a fix that hopefully does not break anything else. We look at a non-zero coefficient to try to guess the correct new base ring, instead of looking at the constant term. This does not fix the following inconsistent behaviour: ``` sage: x.parent().zero()(x=1) 0 sage: parent(_) Rational Field sage: x.parent().one()(x=1) 1 sage: parent(_) Multivariate Polynomial Ring in x, y over Rational Field ``` ### 📝 Checklist - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. URL: #36127 Reported by: Frédéric Chapoton Reviewer(s): Frédéric Chapoton, Marc Mezzarobba
2 parents 52c7956 + 956aaf0 commit 33c99ab

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

src/sage/rings/polynomial/polynomial_element.pyx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,14 @@ cdef class Polynomial(CommutativePolynomial):
605605
606606
TESTS:
607607
608+
One test for a simple evaluation::
609+
610+
sage: x, y = polygens(ZZ, 'x,y')
611+
sage: t = polygen(x.parent(), 't')
612+
sage: F = x*y*t
613+
sage: F(y=1)
614+
x*t
615+
608616
The following shows that :trac:`2360` is indeed fixed. ::
609617
610618
sage: R.<x,y> = ZZ[]
@@ -783,14 +791,20 @@ cdef class Polynomial(CommutativePolynomial):
783791
- Francis Clarke (2012-08-26): fix keyword substitution in the
784792
leading coefficient.
785793
"""
786-
cdef long i, j
794+
cdef long i, j, d, deg
787795
cdef Polynomial pol = self
788-
cdef long d
789796
cdef ETuple etup
790797
cdef list cs
791798
cdef dict coeff_sparse, coeff_dict
792799

793-
cst = self._parent._base.zero() if self.degree() < 0 else self.get_unsafe(0)
800+
deg = self.degree()
801+
if deg < 0:
802+
top = self._parent._base.one()
803+
cst = self._parent._base.zero()
804+
else:
805+
top = self.get_unsafe(deg)
806+
cst = self.get_unsafe(0)
807+
794808
a = args[0] if len(args) == 1 else None
795809
if kwds or not (isinstance(a, Element) or PyNumber_Check(a)):
796810
# slow path
@@ -816,18 +830,22 @@ cdef class Polynomial(CommutativePolynomial):
816830
try:
817831
# Note that we may be calling a different implementation that
818832
# is more permissive about its arguments than we are.
819-
cst = cst(*args, **kwds)
820-
eval_coeffs = True
833+
top = top(*args, **kwds)
821834
except TypeError:
822835
if args: # bwd compat: nonsense *keyword* arguments are okay
823836
raise TypeError("Wrong number of arguments")
837+
else:
838+
eval_coeffs = True
824839

825840
# Evaluate the coefficients, then fall through to evaluate the
826841
# resulting univariate polynomial
827842

828843
if eval_coeffs:
844+
new_base = parent(top)
845+
# tentative common parent of the evaluated coefficients
829846
pol = pol.map_coefficients(lambda c: c(*args, **kwds),
830-
new_base_ring=parent(cst))
847+
new_base_ring=new_base)
848+
cst = cst(*args, **kwds)
831849

832850
R = parent(a)
833851

@@ -840,8 +858,6 @@ cdef class Polynomial(CommutativePolynomial):
840858
if isinstance(a, Polynomial) and a.base_ring() is pol._parent._base:
841859
if (<Polynomial> a).is_gen():
842860
return R(pol)
843-
if (<Polynomial> a).is_zero():
844-
return R(cst)
845861
d = (<Polynomial> a).degree()
846862
if d < 0: # f(0)
847863
return R(cst)
@@ -10210,7 +10226,7 @@ cdef class Polynomial(CommutativePolynomial):
1021010226
R = R.change_ring(new_base_ring)
1021110227
elif isinstance(f, Map):
1021210228
R = R.change_ring(f.codomain())
10213-
return R({k: f(v) for (k,v) in self.dict().items()})
10229+
return R({k: f(v) for k, v in self.dict().items()})
1021410230

1021510231
def is_cyclotomic(self, certificate=False, algorithm="pari"):
1021610232
r"""

0 commit comments

Comments
 (0)