From e923211e324af29e59646ff6f450c78a15e9fef1 Mon Sep 17 00:00:00 2001 From: Dan Schult Date: Tue, 12 Nov 2024 17:39:43 -0500 Subject: [PATCH] DOC: sparse.csgraph: update csgraph docs to use sparray (#21873) * update csgraph docs to use sparray [docs only] * docs for __init__.py [docs only] * make input type descriptions consistent [docs only] --- scipy/sparse/csgraph/__init__.py | 6 +-- scipy/sparse/csgraph/_flow.pyx | 32 ++++++------ scipy/sparse/csgraph/_laplacian.py | 17 ++++--- scipy/sparse/csgraph/_matching.pyx | 46 ++++++++--------- scipy/sparse/csgraph/_min_spanning_tree.pyx | 12 ++--- scipy/sparse/csgraph/_reordering.pyx | 20 ++++---- scipy/sparse/csgraph/_shortest_path.pyx | 48 +++++++++--------- scipy/sparse/csgraph/_tools.pyx | 50 +++++++++---------- scipy/sparse/csgraph/_traversal.pyx | 50 +++++++++---------- scipy/sparse/csgraph/tests/test_reordering.py | 16 +++--- scipy/sparse/csgraph/tests/test_traversal.py | 9 ++-- 11 files changed, 154 insertions(+), 152 deletions(-) diff --git a/scipy/sparse/csgraph/__init__.py b/scipy/sparse/csgraph/__init__.py index 2fcb5bc7206f..00ab19af4748 100644 --- a/scipy/sparse/csgraph/__init__.py +++ b/scipy/sparse/csgraph/__init__.py @@ -83,8 +83,8 @@ ... [2, 0, 0], ... [1, 0, 0]]) >>> G_masked = np.ma.masked_values(G_dense, 0) - >>> from scipy.sparse import csr_matrix - >>> G_sparse = csr_matrix(G_dense) + >>> from scipy.sparse import csr_array + >>> G_sparse = csr_array(G_dense) This becomes more difficult when zero edges are significant. For example, consider the situation when we slightly modify the above graph:: @@ -109,7 +109,7 @@ ... [0, np.inf, np.inf]]) >>> G2_masked = np.ma.masked_invalid(G2_data) >>> from scipy.sparse.csgraph import csgraph_from_dense - >>> # G2_sparse = csr_matrix(G2_data) would give the wrong result + >>> # G2_sparse = csr_array(G2_data) would give the wrong result >>> G2_sparse = csgraph_from_dense(G2_data, null_value=np.inf) >>> G2_sparse.data array([ 2., 0., 2., 0.]) diff --git a/scipy/sparse/csgraph/_flow.pyx b/scipy/sparse/csgraph/_flow.pyx index f881855326c8..df526aee3101 100644 --- a/scipy/sparse/csgraph/_flow.pyx +++ b/scipy/sparse/csgraph/_flow.pyx @@ -21,7 +21,7 @@ class MaximumFlowResult: ---------- flow_value : int The value of the maximum flow. - flow : csr_matrix + flow : csr_array The maximum flow. """ @@ -43,7 +43,7 @@ def maximum_flow(csgraph, source, sink, *, method='dinic'): Parameters ---------- - csgraph : csr_matrix + csgraph : csr_array The square matrix representing a directed graph whose (i, j)'th entry is an integer representing the capacity of the edge between vertices i and j. @@ -132,9 +132,9 @@ def maximum_flow(csgraph, source, sink, *, method='dinic'): Here, the maximum flow is simply the capacity of the edge: >>> import numpy as np - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import maximum_flow - >>> graph = csr_matrix([[0, 5], [0, 0]]) + >>> graph = csr_array([[0, 5], [0, 0]]) >>> maximum_flow(graph, 0, 1).flow_value 5 >>> maximum_flow(graph, 0, 1, method='edmonds_karp').flow_value @@ -145,18 +145,18 @@ def maximum_flow(csgraph, source, sink, *, method='dinic'): (0) --5--> (1) --3--> (2) - >>> graph = csr_matrix([[0, 5, 0], [0, 0, 3], [0, 0, 0]]) + >>> graph = csr_array([[0, 5, 0], [0, 0, 3], [0, 0, 0]]) >>> maximum_flow(graph, 0, 2).flow_value 3 A less trivial example is given in [2]_, Chapter 26.1: - >>> graph = csr_matrix([[0, 16, 13, 0, 0, 0], - ... [0, 0, 10, 12, 0, 0], - ... [0, 4, 0, 0, 14, 0], - ... [0, 0, 9, 0, 0, 20], - ... [0, 0, 0, 7, 0, 4], - ... [0, 0, 0, 0, 0, 0]]) + >>> graph = csr_array([[0, 16, 13, 0, 0, 0], + ... [0, 0, 10, 12, 0, 0], + ... [0, 4, 0, 0, 14, 0], + ... [0, 0, 9, 0, 0, 20], + ... [0, 0, 0, 7, 0, 4], + ... [0, 0, 0, 0, 0, 0]]) >>> maximum_flow(graph, 0, 5).flow_value 23 @@ -175,7 +175,7 @@ def maximum_flow(csgraph, source, sink, *, method='dinic'): by :func:`maximum_bipartite_matching`. Then the CSR representation of the graph constructed above contains this matrix as a block. Here's an example: - >>> graph = csr_matrix([[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 1, 0]]) + >>> graph = csr_array([[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 1, 0]]) >>> print(graph.toarray()) [[0 1 0 1] [1 0 1 0] @@ -191,7 +191,7 @@ def maximum_flow(csgraph, source, sink, *, method='dinic'): ... np.repeat(i + j + 1, j)]) >>> data = np.ones(n + i + j, dtype=int) >>> - >>> graph_flow = csr_matrix((data, indices, indptr)) + >>> graph_flow = csr_array((data, indices, indptr)) >>> print(graph_flow.toarray()) [[0 1 1 1 0 0 0 0 0] [0 0 0 0 0 1 0 1 0] @@ -292,12 +292,12 @@ def _add_reverse_edges(a): Parameters ---------- - a : csr_matrix + a : csr_array The square matrix in CSR format representing a directed graph Returns ------- - res : csr_matrix + res : csr_array A new matrix in CSR format in which the missing edges are represented by explicit zeros. @@ -320,7 +320,7 @@ def _add_reverse_edges(a): # allocate twice the number of non-zeros in `a` for the data, which # will always be enough. It might be too many entries in case `a` has # some reverse edges already; in that case, over-allocating is not - # a problem since csr_matrix implicitly truncates elements of data + # a problem since csr_array implicitly truncates elements of data # and indices that go beyond the indices given by indptr. res_data = np.zeros(2 * a.nnz, ITYPE) cdef ITYPE_t[:] res_data_view = res_data diff --git a/scipy/sparse/csgraph/_laplacian.py b/scipy/sparse/csgraph/_laplacian.py index 8a50cd491069..ff4f259107f6 100644 --- a/scipy/sparse/csgraph/_laplacian.py +++ b/scipy/sparse/csgraph/_laplacian.py @@ -26,7 +26,7 @@ def laplacian( Parameters ---------- - csgraph : array_like or sparse matrix, 2 dimensions + csgraph : array_like or sparse array or matrix, 2 dimensions compressed-sparse graph, with shape (N, N). normed : bool, optional If True, then compute symmetrically normalized Laplacian. @@ -72,9 +72,9 @@ def laplacian( Returns ------- - lap : ndarray, or sparse matrix, or `LinearOperator` + lap : ndarray, or sparse array or matrix, or `LinearOperator` The N x N Laplacian of csgraph. It will be a NumPy array (dense) - if the input was dense, or a sparse matrix otherwise, or + if the input was dense, or a sparse array otherwise, or the format of a function or `LinearOperator` if `form` equals 'function' or 'lo', respectively. diag : ndarray, optional @@ -237,8 +237,9 @@ def laplacian( in a symmetric Laplacian matrix if and only if its graph is symmetric and has all non-negative degrees, like in the examples above. - The output Laplacian matrix is by default a dense array or a sparse matrix - inferring its shape, format, and dtype from the input graph matrix: + The output Laplacian matrix is by default a dense array or a sparse + array or matrix inferring its class, shape, format, and dtype from + the input graph matrix: >>> G = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]]).astype(np.float32) >>> G @@ -276,19 +277,19 @@ def laplacian( Our final example illustrates the latter for a noisy directed linear graph. - >>> from scipy.sparse import diags, random + >>> from scipy.sparse import diags_array, random_array >>> from scipy.sparse.linalg import lobpcg Create a directed linear graph with ``N=35`` vertices using a sparse adjacency matrix ``G``: >>> N = 35 - >>> G = diags(np.ones(N-1), 1, format="csr") + >>> G = diags_array(np.ones(N - 1), offsets=1, format="csr") Fix a random seed ``rng`` and add a random sparse noise to the graph ``G``: >>> rng = np.random.default_rng() - >>> G += 1e-2 * random(N, N, density=0.1, random_state=rng) + >>> G += 1e-2 * random_array((N, N), density=0.1, random_state=rng) Set initial approximations for eigenvectors: diff --git a/scipy/sparse/csgraph/_matching.pyx b/scipy/sparse/csgraph/_matching.pyx index cb1729b09fcd..b315338873eb 100644 --- a/scipy/sparse/csgraph/_matching.pyx +++ b/scipy/sparse/csgraph/_matching.pyx @@ -24,7 +24,7 @@ def maximum_bipartite_matching(graph, perm_type='row'): Parameters ---------- - graph : sparse matrix + graph : sparse array or matrix Input sparse in CSR format whose rows represent one partition of the graph and whose columns represent the other partition. An edge between two vertices is indicated by the corresponding entry in the matrix @@ -72,7 +72,7 @@ def maximum_bipartite_matching(graph, perm_type='row'): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import maximum_bipartite_matching As a simple example, consider a bipartite graph in which the partitions @@ -80,12 +80,12 @@ def maximum_bipartite_matching(graph, perm_type='row'): vertices labelled 0 and 1, and that the other partition contains vertices labelled A, B, and C. Suppose that there are edges connecting 0 and C, 1 and A, and 1 and B. This graph would then be represented by the following - sparse matrix: + sparse array: - >>> graph = csr_matrix([[0, 0, 1], [1, 1, 0]]) + >>> graph = csr_array([[0, 0, 1], [1, 1, 0]]) Here, the 1s could be anything, as long as they end up being stored as - elements in the sparse matrix. We can now calculate maximum matchings as + elements in the sparse array. We can now calculate maximum matchings as follows: >>> print(maximum_bipartite_matching(graph, perm_type='column')) @@ -104,7 +104,7 @@ def maximum_bipartite_matching(graph, perm_type='row'): >>> data = [0, 0, 0] >>> indices = [2, 0, 1] >>> indptr = [0, 1, 3] - >>> graph = csr_matrix((data, indices, indptr)) + >>> graph = csr_array((data, indices, indptr)) >>> print(maximum_bipartite_matching(graph, perm_type='column')) [2 0] >>> print(maximum_bipartite_matching(graph, perm_type='row')) @@ -113,20 +113,20 @@ def maximum_bipartite_matching(graph, perm_type='row'): When one or both of the partitions are empty, the matching is empty as well: - >>> graph = csr_matrix((2, 0)) + >>> graph = csr_array((2, 0)) >>> print(maximum_bipartite_matching(graph, perm_type='column')) [-1 -1] >>> print(maximum_bipartite_matching(graph, perm_type='row')) [] - When the input matrix is square, and the graph is known to admit a perfect + When the input array is square, and the graph is known to admit a perfect matching, i.e. a matching with the property that every vertex in the graph belongs to some edge in the matching, then one can view the output as the - permutation of rows (or columns) turning the input matrix into one with the + permutation of rows (or columns) turning the input array into one with the property that all diagonal elements are non-empty: >>> a = [[0, 1, 2, 0], [1, 0, 0, 1], [2, 0, 0, 3], [0, 1, 3, 0]] - >>> graph = csr_matrix(a) + >>> graph = csr_array(a) >>> perm = maximum_bipartite_matching(graph, perm_type='row') >>> print(graph[perm].toarray()) [[1 0 0 1] @@ -297,8 +297,8 @@ def min_weight_full_bipartite_matching(biadjacency, maximize=False): Parameters ---------- - biadjacency : sparse matrix - Biadjacency matrix of the bipartite graph: A sparse matrix in CSR, CSC, + biadjacency : sparse array or matrix + Biadjacency matrix of the bipartite graph: A sparse array in CSR, CSC, or COO format whose rows represent one partition of the graph and whose columns represent the other partition. An edge between two vertices is indicated by the corresponding entry in the matrix, and the weight of @@ -373,12 +373,12 @@ def min_weight_full_bipartite_matching(biadjacency, maximize=False): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import min_weight_full_bipartite_matching Let us first consider an example in which all weights are equal: - >>> biadjacency = csr_matrix([[1, 1, 1], [1, 0, 0], [0, 1, 0]]) + >>> biadjacency = csr_array([[1, 1, 1], [1, 0, 0], [0, 1, 0]]) Here, all we get is a perfect matching of the graph: @@ -394,14 +394,14 @@ def min_weight_full_bipartite_matching(biadjacency, maximize=False): :func:`maximum_bipartite_matching`: >>> from scipy.sparse.csgraph import maximum_bipartite_matching - >>> biadjacency = csr_matrix([[1, 1, 1], [1, 0, 0], [0, 1, 0]]) + >>> biadjacency = csr_array([[1, 1, 1], [1, 0, 0], [0, 1, 0]]) >>> print(maximum_bipartite_matching(biadjacency, perm_type='column')) [2 0 1] When multiple edges are available, the ones with lowest weights are preferred: - >>> biadjacency = csr_matrix([[3, 3, 6], [4, 3, 5], [10, 1, 8]]) + >>> biadjacency = csr_array([[3, 3, 6], [4, 3, 5], [10, 1, 8]]) >>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency) >>> print(col_ind) [0 2 1] @@ -415,11 +415,11 @@ def min_weight_full_bipartite_matching(biadjacency, maximize=False): cardinalities, the matching is as large as the smaller of the two partitions: - >>> biadjacency = csr_matrix([[0, 1, 1], [0, 2, 3]]) + >>> biadjacency = csr_array([[0, 1, 1], [0, 2, 3]]) >>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency) >>> print(row_ind, col_ind) [0 1] [2 1] - >>> biadjacency = csr_matrix([[0, 1], [3, 1], [1, 4]]) + >>> biadjacency = csr_array([[0, 1], [3, 1], [1, 4]]) >>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency) >>> print(row_ind, col_ind) [0 2] [1 0] @@ -427,20 +427,20 @@ def min_weight_full_bipartite_matching(biadjacency, maximize=False): When one or both of the partitions are empty, the matching is empty as well: - >>> biadjacency = csr_matrix((2, 0)) + >>> biadjacency = csr_array((2, 0)) >>> row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency) >>> print(row_ind, col_ind) [] [] In general, we will always reach the same sum of weights as if we had used :func:`scipy.optimize.linear_sum_assignment` but note that for that one, - missing edges are represented by a matrix entry of ``float('inf')``. Let us - generate a random sparse matrix with integer entries between 1 and 10: + missing edges are represented by a array entry of ``float('inf')``. Let us + generate a random sparse array with integer entries between 1 and 10: >>> import numpy as np - >>> from scipy.sparse import random + >>> from scipy.sparse import random_array >>> from scipy.optimize import linear_sum_assignment - >>> sparse = random(10, 10, random_state=42, density=.5, format='coo') * 10 + >>> sparse = random_array((10, 10), random_state=42, density=.5, format='coo') * 10 >>> sparse.data = np.ceil(sparse.data) >>> dense = sparse.toarray() >>> dense = np.full(sparse.shape, np.inf) diff --git a/scipy/sparse/csgraph/_min_spanning_tree.pyx b/scipy/sparse/csgraph/_min_spanning_tree.pyx index 8d971918c1e4..24af0490e450 100644 --- a/scipy/sparse/csgraph/_min_spanning_tree.pyx +++ b/scipy/sparse/csgraph/_min_spanning_tree.pyx @@ -27,7 +27,7 @@ def minimum_spanning_tree(csgraph, overwrite=False): Parameters ---------- - csgraph : array_like or sparse matrix, 2 dimensions + csgraph : array_like or sparse array or matrix, 2 dimensions The N x N matrix representing an undirected graph over N nodes (see notes below). overwrite : bool, optional @@ -79,12 +79,12 @@ def minimum_spanning_tree(csgraph, overwrite=False): removing the edges with weights 8 and 6. In compressed sparse representation, the solution looks like this: - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import minimum_spanning_tree - >>> X = csr_matrix([[0, 8, 0, 3], - ... [0, 0, 2, 5], - ... [0, 0, 0, 6], - ... [0, 0, 0, 0]]) + >>> X = csr_array([[0, 8, 0, 3], + ... [0, 0, 2, 5], + ... [0, 0, 0, 6], + ... [0, 0, 0, 0]]) >>> Tcsr = minimum_spanning_tree(X) >>> Tcsr.toarray().astype(int) array([[0, 0, 0, 3], diff --git a/scipy/sparse/csgraph/_reordering.pyx b/scipy/sparse/csgraph/_reordering.pyx index c59a1c5f0fcc..e58c6a9d2d12 100644 --- a/scipy/sparse/csgraph/_reordering.pyx +++ b/scipy/sparse/csgraph/_reordering.pyx @@ -27,8 +27,8 @@ def reverse_cuthill_mckee(graph, symmetric_mode=False): Parameters ---------- - graph : sparse matrix - Input sparse in CSC or CSR sparse matrix format. + graph : sparse array or matrix + Input sparse in CSC or CSR sparse array or matrix format. symmetric_mode : bool, optional Is input matrix guaranteed to be symmetric. @@ -48,7 +48,7 @@ def reverse_cuthill_mckee(graph, symmetric_mode=False): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import reverse_cuthill_mckee >>> graph = [ @@ -57,9 +57,9 @@ def reverse_cuthill_mckee(graph, symmetric_mode=False): ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -190,8 +190,8 @@ def structural_rank(graph): Parameters ---------- - graph : sparse matrix - Input sparse matrix. + graph : sparse array or matrix + Input sparse array. Returns ------- @@ -207,7 +207,7 @@ def structural_rank(graph): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import structural_rank >>> graph = [ @@ -216,9 +216,9 @@ def structural_rank(graph): ... [2, 0, 0, 3], ... [0, 1, 3, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 diff --git a/scipy/sparse/csgraph/_shortest_path.pyx b/scipy/sparse/csgraph/_shortest_path.pyx index 1757a8a60311..0376187d122e 100644 --- a/scipy/sparse/csgraph/_shortest_path.pyx +++ b/scipy/sparse/csgraph/_shortest_path.pyx @@ -57,7 +57,7 @@ def shortest_path(csgraph, method='auto', Parameters ---------- - csgraph : array, matrix, or sparse matrix, 2 dimensions + csgraph : array_like, or sparse array or matrix, 2 dimensions The N x N array of distances representing the input graph. method : string ['auto'|'FW'|'D'], optional Algorithm to use for shortest paths. Options are: @@ -138,7 +138,7 @@ def shortest_path(csgraph, method='auto', Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import shortest_path >>> graph = [ @@ -147,9 +147,9 @@ def shortest_path(csgraph, method='auto', ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -244,7 +244,7 @@ def floyd_warshall(csgraph, directed=True, Parameters ---------- - csgraph : array, matrix, or sparse matrix, 2 dimensions + csgraph : array_like, or sparse array or matrix, 2 dimensions The N x N array of distances representing the input graph. directed : bool, optional If True (default), then find the shortest path on a directed graph: @@ -289,7 +289,7 @@ def floyd_warshall(csgraph, directed=True, Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import floyd_warshall >>> graph = [ @@ -298,9 +298,9 @@ def floyd_warshall(csgraph, directed=True, ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -437,7 +437,7 @@ def dijkstra(csgraph, directed=True, indices=None, Parameters ---------- - csgraph : array, matrix, or sparse matrix, 2 dimensions + csgraph : array_like, or sparse array or matrix, 2 dimensions The N x N array of non-negative distances representing the input graph. directed : bool, optional If True (default), then find the shortest path on a directed graph: @@ -518,7 +518,7 @@ def dijkstra(csgraph, directed=True, indices=None, Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import dijkstra >>> graph = [ @@ -527,9 +527,9 @@ def dijkstra(csgraph, directed=True, indices=None, ... [0, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -962,7 +962,7 @@ def bellman_ford(csgraph, directed=True, indices=None, Parameters ---------- - csgraph : array, matrix, or sparse matrix, 2 dimensions + csgraph : array_like, or sparse array or matrix, 2 dimensions The N x N array of distances representing the input graph. directed : bool, optional If True (default), then find the shortest path on a directed graph: @@ -1011,7 +1011,7 @@ def bellman_ford(csgraph, directed=True, indices=None, Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import bellman_ford >>> graph = [ @@ -1020,9 +1020,9 @@ def bellman_ford(csgraph, directed=True, indices=None, ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -1204,7 +1204,7 @@ def johnson(csgraph, directed=True, indices=None, Parameters ---------- - csgraph : array, matrix, or sparse matrix, 2 dimensions + csgraph : array_like, or sparse array or matrix, 2 dimensions The N x N array of distances representing the input graph. directed : bool, optional If True (default), then find the shortest path on a directed graph: @@ -1253,7 +1253,7 @@ def johnson(csgraph, directed=True, indices=None, Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import johnson >>> graph = [ @@ -1262,9 +1262,9 @@ def johnson(csgraph, directed=True, indices=None, ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -1723,7 +1723,7 @@ def yen( Parameters ---------- - csgraph : array or sparse array, 2 dimensions + csgraph : array_like, or sparse array or matrix, 2 dimensions The N x N array of distances representing the input graph. source : int The index of the starting node for the paths. @@ -1787,7 +1787,7 @@ def yen( Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import yen >>> graph = [ @@ -1796,9 +1796,9 @@ def yen( ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 diff --git a/scipy/sparse/csgraph/_tools.pyx b/scipy/sparse/csgraph/_tools.pyx index 8025a499a614..dfa37f7bdfd3 100644 --- a/scipy/sparse/csgraph/_tools.pyx +++ b/scipy/sparse/csgraph/_tools.pyx @@ -30,7 +30,7 @@ def csgraph_from_masked(graph): Returns ------- - csgraph : csr_matrix + csgraph : csr_array Compressed sparse representation of graph, Examples @@ -194,7 +194,7 @@ def csgraph_from_dense(graph, Returns ------- - csgraph : csr_matrix + csgraph : csr_array Compressed sparse representation of graph, Examples @@ -230,7 +230,7 @@ def csgraph_to_dense(csgraph, null_value=0): Parameters ---------- - csgraph : csr_matrix, csc_matrix, or lil_matrix + csgraph : csr_array, csc_array, or lil_array Sparse representation of a graph. null_value : float, optional The value used to indicate null edges in the dense representation. @@ -253,12 +253,12 @@ def csgraph_to_dense(csgraph, null_value=0): graph with multiple edges from node 0 to node 1, of weights 2 and 3. This illustrates the difference in behavior: - >>> from scipy.sparse import csr_matrix, csgraph + >>> from scipy.sparse import csr_array, csgraph >>> import numpy as np >>> data = np.array([2, 3]) >>> indices = np.array([1, 1]) >>> indptr = np.array([0, 2, 2]) - >>> M = csr_matrix((data, indices, indptr), shape=(2, 2)) + >>> M = csr_array((data, indices, indptr), shape=(2, 2)) >>> M.toarray() array([[0, 5], [0, 0]]) @@ -276,11 +276,11 @@ def csgraph_to_dense(csgraph, null_value=0): zero-weight edges. Let's look at the example of a two-node directed graph, connected by an edge of weight zero: - >>> from scipy.sparse import csr_matrix, csgraph + >>> from scipy.sparse import csr_array, csgraph >>> data = np.array([0.0]) >>> indices = np.array([1]) >>> indptr = np.array([0, 1, 1]) - >>> M = csr_matrix((data, indices, indptr), shape=(2, 2)) + >>> M = csr_array((data, indices, indptr), shape=(2, 2)) >>> M.toarray() array([[0., 0.], [0., 0.]]) @@ -294,17 +294,17 @@ def csgraph_to_dense(csgraph, null_value=0): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import csgraph_to_dense - >>> graph = csr_matrix( [ + >>> graph = csr_array( [ ... [0, 1, 2, 0], ... [0, 0, 0, 1], ... [0, 0, 0, 3], ... [0, 0, 0, 0] ... ]) >>> graph - >>> csgraph_to_dense(graph) @@ -348,7 +348,7 @@ def csgraph_to_masked(csgraph): Parameters ---------- - csgraph : csr_matrix, csc_matrix, or lil_matrix + csgraph : csr_array, csc_array, or lil_array Sparse representation of a graph. Returns @@ -358,17 +358,17 @@ def csgraph_to_masked(csgraph): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import csgraph_to_masked - >>> graph = csr_matrix( [ + >>> graph = csr_array( [ ... [0, 1, 2, 0], ... [0, 0, 0, 1], ... [0, 0, 0, 3], ... [0, 0, 0, 0] ... ]) >>> graph - >>> csgraph_to_masked(graph) @@ -422,7 +422,7 @@ def reconstruct_path(csgraph, predecessors, directed=True): Parameters ---------- - csgraph : array_like or sparse matrix + csgraph : array_like or sparse array or matrix The N x N matrix representing the directed or undirected graph from which the predecessors are drawn. predecessors : array_like, one dimension @@ -443,7 +443,7 @@ def reconstruct_path(csgraph, predecessors, directed=True): Examples -------- >>> import numpy as np - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import reconstruct_path >>> graph = [ @@ -452,9 +452,9 @@ def reconstruct_path(csgraph, predecessors, directed=True): ... [0, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -466,10 +466,10 @@ def reconstruct_path(csgraph, predecessors, directed=True): >>> cstree = reconstruct_path(csgraph=graph, predecessors=pred, directed=False) >>> cstree.todense() - matrix([[0., 1., 2., 0.], - [0., 0., 0., 1.], - [0., 0., 0., 0.], - [0., 0., 0., 0.]]) + array([[0., 1., 2., 0.], + [0., 0., 0., 1.], + [0., 0., 0., 0.], + [0., 0., 0., 0.]]) """ from ._validation import validate_graph @@ -567,7 +567,7 @@ def construct_dist_matrix(graph, Examples -------- >>> import numpy as np - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import construct_dist_matrix >>> graph = [ @@ -576,9 +576,9 @@ def construct_dist_matrix(graph, ... [0, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 diff --git a/scipy/sparse/csgraph/_traversal.pyx b/scipy/sparse/csgraph/_traversal.pyx index 82e16dd41d81..1f3ff3657ff3 100644 --- a/scipy/sparse/csgraph/_traversal.pyx +++ b/scipy/sparse/csgraph/_traversal.pyx @@ -29,7 +29,7 @@ def connected_components(csgraph, directed=True, connection='weak', Parameters ---------- - csgraph : array_like or sparse matrix + csgraph : array_like or sparse array or matrix The N x N matrix representing the compressed sparse graph. The input csgraph will be converted to csr format for the calculation. directed : bool, optional @@ -63,7 +63,7 @@ def connected_components(csgraph, directed=True, connection='weak', Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import connected_components >>> graph = [ @@ -73,9 +73,9 @@ def connected_components(csgraph, directed=True, connection='weak', ... [0, 0, 0, 0, 1], ... [0, 0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -134,7 +134,7 @@ def breadth_first_tree(csgraph, i_start, directed=True): Parameters ---------- - csgraph : array_like or sparse matrix + csgraph : array_like or sparse array or matrix The N x N matrix representing the compressed sparse graph. The input csgraph will be converted to csr format for the calculation. i_start : int @@ -176,12 +176,12 @@ def breadth_first_tree(csgraph, i_start, directed=True): In compressed sparse representation, the solution looks like this: - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import breadth_first_tree - >>> X = csr_matrix([[0, 8, 0, 3], - ... [0, 0, 2, 5], - ... [0, 0, 0, 6], - ... [0, 0, 0, 0]]) + >>> X = csr_array([[0, 8, 0, 3], + ... [0, 0, 2, 5], + ... [0, 0, 0, 6], + ... [0, 0, 0, 0]]) >>> Tcsr = breadth_first_tree(X, 0, directed=False) >>> Tcsr.toarray().astype(int) array([[0, 8, 0, 3], @@ -210,7 +210,7 @@ def depth_first_tree(csgraph, i_start, directed=True): Parameters ---------- - csgraph : array_like or sparse matrix + csgraph : array_like or sparse array or matrix The N x N matrix representing the compressed sparse graph. The input csgraph will be converted to csr format for the calculation. i_start : int @@ -252,12 +252,12 @@ def depth_first_tree(csgraph, i_start, directed=True): In compressed sparse representation, the solution looks like this: - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import depth_first_tree - >>> X = csr_matrix([[0, 8, 0, 3], - ... [0, 0, 2, 5], - ... [0, 0, 0, 6], - ... [0, 0, 0, 0]]) + >>> X = csr_array([[0, 8, 0, 3], + ... [0, 0, 2, 5], + ... [0, 0, 0, 6], + ... [0, 0, 0, 0]]) >>> Tcsr = depth_first_tree(X, 0, directed=False) >>> Tcsr.toarray().astype(int) array([[0, 8, 0, 0], @@ -290,7 +290,7 @@ cpdef breadth_first_order(csgraph, i_start, Parameters ---------- - csgraph : array_like or sparse matrix + csgraph : array_like or sparse array or matrix The N x N compressed sparse graph. The input csgraph will be converted to csr format for the calculation. i_start : int @@ -324,7 +324,7 @@ cpdef breadth_first_order(csgraph, i_start, Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import breadth_first_order >>> graph = [ @@ -333,9 +333,9 @@ cpdef breadth_first_order(csgraph, i_start, ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -499,7 +499,7 @@ cpdef depth_first_order(csgraph, i_start, Parameters ---------- - csgraph : array_like or sparse matrix + csgraph : array_like or sparse array or matrix The N x N compressed sparse graph. The input csgraph will be converted to csr format for the calculation. i_start : int @@ -533,7 +533,7 @@ cpdef depth_first_order(csgraph, i_start, Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from scipy.sparse.csgraph import depth_first_order >>> graph = [ @@ -542,9 +542,9 @@ cpdef depth_first_order(csgraph, i_start, ... [2, 0, 0, 3], ... [0, 0, 0, 0] ... ] - >>> graph = csr_matrix(graph) + >>> graph = csr_array(graph) >>> print(graph) - Coords Values (0, 1) 1 @@ -736,7 +736,7 @@ cdef int _connected_components_directed2( """ Uses an iterative version of Tarjan's algorithm to find the strongly connected components of a directed graph represented as a - sparse matrix (scipy.sparse.csc_matrix or scipy.sparse.csr_matrix). + sparse array (scipy.sparse.csc_array or scipy.sparse.csr_array). The algorithmic complexity is for a graph with E edges and V vertices is O(E + V). diff --git a/scipy/sparse/csgraph/tests/test_reordering.py b/scipy/sparse/csgraph/tests/test_reordering.py index 8f4c7cfcc67b..add76cdc29c3 100644 --- a/scipy/sparse/csgraph/tests/test_reordering.py +++ b/scipy/sparse/csgraph/tests/test_reordering.py @@ -13,12 +13,12 @@ def test_graph_reverse_cuthill_mckee(): [0, 1, 0, 0, 0, 1, 0, 1], [0, 0, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 0, 1, 0, 1]], dtype=int) - + graph = csr_array(A) perm = reverse_cuthill_mckee(graph) correct_perm = np.array([6, 3, 7, 5, 1, 2, 4, 0]) assert_equal(perm, correct_perm) - + # Test int64 indices input graph.indices = graph.indices.astype('int64') graph.indptr = graph.indptr.astype('int64') @@ -28,14 +28,14 @@ def test_graph_reverse_cuthill_mckee(): def test_graph_reverse_cuthill_mckee_ordering(): data = np.ones(63,dtype=int) - rows = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, + rows = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, - 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, + 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15]) cols = np.array([0, 2, 5, 8, 10, 1, 3, 9, 11, 0, 2, - 7, 10, 1, 3, 11, 4, 6, 12, 14, 0, 7, 13, + 7, 10, 1, 3, 11, 4, 6, 12, 14, 0, 7, 13, 15, 4, 6, 14, 2, 5, 7, 15, 0, 8, 10, 13, 1, 9, 11, 0, 2, 8, 10, 15, 1, 3, 9, 11, 4, 12, 14, 5, 8, 13, 15, 4, 6, 12, 14, @@ -53,18 +53,18 @@ def test_graph_structural_rank(): [1, 0, 1], [0, 1, 0]]) assert_equal(structural_rank(A), 3) - + # Test square matrix #2 rows = np.array([0,0,0,0,0,1,1,2,2,3,3,3,3,3,3,4,4,5,5,6,6,7,7]) cols = np.array([0,1,2,3,4,2,5,2,6,0,1,3,5,6,7,4,5,5,6,2,6,2,4]) data = np.ones_like(rows) B = coo_array((data,(rows,cols)), shape=(8,8)) assert_equal(structural_rank(B), 6) - + #Test non-square matrix C = csc_array([[1, 0, 2, 0], [2, 0, 4, 0]]) assert_equal(structural_rank(C), 2) - + #Test tall matrix assert_equal(structural_rank(C.T), 2) diff --git a/scipy/sparse/csgraph/tests/test_traversal.py b/scipy/sparse/csgraph/tests/test_traversal.py index e279385e0c14..aef6def21b61 100644 --- a/scipy/sparse/csgraph/tests/test_traversal.py +++ b/scipy/sparse/csgraph/tests/test_traversal.py @@ -84,10 +84,11 @@ def test_return_type(): sup.filter(PendingDeprecationWarning, "the matrix subclass.*") nm_csgraph = np.matrix([[0, 1, 2, 0, 0], - [1, 0, 0, 0, 3], - [2, 0, 0, 7, 0], - [0, 0, 7, 0, 1], - [0, 3, 0, 1, 0]]) + [1, 0, 0, 0, 3], + [2, 0, 0, 7, 0], + [0, 0, 7, 0, 1], + [0, 3, 0, 1, 0]]) + csgraph = csr_matrix(nm_csgraph) assert isinstance(laplacian(csgraph), coo_matrix) assert isinstance(minimum_spanning_tree(csgraph), csr_matrix)