Skip to content

Commit

Permalink
gh-35045: Convert result of multivariate polynomial evaluation into c…
Browse files Browse the repository at this point in the history
…orrect parent

    
Importing trac/u/roed/incorrect_parent_when_evaluating_constant_multivar
iate_polynomial...

(meant to fix #33373)
    
URL: #35045
Reported by: Marc Mezzarobba
Reviewer(s): Marc Mezzarobba, Travis Scrimshaw
  • Loading branch information
Release Manager committed Mar 10, 2023
2 parents f6da2bd + 042fdc5 commit 2b03a1a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,9 @@ def _q_expansion_cached(self, prec, fix_d, subs_d, d_num_prec, fix_prec = False)
Y = SC.f_i_ZZ().base_extend(formal_d.parent())

if (self.parent().is_modular()):
qexp = self._rat.subs(x=X, y=Y, d=formal_d)
# z does not appear in self._rat but we need to specialize it for
# the evaluation to land in the correct parent
qexp = self._rat.subs(x=X, y=Y, z=0, d=formal_d)
else:
Z = SC.E2_ZZ().base_extend(formal_d.parent())
qexp = self._rat.subs(x=X, y=Y, z=Z, d=formal_d)
Expand Down
40 changes: 25 additions & 15 deletions src/sage/rings/polynomial/multi_polynomial_libsingular.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2057,7 +2057,18 @@ cdef class MPolynomial_libsingular(MPolynomial):
9
sage: a.parent() is QQ
True
See :trac:`33373`::
sage: k.<a> = GF(2^4)
sage: R.<x> = PolynomialRing(k, 1)
sage: f = R(1)
sage: S.<y> = PolynomialRing(k, 1)
sage: f(y).parent()
Multivariate Polynomial Ring in y over Finite Field in a of size 2^4
"""
cdef Element sage_res

if len(kwds) > 0:
f = self.subs(**kwds)
if len(x) > 0:
Expand All @@ -2076,29 +2087,28 @@ cdef class MPolynomial_libsingular(MPolynomial):
if l != parent._ring.N:
raise TypeError("number of arguments does not match number of variables in parent")

res_parent = coercion_model.common_parent(parent._base, *x)
cdef poly *res # ownership will be transferred to us in the else block
try:
# Attempt evaluation via singular.
coerced_x = [parent.coerce(e) for e in x]
except TypeError:
# give up, evaluate functional
y = parent.base_ring().zero()
sage_res = parent.base_ring().zero()
for (m,c) in self.dict().iteritems():
y += c*mul([ x[i]**m[i] for i in m.nonzero_positions()])
return y

cdef poly *res # ownership will be transferred to us in the next line
singular_polynomial_call(&res, self._poly, _ring, coerced_x, MPolynomial_libsingular_get_element)
res_parent = coercion_model.common_parent(parent._base, *x)

if res == NULL:
return res_parent(0)
if p_LmIsConstant(res, _ring):
sage_res = si2sa( p_GetCoeff(res, _ring), _ring, parent._base )
p_Delete(&res, _ring) # sage_res contains copy
sage_res += c * mul([x[i] ** m[i] for i in m.nonzero_positions()])
else:
sage_res = new_MP(parent, res) # pass on ownership of res to sage_res
singular_polynomial_call(&res, self._poly, _ring, coerced_x, MPolynomial_libsingular_get_element)

if res == NULL:
return res_parent(0)
if p_LmIsConstant(res, _ring):
sage_res = si2sa( p_GetCoeff(res, _ring), _ring, parent._base )
p_Delete(&res, _ring) # sage_res contains copy
else:
sage_res = new_MP(parent, res) # pass on ownership of res to sage_res

if parent(sage_res) is not res_parent:
if sage_res._parent is not res_parent:
sage_res = res_parent(sage_res)
return sage_res

Expand Down
3 changes: 2 additions & 1 deletion src/sage/schemes/riemann_surfaces/riemann_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,7 @@ def rigorous_line_integral(self, upstairs_edge, differentials, bounding_data):
# CCzg is required to be known as we need to know the ring which the minpolys
# lie in.
CCzg, bounding_data_list = bounding_data
CCz = CCzg.univariate_ring(CCzg.gen(1)).base_ring()

d_edge = tuple(u[0] for u in upstairs_edge)
# Using a try-catch here allows us to retain a certain amount of back
Expand Down Expand Up @@ -2193,7 +2194,7 @@ def local_N(ct, rt):
z_1 = a0lc.abs() * prod((cz - r).abs() - rho_z for r in a0roots)
n = minpoly.degree(CCzg.gen(1))
ai_new = [
(minpoly.coefficient({CCzg.gen(1): i}))(z=cz + self._CCz.gen(0))
CCz(minpoly.coefficient({CCzg.gen(1): i}))(z=cz + self._CCz.gen(0))
for i in range(n)
]
ai_pos = [self._RRz([c.abs() for c in h.list()]) for h in ai_new]
Expand Down
2 changes: 1 addition & 1 deletion src/sage/schemes/toric/points.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ def inhomogeneous_equations(self, ring, nonzero_coordinates, cokernel):
z = [ring.zero()] * nrays
for i, value in zip(nonzero_coordinates, z_nonzero):
z[i] = value
return [poly(z) for poly in self.polynomials]
return [poly.change_ring(ring)(z) for poly in self.polynomials]

def solutions_serial(self, inhomogeneous_equations, log_range):
"""
Expand Down

0 comments on commit 2b03a1a

Please sign in to comment.