示例#1
0
def g_quad(graph, node_list, gui=True):
    '''
    Return quadratic form (numpy array) of networkx graph 'graph', ordered
    according to the node names in 'node_list'.
    
    Q(v,v) = weight(v)
    Q(v,w) = 1 if v, w are connected by an edge; 0 otherwise
    Thus Q is the adjacency matrix everywhere except the diagonal, and just
    the weights down the diagonal.
    '''
    assert len(node_list) == len(graph.nodes(data=False))
    assert is_forest(graph)
    num_bad = num_bad_vertices(graph, node_list)
    if num_bad > 2:
        if gui:
            tkMessageBox.showwarning('Bad vertices', 
                          'More than two bad vertices. (There are %i.)'%num_bad)
        raise ValueError('More than two bad vertices. (There are %i.)'%num_bad)
    # create adjacency matrix, ordered according to node_list
    adj = nx.to_numpy_matrix(graph, nodelist=node_list, dtype=numpy.int)
    for index, node in enumerate(node_list): # change diagonal
        adj[index, index] = graph.node[node]['weight']
    if not is_negative_definite(adj):
        if gui:
            tkMessageBox.showwarning('Quadratic form', 
                                     'Quadratic form is not negative definite')
        print adj
        raise ValueError('quadratric form is not negative definite')        
    return adj
示例#2
0
def s_quad_form(listdata, gui=True):
    '''
    Returns the tuple (numpy.array quadratic_form, bool minus) of the weighted 
    'star-like' tree associated with the plumbed 3-manifold given by Seifert 
    data 'listdata'.
    
    minus = True if orientation of the manifold described by listdata has been
    reversed, False otherwise
    
    Input: listdata [e, (p1, q1),...,(pr, qr)]
    Note: You should run correct_form on listdata; s_quad_form does not do this
          automatically
    
    The 'star-like' tree is formed as follows:
    Center node is a vertex with weight -e.
    There are r branches coming off of the center vertex.
    Each branch has the vertices [-a0, -a1, ... , -an], where a0,a1,...,an
    are the numbers in the continued fraction expansion of pi/qi, for each i.
    (Note: the continued fraction expansion has minus signs; see function
    'cont_fraction'.)
    
    The quadratic form of the weighted graph is defined by
    Q(v, v) = m(v), where m is the weight of the vertex
    Q(v, w) = 1 if v, w are connected by an edge, 0 otherwise
    '''
    new_data, minus = alter_data(listdata, gui) # make e > 0, -pi < qi < 0
    tree = [new_data[0]] # list of weights in star tree [e, a0, a1,...]
    branch_lengths = [] # list of lengths of branches in star tree, not 
                        # including start node
    for pair in new_data[1:]:
        branch = cont_fraction(pair[0], -pair[1])
        branch_lengths.append(len(branch))
        tree.extend(branch)
    size = sum(branch_lengths) + 1 # add start node
    row = 0
    column = 0
    # make the quadratic form matrix
    quad = numpy.zeros(shape=(size, size), dtype=numpy.int)
    # fill in the diagonal
    for index in range(size):
        quad[index,index] = -tree[index]
    # fill in the others (upper right triangle)
    cur_position = 1
    for length in branch_lengths:
        quad[0,cur_position] = 1 # star node
        for index in range(cur_position, cur_position+length-1):
            quad[index,index+1] = 1 # adjacent
        cur_position += length
    symmetric(quad)
    if not is_negative_definite(quad):
        if gui:
            tkMessageBox.showwarning('Quadratic form', 
                                     'Quadratic form is not negative definite')
        print quad
        raise ValueError('quadratric form is not negative definite')        
    # check get the same thing from weighted_graph.py; also checks negative def.
    assert numpy.array_equal(quad, g_quad(make_graph(new_data), \
                                          ['N%i' %num for num in range(size)]))
    return quad, minus