Exemplo n.º 1
0
    def __richcmp__(self, right, op):
        r"""
        Try to compare ``self`` and ``right``.

        .. NOTE::

           Comparison is basically not implemented, or rather it could
           say sets are not equal even though they are.  I don't know
           how one could implement this for a generic symmetric
           difference of sets in a meaningful manner.  So be careful
           when using this.

        EXAMPLES::

            sage: Y = Set(ZZ).symmetric_difference(Set(QQ))
            sage: X = Set(QQ).symmetric_difference(Set(ZZ))
            sage: X == Y
            True
            sage: Y == X
            True

        """
        if not isinstance(right, Set_generic):
            return rich_to_bool(op, -1)
        if not isinstance(right, Set_object_symmetric_difference):
            return rich_to_bool(op, -1)
        if self._X == right._X and self._Y == right._Y or \
           self._X == right._Y and self._Y == right._X:
            return rich_to_bool(op, 0)
        return rich_to_bool(op, -1)
Exemplo n.º 2
0
    def __richcmp__(self, other, op):
        """
        Comparison of truth value.

        EXAMPLES::

            sage: l = [False, Unknown, True]
            sage: for a in l: print([a < b for b in l])
            [False, True, True]
            [False, False, True]
            [False, False, False]

            sage: for a in l: print([a <= b for b in l])
            [True, True, True]
            [False, True, True]
            [False, False, True]
        """
        if other is self:
            return rich_to_bool(op, 0)
        if not isinstance(other, bool):
            return NotImplemented
        if other:
            return rich_to_bool(op, -1)
        else:
            return rich_to_bool(op, +1)
Exemplo n.º 3
0
    def __richcmp__(self, right, op):
        r"""
        Try to compare ``self`` and ``right``.

        .. NOTE::

           Comparison is basically not implemented, or rather it could
           say sets are not equal even though they are.  I don't know
           how one could implement this for a generic symmetric
           difference of sets in a meaningful manner.  So be careful
           when using this.

        EXAMPLES::

            sage: Y = Set(ZZ).symmetric_difference(Set(QQ))
            sage: X = Set(QQ).symmetric_difference(Set(ZZ))
            sage: X == Y
            True
            sage: Y == X
            True

        """
        if not isinstance(right, Set_generic):
            return rich_to_bool(op, -1)
        if not isinstance(right, Set_object_symmetric_difference):
            return rich_to_bool(op, -1)
        if self._X == right._X and self._Y == right._Y or \
           self._X == right._Y and self._Y == right._X:
            return rich_to_bool(op, 0)
        return rich_to_bool(op, -1)
Exemplo n.º 4
0
    def _richcmp_(self, other, op):
        """
        EXAMPLES::

            sage: one = lisp(1); two = lisp(2)
            sage: one == one
            True
            sage: one != two
            True
            sage: one < two
            True
            sage: two > one
            True
            sage: one < 1
            False
            sage: two == 2
            True

        """
        P = self._check_valid()
        if parent(other) is not P:
            other = P(other)

        if P.eval('(= %s %s)' %
                  (self.name(), other.name())) == P._true_symbol():
            return rich_to_bool(op, 0)
        elif P.eval('(< %s %s)' %
                    (self.name(), other.name())) == P._true_symbol():
            return rich_to_bool(op, -1)
        else:
            return rich_to_bool(op, 1)
Exemplo n.º 5
0
    def __richcmp__(self, other, op):
        r"""
        TESTS::

            sage: a1 = AbelianStratum(1,1,1,1)
            sage: c1 = a1.connected_components()[0]
            sage: a2 = AbelianStratum(3,1)
            sage: c2 = a2.connected_components()[0]
            sage: c1 == c1
            True
            sage: c1 == c2
            False
            sage: a1 = AbelianStratum(1,1,1,1)
            sage: c1 = a1.connected_components()[0]
            sage: a2 = AbelianStratum(2, 2)
            sage: c2_hyp, c2_odd = a2.connected_components()
            sage: c1 != c1
            False
            sage: c1 != c2_hyp
            True
            sage: c2_hyp != c2_odd
            True
            sage: c1 == True
            False
        """
        if not isinstance(other, CCA) or type(self) != type(other):
            return NotImplemented

        if self._parent._zeroes < other._parent._zeroes:
            return rich_to_bool(op, 1)
        elif self._parent._zeroes > other._parent._zeroes:
            return rich_to_bool(op, -1)
        return rich_to_bool(op, 0)
Exemplo n.º 6
0
    def _richcmp_(self, rhs, op):
        r"""
        EXAMPLES::

            sage: from pyexactreal import ExactReals
            sage: R = ExactReals()
            sage: x = R.random_element() # a random element in [0, 1]
            sage: x > -x
            True
            sage: x < -x
            False
            sage: -x < x
            True
            sage: -x > x
            False
            sage: -x == -x
            True
            sage: x == -x
            False

        """
        from sage.structure.richcmp import rich_to_bool
        if self._backend < rhs._backend:
            return rich_to_bool(op, -1)
        elif self._backend == rhs._backend:
            return rich_to_bool(op, 0)
        else:
            return rich_to_bool(op, 1)
Exemplo n.º 7
0
    def __richcmp__(self, other, op):
        """
        Comparison of truth value.

        EXAMPLES::

            sage: l = [False, Unknown, True]
            sage: for a in l: print([a < b for b in l])
            [False, True, True]
            [False, False, True]
            [False, False, False]

            sage: for a in l: print([a <= b for b in l])
            [True, True, True]
            [False, True, True]
            [False, False, True]
        """
        if other is self:
            return rich_to_bool(op, 0)
        if not isinstance(other, bool):
            return NotImplemented
        if other:
            return rich_to_bool(op, -1)
        else:
            return rich_to_bool(op, +1)
Exemplo n.º 8
0
    def _richcmp_(self, other, op):
        """
        Comparison of interface elements.

        NOTE:

        GAP has a special role here. It may in some cases raise an error
        when comparing objects, which is unwanted in Python. We catch
        these errors. Moreover, GAP does not recognise certain objects as
        equal even if there definitions are identical.

        NOTE:

        This methods need to be overridden if the subprocess would
        not return a string representation of a boolean value unless
        an explicit print command is used.

        TESTS:

        Here are examples in which GAP succeeds with a comparison::

            sage: gap('SymmetricGroup(8)')==gap('SymmetricGroup(8)')
            True
            sage: gap('SymmetricGroup(8)')>gap('AlternatingGroup(8)')
            False
            sage: gap('SymmetricGroup(8)')<gap('AlternatingGroup(8)')
            True

        Here, GAP fails to compare, and so ``False`` is returned.
        In previous Sage versions, this example actually resulted
        in an error; compare :trac:`5962`.
        ::

            sage: gap('DihedralGroup(8)')==gap('DihedralGroup(8)')
            False

        """
        P = self._check_valid()
        try:
            if P.eval("%s %s %s" % (self.name(), P._equality_symbol(),
                                    other.name())) == P._true_symbol():
                return rich_to_bool(op, 0)
        except RuntimeError:
            pass
        try:
            if P.eval("%s %s %s" % (self.name(), P._lessthan_symbol(),
                                    other.name())) == P._true_symbol():
                return rich_to_bool(op, -1)
        except RuntimeError:
            pass
        try:
            if P.eval("%s %s %s" % (self.name(), P._greaterthan_symbol(),
                                    other.name())) == P._true_symbol():
                return rich_to_bool(op, 1)
        except Exception:
            pass

        return NotImplemented
Exemplo n.º 9
0
 def _richcmp_(self, other, op):
     P = self.parent()
     if P.eval("%s < %s"%(self.name(), other.name())).strip() == 'True':
         return rich_to_bool(op, -1)
     elif P.eval("%s > %s"%(self.name(), other.name())).strip() == 'True':
         return rich_to_bool(op, 1)
     elif P.eval("%s == %s"%(self.name(), other.name())).strip() == 'True':
         return rich_to_bool(op, 0)
     return NotImplemented
Exemplo n.º 10
0
    def _richcmp_(self, other, op):
        """
        Compare ``self`` to ``other``.

        EXAMPLES::

            sage: 1 == unsigned_infinity
            False
        """
        if isinstance(other, LessThanInfinity):
            return rich_to_bool(op, 1)
        return rich_to_bool(op, 0)
Exemplo n.º 11
0
    def _richcmp_(self, other, op):
        """
        Compare the two ideals.

        EXAMPLES:

        Comparison with non-principal ideal::

            sage: R.<x> = ZZ[]
            sage: I = R.ideal([x^3 + 4*x - 1, x + 6])
            sage: J = [x^2] * R
            sage: I > J  # indirect doctest
            True
            sage: J < I  # indirect doctest
            True

        Between two principal ideals::

            sage: P.<x> = PolynomialRing(ZZ)
            sage: I = P.ideal(x^2-2)
            sage: I2 = P.ideal(0)
            sage: I2.is_zero()
            True
            sage: I2 < I
            True
            sage: I3 = P.ideal(x)
            sage: I > I3
            True
        """
        if not isinstance(other, Ideal_generic):
            other = self.ring().ideal(other)

        try:
            if not other.is_principal():
                return rich_to_bool(op, -1)
        except NotImplementedError:
            # If we do not know if the other is principal or not, then we
            #   fallback to the generic implementation
            return Ideal_generic._richcmp_(self, other, op)

        if self.is_zero():
            if not other.is_zero():
                return rich_to_bool(op, -1)
            return rich_to_bool(op, 0)

        # is other.gen() / self.gen() a unit in the base ring?
        g0 = other.gen()
        g1 = self.gen()
        if g0.divides(g1) and g1.divides(g0):
            return rich_to_bool(op, 0)
        return rich_to_bool(op, 1)
Exemplo n.º 12
0
    def _richcmp_(self, other, op):
        """
        Compare the two ideals.

        EXAMPLES:

        Comparison with non-principal ideal::

            sage: R.<x> = ZZ[]
            sage: I = R.ideal([x^3 + 4*x - 1, x + 6])
            sage: J = [x^2] * R
            sage: I > J  # indirect doctest
            True
            sage: J < I  # indirect doctest
            True

        Between two principal ideals::

            sage: P.<x> = PolynomialRing(ZZ)
            sage: I = P.ideal(x^2-2)
            sage: I2 = P.ideal(0)
            sage: I2.is_zero()
            True
            sage: I2 < I
            True
            sage: I3 = P.ideal(x)
            sage: I > I3
            True
        """
        if not isinstance(other, Ideal_generic):
            other = self.ring().ideal(other)

        try:
            if not other.is_principal():
                return rich_to_bool(op, -1)
        except NotImplementedError:
            # If we do not know if the other is principal or not, then we
            #   fallback to the generic implementation
            return Ideal_generic._richcmp_(self, other, op)

        if self.is_zero():
            if not other.is_zero():
                return rich_to_bool(op, -1)
            return rich_to_bool(op, 0)

        # is other.gen() / self.gen() a unit in the base ring?
        g0 = other.gen()
        g1 = self.gen()
        if g0.divides(g1) and g1.divides(g0):
            return rich_to_bool(op, 0)
        return rich_to_bool(op, 1)
Exemplo n.º 13
0
    def _richcmp_(self, other, op):
        r"""
        EXAMPLES::

            sage: K.<a> = Qq(125)
            sage: V, fr, to = K.free_module()
            sage: fr == fr
            True
        """
        # For maps of this type, equality depends only on the parent
        if isinstance(other, pAdicModuleIsomorphism):
            return rich_to_bool(op, 0)
        else:
            return rich_to_bool(op, 1)
Exemplo n.º 14
0
    def _richcmp_(self, other, op):
        r"""
        Compare self and other (where the coercion model has already ensured
        that self and other have the same parent). Hecke operators on the same
        space compare as equal if and only if their matrices are equal, so we
        check if the indices are the same and if not we compute the matrices
        (which is potentially expensive).

        EXAMPLES::

            sage: M = ModularSymbols(Gamma0(7), 4)
            sage: m = M.hecke_operator(3)
            sage: m == m
            True
            sage: m == 2*m
            False
            sage: m == M.hecke_operator(5)
            False

        These last two tests involve a coercion::

            sage: m == m.matrix_form()
            True
            sage: m == m.matrix()
            False
        """
        if not isinstance(other, HeckeOperator):
            if isinstance(other, HeckeAlgebraElement_matrix):
                return richcmp(self.matrix_form(), other, op)
            else:
                raise RuntimeError("Bug in coercion code") # can't get here

        if self.__n == other.__n:
            return rich_to_bool(op, 0)
        return richcmp(self.matrix(), other.matrix(), op)
Exemplo n.º 15
0
    def _richcmp_(self, other, op):
        """
        Compare ``self`` and ``other``.

        TESTS::

            sage: A = ArtinGroup(['B',3])
            sage: x = A([1, 2, 1])
            sage: y = A([2, 1, 2])
            sage: x == y
            True
            sage: x < y^(-1)
            True
            sage: A([]) == A.one()
            True
            sage: x = A([2, 3, 2, 3])
            sage: y = A([3, 2, 3, 2])
            sage: x == y
            True
            sage: x < y^(-1)
            True
        """
        if self.Tietze() == other.Tietze():
            return rich_to_bool(op, 0)
        nfself = [i.Tietze() for i in self.left_normal_form()]
        nfother = [i.Tietze() for i in other.left_normal_form()]
        return richcmp(nfself, nfother, op)
Exemplo n.º 16
0
    def _richcmp_(self, other, op):
        r"""
        Compare this element with ``other``.

        TESTS::

            sage: R = ZpLC(2)
            sage: x = R(1, 5)
            sage: y = R(128, 10)
            sage: z = x + y

            sage: x
            1 + O(2^5)
            sage: z
            1 + O(2^5)

            sage: x == z   # Indirect doctest
            False
            sage: z - x
            2^7 + O(2^10)
        """
        if (self - other).is_zero():
            return rich_to_bool(op, 0)
        else:
            return richcmp(QQ(self.lift()), QQ(other.lift()), op)
Exemplo n.º 17
0
    def __richcmp__(self, other, op):
        """
        Rich comparison.

        EXAMPLES::

            sage: ct1 = CartanType(['A',1],['B',2])
            sage: ct2 = CartanType(['B',2],['A',1])
            sage: ct3 = CartanType(['A',4])
            sage: ct1 == ct1
            True
            sage: ct1 == ct2
            False
            sage: ct1 == ct3
            False

        TESTS:

        Check that :trac:`20418` is fixed::

            sage: ct = CartanType(["A2", "B2"])
            sage: ct == (1, 2, 1)
            False
        """
        if isinstance(other, CartanType_simple):
            return rich_to_bool(op, 1)
        if not isinstance(other, CartanType):
            return NotImplemented
        return richcmp(self._types, other._types, op)
Exemplo n.º 18
0
    def __richcmp__(self, other, op):
        """
        Rich comparison.

        EXAMPLES::

            sage: ct1 = CartanType(['A',1],['B',2])
            sage: ct2 = CartanType(['B',2],['A',1])
            sage: ct3 = CartanType(['A',4])
            sage: ct1 == ct1
            True
            sage: ct1 == ct2
            False
            sage: ct1 == ct3
            False

        TESTS:

        Check that :trac:`20418` is fixed::

            sage: ct = CartanType(["A2", "B2"])
            sage: ct == (1, 2, 1)
            False
        """
        if isinstance(other, CartanType_simple):
            return rich_to_bool(op, 1)
        if not isinstance(other, CartanType):
            return NotImplemented
        return richcmp(self._types, other._types, op)
Exemplo n.º 19
0
    def _richcmp_(self, other, op):
        """
        Compare ``self`` and ``other``.

        TESTS::

            sage: A = ArtinGroup(['B',3])
            sage: x = A([1, 2, 1])
            sage: y = A([2, 1, 2])
            sage: x == y
            True
            sage: x < y^(-1)
            True
            sage: A([]) == A.one()
            True
            sage: x = A([2, 3, 2, 3])
            sage: y = A([3, 2, 3, 2])
            sage: x == y
            True
            sage: x < y^(-1)
            True
        """
        if self.Tietze() == other.Tietze():
            return rich_to_bool(op, 0)
        nfself = [i.Tietze() for i in self.left_normal_form()]
        nfother = [i.Tietze() for i in other.left_normal_form()]
        return richcmp(nfself, nfother, op)
Exemplo n.º 20
0
    def _richcmp_(self, other, op):
        r"""
        Compare self and other (where the coercion model has already ensured
        that self and other have the same parent). Hecke operators on the same
        space compare as equal if and only if their matrices are equal, so we
        check if the indices are the same and if not we compute the matrices
        (which is potentially expensive).

        EXAMPLES::

            sage: M = ModularSymbols(Gamma0(7), 4)
            sage: m = M.hecke_operator(3)
            sage: m == m
            True
            sage: m == 2*m
            False
            sage: m == M.hecke_operator(5)
            False

        These last two tests involve a coercion::

            sage: m == m.matrix_form()
            True
            sage: m == m.matrix()
            False
        """
        if not isinstance(other, HeckeOperator):
            if isinstance(other, HeckeAlgebraElement_matrix):
                return richcmp(self.matrix_form(), other, op)
            else:
                raise RuntimeError("Bug in coercion code")  # can't get here

        if self.__n == other.__n:
            return rich_to_bool(op, 0)
        return richcmp(self.matrix(), other.matrix(), op)
Exemplo n.º 21
0
    def _richcmp_(self, other, op):
        """
        Compare ``self`` and ``other``.

        EXAMPLES::

            sage: P = InfinityRing
            sage: -oo < P(-5) < P(0) < P(1.5) < oo
            True
            sage: P(1) < P(100)
            False
            sage: P(-1) == P(-100)
            True
        """
        if isinstance(other, PlusInfinity):
            return rich_to_bool(op, 0)
        return rich_to_bool(op, 1)
Exemplo n.º 22
0
    def _richcmp_(self, other, op):
        """
        EXAMPLES::

            sage: two = axiom(2)  #optional - axiom
            sage: two == 2        #optional - axiom
            True
            sage: two == 3        #optional - axiom
            False
            sage: two < 3         #optional - axiom
            True
            sage: two > 1         #optional - axiom
            True

            sage: a = axiom(1); b = axiom(2)  #optional - axiom
            sage: a == b                      #optional - axiom
            False
            sage: a < b                       #optional - axiom
            True
            sage: a > b                       #optional - axiom
            False
            sage: b < a                       #optional - axiom
            False
            sage: b > a                       #optional - axiom
            True

        We can also compare more complicated object such as functions::

            sage: f = axiom('sin(x)'); g = axiom('cos(x)')    #optional - axiom
            sage: f == g                                      #optional - axiom
            False

        """
        P = self.parent()
        if 'true' in P.eval("(%s = %s) :: Boolean" %
                            (self.name(), other.name())):
            return rich_to_bool(op, 0)
        elif 'true' in P.eval("(%s < %s) :: Boolean" %
                              (self.name(), other.name())):
            return rich_to_bool(op, -1)
        elif 'true' in P.eval("(%s > %s) :: Boolean" %
                              (self.name(), other.name())):
            return rich_to_bool(op, 1)

        return NotImplemented
Exemplo n.º 23
0
    def __richcmp__(self, other, op):
        """
        Compare the sets ``self`` and ``other``.

        EXAMPLES::

            sage: X = Set(GF(8,'c'))
            sage: X == Set(GF(8,'c'))
            True
            sage: X == Set(GF(4,'a'))
            False
            sage: Set(QQ) == Set(ZZ)
            False
        """
        if not isinstance(other, Set_object_enumerated):
            return NotImplemented
        if self.set() == other.set():
            return rich_to_bool(op, 0)
        return rich_to_bool(op, -1)
Exemplo n.º 24
0
    def __richcmp__(self, other, op):
        """
        Compare the sets ``self`` and ``other``.

        EXAMPLES::

            sage: X = Set(GF(8,'c'))
            sage: X == Set(GF(8,'c'))
            True
            sage: X == Set(GF(4,'a'))
            False
            sage: Set(QQ) == Set(ZZ)
            False
        """
        if not isinstance(other, Set_object_enumerated):
            return NotImplemented
        if self.set() == other.set():
            return rich_to_bool(op, 0)
        return rich_to_bool(op, -1)
Exemplo n.º 25
0
    def _richcmp_(self, right, op):
        """
        Compare the cusps ``self`` and ``right``.

        Comparison is as for elements in the number field, except with
        the cusp oo which is greater than everything but itself.

        The ordering in comparison is only really meaningful for infinity.

        EXAMPLES::

            sage: k.<a> = NumberField(x^3 + x + 1)
            sage: kCusps = NFCusps(k)

        Comparing with infinity::

            sage: c = kCusps((a,2))
            sage: d = kCusps(oo)
            sage: c < d
            True
            sage: kCusps(oo) < d
            False

        Comparison as elements of the number field::

            sage: kCusps(2/3) < kCusps(5/2)
            False
            sage: k(2/3) < k(5/2)
            False
        """
        if self.__b.is_zero():
            if right.__b.is_zero():
                return rich_to_bool(op, 0)
            else:
                return rich_to_bool(op, 1)
        else:
            if right.__b.is_zero():
                return rich_to_bool(op, -1)
            else:
                return richcmp(self._number_field_element_(),
                               right._number_field_element_(), op)
Exemplo n.º 26
0
    def _richcmp_(self, right, op):
        """
        Compare the cusps ``self`` and ``right``.

        Comparison is as for elements in the number field, except with
        the cusp oo which is greater than everything but itself.

        The ordering in comparison is only really meaningful for infinity.

        EXAMPLES::

            sage: k.<a> = NumberField(x^3 + x + 1)
            sage: kCusps = NFCusps(k)

        Comparing with infinity::

            sage: c = kCusps((a,2))
            sage: d = kCusps(oo)
            sage: c < d
            True
            sage: kCusps(oo) < d
            False

        Comparison as elements of the number field::

            sage: kCusps(2/3) < kCusps(5/2)
            False
            sage: k(2/3) < k(5/2)
            False
        """
        if self.__b.is_zero():
            if right.__b.is_zero():
                return rich_to_bool(op, 0)
            else:
                return rich_to_bool(op, 1)
        else:
            if right.__b.is_zero():
                return rich_to_bool(op, -1)
            else:
                return richcmp(self._number_field_element_(),
                               right._number_field_element_(), op)
Exemplo n.º 27
0
    def _richcmp_(self, other, op):
        """
        Compare this polynomial with other.

        Polynomials are first compared by degree, then in dictionary order
        starting with the coefficient of largest degree.

        EXAMPLES::

            sage: R.<x> = PolynomialRing(ZZ, sparse=True)
            sage: 3*x^100 - 12 > 12*x + 5
            True
            sage: 3*x^100 - 12 > 3*x^100 - x^50 + 5
            True
            sage: 3*x^100 - 12 < 3*x^100 - x^50 + 5
            False
            sage: x^100 + x^10 - 1 < x^100 + x^10
            True
            sage: x^100 < x^100 - x^10
            False

        TESTS::

            sage: R.<x> = PolynomialRing(QQ, sparse=True)
            sage: 2*x^2^500 > x^2^500
            True

            sage: Rd = PolynomialRing(ZZ, 'x', sparse=False)
            sage: Rs = PolynomialRing(ZZ, 'x', sparse=True)
            sage: for _ in range(100):
            ....:     pd = Rd.random_element()
            ....:     qd = Rd.random_element()
            ....:     assert bool(pd < qd) == bool(Rs(pd) < Rs(qd))
        """
        d1 = self.degree()
        d2 = other.degree()

        # Special case constant polynomials
        if d1 <= 0 and d2 <= 0:
            return richcmp(self[0], other[0], op)

        # For different degrees, compare the degree
        if d1 != d2:
            return rich_to_bool_sgn(op, d1 - d2)

        degs = set(self.__coeffs) | set(other.__coeffs)
        for i in sorted(degs, reverse=True):
            x = self[i]
            y = other[i]
            res = richcmp_item(x, y, op)
            if res is not NotImplemented:
                return res
        return rich_to_bool(op, 0)
    def _richcmp_(self, other, op):
        """
        Compare this polynomial with other.

        Polynomials are first compared by degree, then in dictionary order
        starting with the coefficient of largest degree.

        EXAMPLES::

            sage: R.<x> = PolynomialRing(ZZ, sparse=True)
            sage: 3*x^100 - 12 > 12*x + 5
            True
            sage: 3*x^100 - 12 > 3*x^100 - x^50 + 5
            True
            sage: 3*x^100 - 12 < 3*x^100 - x^50 + 5
            False
            sage: x^100 + x^10 - 1 < x^100 + x^10
            True
            sage: x^100 < x^100 - x^10
            False

        TESTS::

            sage: R.<x> = PolynomialRing(QQ, sparse=True)
            sage: 2*x^2^500 > x^2^500
            True

            sage: Rd = PolynomialRing(ZZ, 'x', sparse=False)
            sage: Rs = PolynomialRing(ZZ, 'x', sparse=True)
            sage: for _ in range(100):
            ....:     pd = Rd.random_element()
            ....:     qd = Rd.random_element()
            ....:     assert bool(pd < qd) == bool(Rs(pd) < Rs(qd))
        """
        d1 = self.degree()
        d2 = other.degree()

        # Special case constant polynomials
        if d1 <= 0 and d2 <= 0:
            return richcmp(self[0], other[0], op)

        # For different degrees, compare the degree
        if d1 != d2:
            return rich_to_bool_sgn(op, d1 - d2)

        degs = set(self.__coeffs) | set(other.__coeffs)
        for i in sorted(degs, reverse=True):
            x = self[i]
            y = other[i]
            res = richcmp_item(x, y, op)
            if res is not NotImplemented:
                return res
        return rich_to_bool(op, 0)
    def _richcmp_(self, other, op):
        r"""
        EXAMPLES::

            sage: R.<x,y> = QQ[]
            sage: V, fr, to = R.free_module(R)
            sage: fr == loads(dumps(fr))
            True
        """
        if isinstance(other, BaseIsomorphism1D):
            return richcmp(self._basis, other._basis, op)
        else:
            return rich_to_bool(op, 1)
Exemplo n.º 30
0
    def _richcmp_(self, other, op):
        r"""
        EXAMPLES::

            sage: mobj1 = mathics([x^2-1, 2])     # optional - mathics
            sage: mobj2 = mathics('{x^2-1, 2}')   # optional - mathics
            sage: mobj3 = mathics('5*x + y')      # optional - mathics
            sage: mobj1 == mobj2                  # optional - mathics
            True
            sage: mobj1 < mobj2                   # optional - mathics
            False
            sage: mobj1 == mobj3                  # optional - mathics
            False
        """
        P = self.parent()
        if str(P("%s < %s"%(self.name(), other.name()))) == P._true_symbol():
            return rich_to_bool(op, -1)
        elif str(P("%s > %s"%(self.name(), other.name()))) == P._true_symbol():
            return rich_to_bool(op, 1)
        elif str(P("%s == %s"%(self.name(), other.name()))) == P._true_symbol():
            return rich_to_bool(op, 0)
        return NotImplemented
Exemplo n.º 31
0
    def _richcmp_(self, other, op):
        r"""
        Compare this element and ``other``.

        EXAMPLES::

            sage: from pyeantic import RealEmbeddedNumberField
            sage: K = NumberField(x**2 - 2, 'a', embedding=sqrt(AA(2)))
            sage: K = RealEmbeddedNumberField(K)
            sage: K.gen() > 0
            True
            sage: K.gen() < 1
            False

        """
        from sage.structure.richcmp import rich_to_bool
        if self.renf_elem < other.renf_elem:
            return rich_to_bool(op, -1)
        elif self.renf_elem == other.renf_elem:
            return rich_to_bool(op, 0)
        else:
            return rich_to_bool(op, 1)
Exemplo n.º 32
0
    def __richcmp__(self, right, op):
        r"""
        Try to compare ``self`` and ``right``.

        .. NOTE::

           Comparison is basically not implemented, or rather it could
           say sets are not equal even though they are.  I don't know
           how one could implement this for a generic intersection of
           sets in a meaningful manner.  So be careful when using
           this.

        EXAMPLES::

            sage: Y = Set(ZZ).difference(Set(QQ))
            sage: Y == Set([])
            False
            sage: X = Set(QQ).difference(Set(ZZ))
            sage: Y == X
            False
            sage: Z = X.difference(Set(ZZ))
            sage: Z == X
            False

        This illustrates that equality testing for formal unions
        can be misleading in general.

        ::

            sage: X == Set(QQ).difference(Set(ZZ))
            True
        """
        if not isinstance(right, Set_generic):
            return rich_to_bool(op, -1)
        if not isinstance(right, Set_object_difference):
            return rich_to_bool(op, -1)
        if self._X == right._X and self._Y == right._Y:
            return rich_to_bool(op, 0)
        return rich_to_bool(op, -1)
Exemplo n.º 33
0
    def __richcmp__(self, right, op):
        r"""
        Try to compare ``self`` and ``right``.

        .. NOTE::

           Comparison is basically not implemented, or rather it could
           say sets are not equal even though they are.  I don't know
           how one could implement this for a generic intersection of
           sets in a meaningful manner.  So be careful when using
           this.

        EXAMPLES::

            sage: Y = Set(ZZ).difference(Set(QQ))
            sage: Y == Set([])
            False
            sage: X = Set(QQ).difference(Set(ZZ))
            sage: Y == X
            False
            sage: Z = X.difference(Set(ZZ))
            sage: Z == X
            False

        This illustrates that equality testing for formal unions
        can be misleading in general.

        ::

            sage: X == Set(QQ).difference(Set(ZZ))
            True
        """
        if not isinstance(right, Set_generic):
            return rich_to_bool(op, -1)
        if not isinstance(right, Set_object_difference):
            return rich_to_bool(op, -1)
        if self._X == right._X and self._Y == right._Y:
            return rich_to_bool(op, 0)
        return rich_to_bool(op, -1)
Exemplo n.º 34
0
    def _richcmp_(self, other, op):
        """
        EXAMPLES::

            sage: R.<x,y> = QQ[]; S.<a,b> = R.quo(x^2 + y^2); type(a)
            <class 'sage.rings.quotient_ring.QuotientRing_generic_with_category.element_class'>
            sage: a > b    # indirect doctest
            True
            sage: b > a
            False
            sage: a == loads(dumps(a))
            True

        TESTS::

            sage: a == (a+1-1)
            True
            sage: a > b
            True

        See :trac:`7797`::

            sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
            sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
            sage: Q = F.quo(I)
            sage: Q.0^4    # indirect doctest
            ybar*zbar*zbar*xbar + ybar*zbar*zbar*ybar + ybar*zbar*zbar*zbar

        The issue from :trac:`8005` was most likely fixed as part of
        :trac:`9138`::

            sage: F = GF(5)
            sage: R.<x,y>=F[]
            sage: I=Ideal(R, [x, y])
            sage: S.<x1,y1>=QuotientRing(R,I)
            sage: x1^4
            0
        """
        # A containment test is not implemented for univariate polynomial
        # ideals. There are cases in which one would not like to add
        # elements of different degrees. The whole quotient stuff relies
        # in I.reduce(x) returning a normal form of x with respect to I.
        # Hence, we will not use more than that.

        # Since we have to compute normal forms anyway, it makes sense
        # to use it for comparison in the case of an inequality as well.
        if self.__rep == other.__rep:  # Use a shortpath, so that we
            # avoid expensive reductions
            return rich_to_bool(op, 0)
        I = self.parent().defining_ideal()
        return richcmp(I.reduce(self.__rep), I.reduce(other.__rep), op)
Exemplo n.º 35
0
    def _richcmp_(self, other, op):
        """
        EXAMPLES::

            sage: R.<x,y> = QQ[]; S.<a,b> = R.quo(x^2 + y^2); type(a)
            <class 'sage.rings.quotient_ring.QuotientRing_generic_with_category.element_class'>
            sage: a > b    # indirect doctest
            True
            sage: b > a
            False
            sage: a == loads(dumps(a))
            True

        TESTS::

            sage: a == (a+1-1)
            True
            sage: a > b
            True

        See :trac:`7797`::

            sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
            sage: I = F*[x*y+y*z,x^2+x*y-y*x-y^2]*F
            sage: Q = F.quo(I)
            sage: Q.0^4    # indirect doctest
            ybar*zbar*zbar*xbar + ybar*zbar*zbar*ybar + ybar*zbar*zbar*zbar

        The issue from :trac:`8005` was most likely fixed as part of
        :trac:`9138`::

            sage: F = GF(5)
            sage: R.<x,y>=F[]
            sage: I=Ideal(R, [x, y])
            sage: S.<x1,y1>=QuotientRing(R,I)
            sage: x1^4
            0
        """
        # A containment test is not implemented for univariate polynomial
        # ideals. There are cases in which one would not like to add
        # elements of different degrees. The whole quotient stuff relies
        # in I.reduce(x) returning a normal form of x with respect to I.
        # Hence, we will not use more than that.
        #return cmp(self.__rep, other.__rep)
        # Since we have to compute normal forms anyway, it makes sense
        # to use it for comparison in the case of an inequality as well.
        if self.__rep == other.__rep: # Use a shortpath, so that we
                                      # avoid expensive reductions
             return rich_to_bool(op, 0)
        I = self.parent().defining_ideal()
        return richcmp(I.reduce(self.__rep), I.reduce(other.__rep), op)
Exemplo n.º 36
0
    def _richcmp_(self, other, op):
        r"""
        Comparison (using the complex embedding).

        TESTS::

            sage: UCF = UniversalCyclotomicField()
            sage: l = [UCF.gen(3), UCF.gen(3)+1, UCF.gen(5), UCF.gen(5,2),
            ....:      UCF.gen(4), 2*UCF.gen(4), UCF.gen(5)-22/3]
            sage: lQQbar = list(map(QQbar,l))
            sage: lQQbar.sort()
            sage: l.sort()
            sage: lQQbar == list(map(QQbar,l))
            True

            sage: for i in range(len(l)):
            ....:     assert l[i] >= l[i] and l[i] <= l[i]
            ....:     for j in range(i):
            ....:         assert l[i] > l[j] and l[j] < l[i]

            sage: fibonacci(200)*(E(5)+E(5,4)) <= fibonacci(199)
            True
            sage: fibonacci(201)*(E(5)+E(5,4)) <= fibonacci(200)
            False
        """
        if self._obj == other._obj:
            return rich_to_bool(op, 0)

        s = self.real_part()
        o = other.real_part()
        if s == o:
            s = self.imag_part()
            o = other.imag_part()

        from sage.rings.real_mpfi import RealIntervalField
        prec = 53
        R = RealIntervalField(prec)
        sa = s._eval_real_(R)
        oa = o._eval_real_(R)
        while sa.overlaps(oa):
            prec <<= 2
            R = RealIntervalField(prec)
            sa = s._eval_real_(R)
            oa = o._eval_real_(R)
        return sa._richcmp_(oa, op)
Exemplo n.º 37
0
    def _richcmp_(self, other, op):
        r"""
        Comparison (using the complex embedding).

        TESTS::

            sage: UCF = UniversalCyclotomicField()
            sage: l = [UCF.gen(3), UCF.gen(3)+1, UCF.gen(5), UCF.gen(5,2),
            ....:      UCF.gen(4), 2*UCF.gen(4), UCF.gen(5)-22/3]
            sage: lQQbar = list(map(QQbar,l))
            sage: lQQbar.sort()
            sage: l.sort()
            sage: lQQbar == list(map(QQbar,l))
            True

            sage: for i in range(len(l)):
            ....:     assert l[i] >= l[i] and l[i] <= l[i]
            ....:     for j in range(i):
            ....:         assert l[i] > l[j] and l[j] < l[i]

            sage: fibonacci(200)*(E(5)+E(5,4)) <= fibonacci(199)
            True
            sage: fibonacci(201)*(E(5)+E(5,4)) <= fibonacci(200)
            False
        """
        if self._obj == other._obj:
            return rich_to_bool(op, 0)

        s = self.real_part()
        o = other.real_part()
        if s == o:
            s = self.imag_part()
            o = other.imag_part()

        from sage.rings.real_mpfi import RealIntervalField
        prec = 53
        R = RealIntervalField(prec)
        sa = s._eval_real_(R)
        oa = o._eval_real_(R)
        while sa.overlaps(oa):
            prec <<= 2
            R = RealIntervalField(prec)
            sa = s._eval_real_(R)
            oa = o._eval_real_(R)
        return sa._richcmp_(oa, op)
Exemplo n.º 38
0
    def _richcmp_(self, right, op):
        """
        Compare ``self`` and ``right``.

        INPUT:

        - ``self, right`` -- elements of the same finite abelian
           variety subgroup.

        - ``op`` -- comparison operator (see :mod:`sage.structure.richcmp`)

        OUTPUT: boolean

        EXAMPLES::

            sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
            sage: G.0 > G.1
            True
            sage: G.0 == G.0
            True
            sage: 3*G.0 == 0
            True
            sage: 3*G.0 == 5*G.1
            True

        We make sure things that should not be equal are not::

            sage: H = J0(14).finite_subgroup([[1/3,0]])
            sage: G.0 == H.0
            False
            sage: G.0
            [(1/3, 0)]
            sage: H.0
            [(1/3, 0)]
        """
        A = self.parent().abelian_variety()
        from sage.rings.rational_field import QQ
        if self.__element.change_ring(QQ) - right.__element.change_ring(
                QQ) in A.lattice():
            return rich_to_bool(op, 0)
        return richcmp(self.__element, right.__element, op)
Exemplo n.º 39
0
    def _richcmp_(self, right, op):
        """
        Compare ``self`` and ``right``.

        INPUT:

        - ``self, right`` -- elements of the same finite abelian
           variety subgroup.

        - ``op`` -- comparison operator (see :mod:`sage.structure.richcmp`)

        OUTPUT: boolean

        EXAMPLES::

            sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])
            sage: G.0 > G.1
            True
            sage: G.0 == G.0
            True
            sage: 3*G.0 == 0
            True
            sage: 3*G.0 == 5*G.1
            True

        We make sure things that should not be equal are not::

            sage: H = J0(14).finite_subgroup([[1/3,0]])
            sage: G.0 == H.0
            False
            sage: G.0
            [(1/3, 0)]
            sage: H.0
            [(1/3, 0)]
        """
        A = self.parent().abelian_variety()
        from sage.rings.all import QQ
        if self.__element.change_ring(QQ) - right.__element.change_ring(QQ) in A.lattice():
            return rich_to_bool(op, 0)
        return richcmp(self.__element, right.__element, op)
    def _richcmp_(self, other, op):
        r"""
        Comparison.

        For ``self`` and ``other`` that have the same parent the method compares
        their rank.

        TESTS::

            sage: A = TotallyOrderedFiniteSet([3,2,7], facade=False)
            sage: A(3) < A(2) and A(3) <= A(2) and A(2) <= A(2)
            True
            sage: A(2) > A(3) and A(2) >= A(3) and A(7) >= A(7)
            True
            sage: A(3) >= A(7) or A(2) > A(2)
            False
            sage: A(7) < A(2) or A(2) <= A(3) or A(2) < A(2)
            False
        """
        if self.value == other.value:
            return rich_to_bool(op, 0)
        return richcmp(self.rank(), other.rank(), op)
Exemplo n.º 41
0
    def _richcmp_(self, other, op):
        r"""
        Comparison.

        For ``self`` and ``other`` that have the same parent the method compares
        their rank.

        TESTS::

            sage: A = TotallyOrderedFiniteSet([3,2,7], facade=False)
            sage: A(3) < A(2) and A(3) <= A(2) and A(2) <= A(2)
            True
            sage: A(2) > A(3) and A(2) >= A(3) and A(7) >= A(7)
            True
            sage: A(3) >= A(7) or A(2) > A(2)
            False
            sage: A(7) < A(2) or A(2) <= A(3) or A(2) < A(2)
            False
        """
        if self.value == other.value:
            return rich_to_bool(op, 0)
        return richcmp(self.rank(), other.rank(), op)
Exemplo n.º 42
0
    def _richcmp_(self, other, op):
        """
        Compares the generators of two ideals.

        INPUT:

        - ``other`` -- an ideal

        OUTPUT:

        boolean

        EXAMPLES::

            sage: R = ZZ; I = ZZ*2; J = ZZ*(-2)
            sage: I == J
            True
        """
        S = set(self.gens())
        T = set(other.gens())
        if S == T:
            return rich_to_bool(op, 0)
        return richcmp(self.gens(), other.gens(), op)
Exemplo n.º 43
0
    def _richcmp_(self, other, op):
        """
        Compares the generators of two ideals.

        INPUT:

        - ``other`` -- an ideal

        OUTPUT:

        boolean

        EXAMPLES::

            sage: R = ZZ; I = ZZ*2; J = ZZ*(-2)
            sage: I == J
            True
        """
        S = set(self.gens())
        T = set(other.gens())
        if S == T:
            return rich_to_bool(op, 0)
        return richcmp(self.gens(), other.gens(), op)
Exemplo n.º 44
0
    def __richcmp__(self, other, op):
        """
        Implement rich comparison.

        We treat two matrix groups as equal if their generators are
        the same in the same order. Infinitely-generated groups are
        compared by identity.

        INPUT:

        - ``other`` -- anything

        - ``op`` -- comparison operator

        OUTPUT:

        boolean

        EXAMPLES::

            sage: G = GL(2,3)
            sage: H = MatrixGroup(G.gens())
            sage: H == G
            True
            sage: G == H
            True

            sage: MS = MatrixSpace(QQ, 2, 2)
            sage: G = MatrixGroup([MS(1), MS([1,2,3,4])])
            sage: G == G
            True
            sage: G == MatrixGroup(G.gens())
            True

        TESTS::

            sage: G = groups.matrix.GL(4,2)
            sage: H = MatrixGroup(G.gens())
            sage: G == H
            True
            sage: G != H
            False
        """
        if not is_MatrixGroup(other):
            return NotImplemented

        if self is other:
            return rich_to_bool(op, 0)

        lx = self.matrix_space()
        rx = other.matrix_space()
        if lx != rx:
            return richcmp_not_equal(lx, rx, op)

        # compare number of generators
        try:
            n_self = self.ngens()
            n_other = other.ngens()
        except (AttributeError, NotImplementedError):
            return richcmp(id(self), id(other), op)

        if n_self != n_other:
            return richcmp_not_equal(self, other, op)

        from sage.structure.element import is_InfinityElement
        if is_InfinityElement(n_self) or is_InfinityElement(n_other):
            return richcmp(id(self), id(other), op)

        # compact generator matrices
        try:
            self_gens = self.gens()
            other_gens = other.gens()
        except (AttributeError, NotImplementedError):
            return richcmp(id(self), id(other), op)

        assert(n_self == n_other)
        for g, h in zip(self_gens, other_gens):
            lx = g.matrix()
            rx = h.matrix()
            if lx != rx:
                return richcmp_not_equal(lx, rx, op)
        return rich_to_bool(op, 0)
Exemplo n.º 45
0
Arquivo: maple.py Projeto: kliem/sage
    def _richcmp_(self, other, op):
        """
        Compare equality between self and other, using maple.

        These examples are optional, and require Maple to be installed. You
        don't need to install any Sage packages for this.

        EXAMPLES::

            sage: a = maple(5)                             # optional - maple
            sage: b = maple(5)                             # optional - maple
            sage: a == b                                   # optional - maple
            True
            sage: a == 5                                   # optional - maple
            True

        ::

            sage: c = maple(3)                             # optional - maple
            sage: a == c                                   # optional - maple
            False
            sage: a < c                                    # optional - maple
            False
            sage: a < 6                                    # optional - maple
            True
            sage: c <= a                                   # optional - maple
            True

        ::

            sage: M = matrix(ZZ, 2, range(1,5))            # optional - maple
            sage: Mm = maple(M)                            # optional - maple
            sage: Mm == Mm                                 # optional - maple
            True

        TESTS::

            sage: x = var('x')
            sage: t = maple((x+1)^2)                       # optional - maple
            sage: u = maple(x^2+2*x+1)                     # optional - maple
            sage: u == t # todo: not implemented
            True         # returns False, should use 'testeq' in maple
            sage: maple.eval('testeq(%s = %s)' % (t.name(),u.name()))    # optional - maple
            'true'
        """
        P = self.parent()
        if P.eval("evalb(%s %s %s)" % (self.name(), P._equality_symbol(),
                                       other.name())) == P._true_symbol():
            return rich_to_bool(op, 0)
        # Maple does not allow comparing objects of different types and
        # it raises an error in this case.
        # We catch the error, and return True for <
        try:
            if P.eval("evalb(%s %s %s)" % (self.name(), P._lessthan_symbol(),
                                           other.name())) == P._true_symbol():
                return rich_to_bool(op, -1)
        except RuntimeError as e:
            msg = str(e)
            if 'is not valid' in msg and 'to < or <=' in msg:
                if (hash(str(self)) < hash(str(other))):
                    return rich_to_bool(op, -1)
                else:
                    return rich_to_bool(op, 1)
            else:
                raise RuntimeError(e)
        if P.eval("evalb(%s %s %s)" % (self.name(), P._greaterthan_symbol(),
                                       other.name())) == P._true_symbol():
            return rich_to_bool(op, 1)
        return NotImplemented
Exemplo n.º 46
0
    def _richcmp_(self, other, op):
        r"""
        Comparisons

        TESTS::

            sage: F = FreeMonoid(index_set=ZZ)
            sage: a,b,c,d,e = [F.gen(i) for i in range(5)]
            sage: a == a
            True
            sage: a*e == a*e
            True
            sage: a*b*c^3*b*d == (a*b*c)*(c^2*b*d)
            True
            sage: a != b
            True
            sage: a*b != b*a
            True
            sage: a*b*c^3*b*d != (a*b*c)*(c^2*b*d)
            False

            sage: F = FreeMonoid(index_set=ZZ)
            sage: a,b,c,d,e = [F.gen(i) for i in range(5)]
            sage: a < b
            True
            sage: a*b < b*a
            True
            sage: a*b < a*a
            False
            sage: a^2*b < a*b*b
            True
            sage: b > a
            True
            sage: a*b > b*a
            False
            sage: a*b > a*a
            True
            sage: a*b <= b*a
            True
            sage: a*b <= b*a
            True

            sage: FA = FreeAbelianMonoid(index_set=ZZ)
            sage: a,b,c,d,e = [FA.gen(i) for i in range(5)]
            sage: a == a
            True
            sage: a*e == e*a
            True
            sage: a*b*c^3*b*d == a*d*(b^2*c^2)*c
            True
            sage: a != b
            True
            sage: a*b != a*a
            True
            sage: a*b*c^3*b*d != a*d*(b^2*c^2)*c
            False
        """
        if self._monomial == other._monomial:
            # Equal
            return rich_to_bool(op, 0)
        if op == op_EQ or op == op_NE:
            # Not equal
            return rich_to_bool(op, 1)
        return richcmp(self.to_word_list(), other.to_word_list(), op)
Exemplo n.º 47
0
    def _richcmp_(self, other, op):
        r"""
        Comparisons

        TESTS::

            sage: F = FreeMonoid(index_set=ZZ)
            sage: a,b,c,d,e = [F.gen(i) for i in range(5)]
            sage: a == a
            True
            sage: a*e == a*e
            True
            sage: a*b*c^3*b*d == (a*b*c)*(c^2*b*d)
            True
            sage: a != b
            True
            sage: a*b != b*a
            True
            sage: a*b*c^3*b*d != (a*b*c)*(c^2*b*d)
            False

            sage: F = FreeMonoid(index_set=ZZ)
            sage: a,b,c,d,e = [F.gen(i) for i in range(5)]
            sage: a < b
            True
            sage: a*b < b*a
            True
            sage: a*b < a*a
            False
            sage: a^2*b < a*b*b
            True
            sage: b > a
            True
            sage: a*b > b*a
            False
            sage: a*b > a*a
            True
            sage: a*b <= b*a
            True
            sage: a*b <= b*a
            True

            sage: FA = FreeAbelianMonoid(index_set=ZZ)
            sage: a,b,c,d,e = [FA.gen(i) for i in range(5)]
            sage: a == a
            True
            sage: a*e == e*a
            True
            sage: a*b*c^3*b*d == a*d*(b^2*c^2)*c
            True
            sage: a != b
            True
            sage: a*b != a*a
            True
            sage: a*b*c^3*b*d != a*d*(b^2*c^2)*c
            False
        """
        if self._monomial == other._monomial:
            # Equal
            return rich_to_bool(op, 0)
        if op == op_EQ or op == op_NE:
            # Not equal
            return rich_to_bool(op, 1)
        return richcmp(self.to_word_list(), other.to_word_list(), op)
Exemplo n.º 48
0
    def __richcmp__(self, other, op):
        r"""
        The order is given by the natural:

        self < other iff adherance(self) c adherance(other)

        TESTS::

            sage: a = AbelianStratum(1,3)
            sage: b = AbelianStratum(3,1)
            sage: c = AbelianStratum(1,3,marked_separatrix='out')
            sage: d = AbelianStratum(3,1,marked_separatrix='out')
            sage: e = AbelianStratum(1,3,marked_separatrix='in')
            sage: f = AbelianStratum(3,1,marked_separatrix='in')
            sage: a == b  # no difference for unmarked
            True
            sage: c == d  # difference for out mark
            False
            sage: e == f  # difference for in mark
            False
            sage: a == c  # difference between no mark and out mark
            False
            sage: a == e  # difference between no mark and in mark
            False
            sage: c == e  # difference between out mark adn in mark
            False

            sage: a == False
            Traceback (most recent call last):
            ...
            TypeError: the right member must be a stratum

            sage: a != b  # no difference for unmarked
            False
            sage: c != d  # difference for out mark
            True
            sage: e != f  # difference for in mark
            True
            sage: a != c  # difference between no mark and out mark
            True
            sage: a != e  # difference between no mark and in mark
            True
            sage: c != e  # difference between out mark adn in mark
            True
            sage: a != False
            Traceback (most recent call last):
            ...
            TypeError: the right member must be a stratum

            sage: a3 = AbelianStratum(3,2,1)
            sage: a3_out = AbelianStratum(3,2,1,marked_separatrix='out')
            sage: a3_in = AbelianStratum(3,2,1,marked_separatrix='in')
            sage: a3 == a3_out
            False
            sage: a3 == a3_in
            False
            sage: a3_out == a3_in
            False
        """
        if type(self) is not type(other):
            raise TypeError("the right member must be a stratum")

        if op == op_EQ or op == op_NE:
            z_eq = self._zeroes == other._zeroes
            ms_eq = self._marked_separatrix == other._marked_separatrix
            return (z_eq and ms_eq) == (op == op_EQ)

        if self._marked_separatrix != other._marked_separatrix:
            raise TypeError("the other must be a stratum with same marking")

        if self._zeroes < other._zeroes:
            return rich_to_bool(op, 1)
        elif self._zeroes > other._zeroes:
            return rich_to_bool(op, -1)
        return rich_to_bool(op, 0)