def R_to_distn_nonspectral(R): """ The rate matrix must be irreducible and reversible. It is not necessarily symmetric. If the rate matrix is symmetric then this function is overkill because the stationary distribution would be uniform. """ nstates = len(R) V = set(range(nstates)) E = set() for i in range(nstates): for j in range(i): if R[i, j]: if not R[j, i]: raise MatrixUtil.MatrixError( 'the matrix is not reversible') edge = frozenset((i, j)) E.add(edge) nd = graph.g_to_nd(V, E) # construct an arbitrary rooted spanning tree of the states V_component, D_component = graph.nd_to_dag_component(nd, 0) if V_component != V: raise MatrixUtil.MatrixError('the matrix is not irreducible') # compute the stationary probabilities relative to the first state weights = [None] * nstates v_to_children = graph.dag_to_cd(V_component, D_component) preorder_states = graph.topo_sort(V_component, D_component) weights[preorder_states[0]] = 1.0 for parent in preorder_states: for child in v_to_children[parent]: ratio = R[parent, child] / R[child, parent] weights[child] = weights[parent] * ratio total = sum(weights) return np.array(weights) / total
def R_to_distn_nonspectral(R): """ The rate matrix must be irreducible and reversible. It is not necessarily symmetric. If the rate matrix is symmetric then this function is overkill because the stationary distribution would be uniform. """ nstates = len(R) V = set(range(nstates)) E = set() for i in range(nstates): for j in range(i): if R[i, j]: if not R[j, i]: raise MatrixUtil.MatrixError('the matrix is not reversible') edge = frozenset((i,j)) E.add(edge) nd = graph.g_to_nd(V, E) # construct an arbitrary rooted spanning tree of the states V_component, D_component = graph.nd_to_dag_component(nd, 0) if V_component != V: raise MatrixUtil.MatrixError('the matrix is not irreducible') # compute the stationary probabilities relative to the first state weights = [None] * nstates v_to_children = graph.dag_to_cd(V_component, D_component) preorder_states = graph.topo_sort(V_component, D_component) weights[preorder_states[0]] = 1.0 for parent in preorder_states: for child in v_to_children[parent]: ratio = R[parent, child] / R[child, parent] weights[child] = weights[parent] * ratio total = sum(weights) return np.array(weights) / total
def get_dp_edges(V, U): """ Return a sequence of directed edges of an unrooted tree. The returned sequence of directed edges is sorted for dynamic programming. When a directed edge appears in the list, all of the directed edges it points towards will have preceded it. @param V: vertices @param U: undirected edges @return: a sequence of directed edges """ V_meta = set() D_meta = set() nd = graph.g_to_nd(V, U) for v, neighbors in nd.items(): for a in neighbors: V_meta.add((a, v)) V_meta.add((v, a)) for b in neighbors: if a != b: D_meta.add(((a, v), (v, b))) return graph.topo_sort(V_meta, D_meta)
def get_response_content(fs): # read the edges of the directed graph whitelist = set(string.uppercase + string.lowercase + string.digits) pairs = [] for line in fs.strlist: a, b = line.split() if set(a) - whitelist: raise ValueError('invalid name: ' + a) if set(b) - whitelist: raise ValueError('invalid name: ' + b) pairs.append((a, b)) # make the graph in convenient xml form tree, name_to_node, pair_to_edge = make_graph(pairs, fs.width_inches) # modify the node attributes of the svg and get the name id map name_to_node_id, name_pair_to_edge_id = modify_tree( tree, name_to_node, pair_to_edge) # get the topological sort of the node ids names = name_to_node.keys() topo_names = reversed(graph.topo_sort(names, pairs)) topo_ids = [name_to_node_id[name] for name in topo_names] # get the map from node name to child edge ids name_to_edge_ids = dict((name, []) for name in names) for name_pair, edge_id in name_pair_to_edge_id.items(): source_name, sink_name = name_pair name_to_edge_ids[source_name].append(edge_id) # get the map from edge id to sink id edge_id_to_sink_id = {} for name_pair, edge_id in name_pair_to_edge_id.items(): source_name, sink_name = name_pair edge_id_to_sink_id[edge_id] = name_to_node_id[sink_name] # wrap the embedded svg into some html svg_str = etree.tostring(tree) out = StringIO() print >> out, '<html>' print >> out print >> out, '<head>' print >> out, "<script type='text/javascript'>" print >> out, g_script_init print >> out, 'var topo_sorted_node_ids = [' for node_id in topo_ids: print >> out, "'%s'," % node_id print >> out, '];' print >> out, 'var edge_id_to_sink_id = {' for edge_id, sink_id in edge_id_to_sink_id.items(): print >> out, "%s: '%s'," % (edge_id, sink_id) print >> out, '};' print >> out, 'var node_id_to_edge_ids = {' for source_name, edge_ids in name_to_edge_ids.items(): source_id = name_to_node_id[source_name] s = ', '.join("'%s'" % x for x in edge_ids) print >> out, '%s: [%s],' % (source_id, s) print >> out, '};' print >> out, 'var node_id_to_name = {' for name, node_id in name_to_node_id.items(): print >> out, "%s: '%s'," % (node_id, name) print >> out, '};' print >> out, g_script_guts print >> out, '</script>' print >> out, '</head>' print >> out print >> out, '<body>' print >> out print >> out, '<fieldset>' print >> out, '<legend>selections</legend>' print >> out, svg_str print >> out, '</fieldset>' print >> out print >> out, g_html_form print >> out print >> out, '</body>' print >> out, '</html>' return out.getvalue()