def star(n_branches: int = 3, metadata: bool = False) -> Union[sparse.csr_matrix, Bunch]: """Star (undirected). Parameters ---------- n_branches : int Number of branches. metadata : bool If ``True``, return a `Bunch` object with metadata (positions). Returns ------- adjacency or graph : Union[sparse.csr_matrix, Bunch] Adjacency matrix or graph with metadata (positions). Example ------- >>> from sknetwork.data import star >>> adjacency = star() >>> adjacency.shape (4, 4) """ edges = [(0, i + 1) for i in range(n_branches)] adjacency = edgelist2adjacency(edges, undirected=True) if metadata: graph = Bunch() graph.adjacency = adjacency angles = 2 * np.pi * np.arange(n_branches) / n_branches graph.position = np.vstack([np.cos(angles), np.sin(angles)]).T return graph else: return adjacency
def albert_barabasi(n: int = 100, degree: int = 3, undirected: bool = True, seed: Optional[int] = None) \ -> sparse.csr_matrix: """Albert-Barabasi model. Parameters ---------- n : int Number of nodes. degree : int Degree of incoming nodes (less than **n**). undirected : bool If ``True``, return an undirected graph. seed : Seed of the random generator (optional). Returns ------- adjacency : sparse.csr_matrix Adjacency matrix. Example ------- >>> from sknetwork.data import albert_barabasi >>> adjacency = albert_barabasi(30, 3) >>> adjacency.shape (30, 30) References ---------- Albert, R., Barabási, L. (2002). `Statistical mechanics of complex networks <https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.74.47>`_ Reviews of Modern Physics. """ np.random.seed(seed) degrees = np.zeros(n, int) degrees[:degree] = degree - 1 edges = [(i, j) for i in range(degree) for j in range(i)] for i in range(degree, n): neighbors = np.random.choice(i, p=degrees[:i] / degrees.sum(), size=degree, replace=False) degrees[neighbors] += 1 degrees[i] = degree edges += [(i, j) for j in neighbors] return edgelist2adjacency(edges, undirected)
def test_adjacency(self): edge_list = [(1, 2), (3, 4), (1, 0), (1, 2)] adjacency = edgelist2adjacency(edge_list) self.assertEqual(adjacency.nnz, 3) adjacency = edgelist2adjacency(edge_list, undirected=True) self.assertEqual(adjacency.nnz, 6) adjacency = edgelist2adjacency(edge_list, weighted=False) self.assertEqual(np.max(adjacency.data), 1) edge_list = [(1, 2, 1), (3, 4, 3), (1, 0, 1), (1, 2, 2)] adjacency = edgelist2adjacency(edge_list) self.assertEqual(adjacency.nnz, 3) self.assertEqual(adjacency[1, 2], 3) adjacency = edgelist2adjacency(edge_list, undirected=True) self.assertEqual(adjacency.nnz, 6) adjacency = edgelist2adjacency(edge_list, weighted=False) self.assertEqual(np.max(adjacency.data), 1)
def grid(n1: int = 10, n2: int = 10, metadata: bool = False) -> Union[sparse.csr_matrix, Bunch]: """Grid (undirected). Parameters ---------- n1, n2 : int Grid dimension. metadata : bool If ``True``, return a `Bunch` object with metadata. Returns ------- adjacency or graph : Union[sparse.csr_matrix, Bunch] Adjacency matrix or graph with metadata (positions). Example ------- >>> from sknetwork.data import grid >>> adjacency = grid(10, 5) >>> adjacency.shape (50, 50) """ nodes = [(i1, i2) for i1 in range(n1) for i2 in range(n2)] edges = [((i1, i2), (i1 + 1, i2)) for i1 in range(n1 - 1) for i2 in range(n2)] edges += [((i1, i2), (i1, i2 + 1)) for i1 in range(n1) for i2 in range(n2 - 1)] node_id = {u: i for i, u in enumerate(nodes)} edges = list(map(lambda edge: (node_id[edge[0]], node_id[edge[1]]), edges)) adjacency = edgelist2adjacency(edges, undirected=True) if metadata: graph = Bunch() graph.adjacency = adjacency graph.position = np.array(nodes) return graph else: return adjacency