Skip to content
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

rings/infinite polynomial ring fixes #37761

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
12fc4bc
return numerator and denominator as elements of self, restrict elemen…
mantepse Apr 6, 2024
a0deca4
add docstring to numerator, remove wrong denominator method (the inhe…
mantepse Apr 7, 2024
690e048
remove workaround and fix InfinitePolynomialRing instead
mantepse Apr 3, 2024
6d4659c
add documentation and tests, remove cached_method
mantepse Apr 3, 2024
0fe5270
add doctest, fix linter
mantepse Apr 7, 2024
064d6ba
add doctest for coercion issue
mantepse Apr 7, 2024
7b49ae1
Fix missing backticks
mantepse Apr 7, 2024
a36aac5
Fix missing backticks
mantepse Apr 7, 2024
b128a60
remove misleading sentence and whitespace
mantepse Apr 7, 2024
8015042
add missing colon
mantepse Apr 7, 2024
385ee8c
use proper sphinx roles
mantepse Apr 7, 2024
6706a39
remove whitespace
mantepse Apr 8, 2024
575731d
improve docstring formatting
mantepse Apr 8, 2024
97dbbc6
remove unnecessary parens
mantepse Apr 8, 2024
9b76cf6
improve docstring
mantepse Apr 8, 2024
2f607aa
fix sphinx role
mantepse Apr 8, 2024
b42e2d9
Merge branch 'sagemath:develop' into rings/infinite_polynomial_ring_f…
mantepse Apr 13, 2024
91ad38e
Merge branch 'sagemath:develop' into rings/infinite_polynomial_ring_f…
mantepse Jun 17, 2024
a8fa295
Merge branch 'sagemath:develop' into rings/infinite_polynomial_ring_f…
mantepse Jul 12, 2024
0b93f3a
Merge branch 'sagemath:develop' into rings/infinite_polynomial_ring_f…
mantepse Jul 19, 2024
3cdc7ad
revert original fix -- replacing self._base(x) with self._base.coerce…
mantepse Jul 27, 2024
c719db3
Apply suggestions concerning docstring formatting from code review
mantepse Aug 6, 2024
3435194
Merge branch 'develop' into rings/infinite_polynomial_ring_fixes
mantepse Aug 6, 2024
7999167
indent forgotten lines
mantepse Aug 7, 2024
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
157 changes: 126 additions & 31 deletions src/sage/rings/polynomial/infinite_polynomial_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,41 @@
"""
return self._p.is_nilpotent()

def numerator(self):
r"""
Return a numerator of ``self``, computed as ``self * self.denominator()``.

.. WARNING::

This is not the numerator of the rational function
defined by ``self``, which would always be ``self`` since it is a
polynomial.

EXAMPLES::

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: p = 2/3*x[1] + 4/9*x[2] - 2*x[1]*x[3]
sage: num = p.numerator(); num
-18*x_3*x_1 + 4*x_2 + 6*x_1

TESTS::

sage: num.parent()
Infinite polynomial ring in x over Rational Field

Check that :issue:`37756` is fixed::

sage: R.<a> = InfinitePolynomialRing(QQ)
sage: P.<x,y> = QQ[]
sage: FF = P.fraction_field()
sage: FF(a[0])
Traceback (most recent call last):
...
TypeError: Could not find a mapping of the passed element to this ring.
"""
P = self.parent()
return InfinitePolynomial(P, self._p.numerator())

@cached_method
def variables(self):
"""
Expand All @@ -569,9 +604,69 @@
()
"""
if hasattr(self._p, 'variables'):
return tuple(self._p.variables())
P = self.parent()
return tuple(InfinitePolynomial(P, v) for v in self._p.variables())
return ()

def monomials(self):
"""
Return the list of monomials in ``self``.

The returned list is decreasingly ordered by the term ordering of
``self.parent()``.

EXAMPLES::

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: p = x[1]^3 + x[2] - 2*x[1]*x[3]
sage: p.monomials()
[x_3*x_1, x_2, x_1^3]

sage: X.<x> = InfinitePolynomialRing(QQ, order='deglex')
sage: p = x[1]^3 + x[2] - 2*x[1]*x[3]
sage: p.monomials()
[x_1^3, x_3*x_1, x_2]
"""
P = self.parent()
return [InfinitePolynomial(P, m) for m in self._p.monomials()]

def monomial_coefficient(self, mon):
tscrim marked this conversation as resolved.
Show resolved Hide resolved
"""
Return the base ring element that is the coefficient of ``mon``
in ``self``.

This function contrasts with the function :meth:`coefficient`,
which returns the coefficient of a monomial viewing this
polynomial in a polynomial ring over a base ring having fewer
variables.

INPUT:

- ``mon`` -- a monomial in the parent of ``self``

OUTPUT: coefficient in base ring

.. SEEALSO::

For coefficients in a base ring of fewer variables,
look at :meth:`coefficient`.

EXAMPLES::

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: f = 2*x[0]*x[2] + 3*x[1]^2
sage: c = f.monomial_coefficient(x[1]^2); c
3
sage: c.parent()
Rational Field

sage: c = f.coefficient(x[2]); c
2*x_0
sage: c.parent()
Infinite polynomial ring in x over Rational Field
"""
return self._p.monomial_coefficient(mon._p)

@cached_method
def max_index(self):
r"""
Expand Down Expand Up @@ -997,42 +1092,42 @@
sage: a.coefficient({x[0]:1, x[1]:1})
2
"""
P = self.parent()
if self._p == 0:
res = 0
elif isinstance(monomial, self.__class__):
if not (self.parent().has_coerce_map_from(monomial.parent())):
res = 0
return P.zero()

Check warning on line 1097 in src/sage/rings/polynomial/infinite_polynomial_element.py

View check run for this annotation

Codecov / codecov/patch

src/sage/rings/polynomial/infinite_polynomial_element.py#L1097

Added line #L1097 was not covered by tests
if isinstance(monomial, self.__class__):
if not P.has_coerce_map_from(monomial.parent()):
return P.zero()

Check warning on line 1100 in src/sage/rings/polynomial/infinite_polynomial_element.py

View check run for this annotation

Codecov / codecov/patch

src/sage/rings/polynomial/infinite_polynomial_element.py#L1100

Added line #L1100 was not covered by tests
if hasattr(self._p, 'variables'):
VarList = [str(X) for X in self._p.variables()]
else:
if hasattr(self._p, 'variables'):
VarList = [str(X) for X in self._p.variables()]
else:
VarList = []
if hasattr(monomial._p, 'variables'):
VarList.extend([str(X) for X in monomial._p.variables()])
VarList = list(set(VarList))
VarList.sort(key=self.parent().varname_key, reverse=True)
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
if len(VarList) == 1:
# 'xx' is guaranteed to be no variable
# name of monomial, since coercions
# were tested before
R = PolynomialRing(self._p.base_ring(), VarList + ['xx'], order=self.parent()._order)

res = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)(R(self._p).coefficient(R(monomial._p)))
else:
R = PolynomialRing(self._p.base_ring(), VarList, order=self.parent()._order)
res = R(self._p).coefficient(R(monomial._p))
elif isinstance(monomial, dict):
VarList = []

Check warning on line 1104 in src/sage/rings/polynomial/infinite_polynomial_element.py

View check run for this annotation

Codecov / codecov/patch

src/sage/rings/polynomial/infinite_polynomial_element.py#L1104

Added line #L1104 was not covered by tests
if hasattr(monomial._p, 'variables'):
VarList.extend([str(X) for X in monomial._p.variables()])
VarList = list(set(VarList))
VarList.sort(key=P.varname_key, reverse=True)
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
if len(VarList) == 1:
# 'xx' is guaranteed to be no variable
# name of monomial, since coercions
# were tested before
R = PolynomialRing(self._p.base_ring(), VarList + ['xx'], order=P._order)
S = PolynomialRing(self._p.base_ring(), VarList, order=P._order)
res = S(R(self._p).coefficient(R(monomial._p)))
return InfinitePolynomial(P, res)

R = PolynomialRing(self._p.base_ring(), VarList, order=P._order)
res = R(self._p).coefficient(R(monomial._p))
return InfinitePolynomial(P, res)

if isinstance(monomial, dict):
if monomial:
I = iter(monomial)
K = next(I)
del monomial[K]
res = self.coefficient(K).coefficient(monomial)
else:
return self
else:
raise TypeError("Objects of type %s have no coefficients in InfinitePolynomials" % (type(monomial)))
return self.parent()(res)
return self.coefficient(K).coefficient(monomial)
return self
raise TypeError("Objects of type %s have no coefficients in InfinitePolynomials" % (type(monomial)))

Check warning on line 1130 in src/sage/rings/polynomial/infinite_polynomial_element.py

View check run for this annotation

Codecov / codecov/patch

src/sage/rings/polynomial/infinite_polynomial_element.py#L1130

Added line #L1130 was not covered by tests

# Essentials for Buchberger
def reduce(self, I, tailreduce=False, report=None):
Expand Down
19 changes: 15 additions & 4 deletions src/sage/rings/polynomial/infinite_polynomial_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@
class InfinitePolynomialRingFactory(UniqueFactory):
"""
A factory for creating infinite polynomial ring elements. It
handles making sure that they are unique as well as handling
pickling. For more details, see
makes sure that they are unique as well as handling pickling.
For more details, see
:class:`~sage.structure.factory.UniqueFactory` and
:mod:`~sage.rings.polynomial.infinite_polynomial_ring`.

Expand Down Expand Up @@ -564,7 +564,7 @@

def __next__(self):
"""
Return a dictionary that can be used to interprete strings in the base ring of ``self``.
Return a dictionary that can be used to interpret strings in the base ring of ``self``.

EXAMPLES::

Expand Down Expand Up @@ -701,7 +701,7 @@
names = ['x']
for n in names:
if not (isinstance(n, str) and n.isalnum() and (not n[0].isdigit())):
raise ValueError("generator names must be alpha-numeric strings not starting with a digit, but %s is not" % n)
raise ValueError("generator names must be alphanumeric strings not starting with a digit, but %s is not" % n)

Check warning on line 704 in src/sage/rings/polynomial/infinite_polynomial_ring.py

View check run for this annotation

Codecov / codecov/patch

src/sage/rings/polynomial/infinite_polynomial_ring.py#L704

Added line #L704 was not covered by tests
if len(names) != len(set(names)):
raise ValueError("generator names must be pairwise different")
self._names = tuple(names)
Expand Down Expand Up @@ -884,6 +884,17 @@
Traceback (most recent call last):
...
ValueError: cannot convert 1/3 into an element of Infinite polynomial ring in x over Integer Ring

.. WARNING::

The :issue:`37756` is not yet fixed::

sage: L.<x, y> = QQ[]
sage: R.<a> = InfinitePolynomialRing(QQ)
sage: M = InfinitePolynomialRing(L, names=["a"])
sage: c = a[0]
sage: M(c) # known bug
a_0
"""
from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial
# In many cases, the easiest solution is to "simply" evaluate
Expand Down
Loading