Exemple #1
0
    def _calculate_feather(self, graph: nx.classes.graph.Graph) -> np.ndarray:
        """
        Calculating the characteristic function features of a graph.

        Arg types:
            * **graph** *(NetworkX graph)* - A graph to be embedded.

        Return types:
            * **features** *(Numpy vector)* - The embedding of a single graph.
        """
        self.n_nodes = graph.number_of_nodes()
        self.degree_fn = _get_degree_fn(graph)

        A_tilde = self._get_normalized_adjacency(graph)
        X = self._create_node_feature_matrix(graph)
        theta = np.linspace(0.01, self.theta_max, self.eval_points)

        X = np.outer(X, theta)
        X = X.reshape(graph.number_of_nodes(), -1)
        X = np.concatenate([np.cos(X), np.sin(X)], axis=1)

        feature_blocks = []
        for _ in range(self.order):
            X = A_tilde.dot(X)
            feature_blocks.append(X)

        feature_blocks = np.concatenate(feature_blocks, axis=1)
        feature_blocks = self.pool_fn(feature_blocks)

        return feature_blocks
Exemple #2
0
    def _ensure_integrity(
            graph: nx.classes.graph.Graph) -> nx.classes.graph.Graph:
        """Ensure walk traversal conditions."""
        edge_list = [(index, index)
                     for index in range(graph.number_of_nodes())]
        graph.add_edges_from(edge_list)

        return graph
Exemple #3
0
def get_closest_sensors(G: nx.classes.graph.Graph, central_node: str, n: any,
                        shortest_paths: list) -> list:
    """
	Creates a list of sensors closest to the main node (both pressure and flow)
				using NetworkX all_pairs_dijkstra_path_length()
	Arguments:	G - NetworkX graph of the water network
				central_node - name of junction you need sensors positions relative to
				n - number of closest sensors, int or str ('all' for all sensors)
				shortest_paths - list(all_pairs_dijkstra_path_length(G)) from NetworkX
	Returns: 	list of n closest sensors sorted by distance (ascending), or all sensors if n='all'
	"""

    nodes_measured = []  # which junctions have pressure sensors in them?
    edges_measured = []  # which pipes have flow sensors?

    # make lists of node/edge objects with sensors in them
    for node in G.nodes(data=True):
        if node[1]['measurement'] is True:
            nodes_measured.append(node)
    for edge in G.edges(data=True):
        if edge[2]['measurement'] is True:
            edges_measured.append(edge)

    objects_measured = {
        'junctions': nodes_measured,
        'pipes': edges_measured
    }  # sum it up in one var

    # find our central_node in weird all_pairs_dijkstra_path_length(G) format
    for centrum in shortest_paths:
        if centrum[0] == central_node:
            shortest_paths_from_central_node = centrum

# get a list of pressure sensors with their respective distances from central_node
    pressure_sensors_with_distance = []
    for node in objects_measured['junctions']:
        pressure_sensors_with_distance.append(
            (node[0], shortest_paths_from_central_node[1][node[0]]))

    # do the same for flow sensors
    flow_sensors_with_distance = []
    for edge in objects_measured['pipes']:
        flow_sensors_with_distance.append(
            (edge[2]['name'], shortest_paths_from_central_node[1][edge[0]]))

    sensors = pressure_sensors_with_distance + flow_sensors_with_distance

    # sort them by distance (ascending)
    pressure_sensors_sorted_by_distance = sorted(
        pressure_sensors_with_distance, key=lambda sensor: sensor[1])
    flow_sensors_sorted_by_distance = sorted(flow_sensors_with_distance,
                                             key=lambda sensor: sensor[1])
    sensors_sorted_by_distance = sorted(sensors, key=lambda sensor: sensor[1])

    if n == 'all':
        return sensors_sorted_by_distance  # return all sensors
    else:
        return sensors_sorted_by_distance[:n]  # return only n closest sensors
Exemple #4
0
def plot_tree(fig: Figure,
              T: nx.classes.graph.Graph,
              root: Union[str, int],
              row: int = 1,
              col: int = 2):
    """Plot the tree on the figure.

    This function assumes the type of subplot at the given row and col is of
    type scatter plot and has both x and y range of [0,1].

    Args:
        fig (Figure): The figure to which the tree should be plotted.
        T (nx.classes.graph.Graph): Tree to be plotted.
        root (Union[str,int]): Root node of the tree.
        row (int, optional): Subplot row of the figure. Defaults to 1.
        col (int, optional): Subplot col of the figure. Defaults to 2.
    """
    nx.set_node_attributes(T, tree_positions(T, root), 'pos')

    edge_x = []
    edge_y = []
    for edge in T.edges():
        x0, y0 = T.nodes[edge[0]]['pos']
        x1, y1 = T.nodes[edge[1]]['pos']
        edge_x += [x0, x1, None]
        edge_y += [y0, y1, None]
    edge_trace = plt.Scatter(x=edge_x,
                             y=edge_y,
                             line=dict(width=1, color='black'),
                             hoverinfo='none',
                             showlegend=False,
                             mode='lines')
    fig.add_trace(trace=edge_trace, row=row, col=col)

    for node in T.nodes():
        if 'text' in T.nodes[node]:
            text = T.nodes[node]['text']
        else:
            text = node
        if 'template' in T.nodes[node]:
            template = T.nodes[node]['template']
        else:
            template = 'unexplored'
        x, y = T.nodes[node]['pos']
        fig.add_annotation(x=x,
                           y=y,
                           visible=True,
                           text=text,
                           templateitemname=template,
                           row=row,
                           col=col)
    def fit(self, G: nx.classes.graph.Graph) -> Word2Vec:
        """Fit and get the embedding algorithm model.

        Args:
            G (networkx.classes.graph.Graph): A NetworkX graph object.

        Returns:
            (gensim.models.word2vec.Word2Vec): The Word2Vec model.
        """

        self.G = G
        walks = []
        for node in tqdm(G.nodes()):
            for _ in range(self.num_walks):
                walk = []
                walk.append(str(node))
                current_node = node
                previous_node = None
                former_neighbors = []

                for _ in range(self.walk_length):
                    current_neighbors = np.array(
                        list(G.neighbors(current_node)))
                    if np.size(current_neighbors) == 0:
                        break
                    probability = np.array([1 / self.q] *
                                           len(current_neighbors))
                    probability[current_neighbors ==
                                previous_node] = 1 / self.p
                    probability[(np.isin(current_neighbors,
                                         former_neighbors))] = 1

                    next_node = np.random.choice(current_neighbors,
                                                 1,
                                                 p=probability /
                                                 sum(probability))[0]
                    walk.append(str(next_node))

                    former_neighbors = current_neighbors
                    previous_node = current_node
                    current_node = next_node
                walks.append(walk)

        self.model = Word2Vec(walks,
                              size=self.size,
                              window=self.window,
                              seed=self.seed,
                              workers=self.workers,
                              iter=self.iter)

        return self.model
Exemple #6
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a Symm-NMF clustering model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be clustered.
        """
        self._set_seed()
        self._check_graph(graph)
        graph.remove_edges_from(nx.selfloop_edges(graph))
        A_hat = self._create_base_matrix(graph)
        self._setup_embeddings(A_hat)
        for step in range(self.iterations):
            self._do_admm_update(A_hat)
Exemple #7
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a Diff2Vec model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
        """
        self._set_seed()
        self._check_graph(graph)
        diffuser = EulerianDiffuser(self.diffusion_number,
                                    self.diffusion_cover)
        diffuser.do_diffusions(graph)

        model = Word2Vec(diffuser.diffusions,
                         hs=1,
                         alpha=self.learning_rate,
                         iter=self.epochs,
                         size=self.dimensions,
                         window=self.window_size,
                         min_count=self.min_count,
                         workers=self.workers,
                         seed=self.seed)

        num_of_nodes = graph.number_of_nodes()
        self._embedding = [model[str(n)] for n in range(num_of_nodes)]
Exemple #8
0
    def fit(self, graph: nx.classes.graph.Graph, X: Union[np.array,
                                                          coo_matrix]):
        """
        Fitting a SINE model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
            * **X** *(Scipy COO array)* - The matrix of node features.
        """
        self._set_seed()
        self._check_graph(graph)
        self._walker = RandomWalker(self.walk_length, self.walk_number)
        self._walker.do_walks(graph)
        self._features = self._feature_transform(graph, X)
        self._select_walklets()

        model = Word2Vec(self._walklets,
                         hs=0,
                         alpha=self.learning_rate,
                         size=self.dimensions,
                         window=1,
                         min_count=self.min_count,
                         workers=self.workers,
                         seed=self.seed,
                         iter=self.epochs)

        self.embedding = np.array(
            [model[str(n)] for n in range(graph.number_of_nodes())])
Exemple #9
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a Walklets model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
        """
        self._set_seed()
        self._check_graph(graph)
        walker = RandomWalker(self.walk_length, self.walk_number)
        walker.do_walks(graph)
        num_of_nodes = graph.number_of_nodes()

        self._embedding = []
        for power in range(1, self.window_size + 1):
            walklets = self._select_walklets(walker.walks, power)
            model = Word2Vec(walklets,
                             hs=0,
                             alpha=self.learning_rate,
                             epochs=self.epochs,
                             vector_size=self.dimensions,
                             window=1,
                             min_count=self.min_count,
                             workers=self.workers,
                             seed=self.seed)

            embedding = np.array(
                [model.wv[str(n)] for n in range(num_of_nodes)])
            self._embedding.append(embedding)
Exemple #10
0
    def _recursive_position_for_row(
        G: nx.classes.graph.Graph,
        result: dict,
        two_rows_before: List[Hashable],
        last_row: List[Hashable],
        current_height: float,
    ):
        new_row = []
        for v in last_row:
            for x in G.neighbors(v):
                if x not in two_rows_before:
                    new_row.append(x)

        new_row_length = len(new_row)

        if new_row_length == 0:
            return

        if new_row_length == 1:
            result[new_row[0]] = np.array([0, current_height, 0])
        else:
            for i in range(new_row_length):
                result[new_row[i]] = np.array(
                    [-1 + 2 * i / (new_row_length - 1), current_height, 0]
                )

        _recursive_position_for_row(
            G,
            result,
            two_rows_before=last_row,
            last_row=new_row,
            current_height=current_height + 1,
        )
Exemple #11
0
    def fit(self, G: nx.classes.graph.Graph) -> Word2Vec:
        """Fit and get the embedding algorithm model.

        Args:
            G (networkx.classes.graph.Graph): A NetworkX graph object.

        Returns:
            self.model (gensim.models.word2vec.Word2Vec): The Word2Vec model.
        """

        self.G = G
        walks = []
        for node in tqdm(G.nodes()):
            for _ in range(self.num_walks):
                walk = []
                walk.append(str(node))
                current_node = node

                for _ in range(self.walk_length):
                    neighbors = list(nx.all_neighbors(G, current_node))
                    if(len(neighbors) != 0):
                        next_node = np.random.choice(neighbors, 1)[0]
                        walk.append(str(next_node))
                        current_node = next_node
                walks.append(walk)

        self.model = Word2Vec(walks,
                              size=self.size,
                              window=self.window,
                              seed=self.seed,
                              workers=self.workers,
                              iter=self.iter)

        return self.model
Exemple #12
0
def _get_components(graph: nx.classes.graph.Graph, values, cover: Cover,
                    component_method):
    ret = []
    for ce in cover.get_cover_elements():

        filtered = list(
            filter(lambda v: ce['range'][0] <= values[v] <= ce['range'][1],
                   values))
        subg = graph.subgraph(filtered)

        if subg.number_of_edges() == 0:
            components = nx.connected_components(subg)
        elif component_method == 'modularity':
            components = nx.algorithms.community.greedy_modularity_communities(
                subg)
        elif component_method == 'async_label_prop':
            components = nx.algorithms.community.asyn_lpa_communities(subg)
        elif component_method == 'label_prop':
            components = nx.algorithms.community.label_propagation_communities(
                subg)
        # elif component_method == 'centrality':
        #     components = nx.algorithms.community.girvan_newman(subg)
        else:
            components = nx.connected_components(subg)

        for comp in components:
            ret.append({'cover': ce, 'components': comp})

    return ret
Exemple #13
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a DeepWalk model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
        """
        self._set_seed()
        self._check_graph(graph)
        walker = BiasedRandomWalker(self.walk_length, self.walk_number, self.p,
                                    self.q)
        walker.do_walks(graph)

        model = Word2Vec(walker.walks,
                         hs=1,
                         alpha=self.learning_rate,
                         iter=self.epochs,
                         size=self.dimensions,
                         window=self.window_size,
                         min_count=self.min_count,
                         workers=self.workers,
                         seed=self.seed)

        num_of_nodes = graph.number_of_nodes()
        self._embedding = [model[str(n)] for n in range(num_of_nodes)]
Exemple #14
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a GraphWave model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
        """
        self._set_seed()
        self._check_graph(graph)
        graph.remove_edges_from(nx.selfloop_edges(graph))
        self._create_evaluation_points()
        self._check_size(graph)
        self._G = pygsp.graphs.Graph(nx.adjacency_matrix(graph))

        if self.mechanism == "exact":
            self._exact_structural_wavelet_embedding()
        elif self.mechanism == "approximate":
            self._approximate_structural_wavelet_embedding()
        else:
            raise NameError("Unknown method.")
Exemple #15
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a BigClam clustering model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be clustered.
        """
        self._set_seed()
        self._check_graph(graph)
        number_of_nodes = graph.number_of_nodes()
        self._initialize_features(number_of_nodes)
        nodes = [node for node in graph.nodes()]
        for i in range(self.iterations):
            random.shuffle(nodes)
            for node in nodes:
                nebs = [neb for neb in graph.neighbors(node)]
                neb_features = self._embedding[nebs, :]
                node_feature = self._embedding[node, :]
                gradient = self._calculate_gradient(node_feature, neb_features)
                self._do_updates(node, gradient, node_feature)
Exemple #16
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a Social Dimensions model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
        """
        self._set_seed()
        self._check_graph(graph)
        number_of_nodes = graph.number_of_nodes()
        L_tilde = nx.modularity_matrix(graph, nodelist=range(number_of_nodes))
        _, self._embedding = sps.linalg.eigsh(L_tilde, k=self.dimensions,
                                              which='LM', return_eigenvectors=True)
Exemple #17
0
def plot_population_graph(g: nx.classes.graph.Graph):

    boys = [i for i, d in g.nodes(data=True) if d['bipartite'] == 0]
    girls = [j for j, d in g.nodes(data=True) if d['bipartite'] == 1]

    plt.figure(figsize=(12, 8))
    for i in boys:
        plt.scatter(0, int(i[2:]), c='b', s=100, alpha=0.5)
    for j in girls:
        plt.scatter(1, int(j[2:]), c='r', s=100, alpha=0.5)

    for partnership in g.edges():
        coordinates = [(0, int(partnership[0][2:])),
                       (1, int(partnership[1][2:]))]
        plt.plot(coordinates, c='gray', lw=1)
    text_y = round(max(len(boys), len(girls)) * 1.05)
    plt.text(x=0, y=text_y, s='boys', ha='center')
    plt.text(x=1, y=text_y, s='girls', ha='center')
    plt.axis('off')
    plt.xlim([-1, 2])

    plt.show()
Exemple #18
0
    def fit(self, graph: nx.classes.graph.Graph):
        """
        Fitting a Laplacian EigenMaps model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
        """
        self._set_seed()
        graph = self._check_graph(graph)
        number_of_nodes = graph.number_of_nodes()
        L_tilde = nx.normalized_laplacian_matrix(graph, nodelist=range(number_of_nodes))
        _, self._embedding = sps.linalg.eigsh(
            L_tilde, k=self.dimensions, which="SM", return_eigenvectors=True
        )
Exemple #19
0
 def get_dgl_graph(self, nx_graph: nx.classes.graph.Graph):
     graph = dgl.DGLGraph()
     temp_map = {}
     for index, node in enumerate(nx_graph.nodes):
         data = torch.tensor(nx_graph.nodes[node]['feature'],
                             dtype=torch.float32).reshape(1, -1)
         deg = torch.tensor(nx_graph.degree(node),
                            dtype=torch.float32).reshape(1, -1)
         graph.add_nodes(1, {'feature': data, 'degree': deg})
         temp_map[node] = index
     for v0, v1 in nx_graph.edges:
         data = torch.tensor(nx_graph[v0][v1]['feature'],
                             dtype=torch.float32).reshape(1, -1)
         v0_index, v1_index = temp_map[v0], temp_map[v1]
         if v0_index != v1_index:
             graph.add_edge(v0_index, v1_index, {'feature': data})
             graph.add_edge(v1_index, v0_index, {'feature': data})
         else:
             graph.add_edge(v0_index, v1_index, {'feature': data})
     return graph
Exemple #20
0
    def fit(self, graph: nx.classes.graph.Graph, X: Union[np.array,
                                                          coo_matrix]):
        """
        Fitting a FEATHER-N model.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be embedded.
            * **X** *(Scipy COO or Numpy array)* - The matrix of node features.
        """
        self._set_seed()
        self._check_graph(graph)
        X = self._create_reduced_features(X)
        A_tilde = self._create_A_tilde(graph)
        theta = np.linspace(0.01, self.theta_max, self.eval_points)
        X = np.outer(X, theta)
        X = X.reshape(graph.number_of_nodes(), -1)
        X = np.concatenate([np.cos(X), np.sin(X)], axis=1)
        self._feature_blocks = []
        for _ in range(self.order):
            X = A_tilde.dot(X)
            self._feature_blocks.append(X)
        self._feature_blocks = np.concatenate(self._feature_blocks, axis=1)
Exemple #21
0
    def sample(self, graph: nx.classes.graph.Graph) -> nx.classes.graph.Graph:
        """
        Sampling with a shortest path sampler.

        Arg types:
            * **graph** *(NetworkX graph)* - The graph to be sampled from.

        Return types:
            * **new_graph** *(NetworkX graph)* - The graph of sampled nodes.
        """
        self._check_graph(graph)
        self._graph = graph
        self._set_seed_set()
        while len(self._nodes) < self.number_of_nodes:
            source, target = self._sample_a_pair()
            if source != target:
                path = nx.shortest_path(self._graph, source, target)
                for node in path:
                    self._nodes.add(node)
                    if len(self._nodes) >= self.number_of_nodes:
                        break

        new_graph = graph.subgraph(self._nodes)
        return new_graph
Exemple #22
0
def tree_positions(T: nx.classes.graph.Graph,
                   root: Union[str, int]) -> Dict[int, List[float]]:
    """Get positions for every node in the tree T with the given root.

    Args:
        T (nx.classes.graph.Graph): Tree graph.
        root (Union[str,int]): Root of the tree graph

    Returns:
        Dict[int, List[float]]: Dictionary from nodes in T to positions.
    """
    PAD = 0.1
    HORIZONTAL_SPACE = 0.2

    position = {}
    position[root] = (0.5, 1 - PAD)  # root position

    node_to_level = nx.single_source_shortest_path_length(T, root)
    level_count = max(node_to_level.values()) + 1
    levels = {}
    for l in range(level_count):
        levels[l] = [i for i in node_to_level if node_to_level[i] == l]

    level_heights = np.linspace(1.1, -0.1, level_count + 2)[1:-1]
    for l in range(1, level_count):
        # If there are more than 5 nodes in level, spread evenly across width;
        # otherwise, try to put nodes under their parent.
        if len(levels[l]) <= 4:
            # get parents of every pair of children in the level
            children = {}
            for node in levels[l]:
                parent = [i for i in list(T.neighbors(node)) if i < node][0]
                if parent in children:
                    children[parent].append(node)
                else:
                    children[parent] = [node]

            # initial attempt at positioning
            pos = {}
            for parent in children:
                x = position[parent][0]
                d = max((1 / 2)**(l + 1), HORIZONTAL_SPACE / 2)
                pos[children[parent][0]] = [x - d, level_heights[l]]
                pos[children[parent][1]] = [x + d, level_heights[l]]

            # perturb if needed
            keys = list(pos.keys())
            x = [p[0] for p in pos.values()]
            n = len(x) - 1
            while any(
                [x[i + 1] - x[i] + 0.05 < HORIZONTAL_SPACE for i in range(n)]):
                for i in range(len(x) - 1):
                    if abs(x[i + 1] - x[i]) < HORIZONTAL_SPACE:
                        shift = (HORIZONTAL_SPACE - abs(x[i + 1] - x[i])) / 2
                        x[i] -= shift
                        x[i + 1] += shift

            # shift to be within width
            x[0] = x[0] + (max(PAD - x[0], 0))
            for i in range(1, len(x)):
                x[i] = x[i] + max(HORIZONTAL_SPACE - (x[i] - x[i - 1]), 0)

            x[-1] = x[-1] - (max(x[-1] - (1 - PAD), 0))
            for i in reversed(range(len(x) - 1)):
                x[i] = x[i] - max(HORIZONTAL_SPACE - (x[i + 1] - x[i]), 0)

            # update the position dictionary with new x values
            for i in range(len(x)):
                pos[keys[i]][0] = x[i]

            # set position
            for node in pos:
                position[node] = pos[node]
        else:
            level_widths = np.linspace(-0.1, 1.1, len(levels[l]) + 2)[1:-1]
            for j in range(len(levels[l])):
                position[(levels[l][j])] = (level_widths[j], level_heights[i])

    return position
Exemple #23
0
def _determine_graph_layout(
    nx_graph: nx.classes.graph.Graph,
    layout: Union[str, dict] = "spring",
    layout_scale: float = 2,
    layout_config: Union[dict, None] = None,
    partitions: Union[List[List[Hashable]], None] = None,
    root_vertex: Union[Hashable, None] = None,
) -> dict:
    automatic_layouts = {
        "circular": nx.layout.circular_layout,
        "kamada_kawai": nx.layout.kamada_kawai_layout,
        "planar": nx.layout.planar_layout,
        "random": nx.layout.random_layout,
        "shell": nx.layout.shell_layout,
        "spectral": nx.layout.spectral_layout,
        "partite": nx.layout.multipartite_layout,
        "tree": _tree_layout,
        "spiral": nx.layout.spiral_layout,
        "spring": nx.layout.spring_layout,
    }

    custom_layouts = ["random", "partite", "tree"]

    if layout_config is None:
        layout_config = {}

    if isinstance(layout, dict):
        return layout
    elif layout in automatic_layouts and layout not in custom_layouts:
        auto_layout = automatic_layouts[layout](
            nx_graph, scale=layout_scale, **layout_config
        )
        return dict([(k, np.append(v, [0])) for k, v in auto_layout.items()])
    elif layout == "tree":
        return _tree_layout(
            nx_graph,
            root_vertex=root_vertex,
            scale=layout_scale,
        )
    elif layout == "partite":
        if partitions is None or len(partitions) == 0:
            raise ValueError(
                "The partite layout requires the 'partitions' parameter to contain the partition of the vertices"
            )
        partition_count = len(partitions)
        for i in range(partition_count):
            for v in partitions[i]:
                if nx_graph.nodes[v] is None:
                    raise ValueError(
                        "The partition must contain arrays of vertices in the graph"
                    )
                nx_graph.nodes[v]["subset"] = i
        # Add missing vertices to their own side
        for v in nx_graph.nodes:
            if "subset" not in nx_graph.nodes[v]:
                nx_graph.nodes[v]["subset"] = partition_count

        auto_layout = automatic_layouts["partite"](
            nx_graph, scale=layout_scale, **layout_config
        )
        return dict([(k, np.append(v, [0])) for k, v in auto_layout.items()])
    elif layout == "random":
        # the random layout places coordinates in [0, 1)
        # we need to rescale manually afterwards...
        auto_layout = automatic_layouts["random"](nx_graph, **layout_config)
        for k, v in auto_layout.items():
            auto_layout[k] = 2 * layout_scale * (v - np.array([0.5, 0.5]))
        return dict([(k, np.append(v, [0])) for k, v in auto_layout.items()])
    else:
        raise ValueError(
            f"The layout '{layout}' is neither a recognized automatic layout, "
            "nor a vertex placement dictionary."
        )
def create_embedding(args: argparse.Namespace,
                     G: nx.classes.graph.Graph) -> None:
    """Load the graph from a file in the input directory.

    Args:
        args (argparse.Namespace): The provided application arguments.
        G (networkx.classes.graph.Graph): The NetworkX graph object.
    """

    if args.method == 'node2vec_snap':
        """Implementation: https://github.com/aditya-grover/node2vec (SNAP - Stanford Network Analysis Project)."""

        G = node2vec.Graph(G, args.directed, args.p, args.q)
        G.preprocess_transition_probs()
        walks = G.simulate_walks(args.num_walks, args.walk_length)
        walks = [list(map(str, walk)) for walk in walks]
        model = Word2Vec(walks,
                         size=args.dimensions,
                         window=args.window_size,
                         seed=args.seed,
                         workers=args.workers,
                         iter=args.iter)
        model.wv.save_word2vec_format(args.output)

    elif args.method == 'node2vec_eliorc':
        """Implementation: https://github.com/eliorc/node2vec."""

        node2vecTmp = Node2Vec(graph=G,
                               walk_length=args.walk_length,
                               num_walks=args.num_walks,
                               dimensions=args.dimensions,
                               workers=args.workers)
        model = node2vecTmp.fit(window=args.window_size,
                                seed=args.seed,
                                workers=args.workers,
                                iter=args.iter)
        model.wv.save_word2vec_format(args.output)

    elif args.method == 'node2vec_custom':
        """Custom implementation."""

        model = CustomNode2Vec(num_walks=args.num_walks,
                               walk_length=args.walk_length,
                               p=args.p,
                               q=args.q,
                               size=args.dimensions,
                               window=args.window_size,
                               seed=args.seed,
                               workers=args.workers,
                               iter=args.iter)
        model.fit(G=G)
        model.save_embedding(args.output)

    elif args.method == 'deepwalk_phanein':
        """Implementation: https://github.com/phanein/deepwalk."""

        os.system(
            f"deepwalk --format edgelist --input {args.input} " +
            f"--number-walks {args.num_walks} --representation-size {args.dimensions} "
            +
            f"--walk-length {args.walk_length} --window-size {args.window_size} "
            +
            f"--workers {args.workers} --seed {args.seed} --output {args.output}"
        )

    elif args.method == 'deepwalk_custom':
        """Custom implementation"""

        model = CustomDeepWalk(num_walks=args.num_walks,
                               walk_length=args.walk_length,
                               size=args.dimensions,
                               window=args.window_size,
                               seed=args.seed,
                               workers=args.workers,
                               iter=args.iter)
        model.fit(G=G)
        model.save_embedding(args.output)

    else:
        raise ValueError(f'Invalid embedding algorithm: {args.method}')
Exemple #25
0
def _tree_layout(
    T: nx.classes.graph.Graph,
    root_vertex: Union[Hashable, None],
    scale: Union[float, tuple] = 2,
    orientation: str = "down",
):
    children = {root_vertex: list(T.neighbors(root_vertex))}

    if not nx.is_tree(T):
        raise ValueError("The tree layout must be used with trees")
    if root_vertex is None:
        raise ValueError("The tree layout requires the root_vertex parameter")

    # The following code is SageMath's tree layout implementation, taken from
    # https://github.com/sagemath/sage/blob/cc60cfebc4576fed8b01f0fc487271bdee3cefed/src/sage/graphs/graph_plot.py#L1447

    # Always make a copy of the children because they get eaten
    stack = [list(children[root_vertex]).copy()]
    stick = [root_vertex]
    parent = {u: root_vertex for u in children[root_vertex]}
    pos = {}
    obstruction = [0.0] * len(T)
    if orientation == "down":
        o = -1
    else:
        o = 1

    def slide(v, dx):
        """
        Shift the vertex v and its descendants to the right by dx.
        Precondition: v and its descendents have already had their
        positions computed.
        """
        level = [v]
        while level:
            nextlevel = []
            for u in level:
                x, y = pos[u]
                x += dx
                obstruction[y] = max(x + 1, obstruction[y])
                pos[u] = x, y
                nextlevel += children[u]
            level = nextlevel

    while stack:
        C = stack[-1]
        if not C:
            p = stick.pop()
            stack.pop()
            cp = children[p]
            y = o * len(stack)
            if not cp:
                x = obstruction[y]
                pos[p] = x, y
            else:
                x = sum(pos[c][0] for c in cp) / float(len(cp))
                pos[p] = x, y
                ox = obstruction[y]
                if x < ox:
                    slide(p, ox - x)
                    x = ox
            obstruction[y] = x + 1
            continue

        t = C.pop()
        pt = parent[t]

        ct = [u for u in list(T.neighbors(t)) if u != pt]
        for c in ct:
            parent[c] = t
        children[t] = copy(ct)

        stack.append(ct)
        stick.append(t)

    # the resulting layout is then rescaled again to fit on Manim's canvas

    x_min = min(pos.values(), key=lambda t: t[0])[0]
    x_max = max(pos.values(), key=lambda t: t[0])[0]
    y_min = min(pos.values(), key=lambda t: t[1])[1]
    y_max = max(pos.values(), key=lambda t: t[1])[1]
    center = np.array([x_min + x_max, y_min + y_max, 0]) / 2
    height = y_max - y_min
    width = x_max - x_min
    if isinstance(scale, (float, int)):
        sf = 2 * scale / max(width, height)
    else:
        sf = np.array([2 * scale[0] / width, 2 * scale[1] / height, 0])
    return {
        v: (np.array([x, y, 0]) - center) * sf
        for v, (x, y) in pos.items()
    }
Exemple #26
0
def merge_nodes(G: nx.classes.graph.Graph, new_inst_type: str,
                list_of_nodes: list, matched_ports: dict):
    """
    Merges the  given nodes in list_of_nodes and returns a
     reduced graph.
     
    Parameters
    ----------
    G : netowrkx graph
        DESCRIPTION. Bipartite graph of circuit
    new_inst_type : str
        DESCRIPTION. name of new subckt to be created, 
        A super node is created in graph havinge a subgraph in its values
    list_of_nodes : list
        DESCRIPTION.
    matched_ports : dict
        DESCRIPTION. dictionary of {subkt port: connected net} be added in dubckt

    Returns
    -------
    G : nx.classes.graph.Graph
        returns updated graph.

    """
    for node in list_of_nodes:
        if not G.nodes[node]:
            logger.debug("node not in graph anymore")
            return G, nx.Graph
    logger.debug(f"Is input bipartite: {nx.is_bipartite(G)}")
    assert len(list_of_nodes) > 1
    #  print("Merging nodes",list_of_nodes)
    new_node = ""
    ports = {}
    subgraph = nx.Graph()
    max_value = {}
    for node in list_of_nodes:
        new_node += '_' + node
        subgraph.add_node(node,
                          inst_type=G.nodes[node]["inst_type"],
                          real_inst_type=G.nodes[node]["real_inst_type"],
                          ports=G.nodes[node]['ports'],
                          edge_weight=G.nodes[node]['edge_weight'],
                          values=merged_value({}, G.nodes[node]['values']))
        if 'ports_match' in G.nodes[node].keys():
            subgraph.nodes[node]["ports_match"] = G.nodes[node]['ports_match']

        logger.debug(f"removing node {G.nodes[node]}")
        max_value = merged_value(max_value, G.nodes[node]['values'])

        nbr = G.neighbors(node)
        for ele in nbr:
            if ele not in subgraph.nodes():
                if ele in matched_ports.keys():
                    subgraph.add_node(ele,
                                      inst_type=G.nodes[ele]["inst_type"],
                                      net_type="external")
                else:
                    subgraph.add_node(ele,
                                      inst_type=G.nodes[ele]["inst_type"],
                                      net_type=G.nodes[ele]["net_type"])

            #print("adding edge b/w:",node,ele,G[node][ele]["weight"])
            subgraph.add_edge(node, ele, weight=G[node][ele]["weight"])

            if ele in ports:
                # had to remove addition as combination of weight for cmc caused gate to be considered source
                # changed to bitwise and as all connections of CMB were considered as gate
                ports[ele] = ports[ele] | G[node][ele]["weight"]

            else:
                ports[ele] = G[node][ele]["weight"]

    new_node = new_node[1:]
    G.add_node(new_node,
               inst_type=new_inst_type,
               real_inst_type=new_inst_type,
               ports=list(matched_ports.keys()),
               edge_weight=list(ports.values()),
               ports_match=matched_ports,
               values=max_value)
    #logger.debug(f"creating a super node of combination of nodes: {new_inst_type}")
    for pins in list(ports):
        if set(G.neighbors(pins)) <= set(
                list_of_nodes) and G.nodes[pins]["net_type"] == 'internal':
            del ports[pins]
            G.remove_node(pins)
    for node in list_of_nodes:
        G.remove_node(node)
    for pins in ports:
        G.add_edge(new_node, pins, weight=ports[pins])
        #logger.debug(f"new ports: {pins},{ports[pins]}")

    check_nodes(subgraph)

    return G, subgraph, new_node
Exemple #27
0
def _weighted_directed_degree(node: int,
                              graph: nx.classes.graph.Graph) -> float:
    out = graph.degree(node, weight="weight")

    return out
Exemple #28
0
 def _check_indexing(self, graph: nx.classes.graph.Graph):
     """Checking the consecutive numeric indexing."""
     numeric_indices = [index for index in range(graph.number_of_nodes())]
     node_indices = sorted([node for node in graph.nodes()])
     assert numeric_indices == node_indices, "The node indexing is wrong."