Skip to content

Commit 9251f8b

Browse files
author
Release Manager
committed
sagemathgh-40392: moving two methods to the categories of rings and fields as another step towards getting rid of the auld `Ring` class. - epsilon method to Rings : This method is apparently not used anywhere inside sage. Let's assume it may be used somewhere outside in the wild. - an_embedding method to Fields - also removing a duplicate method in the category of Fields ### 📝 Checklist - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. URL: sagemath#40392 Reported by: Frédéric Chapoton Reviewer(s):
2 parents 2fc8c55 + 2d4b2b8 commit 9251f8b

File tree

4 files changed

+113
-123
lines changed

4 files changed

+113
-123
lines changed

src/doc/en/thematic_tutorials/coercion_and_categories.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ as this base class still provides a few more methods than a general parent::
120120
'_one_element',
121121
'_pseudo_fraction_field',
122122
'_zero_element',
123-
'an_embedding',
124123
'base_extend',
125-
'epsilon',
126124
'extension',
127125
'fraction_field',
128126
'gen',

src/sage/categories/fields.py

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,58 @@ def algebraic_closure(self):
277277
"""
278278
raise NotImplementedError("algebraic closures of general fields not implemented")
279279

280+
def an_embedding(self, K):
281+
r"""
282+
Return some embedding of this field into another field `K`,
283+
and raise a :class:`ValueError` if none exists.
284+
285+
EXAMPLES::
286+
287+
sage: GF(2).an_embedding(GF(4))
288+
Ring morphism:
289+
From: Finite Field of size 2
290+
To: Finite Field in z2 of size 2^2
291+
Defn: 1 |--> 1
292+
sage: GF(4).an_embedding(GF(8))
293+
Traceback (most recent call last):
294+
...
295+
ValueError: no embedding from Finite Field in z2 of size 2^2 to Finite Field in z3 of size 2^3
296+
sage: GF(4).an_embedding(GF(16))
297+
Ring morphism:
298+
From: Finite Field in z2 of size 2^2
299+
To: Finite Field in z4 of size 2^4
300+
Defn: z2 |--> z4^2 + z4
301+
302+
::
303+
304+
sage: CyclotomicField(5).an_embedding(QQbar)
305+
Coercion map:
306+
From: Cyclotomic Field of order 5 and degree 4
307+
To: Algebraic Field
308+
sage: CyclotomicField(3).an_embedding(CyclotomicField(7))
309+
Traceback (most recent call last):
310+
...
311+
ValueError: no embedding from Cyclotomic Field of order 3 and degree 2 to Cyclotomic Field of order 7 and degree 6
312+
sage: CyclotomicField(3).an_embedding(CyclotomicField(6))
313+
Generic morphism:
314+
From: Cyclotomic Field of order 3 and degree 2
315+
To: Cyclotomic Field of order 6 and degree 2
316+
Defn: zeta3 -> zeta6 - 1
317+
"""
318+
if self.characteristic() != K.characteristic():
319+
raise ValueError(f'no embedding from {self} to {K}: incompatible characteristics')
320+
321+
H = self.Hom(K)
322+
try:
323+
return H.natural_map()
324+
except TypeError:
325+
pass
326+
from sage.categories.sets_cat import EmptySetError
327+
try:
328+
return H.an_element()
329+
except EmptySetError:
330+
raise ValueError(f'no embedding from {self} to {K}')
331+
280332
def prime_subfield(self):
281333
"""
282334
Return the prime subfield of ``self``.
@@ -699,22 +751,6 @@ def vector_space(self, *args, **kwds):
699751
"""
700752
return self.free_module(*args, **kwds)
701753

702-
def _pseudo_fraction_field(self):
703-
"""
704-
The fraction field of ``self`` is always available as ``self``.
705-
706-
EXAMPLES::
707-
708-
sage: QQ._pseudo_fraction_field()
709-
Rational Field
710-
sage: K = GF(5)
711-
sage: K._pseudo_fraction_field()
712-
Finite Field of size 5
713-
sage: K._pseudo_fraction_field() is K
714-
True
715-
"""
716-
return self
717-
718754
class ElementMethods:
719755
def euclidean_degree(self):
720756
r"""

src/sage/categories/rings.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,67 @@ def random_element(self, *args):
17471747
a, b = args[0], args[1]
17481748
return randint(a, b) * self.one()
17491749

1750+
@cached_method
1751+
def epsilon(self):
1752+
"""
1753+
Return the precision error of elements in this ring.
1754+
1755+
.. NOTE:: This is not used anywhere inside the code base.
1756+
1757+
EXAMPLES::
1758+
1759+
sage: RDF.epsilon()
1760+
2.220446049250313e-16
1761+
sage: ComplexField(53).epsilon() # needs sage.rings.real_mpfr
1762+
2.22044604925031e-16
1763+
sage: RealField(10).epsilon() # needs sage.rings.real_mpfr
1764+
0.0020
1765+
1766+
For exact rings, zero is returned::
1767+
1768+
sage: ZZ.epsilon()
1769+
0
1770+
1771+
This also works over derived rings::
1772+
1773+
sage: RR['x'].epsilon() # needs sage.rings.real_mpfr
1774+
2.22044604925031e-16
1775+
sage: QQ['x'].epsilon()
1776+
0
1777+
1778+
For the symbolic ring, there is no reasonable answer::
1779+
1780+
sage: SR.epsilon() # needs sage.symbolic
1781+
Traceback (most recent call last):
1782+
...
1783+
NotImplementedError
1784+
"""
1785+
one = self.one()
1786+
1787+
# ulp is only defined in some real fields
1788+
try:
1789+
return one.ulp()
1790+
except AttributeError:
1791+
pass
1792+
1793+
try:
1794+
eps = one.real().ulp()
1795+
except AttributeError:
1796+
pass
1797+
else:
1798+
return self(eps)
1799+
1800+
if self.is_exact():
1801+
return self.zero()
1802+
1803+
S = self.base_ring()
1804+
if self is not S:
1805+
try:
1806+
return self(S.epsilon())
1807+
except AttributeError:
1808+
pass
1809+
raise NotImplementedError
1810+
17501811
class ElementMethods:
17511812
def is_unit(self) -> bool:
17521813
r"""

src/sage/rings/ring.pyx

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -484,59 +484,6 @@ cdef class Ring(ParentWithGens):
484484
return 1
485485
raise NotImplementedError
486486

487-
@cached_method
488-
def epsilon(self):
489-
"""
490-
Return the precision error of elements in this ring.
491-
492-
EXAMPLES::
493-
494-
sage: RDF.epsilon()
495-
2.220446049250313e-16
496-
sage: ComplexField(53).epsilon() # needs sage.rings.real_mpfr
497-
2.22044604925031e-16
498-
sage: RealField(10).epsilon() # needs sage.rings.real_mpfr
499-
0.0020
500-
501-
For exact rings, zero is returned::
502-
503-
sage: ZZ.epsilon()
504-
0
505-
506-
This also works over derived rings::
507-
508-
sage: RR['x'].epsilon() # needs sage.rings.real_mpfr
509-
2.22044604925031e-16
510-
sage: QQ['x'].epsilon()
511-
0
512-
513-
For the symbolic ring, there is no reasonable answer::
514-
515-
sage: SR.epsilon() # needs sage.symbolic
516-
Traceback (most recent call last):
517-
...
518-
NotImplementedError
519-
"""
520-
one = self.one()
521-
try:
522-
return one.ulp()
523-
except AttributeError:
524-
pass
525-
526-
try:
527-
eps = one.real().ulp()
528-
except AttributeError:
529-
pass
530-
else:
531-
return self(eps)
532-
533-
B = self._base
534-
if B is not None and B is not self:
535-
eps = self.base_ring().epsilon()
536-
return self(eps)
537-
if self.is_exact():
538-
return self.zero()
539-
raise NotImplementedError
540487

541488
cdef class CommutativeRing(Ring):
542489
"""
@@ -757,58 +704,6 @@ cdef class Field(CommutativeRing):
757704
"""
758705
_default_category = _Fields
759706

760-
def an_embedding(self, K):
761-
r"""
762-
Return some embedding of this field into another field `K`,
763-
and raise a :class:`ValueError` if none exists.
764-
765-
EXAMPLES::
766-
767-
sage: GF(2).an_embedding(GF(4))
768-
Ring morphism:
769-
From: Finite Field of size 2
770-
To: Finite Field in z2 of size 2^2
771-
Defn: 1 |--> 1
772-
sage: GF(4).an_embedding(GF(8))
773-
Traceback (most recent call last):
774-
...
775-
ValueError: no embedding from Finite Field in z2 of size 2^2 to Finite Field in z3 of size 2^3
776-
sage: GF(4).an_embedding(GF(16))
777-
Ring morphism:
778-
From: Finite Field in z2 of size 2^2
779-
To: Finite Field in z4 of size 2^4
780-
Defn: z2 |--> z4^2 + z4
781-
782-
::
783-
784-
sage: CyclotomicField(5).an_embedding(QQbar)
785-
Coercion map:
786-
From: Cyclotomic Field of order 5 and degree 4
787-
To: Algebraic Field
788-
sage: CyclotomicField(3).an_embedding(CyclotomicField(7))
789-
Traceback (most recent call last):
790-
...
791-
ValueError: no embedding from Cyclotomic Field of order 3 and degree 2 to Cyclotomic Field of order 7 and degree 6
792-
sage: CyclotomicField(3).an_embedding(CyclotomicField(6))
793-
Generic morphism:
794-
From: Cyclotomic Field of order 3 and degree 2
795-
To: Cyclotomic Field of order 6 and degree 2
796-
Defn: zeta3 -> zeta6 - 1
797-
"""
798-
if self.characteristic() != K.characteristic():
799-
raise ValueError(f'no embedding from {self} to {K}: incompatible characteristics')
800-
801-
H = self.Hom(K)
802-
try:
803-
return H.natural_map()
804-
except TypeError:
805-
pass
806-
from sage.categories.sets_cat import EmptySetError
807-
try:
808-
return H.an_element()
809-
except EmptySetError:
810-
raise ValueError(f'no embedding from {self} to {K}')
811-
812707

813708
cdef class Algebra(Ring):
814709
def __init__(self, base_ring, *args, **kwds):

0 commit comments

Comments
 (0)