def jacobi(a_matrix: sp.csr_matrix, residual: np.array) -> np.array: """Return vector(np.matrix) obtained by multiplication of inverted a_matrix argument diagonal by residual vector.""" _to_return = {} # type: dict if 'inverted' not in _to_return: # we want to calculate matrix inversion only once... _to_return['inverted'] = 1.0 / (a_matrix.diagonal(0) + 1e-6) return _to_return['inverted'] * residual
def is_bipartite(adjacency: sparse.csr_matrix, return_biadjacency: bool = False) \ -> Union[bool, Tuple[bool, Optional[sparse.csr_matrix], Optional[np.ndarray], Optional[np.ndarray]]]: """Check whether an undirected graph is bipartite. * Graphs Parameters ---------- adjacency : Adjacency matrix of the graph (symmetric). return_biadjacency : If ``True``, return a biadjacency matrix of the graph if bipartite. Returns ------- is_bipartite : bool A boolean denoting if the graph is bipartite. biadjacency : sparse.csr_matrix A biadjacency matrix of the graph if bipartite (optional). rows : np.ndarray Index of rows in the original graph (optional). cols : np.ndarray Index of columns in the original graph (optional). """ if not is_symmetric(adjacency): raise ValueError('The graph must be undirected.') if adjacency.diagonal().any(): if return_biadjacency: return False, None, None, None else: return False n = adjacency.indptr.shape[0] - 1 coloring = np.full(n, -1, dtype=int) exists_remaining = n while exists_remaining: src = np.argwhere(coloring == -1)[0, 0] next_nodes = [src] coloring[src] = 0 exists_remaining -= 1 while next_nodes: node = next_nodes.pop() for neighbor in adjacency.indices[adjacency.indptr[node]:adjacency. indptr[node + 1]]: if coloring[neighbor] == -1: coloring[neighbor] = 1 - coloring[node] next_nodes.append(neighbor) exists_remaining -= 1 elif coloring[neighbor] == coloring[node]: if return_biadjacency: return False, None, None, None else: return False if return_biadjacency: rows = np.argwhere(coloring == 0).ravel() cols = np.argwhere(coloring == 1).ravel() return True, adjacency[rows, :][:, cols], rows, cols else: return True
def is_bipartite( adjacency: sparse.csr_matrix, return_biadjacency: bool = False ) -> Union[bool, Tuple[bool, Optional[sparse.csr_matrix]]]: """Check whether an undirected graph is bipartite and can return a possible biadjacency. Parameters ---------- adjacency: The symmetric adjacency matrix of the graph. return_biadjacency: If ``True`` , a possible biadjacency is returned if the graph is bipartite (None is returned otherwise) Returns ------- is_bipartite: bool A boolean denoting if the graph is bipartite biadjacency: sparse.csr_matrix A possible biadjacency of the bipartite graph (None if the graph is not bipartite) """ if not is_symmetric(adjacency): raise ValueError('The graph must be undirected.') if adjacency.diagonal().any(): if return_biadjacency: return False, None else: return False n_nodes = adjacency.indptr.shape[0] - 1 coloring = np.full(n_nodes, -1, dtype=int) exists_remaining = n_nodes while exists_remaining: src = np.argwhere(coloring == -1)[0, 0] next_nodes = [src] coloring[src] = 0 exists_remaining -= 1 while next_nodes: node = next_nodes.pop() for neighbor in adjacency.indices[adjacency.indptr[node]:adjacency. indptr[node + 1]]: if coloring[neighbor] == -1: coloring[neighbor] = 1 - coloring[node] next_nodes.append(neighbor) exists_remaining -= 1 elif coloring[neighbor] == coloring[node]: if return_biadjacency: return False, None else: return False if return_biadjacency: return True, adjacency[coloring == 0, :][:, coloring == 1] else: return True
def distanceNormalize(pSparseCsrMatrix: sparse.csr_matrix, pWindowSize_bins: int): #compute the means along the diagonals (= same distance) #and divide all values on the diagonals by their respective mean diagList = [] winsize = min(pSparseCsrMatrix.shape[0], pWindowSize_bins) winsize = max(winsize, 0) #ensure positivity for i in range(-winsize+1, winsize): diagArr = pSparseCsrMatrix.diagonal(i).astype("float32") meanVal = np.mean(diagArr[diagArr != 0]) #as in Farre et al diagArr /= meanVal diagArr[diagArr == 0.0] = 1.0 #as in Farre et al. diagList.append(diagArr) distNormalizedMatrix = sparse.diags(diagList,np.arange(-winsize+1, winsize),format="csr") return distNormalizedMatrix
def _assemble_neumann_common( self, g: pp.Grid, data: Dict, M: sps.csr_matrix, mass: sps.csr_matrix, bc_weight: float = None, ) -> Tuple[sps.csr_matrix, np.ndarray]: """ Impose Neumann boundary discretization on an already assembled system matrix. Common implementation for VEM and RT0. The parameter mass should be adapted to the discretization method in question """ norm = sps.linalg.norm(mass, np.inf) if bc_weight else 1 parameter_dictionary = data[pp.PARAMETERS][self.keyword] bc = parameter_dictionary["bc"] # assign the Neumann boundary conditions # For dual discretizations, internal boundaries # are handled by assigning Dirichlet conditions. THus, we remove them # from the is_neu (where they belong by default) and add them in # is_dir. is_neu = np.logical_and(bc.is_neu, np.logical_not(bc.is_internal)) if bc and np.any(is_neu): is_neu = np.hstack((is_neu, np.zeros(g.num_cells, dtype=np.bool))) is_neu = np.where(is_neu)[0] # set in an efficient way the essential boundary conditions, by # clear the rows and put norm in the diagonal for row in is_neu: M.data[M.indptr[row]:M.indptr[row + 1]] = 0.0 d = M.diagonal() d[is_neu] = norm M.setdiag(d) return M, norm
def is_acyclic(adjacency: sparse.csr_matrix) -> bool: """Check whether a graph has no cycle. Parameters ---------- adjacency: Adjacency matrix of the graph. Returns ------- is_acyclic : bool A boolean with value True if the graph has no cycle and False otherwise """ n_nodes = adjacency.shape[0] n_cc = sparse.csgraph.connected_components(adjacency, (not is_symmetric(adjacency)), 'strong', False) if n_cc == n_nodes: # check for self-loops (= cycles) return (adjacency.diagonal() == 0).all() else: return False
def mask_test_edges(adj: sp.csr_matrix): # Function to build test set with 2% positive links # Remove diagonal elements adj = adj - sp.dia_matrix((adj.diagonal()[np.newaxis, :], [0]), shape=adj.shape) adj.eliminate_zeros() adj_triu = sp.triu(adj) adj_tuple = sparse_to_tuple(adj_triu) edges = adj_tuple[0] edges_all = sparse_to_tuple(adj)[0] num_test = int(np.floor(edges.shape[0] / 10.)) num_val = int(np.floor(edges.shape[0] / 10.)) # split to get the training, valid and test set. all_edge_idx = range(edges.shape[0]) all_edge_idx = list(all_edge_idx) np.random.shuffle(all_edge_idx) val_edge_idx = all_edge_idx[:num_val] test_edge_idx = all_edge_idx[num_val:(num_val + num_test)] test_edges = edges[test_edge_idx] val_edges = edges[val_edge_idx] train_edges = np.delete(edges, np.hstack([test_edge_idx, val_edge_idx]), axis=0) def ismember(a, b): rows_close = np.all((a - b[:, None]) == 0, axis=-1) return np.any(rows_close) test_edges_false = [] while len(test_edges_false) < len(test_edges): n_rnd = len(test_edges) - len(test_edges_false) # num_nodes = adj.shape[0] rnd = np.random.randint(0, adj.shape[0], size=2 * n_rnd) idxs_i = rnd[:n_rnd] idxs_j = rnd[n_rnd:] for i in range(n_rnd): idx_i = idxs_i[i] idx_j = idxs_j[i] if idx_i == idx_j: continue if ismember([idx_i, idx_j], edges_all): continue if test_edges_false: if ismember([idx_j, idx_i], np.array(test_edges_false)): continue if ismember([idx_i, idx_j], np.array(test_edges_false)): continue test_edges_false.append([idx_i, idx_j]) val_edges_false = [] while len(val_edges_false) < len(val_edges): n_rnd = len(val_edges) - len(val_edges_false) rnd = np.random.randint(0, adj.shape[0], size=2 * n_rnd) idxs_i = rnd[:n_rnd] idxs_j = rnd[n_rnd:] for i in range(n_rnd): idx_i = idxs_i[i] idx_j = idxs_j[i] if idx_i == idx_j: continue if ismember([idx_i, idx_j], train_edges): continue if ismember([idx_j, idx_i], train_edges): continue if ismember([idx_i, idx_j], val_edges): continue if ismember([idx_j, idx_i], val_edges): continue if val_edges_false: if ismember([idx_j, idx_i], np.array(val_edges_false)): continue if ismember([idx_i, idx_j], np.array(val_edges_false)): continue val_edges_false.append([idx_i, idx_j]) # Re-build adj matrix data = np.ones(train_edges.shape[0]) adj_train = sp.csr_matrix((data, (train_edges[:, 0], train_edges[:, 1])), shape=adj.shape) adj_train = adj_train + adj_train.T return adj_train, train_edges, val_edges, val_edges_false, test_edges, test_edges_false