Skip to content

Commit

Permalink
Trac #33463: Fix some corner and special cases concerning localizatio…
Browse files Browse the repository at this point in the history
…n of integral domains

The aime of this ticket is to fix the following issues:

{{{#!sage
sage: L = ZZ.localization(5)
sage: o = L(0)
sage: o.is_unit()
Traceback (most recent call last)
...
RecursionError: maximum recursion depth exceeded while calling a Python
object
}}}

{{{#!sage
sage: R = ZZ.localization(5)
sage: S = R.localization(~5)
Traceback (most recent call last)
...
TypeError: no conversion of this rational to integer
}}}

{{{#!sage
sage: Lau.<u, v> = LaurentPolynomialRing(ZZ)
sage: LauL = Lau.localization(u+1)
sage: LauL(~u)
Traceback (most recent call last)
...
NotImplementedError:
}}}

In addition a method `factor` is added.

URL: https://trac.sagemath.org/33463
Reported by: soehms
Ticket author(s): Sebastian Oehms
Reviewer(s): Travis Scrimshaw, Samuel Lelièvre
  • Loading branch information
Release Manager committed Mar 8, 2022
2 parents 48a3b47 + fc1865a commit b9155bf
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/sage/rings/localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
AUTHORS:
- Sebastian Oehms 2019-12-09: initial version.
- Sebastian Oehms 2022-03-05: fix some corner cases and add :meth:`factor` (:trac:`33463`)
"""


Expand Down Expand Up @@ -362,6 +363,35 @@ def _lmul_(self, c):
"""
return self.parent()._fraction_to_element(self._value * c)

def factor(self, proof=None):
r"""
Return the factorization of this polynomial.
INPUT:
- ``proof`` -- (optional) if given it is passed to the
corresponding method of the numerator of ``self``
EXAMPLES::
sage: P.<X, Y> = QQ['x, y']
sage: L = P.localization(X-Y)
sage: x, y = L.gens()
sage: p = (x^2 - y^2)/(x-y)^2
sage: p.factor()
(1/(x - y)) * (x + y)
"""
num = self._value.numerator()
den = self._value.denominator()
if proof is not None:
F = num.factor(proof=proof)
else:
F = num.factor()
P = self.parent()
fac = [(P(f), e) for (f, e) in F]
from sage.structure.factorization import Factorization
return Factorization(fac, unit=~P(den)*F.unit())

def _im_gens_(self, codomain, im_gens, base_map=None):
"""
EXAMPLES::
Expand Down Expand Up @@ -589,7 +619,20 @@ class Localization(IntegralDomain, UniqueRepresentation):
...
ValueError: factor x^2 + 2 of denominator is not a unit
sage: Lau.<u, v> = LaurentPolynomialRing(ZZ)
sage: LauL = Lau.localization(u+1)
sage: LauL(~u).parent()
Multivariate Polynomial Ring in u, v over Integer Ring localized at (v, u, u + 1)
More examples will be shown typing ``sage.rings.localization?``
TESTS:
Check that :trac:`33463` is fixed::
sage: R = ZZ.localization(5)
sage: R.localization(~5)
Integer Ring localized at (5,)
"""

Element = LocalizationElement
Expand All @@ -612,8 +655,14 @@ def __init__(self, base_ring, additional_units, names=None, normalize=True, cate
if not type(additional_units) is list:
additional_units = [additional_units]

from sage.rings.polynomial.laurent_polynomial_ring import is_LaurentPolynomialRing
if is_LaurentPolynomialRing(base_ring):
additional_units += list(base_ring.gens())
base_ring = base_ring.polynomial_ring()

if isinstance(base_ring, Localization):
# don't allow recursive constructions
additional_units = [au for au in additional_units if ~au not in base_ring._additional_units] # :trac:`33463`
additional_units += base_ring._additional_units
base_ring = base_ring.base_ring()

Expand Down Expand Up @@ -791,7 +840,18 @@ def _cut_off_additional_units_from_base_ring_element(self, x):
1
sage: L._cut_off_additional_units_from_base_ring_element(x*z)
1
TESTS:
Check that :trac:`33463` is fixed::
sage: L = ZZ.localization(5)
sage: L(0).is_unit()
False
"""
if x.is_zero() or x.numerator().is_unit():
# treat corner cases
return x
add_units = self._additional_units
res = x
for au in add_units:
Expand Down

0 comments on commit b9155bf

Please sign in to comment.