Skip to content

Commit a6c8806

Browse files
author
Release Manager
committed
gh-39555: Added option to return explicit polynomial in .in_subalgebra <!-- ^ Please provide a concise and informative title. --> <!-- ^ Don't put issue numbers in the title, do this in the PR description below. --> <!-- ^ For example, instead of "Fixes #12345" use "Introduce new method to calculate 1 + 2". --> <!-- v Describe your changes below in detail. --> <!-- v Why is this change required? What problem does it solve? --> <!-- v If this PR resolves an open issue, please link to it here. For example, "Fixes #12345". --> Fixes #39225. Previously the function in_subalgebra in src/sage/rins/polynomial/multi_polynomial_libsingular.pyx returned True or False, depending on whether the polynomial was present in the provided subalgebra. When the parameter 'algorithm' was set to 'groebner' it would do this by generating a polynomial, but this polynomial would not be made available to the user. This function was enhanced by adding a key-word only argument 'certificate' to the function which defaults to False. When the value provided for this argument evaluates to False the function behaves as before. When the value provided evaluates to True and the Groebner algorithm is used the function returns the polynomial generated by the algorithm when it would have otherwise returned True, and returns None when it would have otherwise returned False. Additionally, if the value provided for the 'certificate' argument is a string which evaluates to True then that string will be used to name the variables in the generated polynomial. The existing example for this function has been modified to test this new functionality. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [X] The title is concise and informative. - [X] The description explains in detail what this PR is about. - [X] I have linked a relevant issue or discussion. - [X] I have created tests covering the changes. - [X] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - #12345: short description why this is a dependency --> <!-- - #34567: ... --> URL: #39555 Reported by: Caleb Van't Land Reviewer(s): Caleb Van't Land, Travis Scrimshaw
2 parents fc1166b + d0845dd commit a6c8806

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/sage/rings/polynomial/multi_polynomial_libsingular.pyx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6073,7 +6073,7 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base):
60736073
else:
60746074
return self * self.denominator()
60756075

6076-
def in_subalgebra(self, J, algorithm='algebra_containment'):
6076+
def in_subalgebra(self, J, algorithm='algebra_containment', *, certificate=False):
60776077
"""
60786078
Return whether this polynomial is contained in the subalgebra
60796079
generated by ``J``
@@ -6104,6 +6104,12 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base):
61046104
and only if the remainder involves only the new variables
61056105
`z_i`.
61066106
6107+
- ``certificate`` -- boolean (default: ``False``) or string; if``True``
6108+
and ``algorithm='groebner'``, return the polynomial generated by
6109+
the algorithm if such a polynomial exists, otherwise return ``None``;
6110+
if a nonempty string, then this is used as the name of the variables
6111+
in the returned polynomial, otherwise the name will be ``'newgens'``
6112+
61076113
EXAMPLES::
61086114
61096115
sage: P.<x,y,z> = QQ[]
@@ -6115,6 +6121,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base):
61156121
True
61166122
sage: (a^2).in_subalgebra(J, algorithm='groebner')
61176123
True
6124+
sage: (a^2).in_subalgebra(J, algorithm='groebner', certificate='x')
6125+
x0^2*x1^2
61186126
sage: (a + a^2).in_subalgebra(J)
61196127
True
61206128
"""
@@ -6135,14 +6143,22 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base):
61356143
elif algorithm == "insubring":
61366144
return singular_function('inSubring')(self, R.ideal(J))[0] == 1
61376145
elif algorithm == "groebner":
6138-
new_gens = [f"newgens{i}" for i in range(len(J))]
6146+
var_name = "newgens"
6147+
if (certificate and isinstance(certificate, str)):
6148+
var_name = certificate
6149+
new_gens = [f"{var_name}{i}" for i in range(len(J))]
61396150
ngens = len(new_gens)
61406151
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
61416152
S = PolynomialRing(R.base_ring(), R.gens() + tuple(new_gens),
61426153
order=f'degrevlex({len(R.gens())}),degrevlex({ngens})')
61436154
new_gens = S.gens()[-ngens:]
61446155
I = S.ideal([g - S(j) for (g,j) in zip(new_gens, J)])
61456156
z = S(self).reduce(I)
6157+
if certificate:
6158+
if set(z.variables()).issubset(new_gens):
6159+
T = PolynomialRing(R.base_ring(), tuple(new_gens))
6160+
return T(z)
6161+
return None
61466162
return set(z.variables()).issubset(new_gens)
61476163
else:
61486164
raise ValueError("unknown algorithm")

0 commit comments

Comments
 (0)