Skip to content

Commit 1b36a5e

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 11fe9de + 2d4b2b8 commit 1b36a5e

File tree

6 files changed

+116
-126
lines changed

6 files changed

+116
-126
lines changed

build/pkgs/configure/checksums.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
tarball=configure-VERSION.tar.gz
2-
sha1=e4a5aaaa785d20ffb9a1a2e6bb0420bfc3d2c1db
3-
sha256=eaf5cb555f81f8c84f84e7aae69e3e1238e8e971723d31833f6787bd5be1aea5
2+
sha1=67b7bde0cd4b84da82fd0f59930f4b3a203f652b
3+
sha256=2b73756c59bb266c2bf1bdf522fe0a3d511c2d7bbf95f803a8f5579853b8f95e
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
25fc6f0d11318fc70ba7b3c44e0e3aed45be8b23
1+
5689e2b6ea8b8752e614957df1f0a93e5668b3f4

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy