Ejemplo n.º 1
0
def get_response_content(fs):
    # read the tree
    T, B, N = FtreeIO.newick_to_TBN(fs.tree)
    leaves = Ftree.T_to_leaves(T)
    internal = Ftree.T_to_internal_vertices(T)
    # get the distinguished vertex of articulation
    r = get_unique_vertex(N, fs.vertex)
    if r not in internal:
        raise ValueError(
                'the distinguished vertex should have degree at least two')
    # Partition the leaves with respect to the given root.
    # Each set of leaves will eventually define a connected component.
    R = Ftree.T_to_R_specific(T, r)
    v_to_sinks = Ftree.R_to_v_to_sinks(R)
    # break some edges
    R_pruned = set(R)
    neighbors = Ftree.T_to_v_to_neighbors(T)[r]
    for adj in neighbors:
        R_pruned.remove((r, adj))
    T_pruned = Ftree.R_to_T(R_pruned)
    # get the leaf partition
    ordered_leaves = []
    leaf_lists = []
    for adj in neighbors:
        R_subtree = Ftree.T_to_R_specific(T_pruned, adj)
        C = sorted(b for a, b in R_subtree if b not in v_to_sinks)
        ordered_leaves.extend(C)
        leaf_lists.append(C)
    # define the vertices to keep and those to remove
    keepers = ordered_leaves + [r]
    # get the schur complement
    L_schur = Ftree.TB_to_L_schur(T, B, keepers)
    # get principal submatrices of the schur complement
    principal_matrices = []
    accum = 0
    for component_leaves in leaf_lists:
        n = len(component_leaves)
        M = L_schur[accum:accum+n, accum:accum+n]
        principal_matrices.append(M)
        accum += n
    # write the report
    out = StringIO()
    print >> out, 'algebraic connectivity:'
    print >> out, get_algebraic_connectivity(T, B, leaves)
    print >> out
    print >> out
    print >> out, 'perron values:'
    print >> out
    for M, leaf_list in zip(principal_matrices, leaf_lists):
        value = scipy.linalg.eigh(M, eigvals_only=True)[0]
        name_list = [N[v] for v in leaf_list]
        print >> out, name_list
        print >> out, value
        print >> out
    return out.getvalue()
Ejemplo n.º 2
0
def get_response_content(fs):
    # read the tree
    T, B, N = FtreeIO.newick_to_TBN(fs.tree)
    leaves = Ftree.T_to_leaves(T)
    internal = Ftree.T_to_internal_vertices(T)
    # get the valuations with harmonic extensions
    w, V = Ftree.TB_to_harmonic_extension(T, B, leaves, internal)
    # get the Fiedler valuations with harmonic extensions
    h = V[:, 0]
    # check for vertices with small valuations
    eps = 1e-8
    if any(abs(x) < x for x in h):
        raise ValueError('the tree has no clear harmonic Fiedler point')
    # find the edge contining the harmonic Fiedler point
    v_to_val = dict((v, h[i]) for i, v in enumerate(leaves + internal))
    d_edges = [(a, b) for a, b in T if v_to_val[a] * v_to_val[b] < 0]
    if len(d_edges) != 1:
        raise ValueError('expected the point to fall clearly on a single edge')
    d_edge = d_edges[0]
    a, b = d_edge
    # find the proportion along the directed edge
    t = v_to_val[a] / (v_to_val[a] - v_to_val[b])
    # find the distance from the new root to each endpoint vertices
    u_edge = frozenset(d_edge)
    d = B[u_edge]
    da = t * d
    db = (1 - t) * d
    # create the new tree
    r = max(Ftree.T_to_order(T)) + 1
    N[r] = fs.root_name
    T.remove(u_edge)
    del B[u_edge]
    ea = frozenset((r, a))
    eb = frozenset((r, b))
    T.add(ea)
    T.add(eb)
    B[ea] = da
    B[eb] = db
    # add a new leaf with arbitrary branch length
    leaf = r + 1
    N[leaf] = fs.leaf_name
    u_edge = frozenset((r, leaf))
    T.add(u_edge)
    B[u_edge] = 1.0
    # get the best branch length to cause eigenvalue multiplicity
    blen = scipy.optimize.golden(get_gap, (T, B, u_edge),
                                 full_output=False,
                                 tol=1e-12)
    B[u_edge] = blen
    # return the string representation of the new tree
    R = Ftree.T_to_R_specific(T, r)
    return FtreeIO.RBN_to_newick(R, B, N)
Ejemplo n.º 3
0
def get_response_content(fs):
    # read the tree
    T, B, N = FtreeIO.newick_to_TBN(fs.tree)
    leaves = Ftree.T_to_leaves(T)
    internal = Ftree.T_to_internal_vertices(T)
    # get the valuations with harmonic extensions
    w, V = Ftree.TB_to_harmonic_extension(T, B, leaves, internal)
    # get the Fiedler valuations with harmonic extensions
    h = V[:, 0]
    # check for vertices with small valuations
    eps = 1e-8
    if any(abs(x) < x for x in h):
        raise ValueError('the tree has no clear harmonic Fiedler point')
    # find the edge contining the harmonic Fiedler point
    v_to_val = dict((v, h[i]) for i, v in enumerate(leaves + internal))
    d_edges = [(a, b) for a, b in T if v_to_val[a] * v_to_val[b] < 0]
    if len(d_edges) != 1:
        raise ValueError('expected the point to fall clearly on a single edge')
    d_edge = d_edges[0]
    a, b = d_edge
    # find the proportion along the directed edge
    t = v_to_val[a] / (v_to_val[a] - v_to_val[b])
    # find the distance from the new root to each endpoint vertices
    u_edge = frozenset(d_edge)
    d = B[u_edge]
    da = t * d
    db = (1 - t) * d
    # create the new tree
    r = max(Ftree.T_to_order(T)) + 1
    T.remove(u_edge)
    del B[u_edge]
    ea = frozenset((r, a))
    eb = frozenset((r, b))
    T.add(ea)
    T.add(eb)
    B[ea] = da
    B[eb] = db
    R = Ftree.T_to_R_specific(T, r)
    # return the string representation of the new tree
    return FtreeIO.RBN_to_newick(R, B, N)
Ejemplo n.º 4
0
 def set_root(self, v):
     """
     This is slow, probably as a result of the design.
     """
     self.R = Ftree.T_to_R_specific(Ftree.R_to_T(self.R), v)
     self.v_to_source = Ftree.R_to_v_to_source(self.R)