def convert_ensmallen_graph_to_networkx_graph(graph: Graph) -> nx.Graph: """Return networkX graph derived from the provided Ensmallen Graph. Parameters ----------- graph: Graph The graph to be converted. """ if graph.is_directed(): result_graph = nx.DiGraph() else: result_graph = nx.Graph() result_graph.add_nodes_from(graph.get_node_ids()) if graph.has_edge_weights(): result_graph.add_weighted_edges_from([ (src_name, dst_name, edge_weight) for (src_name, dst_name), edge_weight in zip( graph.get_directed_edge_node_ids(), graph.get_edge_weights()) ]) else: result_graph.add_edges_from( graph.get_edge_node_ids(directed=graph.is_directed())) return result_graph
def graph_to_sparse_tensor( graph: Graph, use_weights: bool, use_simmetric_normalized_laplacian: bool, handling_multi_graph: str = "warn", ) -> tf.SparseTensor: """Returns provided graph as sparse Tensor. Parameters ------------------- graph: Graph, The graph to convert. use_weights: bool, Whether to load the graph weights. use_simmetric_normalized_laplacian: bool Whether to use the symmetrically normalized laplacian handling_multi_graph: str = "warn" How to behave when dealing with multigraphs. Possible behaviours are: - "warn", which warns the user and drops the multi-edges. - "raise" - "drop" Raises ------------------- ValueError, If the weights are requested but the graph does not contain any. ValueError, If the graph contains singletons. ValueError, If the graph is a multigraph. Returns ------------------- SparseTensor with (weighted) adjacency matrix. """ if use_weights and not graph.has_edge_weights(): raise ValueError("Edge weights were requested but the provided graph " "does not contain any edge weight.") if graph.has_singleton_nodes(): raise ValueError( f"In the provided {graph.get_name()} graph there are " f"{graph.get_number_of_singleton_nodes()} singleton nodes." "The GCN model does not support operations on graph containing " "singletons. You can either choose to drop singletons from " "the graph by using the `graph.remove_singleton_nodes()` " "method or alternatively you can add selfloops to them by " "using the `graph.add_selfloops()` method.") if graph.is_multigraph(): message = ( "The GCN model does not currently support convolutions on a multigraph. " "We are dropping the parallel edges before computing the adjacency matrix." ) if handling_multi_graph == "warn": warnings.warn(message) elif handling_multi_graph == "raise": raise ValueError(message) graph = graph.remove_parallel_edges() if use_simmetric_normalized_laplacian: edge_node_ids, weights = graph.get_symmetric_normalized_laplacian_coo_matrix( ) return tf.sparse.reorder( tf.SparseTensor( edge_node_ids, np.abs(weights), (graph.get_number_of_nodes(), graph.get_number_of_nodes()))) return tf.SparseTensor( graph.get_directed_edge_node_ids(), (graph.get_edge_weights() if use_weights else tf.ones(graph.get_number_of_directed_edges())), (graph.get_number_of_nodes(), graph.get_number_of_nodes()))