def is_locally_solvable(self, p):
        r"""
        Returns True if and only if ``self`` has a solution over the
        `p`-adic numbers. Here `p` is a prime number or equals
        `-1`, infinity, or `\RR` to denote the infinite place.

        EXAMPLES::

            sage: C = Conic(QQ, [1,2,3])
            sage: C.is_locally_solvable(-1)
            False
            sage: C.is_locally_solvable(2)
            False
            sage: C.is_locally_solvable(3)
            True
            sage: C.is_locally_solvable(QQ.hom(RR))
            False
            sage: D = Conic(QQ, [1, 2, -3])
            sage: D.is_locally_solvable(infinity)
            True
            sage: D.is_locally_solvable(RR)
            True

        """
        from sage.categories.map import Map
        from sage.categories.all import Rings

        D, T = self.diagonal_matrix()
        abc = [D[j, j] for j in range(3)]
        if abc[2] == 0:
            return True
        a = -abc[0]/abc[2]
        b = -abc[1]/abc[2]
        if is_RealField(p) or is_InfinityElement(p):
            p = -1
        elif isinstance(p, Map) and p.category_for().is_subcategory(Rings()):
            # p is a morphism of Rings
            if p.domain() is QQ and is_RealField(p.codomain()):
                p = -1
            else:
                raise TypeError("p (=%s) needs to be a prime of base field " \
                                 "B ( =`QQ`) in is_locally_solvable" % p)
        if hilbert_symbol(a, b, p) == -1:
            if self._local_obstruction is None:
                self._local_obstruction = p
            return False
        return True
    def is_locally_solvable(self, p):
        r"""
        Returns True if and only if ``self`` has a solution over the
        `p`-adic numbers. Here `p` is a prime number or equals
        `-1`, infinity, or `\RR` to denote the infinite place.

        EXAMPLES::

            sage: C = Conic(QQ, [1,2,3])
            sage: C.is_locally_solvable(-1)
            False
            sage: C.is_locally_solvable(2)
            False
            sage: C.is_locally_solvable(3)
            True
            sage: C.is_locally_solvable(QQ.hom(RR))
            False
            sage: D = Conic(QQ, [1, 2, -3])
            sage: D.is_locally_solvable(infinity)
            True
            sage: D.is_locally_solvable(RR)
            True

        """
        from sage.categories.map import Map
        from sage.categories.all import Rings

        D, T = self.diagonal_matrix()
        abc = [D[j, j] for j in range(3)]
        if abc[2] == 0:
            return True
        a = -abc[0] / abc[2]
        b = -abc[1] / abc[2]
        if is_RealField(p) or is_InfinityElement(p):
            p = -1
        elif isinstance(p, Map) and p.category_for().is_subcategory(Rings()):
            # p is a morphism of Rings
            if p.domain() is QQ and is_RealField(p.codomain()):
                p = -1
            else:
                raise TypeError("p (=%s) needs to be a prime of base field " \
                                 "B ( =`QQ`) in is_locally_solvable" % p)
        if hilbert_symbol(a, b, p) == -1:
            if self._local_obstruction is None:
                self._local_obstruction = p
            return False
        return True
Exemple #3
0
    def __init__(self, number_field, a, b=None, parent=None, lreps=None):
        """
        Constructor of number field cusps. See ``NFCusp`` for full
        documentation.

        EXAMPLES::

            sage: k.<a> = NumberField(x^2 + 1)
            sage: c = NFCusp(k, 3, a+1); c
            Cusp [3: a + 1] of Number Field in a with defining polynomial x^2 + 1
            sage: c.parent()
            Set of all cusps of Number Field in a with defining polynomial x^2 + 1
            sage: kCusps = NFCusps(k)
            sage: c.parent() is kCusps
            True
        """
        if parent is None:
            parent = NFCusps(number_field)
        Element.__init__(self, parent)
        R = number_field.maximal_order()
        if b is None:
            if not a:#that is cusp "0"
                self.__a = R(0)
                self.__b = R(1)
                return
            if isinstance(a, NFCusp):
                if a.parent() == parent:
                    self.__a = R(a.__a)
                    self.__b = R(a.__b)
                else:
                    raise ValueError("Cannot coerce cusps from one field to another")
            elif a in R:
                self.__a = R(a)
                self.__b = R(1)
            elif a in number_field:
                self.__b = R(a.denominator())
                self.__a = R(a * self.__b)
            elif is_InfinityElement(a):
                self.__a = R(1)
                self.__b = R(0)
            elif isinstance(a, (int, long)):
                self.__a = R(a)
                self.__b = R(1)
            elif isinstance(a, (tuple, list)):
                if len(a) != 2:
                    raise TypeError("Unable to convert %s to a cusp \
                                      of the number field"%a)
                if a[1].is_zero():
                    self.__a = R(1)
                    self.__b = R(0)
                elif a[0] in R and a[1] in R:
                    self.__a = R(a[0])
                    self.__b = R(a[1])
                elif isinstance(a[0], NFCusp):#we know that a[1] is not zero
                    if a[1] == 1:
                        self.__a = a[0].__a
                        self.__b = a[0].__b
                    else:
                        r = a[0].__a / (a[0].__b * a[1])
                        self.__b = R(r.denominator())
                        self.__a = R(r*self.__b)
                else:
                    try:
                        r = number_field(a[0]/a[1])
                        self.__b = R(r.denominator())
                        self.__a = R(r * self.__b)
                    except (ValueError, TypeError):
                        raise TypeError("Unable to convert %s to a cusp \
                                          of the number field"%a)
            else:
                try:
                    r = number_field(a)
                    self.__b = R(r.denominator())
                    self.__a = R(r * self.__b)
                except (ValueError, TypeError):
                    raise TypeError("Unable to convert %s to a cusp \
                                      of the number field"%a)
        else:#'b' is given
            if is_InfinityElement(b):
                if is_InfinityElement(a) or (isinstance(a, NFCusp) and a.is_infinity()):
                    raise TypeError("Unable to convert (%s, %s) \
                                      to a cusp of the number field"%(a, b))
                self.__a = R(0)
                self.__b = R(1)
                return
            elif not b:
                if not a:
                     raise TypeError("Unable to convert (%s, %s) \
                                       to a cusp of the number field"%(a, b))
                self.__a = R(1)
                self.__b = R(0)
                return
            if not a:
                self.__a = R(0)
                self.__b = R(1)
                return
            if (b in R or isinstance(b, (int, long))) and (a in R or isinstance(a, (int, long))):
                self.__a = R(a)
                self.__b = R(b)
            else:
                if a in R or a in number_field:
                    r = a / b
                elif is_InfinityElement(a):
                    self.__a = R(1)
                    self.__b = R(0)
                    return
                elif isinstance(a, NFCusp):
                    if a.is_infinity():
                        self.__a = R(1)
                        self.__b = R(0)
                        return
                    r = a.__a / (a.__b * b)
                elif isinstance(a, (int, long)):
                    r = R(a) / b
                elif isinstance(a, (tuple, list)):
                    if len(a) != 2:
                        raise TypeError("Unable to convert (%s, %s) \
                                          to a cusp of the number field"%(a, b))
                    r = R(a[0]) / (R(a[1]) * b)
                else:
                    try:
                        r = number_field(a) / b
                    except (ValueError, TypeError):
                        raise TypeError("Unable to convert (%s, %s) \
                                          to a cusp of the number field"%(a, b))
                self.__b = R(r.denominator())
                self.__a = R(r * self.__b)
        if not lreps is None:
        # Changes the representative of the cusp so the ideal associated
        # to the cusp is one of the ideals of the given list lreps.
        # Note: the trivial class is always represented by (1).
            I = self.ideal()
            for J in lreps:
                if (J/I).is_principal():
                    newI = J
            l = (newI/I).gens_reduced()[0]
            self.__a = R(l * self.__a)
            self.__b = R(l * self.__b)
    def __init__(self, number_field, a, b=None, parent=None, lreps=None):
        """
        Constructor of number field cusps. See ``NFCusp`` for full
        documentation.

        EXAMPLES::

            sage: k.<a> = NumberField(x^2 + 1)
            sage: c = NFCusp(k, 3, a+1); c
            Cusp [3: a + 1] of Number Field in a with defining polynomial x^2 + 1
            sage: c.parent()
            Set of all cusps of Number Field in a with defining polynomial x^2 + 1
            sage: kCusps = NFCusps(k)
            sage: c.parent() is kCusps
            True
        """
        if parent is None:
            parent = NFCusps(number_field)
        Element.__init__(self, parent)
        R = number_field.maximal_order()
        if b is None:
            if not a:  #that is cusp "0"
                self.__a = R(0)
                self.__b = R(1)
                return
            if isinstance(a, NFCusp):
                if a.parent() == parent:
                    self.__a = R(a.__a)
                    self.__b = R(a.__b)
                else:
                    raise ValueError(
                        "Cannot coerce cusps from one field to another")
            elif a in R:
                self.__a = R(a)
                self.__b = R(1)
            elif a in number_field:
                self.__b = R(a.denominator())
                self.__a = R(a * self.__b)
            elif is_InfinityElement(a):
                self.__a = R(1)
                self.__b = R(0)
            elif isinstance(a, (int, long)):
                self.__a = R(a)
                self.__b = R(1)
            elif isinstance(a, (tuple, list)):
                if len(a) != 2:
                    raise TypeError("Unable to convert %s to a cusp \
                                      of the number field" % a)
                if a[1].is_zero():
                    self.__a = R(1)
                    self.__b = R(0)
                elif a[0] in R and a[1] in R:
                    self.__a = R(a[0])
                    self.__b = R(a[1])
                elif isinstance(a[0], NFCusp):  #we know that a[1] is not zero
                    if a[1] == 1:
                        self.__a = a[0].__a
                        self.__b = a[0].__b
                    else:
                        r = a[0].__a / (a[0].__b * a[1])
                        self.__b = R(r.denominator())
                        self.__a = R(r * self.__b)
                else:
                    try:
                        r = number_field(a[0] / a[1])
                        self.__b = R(r.denominator())
                        self.__a = R(r * self.__b)
                    except (ValueError, TypeError):
                        raise TypeError("Unable to convert %s to a cusp \
                                          of the number field" % a)
            else:
                try:
                    r = number_field(a)
                    self.__b = R(r.denominator())
                    self.__a = R(r * self.__b)
                except (ValueError, TypeError):
                    raise TypeError("Unable to convert %s to a cusp \
                                      of the number field" % a)
        else:  #'b' is given
            if is_InfinityElement(b):
                if is_InfinityElement(a) or (isinstance(a, NFCusp)
                                             and a.is_infinity()):
                    raise TypeError("Unable to convert (%s, %s) \
                                      to a cusp of the number field" % (a, b))
                self.__a = R(0)
                self.__b = R(1)
                return
            elif not b:
                if not a:
                    raise TypeError("Unable to convert (%s, %s) \
                                       to a cusp of the number field" % (a, b))
                self.__a = R(1)
                self.__b = R(0)
                return
            if not a:
                self.__a = R(0)
                self.__b = R(1)
                return
            if (b in R or isinstance(b,
                                     (int, long))) and (a in R or isinstance(
                                         a, (int, long))):
                self.__a = R(a)
                self.__b = R(b)
            else:
                if a in R or a in number_field:
                    r = a / b
                elif is_InfinityElement(a):
                    self.__a = R(1)
                    self.__b = R(0)
                    return
                elif isinstance(a, NFCusp):
                    if a.is_infinity():
                        self.__a = R(1)
                        self.__b = R(0)
                        return
                    r = a.__a / (a.__b * b)
                elif isinstance(a, (int, long)):
                    r = R(a) / b
                elif isinstance(a, (tuple, list)):
                    if len(a) != 2:
                        raise TypeError("Unable to convert (%s, %s) \
                                          to a cusp of the number field" %
                                        (a, b))
                    r = R(a[0]) / (R(a[1]) * b)
                else:
                    try:
                        r = number_field(a) / b
                    except (ValueError, TypeError):
                        raise TypeError("Unable to convert (%s, %s) \
                                          to a cusp of the number field" %
                                        (a, b))
                self.__b = R(r.denominator())
                self.__a = R(r * self.__b)
        if not lreps is None:
            # Changes the representative of the cusp so the ideal associated
            # to the cusp is one of the ideals of the given list lreps.
            # Note: the trivial class is always represented by (1).
            I = self.ideal()
            for J in lreps:
                if (J / I).is_principal():
                    newI = J
            l = (newI / I).gens_reduced()[0]
            self.__a = R(l * self.__a)
            self.__b = R(l * self.__b)
Exemple #5
0
    def _cmp_generators(self, other):
        """
        Implement 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.

        OUTPUT:

        ``-1``, ``0``, or ``+1``.

        EXAMPLES::

            sage: G = GL(2,3)
            sage: H = MatrixGroup(G.gens())
            sage: G._cmp_generators(H)
            0
            sage: cmp(G,H)
            0
            sage: cmp(H,G)
            0
            sage: G == H
            True
        """
        if not is_MatrixGroup(other):
            return cmp(type(self), type(other))
        c = cmp(self.matrix_space(), other.matrix_space())
        if c != 0:
            return c

        def identity_cmp():
            return cmp(id(self), id(other))

        # compare number of generators
        try:
            n_self = self.ngens()
            n_other = other.ngens()
        except (AttributeError, NotImplementedError):
            return identity_cmp()
        c = cmp(n_self, n_other)
        if c != 0:
            return c
        from sage.structure.element import is_InfinityElement
        if is_InfinityElement(n_self) or is_InfinityElement(n_other):
            return identity_cmp()

        # compacte generator matrices
        try:
            self_gens = self.gens()
            other_gens = other.gens()
        except (AttributeError, NotImplementedError):
            return identity_cmp()
        assert(n_self == n_other)
        for g,h in zip(self_gens, other_gens):
            c = cmp(g.matrix(), h.matrix())
            if c != 0:
                return c
        return c
Exemple #6
0
    def _cmp_generators(self, other):
        """
        Implement 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.

        OUTPUT:

        ``-1``, ``0``, or ``+1``.

        EXAMPLES::

            sage: G = GL(2,3)
            sage: H = MatrixGroup(G.gens())
            sage: G._cmp_generators(H)
            0
            sage: cmp(G,H)
            0
            sage: cmp(H,G)
            0
            sage: G == H
            True
        """
        if not is_MatrixGroup(other):
            return cmp(type(self), type(other))
        c = cmp(self.matrix_space(), other.matrix_space())
        if c != 0:
            return c

        def identity_cmp():
            return cmp(id(self), id(other))

        # compare number of generators
        try:
            n_self = self.ngens()
            n_other = other.ngens()
        except (AttributeError, NotImplementedError):
            return identity_cmp()
        c = cmp(n_self, n_other)
        if c != 0:
            return c
        from sage.structure.element import is_InfinityElement
        if is_InfinityElement(n_self) or is_InfinityElement(n_other):
            return identity_cmp()

        # compacte generator matrices
        try:
            self_gens = self.gens()
            other_gens = other.gens()
        except (AttributeError, NotImplementedError):
            return identity_cmp()
        assert(n_self == n_other)
        for g,h in zip(self_gens, other_gens):
            c = cmp(g.matrix(), h.matrix())
            if c != 0:
                return c
        return c
Exemple #7
0
    def __init__(self, a, b=None, parent=None, check=True):
        r"""
        Create the cusp a/b in `\mathbb{P}^1(\QQ)`, where if b=0
        this is the cusp at infinity.

        When present, b must either be Infinity or coercible to an
        Integer.

        EXAMPLES::

            sage: Cusp(2,3)
            2/3
            sage: Cusp(3,6)
            1/2
            sage: Cusp(1,0)
            Infinity
            sage: Cusp(infinity)
            Infinity
            sage: Cusp(5)
            5
            sage: Cusp(1/2)
            1/2
            sage: Cusp(1.5)
            3/2
            sage: Cusp(int(7))
            7
            sage: Cusp(1, 2, check=False)
            1/2
            sage: Cusp('sage', 2.5, check=False)          # don't do this!
            sage/2.50000000000000

        ::

            sage: I**2
            -1
            sage: Cusp(I)
            Traceback (most recent call last):
            ...
            TypeError: unable to convert I to a cusp

        ::

            sage: a = Cusp(2,3)
            sage: loads(a.dumps()) == a
            True

        ::

            sage: Cusp(1/3,0)
            Infinity
            sage: Cusp((1,0))
            Infinity

        TESTS::

            sage: Cusp("1/3", 5)
            1/15
            sage: Cusp(Cusp(3/5), 7)
            3/35
            sage: Cusp(5/3, 0)
            Infinity
            sage: Cusp(3,oo)
            0
            sage: Cusp((7,3), 5)
            7/15
            sage: Cusp(int(5), 7)
            5/7

        ::

            sage: Cusp(0,0)
            Traceback (most recent call last):
            ...
            TypeError: unable to convert (0, 0) to a cusp

        ::

            sage: Cusp(oo,oo)
            Traceback (most recent call last):
            ...
            TypeError: unable to convert (+Infinity, +Infinity) to a cusp

        ::

            sage: Cusp(Cusp(oo),oo)
            Traceback (most recent call last):
            ...
            TypeError: unable to convert (Infinity, +Infinity) to a cusp
        """
        if parent is None:
            parent = Cusps
        Element.__init__(self, parent)

        if not check:
            self.__a = a
            self.__b = b
            return

        if b is None:
            if isinstance(a, Integer):
                self.__a = a
                self.__b = ZZ.one()
            elif isinstance(a, Rational):
                self.__a = a.numer()
                self.__b = a.denom()
            elif is_InfinityElement(a):
                self.__a = ZZ.one()
                self.__b = ZZ.zero()
            elif isinstance(a, Cusp):
                self.__a = a.__a
                self.__b = a.__b
            elif isinstance(a, integer_types):
                self.__a = ZZ(a)
                self.__b = ZZ.one()
            elif isinstance(a, (tuple, list)):
                if len(a) != 2:
                    raise TypeError("unable to convert %r to a cusp" % a)
                if ZZ(a[1]) == 0:
                    self.__a = ZZ.one()
                    self.__b = ZZ.zero()
                    return
                try:
                    r = QQ((a[0], a[1]))
                    self.__a = r.numer()
                    self.__b = r.denom()
                except (ValueError, TypeError):
                    raise TypeError("unable to convert %r to a cusp" % a)
            else:
                try:
                    r = QQ(a)
                    self.__a = r.numer()
                    self.__b = r.denom()
                except (ValueError, TypeError):
                    raise TypeError("unable to convert %r to a cusp" % a)
            return

        if is_InfinityElement(b):
            if is_InfinityElement(a) or (isinstance(a, Cusp) and a.is_infinity()):
                raise TypeError("unable to convert (%r, %r) to a cusp" % (a, b))
            self.__a = ZZ.zero()
            self.__b = ZZ.one()
            return
        elif not b:
            if not a:
                raise TypeError("unable to convert (%r, %r) to a cusp" % (a, b))
            self.__a = ZZ.one()
            self.__b = ZZ.zero()
            return

        if isinstance(a, Integer) or isinstance(a, Rational):
            r = a / ZZ(b)
        elif is_InfinityElement(a):
            self.__a = ZZ.one()
            self.__b = ZZ.zero()
            return
        elif isinstance(a, Cusp):
            if a.__b:
                r = a.__a / (a.__b * b)
            else:
                self.__a = ZZ.one()
                self.__b = ZZ.zero()
                return
        elif isinstance(a, integer_types):
            r = ZZ(a) / b
        elif isinstance(a, (tuple, list)):
            if len(a) != 2:
                raise TypeError("unable to convert (%r, %r) to a cusp" % (a, b))
            r = ZZ(a[0]) / (ZZ(a[1]) * b)
        else:
            try:
                r = QQ(a) / b
            except (ValueError, TypeError):
                raise TypeError("unable to convert (%r, %r) to a cusp" % (a, b))

        self.__a = r.numer()
        self.__b = r.denom()
Exemple #8
0
    def __init__(self, a, b=None, parent=None, check=True):
        r"""
        Create the cusp a/b in `\mathbb{P}^1(\QQ)`, where if b=0
        this is the cusp at infinity.

        When present, b must either be Infinity or coercible to an
        Integer.

        EXAMPLES::

            sage: Cusp(2,3)
            2/3
            sage: Cusp(3,6)
            1/2
            sage: Cusp(1,0)
            Infinity
            sage: Cusp(infinity)
            Infinity
            sage: Cusp(5)
            5
            sage: Cusp(1/2)
            1/2
            sage: Cusp(1.5)
            3/2
            sage: Cusp(int(7))
            7
            sage: Cusp(1, 2, check=False)
            1/2
            sage: Cusp('sage', 2.5, check=False)          # don't do this!
            sage/2.50000000000000

        ::

            sage: I**2
            -1
            sage: Cusp(I)
            Traceback (most recent call last):
            ...
            TypeError: Unable to convert I to a Cusp

        ::

            sage: a = Cusp(2,3)
            sage: loads(a.dumps()) == a
            True

        ::

            sage: Cusp(1/3,0)
            Infinity
            sage: Cusp((1,0))
            Infinity

        TESTS::

            sage: Cusp("1/3", 5)
            1/15
            sage: Cusp(Cusp(3/5), 7)
            3/35
            sage: Cusp(5/3, 0)
            Infinity
            sage: Cusp(3,oo)
            0
            sage: Cusp((7,3), 5)
            7/15
            sage: Cusp(int(5), 7)
            5/7

        ::

            sage: Cusp(0,0)
            Traceback (most recent call last):
            ...
            TypeError: Unable to convert (0, 0) to a Cusp

        ::

            sage: Cusp(oo,oo)
            Traceback (most recent call last):
            ...
            TypeError: Unable to convert (+Infinity, +Infinity) to a Cusp

        ::

            sage: Cusp(Cusp(oo),oo)
            Traceback (most recent call last):
            ...
            TypeError: Unable to convert (Infinity, +Infinity) to a Cusp
        """
        if parent is None:
            parent = Cusps
        Element.__init__(self, parent)

        if not check:
            self.__a = a; self.__b = b
            return

        if b is None:
            if isinstance(a, Integer):
                self.__a = a
                self.__b = ZZ(1)
            elif isinstance(a, Rational):
                self.__a = a.numer()
                self.__b = a.denom()
            elif is_InfinityElement(a):
                self.__a = ZZ(1)
                self.__b = ZZ(0)
            elif isinstance(a, Cusp):
                self.__a = a.__a
                self.__b = a.__b
            elif isinstance(a, (int, long)):
                self.__a = ZZ(a)
                self.__b = ZZ(1)
            elif isinstance(a, (tuple, list)):
                if len(a) != 2:
                    raise TypeError, "Unable to convert %s to a Cusp"%a
                if ZZ(a[1]) == 0:
                    self.__a = ZZ(1)
                    self.__b = ZZ(0)
                    return
                try:
                    r = QQ((a[0], a[1]))
                    self.__a = r.numer()
                    self.__b = r.denom()
                except (ValueError, TypeError):
                    raise TypeError, "Unable to convert %s to a Cusp"%a
            else:
                try:
                    r = QQ(a)
                    self.__a = r.numer()
                    self.__b = r.denom()
                except (ValueError, TypeError):
                    raise TypeError, "Unable to convert %s to a Cusp"%a
            return

        if is_InfinityElement(b):
            if is_InfinityElement(a) or (isinstance(a, Cusp) and a.is_infinity()):
                raise TypeError, "Unable to convert (%s, %s) to a Cusp"%(a, b)
            self.__a = ZZ(0)
            self.__b = ZZ(1)
            return
        elif not b:
            if not a:
                raise TypeError, "Unable to convert (%s, %s) to a Cusp"%(a, b)
            self.__a = ZZ(1)
            self.__b = ZZ(0)
            return

        if isinstance(a, Integer) or isinstance(a, Rational):
            r = a / ZZ(b)
        elif is_InfinityElement(a):
            self.__a = ZZ(1)
            self.__b = ZZ(0)
            return
        elif isinstance(a, Cusp):
            if a.__b:
                r = a.__a / (a.__b * b)
            else:
                self.__a = ZZ(1)
                self.__b = ZZ(0)
                return
        elif isinstance(a, (int, long)):
            r = ZZ(a) / b
        elif isinstance(a, (tuple, list)):
            if len(a) != 2:
                raise TypeError, "Unable to convert (%s, %s) to a Cusp"%(a, b)
            r = ZZ(a[0]) / (ZZ(a[1]) * b)
        else:
            try:
                r = QQ(a) / b
            except (ValueError, TypeError):
                raise TypeError, "Unable to convert (%s, %s) to a Cusp"%(a, b)

        self.__a = r.numer()
        self.__b = r.denom()
Exemple #9
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)
Exemple #10
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)