コード例 #1
0
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
コード例 #2
0
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
コード例 #3
0
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
コード例 #4
0
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
コード例 #5
0
ファイル: dual_elliptic.py プロジェクト: Pavan4568/porepy
    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
コード例 #6
0
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
コード例 #7
0
ファイル: utils.py プロジェクト: isjakewong/MIRACLE
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