Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
get rid of _cmp_ comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
fchapoton committed Jul 13, 2020
1 parent 467fbc7 commit 066b9d9
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 76 deletions.
33 changes: 16 additions & 17 deletions src/sage/rings/complex_mpc.pyx
Expand Up @@ -70,6 +70,7 @@ from sage.libs.mpc cimport *
from sage.structure.parent cimport Parent
from sage.structure.parent_gens cimport ParentWithGens
from sage.structure.element cimport RingElement, Element, ModuleElement
from sage.structure.richcmp cimport rich_to_bool
from sage.categories.map cimport Map
from sage.libs.pari.all import pari

Expand Down Expand Up @@ -912,20 +913,21 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement):
sage: b = C(393.39203845902384098234098230948209384028340)
sage: loads(dumps(b)) == b
True
sage: C(1)
1.0000000000000000000000000000000000000000000000000000000000
sage: b = C(1)/C(0); b
NaN + NaN*I
sage: loads(dumps(b)) == b
True
sage: b = C(-1)/C(0.); b
NaN + NaN*I
sage: loads(dumps(b)) == b
True
sage: b = C(-1).sqrt(); b
1.0000000000000000000000000000000000000000000000000000000000*I
sage: loads(dumps(b)) == b
True
Some tests with ``NaN``, which cannot be compared to anything::
sage: b = C(1)/C(0); b
NaN + NaN*I
sage: loads(dumps(b))
NaN + NaN*I
sage: b = C(-1)/C(0.); b
NaN + NaN*I
sage: loads(dumps(b))
NaN + NaN*I
"""
s = self.str(32)
return (__create_MPComplexNumber_version0, (self._parent, s, 32))
Expand Down Expand Up @@ -1259,7 +1261,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement):
"""
return gmpy2.GMPy_MPC_From_mpfr(self.value.re, self.value.im)

cpdef int _cmp_(self, other) except -2:
cpdef _richcmp_(self, other, int op):
r"""
Compare ``self`` to ``other``.
Expand All @@ -1275,19 +1277,16 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement):
"""
cdef MPComplexNumber z = <MPComplexNumber>other
# NaN should compare to nothing
if mpfr_nan_p (self.value.re) or mpfr_nan_p (self.value.im) or mpfr_nan_p (z.value.re) or mpfr_nan_p (z.value.im):
if mpfr_nan_p(self.value.re) or mpfr_nan_p(self.value.im) or mpfr_nan_p(z.value.re) or mpfr_nan_p(z.value.im):
return False
cdef int c = mpc_cmp(self.value, z.value)
cdef int cre = MPC_INEX_RE(c)
cdef int cim
if cre:
if cre>0: return 1
else: return -1
return rich_to_bool(op, cre)
else:
cim = MPC_INEX_IM(c)
if cim>0: return 1
elif cim<0: return -1
else: return 0
return rich_to_bool(op, cim)

def __nonzero__(self):
"""
Expand Down
24 changes: 12 additions & 12 deletions src/sage/rings/integer.pyx
Expand Up @@ -937,14 +937,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
c = mpz_cmp((<Integer>left).value, (<Integer>right).value)
elif isinstance(right, Rational):
c = -mpq_cmp_z((<Rational>right).value, (<Integer>left).value)
elif isinstance(right, long):
elif isinstance(right, int):
mpz_init(mpz_tmp)
mpz_set_pylong(mpz_tmp, right)
c = mpz_cmp((<Integer>left).value, mpz_tmp)
mpz_clear(mpz_tmp)
elif isinstance(right, int):
# this case should only occur in python 2
c = mpz_cmp_si((<Integer>left).value, PyInt_AS_LONG(right))
elif isinstance(right, float):
d = right
if isnan(d):
Expand All @@ -955,20 +952,23 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):

return rich_to_bool_sgn(op, c)

cpdef int _cmp_(left, right) except -2:
cpdef _richcmp_(left, right, int op):
r"""
EXAMPLES::
sage: 1._cmp_(2)
-1
sage: 0._cmp_(0)
0
sage: (-3**10 + 1)._cmp_(-3**10)
1
sage: from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_GE
sage: 1._richcmp_(2, op_LT)
True
sage: 0._richcmp_(0, op_EQ)
True
sage: (-4)._richcmp_(-4, op_NE)
False
sage: (-3**10 + 1)._richcmp_(-3**10, op_GE)
True
"""
cdef int c
c = mpz_cmp((<Integer>left).value, (<Integer>right).value)
return (c > 0) - (c < 0)
return rich_to_bool_sgn(op, c)

def __copy__(self):
"""
Expand Down
66 changes: 19 additions & 47 deletions src/sage/structure/element.pyx
Expand Up @@ -315,6 +315,7 @@ from sage.arith.long cimport integer_check_long_py
from sage.arith.power cimport generic_power as arith_generic_power
from sage.arith.numerical_approx cimport digits_to_bits
from sage.misc.decorators import sage_wraps
from sage.misc.superseded import deprecation


def make_element(_class, _dict, parent):
Expand Down Expand Up @@ -373,7 +374,6 @@ cdef class Element(SageObject):
Subtypes must either call ``__init__()`` to set ``_parent``, or may
set ``_parent`` themselves if that would be more efficient.
.. automethod:: _cmp_
.. automethod:: _richcmp_
.. automethod:: __add__
.. automethod:: __sub__
Expand Down Expand Up @@ -1075,18 +1075,12 @@ cdef class Element(SageObject):
return self.parent(), str(self)

####################################################################
# In a Cython or a Python class, you must define either _cmp_
# (if your subclass is totally ordered), _richcmp_ (if your subclass
# is partially ordered), or both (if your class has both a total order
# and a partial order, or if that gives better performance).
# In a Cython or a Python class, you must define _richcmp_
#
# Rich comparisons (like a < b) will default to using _richcmp_,
# three-way comparisons (like cmp(a,b)) will default to using
# _cmp_. But if you define just one of _richcmp_ and _cmp_, it will
# be used for all kinds of comparisons.
# Rich comparisons (like a < b) will use _richcmp_
#
# In the _cmp_ and _richcmp_ methods, you can assume that both
# arguments have identical parents.
# In the _richcmp_ method, you can assume that both arguments have
# identical parents.
####################################################################
def __richcmp__(self, other, int op):
"""
Expand Down Expand Up @@ -1118,13 +1112,12 @@ cdef class Element(SageObject):

cpdef _richcmp_(left, right, int op):
r"""
Default implementation of rich comparisons for elements with
Basic default implementation of rich comparisons for elements with
equal parents.
It tries to see if ``_cmp_`` is implemented. Otherwise it does a
comparison by id for ``==`` and ``!=``. Calling this default method
with ``<``, ``<=``, ``>`` or ``>=`` will raise a
``NotImplementedError``.
It does a comparison by id for ``==`` and ``!=``. Calling this
default method with ``<``, ``<=``, ``>`` or ``>=`` will return
``NotImplemented``.
EXAMPLES::
Expand All @@ -1139,7 +1132,7 @@ cdef class Element(SageObject):
sage: e1 < e2 # indirect doctest
Traceback (most recent call last):
...
NotImplementedError: comparison not implemented for <... 'sage.structure.element.Element'>
TypeError: '<' not supported between instances of 'sage.structure.element.Element' and 'sage.structure.element.Element'
We now create an ``Element`` class where we define ``_richcmp_``
and check that comparison works::
Expand All @@ -1160,44 +1153,23 @@ cdef class Element(SageObject):
sage: b = FloatCmp(2)
sage: a <= b, b <= a
(True, False)
This works despite ``_cmp_`` not being implemented::
sage: a._cmp_(b)
Traceback (most recent call last):
...
NotImplementedError: comparison not implemented for <... '...FloatCmp'>
"""
# Obvious case
if left is right:
return rich_to_bool(op, 0)

cdef int c
try:
c = left._cmp_(right)
except NotImplementedError:
# Check equality by id(), knowing that left is not right
if op == Py_EQ:
return False
if op == Py_NE:
return True
raise
assert -1 <= c <= 1
return rich_to_bool(op, c)
# Check equality by id(), knowing that left is not right
if op == Py_EQ:
return False
if op == Py_NE:
return True
return NotImplemented

cpdef int _cmp_(left, right) except -2:
"""
Default three-way comparison method which only checks for a
Python class defining ``__cmp__``.
This was the old comparison framework. Now deprecated. Do not use.
"""
try:
left_cmp = left.__cmp__
except AttributeError:
pass
else:
return left_cmp(right)
msg = LazyFormat("comparison not implemented for %r") % type(left)
raise NotImplementedError(msg)
deprecation(30130, "please use _richcmp_ for comparison methods")
raise NotImplementedError("__cmp__ and _cmp_ are deprecated")

##################################################
# Arithmetic using the coercion model
Expand Down

0 comments on commit 066b9d9

Please sign in to comment.