Beispiel #1
0
def get_graph(d_lst):
    '''
    Parameters
    ----------
    d_lst : list<Div>
        A list of "Div" objects.

    Returns
    -------
    sage_Graph

        A labeled "Graph()" where the elements
        of "d_lst" are the vertices.
        Different vertices are connected if
        their corresponding intersection product
        is non-zero and the edge is labeled with
        the intersection product.
    '''
    G = sage_Graph()
    G.add_vertices(range(len(d_lst)))

    for i in range(len(d_lst)):
        for j in range(len(d_lst)):
            if d_lst[i] * d_lst[j] > 0 and i != j:
                G.add_edge(i, j, d_lst[i] * d_lst[j])

    return G
Beispiel #2
0
def get_ext_graph(d_lst, M):
    '''
    Parameters
    ----------
    d_lst : list<Div> 
        A list of "Div" objects of equal rank.
        
    M : sage_matrix<sage_ZZ>   
        A square matrix with integral coefficients
        of rank "d_lst[0].rank()" 
    
    Returns
    -------
        A labeled "sage_Graph()" where the elements 
        of "d_lst" are the vertices. 
        A pair of non-orthogonal vertices are connected 
        by and edge labeled with their 
        non-zero intersection product. 
        Two vertices which are related 
        via M are connected with an edge labeled 1000.
        Labeled self-loops are also included.        
    '''
    NSTools.p('d_lst =', len(d_lst), d_lst, ', M =', list(M))

    G = sage_Graph()
    G.add_vertices(range(len(d_lst)))

    for i in range(len(d_lst)):
        for j in range(len(d_lst)):
            if d_lst[i] * d_lst[j] != 0:
                G.add_edge(i, j, d_lst[i] * d_lst[j])

    for i in range(len(d_lst)):
        j = d_lst.index(d_lst[i].mat_mul(M))
        G.add_edge(i, j, 1000)

    return G
Beispiel #3
0
def usecase__analyze_graphs(max_rank):
    '''
    We analyze the graphs of DPLattice objects in the output  
    of DPLattice.get_cls().
    
    Parameters
    ----------
    max_rank : int
        Maximal rank of DPLattice objects that are considered. 
    '''

    # Examine which of the graphs associated to DPLattices
    # are isomorphic to one of the constructed graphs.
    #
    NSTools.p('\t Compare contructed graphs with classified graphs...')
    rownr = -1
    max_verts = 0
    for rank in range(3, max_rank + 1):
        NSTools.p('\t ---')
        for dpl in DPLattice.get_cls(rank):
            rownr += 1

            # retrieve the graph SG for analysis
            SG, SG_data = dpl.get_SG()

            if SG.num_verts() <= 3:
                continue

            # check if each edge label is in [2,4]
            if [e for e in SG_data[3] if e not in [2, 4]] != []:
                continue

            # initialize string
            s = ''
            s += str(rownr) + ' ' + 'rank=' + str(rank) + ' '

            # Initialize G_lst which is a list of tuples (G,G_str)
            # where G is a constructed graph and G_str is its string identifier.
            # The identifiers are according Theorem 1 in arXiv:1807.05881v2.
            #
            G_lst = []
            for nv1 in range(1, SG.num_verts() + 1):
                for nv2 in range(1, SG.num_verts() + 1):

                    # determine list c_lst of 2-element subsets of [1,...,m]
                    # so that m is minimal under the condition that len(c_lst)>=nv1
                    c_lst = []
                    for i in range(2 * nv1):
                        c_lst = list(sage_Combinations(i, 2))
                        if len(c_lst) >= nv1:
                            break

                    # construct graphs
                    #
                    Gd = sage_Graph()
                    Gd.add_vertices(range(nv1))
                    G_lst += [(Gd, 'Gd:' + str(nv1))]

                    Ge = sage_Graph()
                    Ge.add_vertices(range(nv1))
                    for i in Ge.vertices():
                        for j in Ge.vertices():
                            Ge.add_edge(i, j, 2)
                    G_lst += [(Ge, 'Ge:' + str(nv1))]

                    Gf = sage_Graph()
                    Gf.add_vertices(range(len(c_lst)))
                    for i in Gf.vertices():
                        for j in Gf.vertices():
                            q = len([c for c in c_lst[i] if c in c_lst[j]])
                            Gf.add_edge(i, j, 4 - 2 * q)
                    G_lst += [(Gf, 'Gf:' + str(Gf.num_verts()))]

                    Gg = sage_Graph()
                    Gg.add_vertices(range(len(c_lst)))
                    for i in Gg.vertices():
                        for j in Gg.vertices():
                            q = len([c for c in c_lst[i] if c in c_lst[j]])
                            if q > 0:
                                Gg.add_edge(i, j, 2)
                    G_lst += [(Gg, 'Gg:' + str(Gg.num_verts()))]

                    # construct combined graphs
                    #
                    if nv1 + nv2 > SG.num_verts():
                        continue

                    Gd2 = sage_Graph()
                    Gd2.add_vertices(range(nv2))

                    Ge2 = sage_Graph()
                    Ge2.add_vertices(range(nv2))
                    for i in Ge2.vertices():
                        for j in Ge2.vertices():
                            Ge2.add_edge(i, j, 2)

                    if nv1 + nv2 == SG.num_verts():

                        if (Gd.num_verts(), Ge2.num_verts()) != (1, 1):
                            Gde = sage_Graph()
                            Gde.add_vertices(Ge2.vertices())
                            Gde.add_edges(Ge2.edges())
                            for i in range(Ge2.num_verts() - 1, -1, -1):
                                Gde.relabel({i: i + Gd.num_verts()})
                            Gde.add_vertices(Gd.vertices())
                            Gde.add_edges(Gd.edges())
                            for i in range(Gd.num_verts()):
                                for j in range(Gd.num_verts(),
                                               Gde.num_verts()):
                                    Gde.add_edge(i, j, 2)
                            G_lst += [(Gde, 'Gde:' + str(Gd.num_verts()) +
                                       '+' + str(Ge2.num_verts()))]

                    if len(c_lst) + nv2 == SG.num_verts():

                        Gfd = sage_Graph()
                        Gfd.add_vertices(Gd2.vertices())
                        Gfd.add_edges(Gd2.edges())
                        for i in range(Gd2.num_verts() - 1, -1, -1):
                            Gfd.relabel({i: i + Gf.num_verts()})
                        Gfd.add_vertices(Gf.vertices())
                        Gfd.add_edges(Gf.edges())
                        for i in range(Gf.num_verts()):
                            for j in range(Gf.num_verts(), Gfd.num_verts()):
                                Gfd.add_edge(i, j, 2)
                        G_lst += [(Gfd, 'Gfd:' + str(Gf.num_verts()) + '+' +
                                   str(Gd2.num_verts()))]

                        Gge = sage_Graph()
                        Gge.add_vertices(Ge2.vertices())
                        Gge.add_edges(Ge2.edges())
                        for i in range(Ge2.num_verts() - 1, -1, -1):
                            Gge.relabel({i: i + Gg.num_verts()})
                        Gge.add_vertices(Gg.vertices())
                        Gge.add_edges(Gg.edges())
                        for i in range(Gg.num_verts()):
                            for j in range(Gg.num_verts(), Gge.num_verts()):
                                Gge.add_edge(i, j, 2)
                        G_lst += [(Gge, 'Gge:' + str(Gg.num_verts()) + '+' +
                                   str(Ge2.num_verts()))]

            # check for each of the constructed graphs whether
            # it is isomorphic to dpl.get_SG()
            #
            for (G, G_str) in G_lst:
                if SG.is_isomorphic(G, edge_labels=True):
                    max_verts = max(max_verts, G.num_verts())
                    if G_str not in s:
                        s += G_str + ' '

            if ':' in s:
                NSTools.p('\t', s)

    NSTools.p('max_verts =', max_verts)
Beispiel #4
0
def get_dynkin_type(d_lst):
    '''
    Parameters
    ----------
    d_lst : list<Div>
        A list of lists of "Div" objects "d" of 
        the same rank, such that 
            d*d=-2 and d*(-3h+e1+...+er)=0 
        where 
            r=rank-1 and rank in [3,...,9].  
        We assume that "is_root_basis(d_lst)==True":
        linear independent, self intersection number -2
        and pairwise product either 0 or 1.            
                     
    Returns
    -------
    string
        Returns a string denoting the Dynkin type of a 
        root system with basis "d_lst".  
        Returns 'A0' if "d_lst==[]".
    
    Note
    ----
        For example:
        [<1145>, <1123>, <23>, <45>, <56>, <78>] --> '3A1+A3'
        where <1145> is shorthand for "Div.new('1145')".      
        
    Raises
    ------
    ValueError
        If the Dynkin type of d_lst cannot be recognized.
         
    '''
    if d_lst == []: return 'A0'

    # check whether values are cached
    #
    construct_dynkin_types = True
    max_r = d_lst[0].rank() - 1
    key = 'get_dynkin_type_' + str(max_r)
    for r in range(max_r, 8 + 1):
        if 'get_dynkin_type_' + str(r) in NSTools.get_tool_dct():
            key = 'get_dynkin_type_' + str(r)
            construct_dynkin_types = False

    # construct list of dynkin types if values are not cached
    #
    if construct_dynkin_types:
        NSTools.p('Constructing list of Dynkin types... max_r =', max_r)

        ade_lst = []
        for comb_lst in sage_Combinations(max_r * ['A', 'D', 'E'], max_r):
            for perm_lst in sage_Permutations(comb_lst):
                ade_lst += [perm_lst]
        #
        # "ade_lst" contains all combinations of 'A', 'D', 'E'
        # and looks as follows:
        #
        #     ade_lst[0] = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A']
        #     ade_lst[1] = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'D']
        #     ade_lst[2] = ['A', 'A', 'A', 'A', 'A', 'A', 'D', 'A']
        #     ...
        #     ade_lst[?] = ['A', 'D', 'A', 'D', 'A', 'D', 'E', 'A']
        #     ...
        #     ade_lst[-1]= ['E', 'E', 'E', 'E', 'E', 'E', 'E', 'E']
        #

        type_lst = []
        ts_lst = []
        for ade in ade_lst:
            for r in range(1, max_r + 1):
                for p_lst in sage_Partitions(r + max_r, length=max_r):

                    # obtain type list
                    t_lst = [(ade[i], p_lst[i] - 1) for i in range(max_r)
                             if p_lst[i] != 1]
                    t_lst.sort()

                    # obtain Root system
                    # or continue if invalid Cartan/Dynkin type
                    if ('D', 2) in t_lst or ('D', 3) in t_lst:
                        continue
                    try:
                        rs = sage_RootSystem(t_lst)
                    except ValueError as err:
                        continue  # not a valid Cartan type

                    # obtain graph G
                    mat = list(-1 * rs.cartan_matrix())
                    G = sage_Graph()
                    G.add_vertices(range(len(mat)))
                    for i in range(len(mat)):
                        for j in range(len(mat[0])):
                            if mat[i][j] == 1:
                                G.add_edge(i, j)

                    # obtain string for type
                    # Example: [(A,1),(A,1),(A,1),(A,3)] ---> '3A1+A3'
                    tmp_lst = [t for t in t_lst]
                    ts = ''
                    while len(tmp_lst) > 0:
                        t = tmp_lst[0]
                        c = tmp_lst.count(t)
                        while t in tmp_lst:
                            tmp_lst.remove(t)
                        if ts != '':
                            ts += '+'
                        if c > 1:
                            ts += str(c)

                        ts += t[0] + str(t[1])

                    # add to type_lst if new
                    if ts not in ts_lst:
                        type_lst += [(G, ts, t_lst)]
                        ts_lst += [ts]
                        NSTools.p('added to list: ', ts,
                                  '\t\t...please wait...')

        NSTools.p('Finished constructing list of Dynkin types.')
        # cache the constructed "type_lst"
        NSTools.get_tool_dct()[key] = type_lst
        NSTools.save_tool_dct()

    # end if
    else:
        type_lst = NSTools.get_tool_dct()[key]
    G1 = get_graph(d_lst)

    # loop through all types and check equivalence
    for (G2, ts, t_lst) in type_lst:
        if G1.is_isomorphic(G2):
            return ts

    raise ValueError('Could not recognize Dynkin type: ', d_lst)
Beispiel #5
0
    def get_SG(self):
        '''
        The simple family graph associated to the 
        Neron-Severi lattice of a weak del Pezzo surface
        is defined as the incidence diagram of self.real_fam_lst,
        with the edges labeled <=1 removed. 
        All vertices are labeled with the index of the element in 
        self.real_fam_lst. 
        
        In the mathematical version (see arxiv paper) the vertices 
        are labeled with the dimension of the linear series, which is 
        always 1 with one exception: 
        If len(self.real_fam_lst)==0 and rank==3, then
        the simple family graph consists of a single vertex labeled 2. 
        
        Example
        -------
        # The following graph is related to the E8 root system:
        #
        dpl = DPLattice.get_cls( 9 )[0]
        assert set(dpl.get_SG().num_verts()) == {2160}
        assert set(dpl.get_SG().get_degree()) == {2095}
        assert set(dpl.get_SG().edge_labels()) == {2,3,4,5,6,7,8}

        
        Returns
        -------
        sage_GRAPH, [int, int, list<int>, list<int>, bool, bool, bool, bool ]
            The simple family graph self.SG and a list self.SG_data 
            associated to the current DPLattice object.
            Here self.SG_data consists of data that describes self.SG.
            This method also initializes self.SG and self.SG_data.
        '''

        if self.SG != None:
            return self.SG, self.SG_data

        if self.get_rank() == 9 and self.get_numbers()[-1] > 800:
            NSTools.p(
                'Initializing simple family graph of current DPLattice object...',
                self.get_rank(), self.get_marked_Mtype(), self.get_real_type())

        f = self.real_fam_lst
        f_range = range(len(f))

        self.SG = sage_Graph()
        self.SG.add_vertices(f_range)
        for i in f_range:
            for j in f_range:
                if f[i] * f[j] > 1:
                    self.SG.add_edge(i, j, f[i] * f[j])

        self.SG_data = [
            self.SG.num_verts(),  # number of vertices
            self.SG.num_edges(),  # number of edges
            sorted(list(set(
                self.SG.degree()))),  # possible numbers of outgoing edges
            sorted(list(set(self.SG.edge_labels()))),  # possible edge labels
            self.SG.is_clique(),  # True iff the graph is complete.
            self.SG.is_connected(),
            self.SG.is_vertex_transitive(),
            self.SG.is_edge_transitive()
        ]

        return self.SG, self.SG_data