Пример #1
0
    def cartan_type(self):
        """
        Return the Cartan type of ``self``.

        EXAMPLES::

            sage: FiniteWeylGroups().example().cartan_type()
            ['A', 3] relabelled by {1: 0, 2: 1, 3: 2}
        """
        from sage.combinat.root_system.cartan_type import CartanType
        C = CartanType(['A', self.n - 1])
        C = C.relabel(lambda i: i - 1)
        return C
Пример #2
0
    def cartan_type(self):
        """
        Return the Cartan type of ``self``.

        EXAMPLES::

            sage: FiniteWeylGroups().example().cartan_type()
            ['A', 3] relabelled by {1: 0, 2: 1, 3: 2}
        """
        from sage.combinat.root_system.cartan_type import CartanType
        C = CartanType(['A',self.n-1])
        C = C.relabel(lambda i:i-1)
        return C
Пример #3
0
    def cartan_type(self):
        r"""
        Return the Cartan type of ``self``.

        EXAMPLES::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            ['A', 3]

            sage: W = ReflectionGroup(['A',3], ['B',3])                 # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            A3xB3 relabelled by {1: 3, 2: 2, 3: 1}

        TESTS:

        Check that dihedral types are handled properly::

            sage: W = ReflectionGroup(['I',3]); W                       # optional - gap3
            Irreducible real reflection group of rank 2 and type A2

            sage: W = ReflectionGroup(['I',4]); W                       # optional - gap3
            Irreducible real reflection group of rank 2 and type C2

            sage: W = ReflectionGroup(['I',5]); W                       # optional - gap3
            Irreducible real reflection group of rank 2 and type I2(5)
        """
        if len(self._type) == 1:
            ct = self._type[0]
            if ct['series'] == "I":
                C = CartanType([ct['series'], ct['bond']])
            else:
                C = CartanType([ct['series'], ct['rank']])
            CG = C.coxeter_diagram()
            G = self.coxeter_diagram()
            return C.relabel(
                CG.is_isomorphic(G, edge_labels=True, certificate=True)[1])
        else:
            return CartanType(
                [W.cartan_type() for W in self.irreducible_components()])
Пример #4
0
    def cartan_type(self):
        r"""
        Return the Cartan type of ``self``.

        EXAMPLES::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            ['A', 3]

            sage: W = ReflectionGroup(['A',3], ['B',3])                 # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            A3xB3 relabelled by {1: 3, 2: 2, 3: 1}                      
        """
        if len(self._type) == 1:
            ct = self._type[0]
            C = CartanType([ct['series'], ct['rank']])
            CG = C.coxeter_diagram()
            G = self.coxeter_diagram()
            return C.relabel(CG.is_isomorphic(G, edge_labels=True, certificate=True)[1])
        else:
            return CartanType([W.cartan_type() for W in self.irreducible_components()])
Пример #5
0
    def cartan_type(self):
        r"""
        Return the Cartan type of ``self``.

        EXAMPLES::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            ['A', 3]

            sage: W = ReflectionGroup(['A',3], ['B',3])                 # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            A3xB3 relabelled by {1: 3, 2: 2, 3: 1}                      
        """
        if len(self._type) == 1:
            ct = self._type[0]
            C = CartanType([ct['series'], ct['rank']])
            CG = C.coxeter_diagram()
            G = self.coxeter_diagram()
            return C.relabel(CG.is_isomorphic(G, edge_labels=True, certificate=True)[1])
        else:
            return CartanType([W.cartan_type() for W in self.irreducible_components()])
Пример #6
0
    def cartan_type(self):
        r"""
        Return the Cartan type of ``self``.

        EXAMPLES::

            sage: W = ReflectionGroup(['A',3])                          # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            ['A', 3]

            sage: W = ReflectionGroup(['A',3], ['B',2])                 # optional - gap3
            sage: W.cartan_type()                                       # optional - gap3
            A3xB2
        """
        if len(self._type) == 1:
            ct = self._type[0]
            C = CartanType([ct['series'], ct['rank']])
            return C.relabel(
                {i + 1: ii
                 for i, ii in enumerate(self.index_set())})
        else:
            return CartanType(
                [W.cartan_type() for W in self.irreducible_components()])
Пример #7
0
def find_cartan_type_from_matrix(CM):
    r"""
    Find a Cartan type by direct comparison of Dynkin diagrams given from
    the generalized Cartan matrix ``CM`` and return ``None`` if not found.

    INPUT:

    - ``CM`` -- a generalized Cartan matrix

    EXAMPLES::

        sage: from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix
        sage: CM = CartanMatrix([[2,-1,-1], [-1,2,-1], [-1,-1,2]])
        sage: find_cartan_type_from_matrix(CM)
        ['A', 2, 1]
        sage: CM = CartanMatrix([[2,-1,0], [-1,2,-2], [0,-1,2]])
        sage: find_cartan_type_from_matrix(CM)
        ['C', 3] relabelled by {1: 0, 2: 1, 3: 2}
        sage: CM = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
        sage: find_cartan_type_from_matrix(CM)
    """
    types = []
    for S in CM.dynkin_diagram().connected_components_subgraphs():
        S = DiGraph(S)  # We need a simple digraph here
        n = S.num_verts()
        # Build the list to test based upon rank
        if n == 1:
            types.append(CartanType(['A', 1]))
            continue

        test = [['A', n]]
        if n >= 2:
            if n == 2:
                test += [['G', 2], ['A', 2, 2]]
            test += [['B', n], ['A', n - 1, 1]]
        if n >= 3:
            if n == 3:
                test.append(['G', 2, 1])
            test += [['C', n], ['BC', n - 1, 2], ['C', n - 1, 1]]
        if n >= 4:
            if n == 4:
                test.append(['F', 4])
            test += [['D', n], ['B', n - 1, 1]]
        if n >= 5:
            if n == 5:
                test.append(['F', 4, 1])
            test.append(['D', n - 1, 1])
        if n == 6:
            test.append(['E', 6])
        elif n == 7:
            test += [['E', 7], ['E', 6, 1]]
        elif n == 8:
            test += [['E', 8], ['E', 7, 1]]
        elif n == 9:
            test.append(['E', 8, 1])

        # Test every possible Cartan type and its dual
        found = False
        for x in test:
            ct = CartanType(x)
            T = DiGraph(ct.dynkin_diagram())  # We need a simple digraph here
            iso, match = T.is_isomorphic(S, certificate=True, edge_labels=True)
            if iso:
                types.append(ct.relabel(match))
                found = True
                break

            if ct == ct.dual():
                continue  # self-dual, so nothing more to test

            ct = ct.dual()
            T = DiGraph(ct.dynkin_diagram())  # We need a simple digraph here
            iso, match = T.is_isomorphic(S, certificate=True, edge_labels=True)
            if iso:
                types.append(ct.relabel(match))
                found = True
                break
        if not found:
            return None

    return CartanType(types)
Пример #8
0
    def __classcall_private__(cls,
                              data=None,
                              index_set=None,
                              cartan_type=None,
                              cartan_type_check=True):
        """
        Normalize input so we can inherit from sparse integer matrix.

        .. NOTE::

            To disable the Cartan type check, use the optional argument
            ``cartan_type_check = False``.

        EXAMPLES::

            sage: C = CartanMatrix(['A',1,1])
            sage: C2 = CartanMatrix([[2, -2], [-2, 2]])
            sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1])
            sage: C == C2 and C == C3
            True

        TESTS:

        Check that :trac:`15740` is fixed::

            sage: d = DynkinDiagram()
            sage: d.add_edge('a', 'b', 2)
            sage: d.index_set()
            ('a', 'b')
            sage: cm = CartanMatrix(d)
            sage: cm.index_set()
            ('a', 'b')
        """
        # Special case with 0 args and kwds has Cartan type
        if cartan_type is not None and data is None:
            data = CartanType(cartan_type)

        if data is None:
            data = []
            n = 0
            index_set = tuple()
            cartan_type = None
            subdivisions = None
        elif isinstance(data, CartanMatrix):
            if index_set is not None:
                d = {a: index_set[i] for i, a in enumerate(data.index_set())}
                return data.relabel(d)
            return data
        else:
            dynkin_diagram = None
            subdivisions = None

            from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class
            if isinstance(data, DynkinDiagram_class):
                dynkin_diagram = data
                cartan_type = data._cartan_type
            else:
                try:
                    cartan_type = CartanType(data)
                    dynkin_diagram = cartan_type.dynkin_diagram()
                except (TypeError, ValueError):
                    pass

            if dynkin_diagram is not None:
                n = dynkin_diagram.rank()
                index_set = dynkin_diagram.index_set()
                oir = dynkin_diagram.odd_isotropic_roots()
                reverse = {a: i for i, a in enumerate(index_set)}
                data = {(i, i): 2 if index_set[i] not in oir else 0
                        for i in range(n)}
                for (i, j, l) in dynkin_diagram.edge_iterator():
                    data[(reverse[j], reverse[i])] = -l
            else:
                M = matrix(data)
                if not is_generalized_cartan_matrix(M):
                    raise ValueError(
                        "the input matrix is not a generalized Cartan matrix")
                n = M.ncols()
                data = M.dict()
                subdivisions = M._subdivisions

            if index_set is None:
                index_set = tuple(range(n))
            else:
                index_set = tuple(index_set)

        if len(index_set) != n and len(set(index_set)) != n:
            raise ValueError("the given index set is not valid")

        # We can do the Cartan type initialization later as this is not
        #   a unique representation
        mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, False, True)
        # FIXME: We have to initialize the CartanMatrix part separately because
        #   of the __cinit__ of the matrix. We should get rid of this workaround
        mat._CM_init(cartan_type, index_set, cartan_type_check)
        mat._subdivisions = subdivisions
        return mat
Пример #9
0
    def __classcall_private__(cls, data=None, index_set=None,
                              cartan_type=None, cartan_type_check=True,
                              borcherds=None):
        """
        Normalize input so we can inherit from sparse integer matrix.

        .. NOTE::

            To disable the Cartan type check, use the optional argument
            ``cartan_type_check = False``.

        EXAMPLES::

            sage: C = CartanMatrix(['A',1,1])
            sage: C2 = CartanMatrix([[2, -2], [-2, 2]])
            sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1])
            sage: C == C2 and C == C3
            True

        TESTS:

        Check that :trac:`15740` is fixed::

            sage: d = DynkinDiagram()
            sage: d.add_edge('a', 'b', 2)
            sage: d.index_set()
            ('a', 'b')
            sage: cm = CartanMatrix(d)
            sage: cm.index_set()
            ('a', 'b')
        """
        # Special case with 0 args and kwds has Cartan type
        if cartan_type is not None and data is None:
            data = CartanType(cartan_type)

        if data is None:
            data = []
            n = 0
            index_set = tuple()
            cartan_type = None
            subdivisions = None
        elif isinstance(data, CartanMatrix):
            if index_set is not None:
                d = {a: index_set[i] for i,a in enumerate(data.index_set())}
                return data.relabel(d)
            return data
        else:
            dynkin_diagram = None
            subdivisions = None

            from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class
            if isinstance(data, DynkinDiagram_class):
                dynkin_diagram = data
                cartan_type = data._cartan_type
            else:
                try:
                    cartan_type = CartanType(data)
                    dynkin_diagram = cartan_type.dynkin_diagram()
                except (TypeError, ValueError):
                    pass

            if dynkin_diagram is not None:
                n = dynkin_diagram.rank()
                index_set = dynkin_diagram.index_set()
                oir = dynkin_diagram.odd_isotropic_roots()
                reverse = {a: i for i,a in enumerate(index_set)}
                if isinstance(borcherds, (list, tuple)):
                    if (len(borcherds) != len(index_set)
                        and not all(val in ZZ
                                    and (val == 2 or (val % 2 == 0 and val < 0))
                                    for val in borcherds)):
                        raise ValueError("the input data is not a Borcherds-Cartan matrix")
                    data = {(i, i): val if index_set[i] not in oir else 0
                            for i,val in enumerate(borcherds)}
                else:
                    data = {(i, i): 2 if index_set[i] not in oir else 0
                            for i in range(n)}
                for (i,j,l) in dynkin_diagram.edge_iterator():
                    data[(reverse[j], reverse[i])] = -l
            else:
                M = matrix(data)
                if borcherds:
                    if not is_borcherds_cartan_matrix(M):
                        raise ValueError("the input matrix is not a Borcherds-Cartan matrix")
                else:
                    if not is_generalized_cartan_matrix(M):
                        raise ValueError("the input matrix is not a generalized Cartan matrix")
                n = M.ncols()
                data = M.dict()
                subdivisions = M._subdivisions

            if index_set is None:
                index_set = tuple(range(n))
            else:
                index_set = tuple(index_set)

        if len(index_set) != n and len(set(index_set)) != n:
            raise ValueError("the given index set is not valid")

        # We can do the Cartan type initialization later as this is not
        #   a unique representation
        mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, False, True)
        # FIXME: We have to initialize the CartanMatrix part separately because
        #   of the __cinit__ of the matrix. We should get rid of this workaround
        mat._CM_init(cartan_type, index_set, cartan_type_check)
        mat._subdivisions = subdivisions
        return mat
Пример #10
0
def find_cartan_type_from_matrix(CM):
    r"""
    Find a Cartan type by direct comparison of Dynkin diagrams given from
    the generalized Cartan matrix ``CM`` and return ``None`` if not found.

    INPUT:

    - ``CM`` -- a generalized Cartan matrix

    EXAMPLES::

        sage: from sage.combinat.root_system.cartan_matrix import find_cartan_type_from_matrix
        sage: CM = CartanMatrix([[2,-1,-1], [-1,2,-1], [-1,-1,2]])
        sage: find_cartan_type_from_matrix(CM)
        ['A', 2, 1]
        sage: CM = CartanMatrix([[2,-1,0], [-1,2,-2], [0,-1,2]])
        sage: find_cartan_type_from_matrix(CM)
        ['C', 3] relabelled by {1: 0, 2: 1, 3: 2}
        sage: CM = CartanMatrix([[2,-1,-2], [-1,2,-1], [-2,-1,2]])
        sage: find_cartan_type_from_matrix(CM)
    """
    types = []
    for S in CM.dynkin_diagram().connected_components_subgraphs():
        S = DiGraph(S) # We need a simple digraph here
        n = S.num_verts()
        # Build the list to test based upon rank
        if n == 1:
            types.append(CartanType(['A', 1]))
            continue

        test = [['A', n]]
        if n >= 2:
            if n == 2:
                test += [['G',2], ['A',2,2]]
            test += [['B',n], ['A',n-1,1]]
        if n >= 3:
            if n == 3:
                test.append(['G',2,1])
            test += [['C',n], ['BC',n-1,2], ['C',n-1,1]]
        if n >= 4:
            if n == 4:
                test.append(['F',4])
            test += [['D',n], ['B',n-1,1]]
        if n >= 5:
            if n == 5:
                test.append(['F',4,1])
            test.append(['D',n-1,1])
        if n == 6:
            test.append(['E',6])
        elif n == 7:
            test += [['E',7], ['E',6,1]]
        elif n == 8:
            test += [['E',8], ['E',7,1]]
        elif n == 9:
            test.append(['E',8,1])

        # Test every possible Cartan type and its dual
        found = False
        for x in test:
            ct = CartanType(x)
            T = DiGraph(ct.dynkin_diagram()) # We need a simple digraph here
            iso, match = T.is_isomorphic(S, certificate=True, edge_labels=True)
            if iso:
                types.append(ct.relabel(match))
                found = True
                break

            if ct == ct.dual():
                continue # self-dual, so nothing more to test

            ct = ct.dual()
            T = DiGraph(ct.dynkin_diagram()) # We need a simple digraph here
            iso, match = T.is_isomorphic(S, certificate=True, edge_labels=True)
            if iso:
                types.append(ct.relabel(match))
                found = True
                break
        if not found:
            return None

    return CartanType(types)
Пример #11
0
    def cartan_type(self):
        r"""
        Returns the Cartan type of the Cartan companion of self.b_matrix()

        Only crystallographic types are implemented

        Warning: this function is redundant but the corresonding method in
        CartanType does not recognize all the types
        """
        A = self.cartan_companion()
        n = self.rk
        degrees_dict = dict(zip(range(n),map(sum,2-A)))
        degrees_set = Set(degrees_dict.values())

        types_to_check = [ ["A",n] ]
        if n > 1:
            types_to_check.append(["B",n])
        if n > 2:
            types_to_check.append(["C",n])
        if n > 3:
            types_to_check.append(["D",n])
        if n >=6 and n <= 8:
            types_to_check.append(["E",n])
        if n == 4:
            types_to_check.append(["F",n])
        if n == 2:
            types_to_check.append(["G",n])
        if n >1:
            types_to_check.append(["A", n-1,1])
            types_to_check.append(["B", n-1,1])
            types_to_check.append(["BC",n-1,2])
            types_to_check.append(["A", 2*n-2,2])
            types_to_check.append(["A", 2*n-3,2])
        if n>2:
            types_to_check.append(["C", n-1,1])
            types_to_check.append(["D", n,2])
        if n>3:
            types_to_check.append(["D", n-1,1])
        if n >=7 and n <= 9:
            types_to_check.append(["E",n-1,1])
        if n == 5:
            types_to_check.append(["F",4,1])
        if n == 3:
            types_to_check.append(["G",n-1,1])
            types_to_check.append(["D",4,3])
        if n == 5:
            types_to_check.append(["E",6,2])

        for ct_name in types_to_check:
            ct = CartanType(ct_name)
            if 0 not in ct.index_set():
                ct = ct.relabel(dict(zip(range(1,n+1),range(n))))
            ct_matrix = ct.cartan_matrix()
            ct_degrees_dict = dict(zip(range(n),map(sum,2-ct_matrix)))
            if Set(ct_degrees_dict.values()) != degrees_set:
                continue
            for p in Permutations(range(n)):
                relabeling = dict(zip(range(n),p))
                ct_new = ct.relabel(relabeling)
                if ct_new.cartan_matrix() == A:
                    return copy(ct_new)
        raise ValueError("Type not recognized")
Пример #12
0
    def cartan_type(self):
        r"""
        Returns the Cartan type of the Cartan companion of self.b_matrix()

        Only crystallographic types are implemented

        Warning: this function is redundant but the corresonding method in
        CartanType does not recognize all the types
        """
        A = self.cartan_companion()
        n = self.rk
        degrees_dict = dict(zip(range(n), map(sum, 2 - A)))
        degrees_set = Set(degrees_dict.values())

        types_to_check = [["A", n]]
        if n > 1:
            types_to_check.append(["B", n])
        if n > 2:
            types_to_check.append(["C", n])
        if n > 3:
            types_to_check.append(["D", n])
        if n >= 6 and n <= 8:
            types_to_check.append(["E", n])
        if n == 4:
            types_to_check.append(["F", n])
        if n == 2:
            types_to_check.append(["G", n])
        if n > 1:
            types_to_check.append(["A", n - 1, 1])
            types_to_check.append(["B", n - 1, 1])
            types_to_check.append(["BC", n - 1, 2])
            types_to_check.append(["A", 2 * n - 2, 2])
            types_to_check.append(["A", 2 * n - 3, 2])
        if n > 2:
            types_to_check.append(["C", n - 1, 1])
            types_to_check.append(["D", n, 2])
        if n > 3:
            types_to_check.append(["D", n - 1, 1])
        if n >= 7 and n <= 9:
            types_to_check.append(["E", n - 1, 1])
        if n == 5:
            types_to_check.append(["F", 4, 1])
        if n == 3:
            types_to_check.append(["G", n - 1, 1])
            types_to_check.append(["D", 4, 3])
        if n == 5:
            types_to_check.append(["E", 6, 2])

        for ct_name in types_to_check:
            ct = CartanType(ct_name)
            if 0 not in ct.index_set():
                ct = ct.relabel(dict(zip(range(1, n + 1), range(n))))
            ct_matrix = ct.cartan_matrix()
            ct_degrees_dict = dict(zip(range(n), map(sum, 2 - ct_matrix)))
            if Set(ct_degrees_dict.values()) != degrees_set:
                continue
            for p in Permutations(range(n)):
                relabeling = dict(zip(range(n), p))
                ct_new = ct.relabel(relabeling)
                if ct_new.cartan_matrix() == A:
                    return copy(ct_new)
        raise ValueError("Type not recognized")