diff --git a/tests/csgraph/__init__.py b/tests/csgraph/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/csgraph/meson.build b/tests/csgraph/meson.build deleted file mode 100644 index 7ad02ba3b2..0000000000 --- a/tests/csgraph/meson.build +++ /dev/null @@ -1,20 +0,0 @@ -python_sources = [ - '__init__.py', - 'test_connected_components.py', - 'test_conversions.py', - 'test_flow.py', - 'test_graph_laplacian.py', - 'test_matching.py', - 'test_pydata_sparse.py', - 'test_reordering.py', - 'test_shortest_path.py', - 'test_spanning_tree.py', - 'test_traversal.py' -] - - -py3.install_sources( - python_sources, - subdir: 'scipy/sparse/csgraph/tests', - install_tag: 'tests' -) diff --git a/tests/csgraph/test_connected_components.py b/tests/csgraph/test_connected_components.py deleted file mode 100644 index 0b190a24de..0000000000 --- a/tests/csgraph/test_connected_components.py +++ /dev/null @@ -1,119 +0,0 @@ -import numpy as np -from numpy.testing import assert_equal, assert_array_almost_equal -from scipy.sparse import csgraph, csr_array - - -def test_weak_connections(): - Xde = np.array([[0, 1, 0], - [0, 0, 0], - [0, 0, 0]]) - - Xsp = csgraph.csgraph_from_dense(Xde, null_value=0) - - for X in Xsp, Xde: - n_components, labels =\ - csgraph.connected_components(X, directed=True, - connection='weak') - - assert_equal(n_components, 2) - assert_array_almost_equal(labels, [0, 0, 1]) - - -def test_strong_connections(): - X1de = np.array([[0, 1, 0], - [0, 0, 0], - [0, 0, 0]]) - X2de = X1de + X1de.T - - X1sp = csgraph.csgraph_from_dense(X1de, null_value=0) - X2sp = csgraph.csgraph_from_dense(X2de, null_value=0) - - for X in X1sp, X1de: - n_components, labels =\ - csgraph.connected_components(X, directed=True, - connection='strong') - - assert_equal(n_components, 3) - labels.sort() - assert_array_almost_equal(labels, [0, 1, 2]) - - for X in X2sp, X2de: - n_components, labels =\ - csgraph.connected_components(X, directed=True, - connection='strong') - - assert_equal(n_components, 2) - labels.sort() - assert_array_almost_equal(labels, [0, 0, 1]) - - -def test_strong_connections2(): - X = np.array([[0, 0, 0, 0, 0, 0], - [1, 0, 1, 0, 0, 0], - [0, 0, 0, 1, 0, 0], - [0, 0, 1, 0, 1, 0], - [0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 1, 0]]) - n_components, labels =\ - csgraph.connected_components(X, directed=True, - connection='strong') - assert_equal(n_components, 5) - labels.sort() - assert_array_almost_equal(labels, [0, 1, 2, 2, 3, 4]) - - -def test_weak_connections2(): - X = np.array([[0, 0, 0, 0, 0, 0], - [1, 0, 0, 0, 0, 0], - [0, 0, 0, 1, 0, 0], - [0, 0, 1, 0, 1, 0], - [0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 1, 0]]) - n_components, labels =\ - csgraph.connected_components(X, directed=True, - connection='weak') - assert_equal(n_components, 2) - labels.sort() - assert_array_almost_equal(labels, [0, 0, 1, 1, 1, 1]) - - -def test_ticket1876(): - # Regression test: this failed in the original implementation - # There should be two strongly-connected components; previously gave one - g = np.array([[0, 1, 1, 0], - [1, 0, 0, 1], - [0, 0, 0, 1], - [0, 0, 1, 0]]) - n_components, labels = csgraph.connected_components(g, connection='strong') - - assert_equal(n_components, 2) - assert_equal(labels[0], labels[1]) - assert_equal(labels[2], labels[3]) - - -def test_fully_connected_graph(): - # Fully connected dense matrices raised an exception. - # https://github.com/scipy/scipy/issues/3818 - g = np.ones((4, 4)) - n_components, labels = csgraph.connected_components(g) - assert_equal(n_components, 1) - - -def test_int64_indices_undirected(): - # See https://github.com/scipy/scipy/issues/18716 - g = csr_array(([1], np.array([[0], [1]], dtype=np.int64)), shape=(2, 2)) - assert g.indices.dtype == np.int64 - n, labels = csgraph.connected_components(g, directed=False) - assert n == 1 - assert_array_almost_equal(labels, [0, 0]) - - -def test_int64_indices_directed(): - # See https://github.com/scipy/scipy/issues/18716 - g = csr_array(([1], np.array([[0], [1]], dtype=np.int64)), shape=(2, 2)) - assert g.indices.dtype == np.int64 - n, labels = csgraph.connected_components(g, directed=True, - connection='strong') - assert n == 2 - assert_array_almost_equal(labels, [1, 0]) - diff --git a/tests/csgraph/test_conversions.py b/tests/csgraph/test_conversions.py deleted file mode 100644 index e7900d67b5..0000000000 --- a/tests/csgraph/test_conversions.py +++ /dev/null @@ -1,61 +0,0 @@ -import numpy as np -from numpy.testing import assert_array_almost_equal -from scipy.sparse import csr_matrix -from scipy.sparse.csgraph import csgraph_from_dense, csgraph_to_dense - - -def test_csgraph_from_dense(): - np.random.seed(1234) - G = np.random.random((10, 10)) - some_nulls = (G < 0.4) - all_nulls = (G < 0.8) - - for null_value in [0, np.nan, np.inf]: - G[all_nulls] = null_value - with np.errstate(invalid="ignore"): - G_csr = csgraph_from_dense(G, null_value=0) - - G[all_nulls] = 0 - assert_array_almost_equal(G, G_csr.toarray()) - - for null_value in [np.nan, np.inf]: - G[all_nulls] = 0 - G[some_nulls] = null_value - with np.errstate(invalid="ignore"): - G_csr = csgraph_from_dense(G, null_value=0) - - G[all_nulls] = 0 - assert_array_almost_equal(G, G_csr.toarray()) - - -def test_csgraph_to_dense(): - np.random.seed(1234) - G = np.random.random((10, 10)) - nulls = (G < 0.8) - G[nulls] = np.inf - - G_csr = csgraph_from_dense(G) - - for null_value in [0, 10, -np.inf, np.inf]: - G[nulls] = null_value - assert_array_almost_equal(G, csgraph_to_dense(G_csr, null_value)) - - -def test_multiple_edges(): - # create a random square matrix with an even number of elements - np.random.seed(1234) - X = np.random.random((10, 10)) - Xcsr = csr_matrix(X) - - # now double-up every other column - Xcsr.indices[::2] = Xcsr.indices[1::2] - - # normal sparse toarray() will sum the duplicated edges - Xdense = Xcsr.toarray() - assert_array_almost_equal(Xdense[:, 1::2], - X[:, ::2] + X[:, 1::2]) - - # csgraph_to_dense chooses the minimum of each duplicated edge - Xdense = csgraph_to_dense(Xcsr) - assert_array_almost_equal(Xdense[:, 1::2], - np.minimum(X[:, ::2], X[:, 1::2])) diff --git a/tests/csgraph/test_flow.py b/tests/csgraph/test_flow.py deleted file mode 100644 index 8bb129a572..0000000000 --- a/tests/csgraph/test_flow.py +++ /dev/null @@ -1,201 +0,0 @@ -import numpy as np -from numpy.testing import assert_array_equal -import pytest - -from scipy.sparse import csr_matrix, csc_matrix -from scipy.sparse.csgraph import maximum_flow -from scipy.sparse.csgraph._flow import ( - _add_reverse_edges, _make_edge_pointers, _make_tails -) - -methods = ['edmonds_karp', 'dinic'] - -def test_raises_on_dense_input(): - with pytest.raises(TypeError): - graph = np.array([[0, 1], [0, 0]]) - maximum_flow(graph, 0, 1) - maximum_flow(graph, 0, 1, method='edmonds_karp') - - -def test_raises_on_csc_input(): - with pytest.raises(TypeError): - graph = csc_matrix([[0, 1], [0, 0]]) - maximum_flow(graph, 0, 1) - maximum_flow(graph, 0, 1, method='edmonds_karp') - - -def test_raises_on_floating_point_input(): - with pytest.raises(ValueError): - graph = csr_matrix([[0, 1.5], [0, 0]], dtype=np.float64) - maximum_flow(graph, 0, 1) - maximum_flow(graph, 0, 1, method='edmonds_karp') - - -def test_raises_on_non_square_input(): - with pytest.raises(ValueError): - graph = csr_matrix([[0, 1, 2], [2, 1, 0]]) - maximum_flow(graph, 0, 1) - - -def test_raises_when_source_is_sink(): - with pytest.raises(ValueError): - graph = csr_matrix([[0, 1], [0, 0]]) - maximum_flow(graph, 0, 0) - maximum_flow(graph, 0, 0, method='edmonds_karp') - - -@pytest.mark.parametrize('method', methods) -@pytest.mark.parametrize('source', [-1, 2, 3]) -def test_raises_when_source_is_out_of_bounds(source, method): - with pytest.raises(ValueError): - graph = csr_matrix([[0, 1], [0, 0]]) - maximum_flow(graph, source, 1, method=method) - - -@pytest.mark.parametrize('method', methods) -@pytest.mark.parametrize('sink', [-1, 2, 3]) -def test_raises_when_sink_is_out_of_bounds(sink, method): - with pytest.raises(ValueError): - graph = csr_matrix([[0, 1], [0, 0]]) - maximum_flow(graph, 0, sink, method=method) - - -@pytest.mark.parametrize('method', methods) -def test_simple_graph(method): - # This graph looks as follows: - # (0) --5--> (1) - graph = csr_matrix([[0, 5], [0, 0]]) - res = maximum_flow(graph, 0, 1, method=method) - assert res.flow_value == 5 - expected_flow = np.array([[0, 5], [-5, 0]]) - assert_array_equal(res.flow.toarray(), expected_flow) - - -@pytest.mark.parametrize('method', methods) -def test_bottle_neck_graph(method): - # This graph cannot use the full capacity between 0 and 1: - # (0) --5--> (1) --3--> (2) - graph = csr_matrix([[0, 5, 0], [0, 0, 3], [0, 0, 0]]) - res = maximum_flow(graph, 0, 2, method=method) - assert res.flow_value == 3 - expected_flow = np.array([[0, 3, 0], [-3, 0, 3], [0, -3, 0]]) - assert_array_equal(res.flow.toarray(), expected_flow) - - -@pytest.mark.parametrize('method', methods) -def test_backwards_flow(method): - # This example causes backwards flow between vertices 3 and 4, - # and so this test ensures that we handle that accordingly. See - # https://stackoverflow.com/q/38843963/5085211 - # for more information. - graph = csr_matrix([[0, 10, 0, 0, 10, 0, 0, 0], - [0, 0, 10, 0, 0, 0, 0, 0], - [0, 0, 0, 10, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 10], - [0, 0, 0, 10, 0, 10, 0, 0], - [0, 0, 0, 0, 0, 0, 10, 0], - [0, 0, 0, 0, 0, 0, 0, 10], - [0, 0, 0, 0, 0, 0, 0, 0]]) - res = maximum_flow(graph, 0, 7, method=method) - assert res.flow_value == 20 - expected_flow = np.array([[0, 10, 0, 0, 10, 0, 0, 0], - [-10, 0, 10, 0, 0, 0, 0, 0], - [0, -10, 0, 10, 0, 0, 0, 0], - [0, 0, -10, 0, 0, 0, 0, 10], - [-10, 0, 0, 0, 0, 10, 0, 0], - [0, 0, 0, 0, -10, 0, 10, 0], - [0, 0, 0, 0, 0, -10, 0, 10], - [0, 0, 0, -10, 0, 0, -10, 0]]) - assert_array_equal(res.flow.toarray(), expected_flow) - - -@pytest.mark.parametrize('method', methods) -def test_example_from_clrs_chapter_26_1(method): - # See page 659 in CLRS second edition, but note that the maximum flow - # we find is slightly different than the one in CLRS; we push a flow of - # 12 to v_1 instead of v_2. - 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]]) - res = maximum_flow(graph, 0, 5, method=method) - assert res.flow_value == 23 - expected_flow = np.array([[0, 12, 11, 0, 0, 0], - [-12, 0, 0, 12, 0, 0], - [-11, 0, 0, 0, 11, 0], - [0, -12, 0, 0, -7, 19], - [0, 0, -11, 7, 0, 4], - [0, 0, 0, -19, -4, 0]]) - assert_array_equal(res.flow.toarray(), expected_flow) - - -@pytest.mark.parametrize('method', methods) -def test_disconnected_graph(method): - # This tests the following disconnected graph: - # (0) --5--> (1) (2) --3--> (3) - graph = csr_matrix([[0, 5, 0, 0], - [0, 0, 0, 0], - [0, 0, 9, 3], - [0, 0, 0, 0]]) - res = maximum_flow(graph, 0, 3, method=method) - assert res.flow_value == 0 - expected_flow = np.zeros((4, 4), dtype=np.int32) - assert_array_equal(res.flow.toarray(), expected_flow) - - -@pytest.mark.parametrize('method', methods) -def test_add_reverse_edges_large_graph(method): - # Regression test for https://github.com/scipy/scipy/issues/14385 - n = 100_000 - indices = np.arange(1, n) - indptr = np.array(list(range(n)) + [n - 1]) - data = np.ones(n - 1, dtype=np.int32) - graph = csr_matrix((data, indices, indptr), shape=(n, n)) - res = maximum_flow(graph, 0, n - 1, method=method) - assert res.flow_value == 1 - expected_flow = graph - graph.transpose() - assert_array_equal(res.flow.data, expected_flow.data) - assert_array_equal(res.flow.indices, expected_flow.indices) - assert_array_equal(res.flow.indptr, expected_flow.indptr) - - -@pytest.mark.parametrize("a,b_data_expected", [ - ([[]], []), - ([[0], [0]], []), - ([[1, 0, 2], [0, 0, 0], [0, 3, 0]], [1, 2, 0, 0, 3]), - ([[9, 8, 7], [4, 5, 6], [0, 0, 0]], [9, 8, 7, 4, 5, 6, 0, 0])]) -def test_add_reverse_edges(a, b_data_expected): - """Test that the reversal of the edges of the input graph works - as expected. - """ - a = csr_matrix(a, dtype=np.int32, shape=(len(a), len(a))) - b = _add_reverse_edges(a) - assert_array_equal(b.data, b_data_expected) - - -@pytest.mark.parametrize("a,expected", [ - ([[]], []), - ([[0]], []), - ([[1]], [0]), - ([[0, 1], [10, 0]], [1, 0]), - ([[1, 0, 2], [0, 0, 3], [4, 5, 0]], [0, 3, 4, 1, 2]) -]) -def test_make_edge_pointers(a, expected): - a = csr_matrix(a, dtype=np.int32) - rev_edge_ptr = _make_edge_pointers(a) - assert_array_equal(rev_edge_ptr, expected) - - -@pytest.mark.parametrize("a,expected", [ - ([[]], []), - ([[0]], []), - ([[1]], [0]), - ([[0, 1], [10, 0]], [0, 1]), - ([[1, 0, 2], [0, 0, 3], [4, 5, 0]], [0, 0, 1, 2, 2]) -]) -def test_make_tails(a, expected): - a = csr_matrix(a, dtype=np.int32) - tails = _make_tails(a) - assert_array_equal(tails, expected) diff --git a/tests/csgraph/test_graph_laplacian.py b/tests/csgraph/test_graph_laplacian.py deleted file mode 100644 index 88805db0c9..0000000000 --- a/tests/csgraph/test_graph_laplacian.py +++ /dev/null @@ -1,368 +0,0 @@ -import pytest -import numpy as np -from numpy.testing import assert_allclose -from pytest import raises as assert_raises -from scipy import sparse - -from scipy.sparse import csgraph -from scipy._lib._util import np_long, np_ulong - - -def check_int_type(mat): - return np.issubdtype(mat.dtype, np.signedinteger) or np.issubdtype( - mat.dtype, np_ulong - ) - - -def test_laplacian_value_error(): - for t in int, float, complex: - for m in ([1, 1], - [[[1]]], - [[1, 2, 3], [4, 5, 6]], - [[1, 2], [3, 4], [5, 5]]): - A = np.array(m, dtype=t) - assert_raises(ValueError, csgraph.laplacian, A) - - -def _explicit_laplacian(x, normed=False): - if sparse.issparse(x): - x = x.toarray() - x = np.asarray(x) - y = -1.0 * x - for j in range(y.shape[0]): - y[j,j] = x[j,j+1:].sum() + x[j,:j].sum() - if normed: - d = np.diag(y).copy() - d[d == 0] = 1.0 - y /= d[:,None]**.5 - y /= d[None,:]**.5 - return y - - -def _check_symmetric_graph_laplacian(mat, normed, copy=True): - if not hasattr(mat, 'shape'): - mat = eval(mat, dict(np=np, sparse=sparse)) - - if sparse.issparse(mat): - sp_mat = mat - mat = sp_mat.toarray() - else: - sp_mat = sparse.csr_matrix(mat) - - mat_copy = np.copy(mat) - sp_mat_copy = sparse.csr_matrix(sp_mat, copy=True) - - n_nodes = mat.shape[0] - explicit_laplacian = _explicit_laplacian(mat, normed=normed) - laplacian = csgraph.laplacian(mat, normed=normed, copy=copy) - sp_laplacian = csgraph.laplacian(sp_mat, normed=normed, - copy=copy) - - if copy: - assert_allclose(mat, mat_copy) - _assert_allclose_sparse(sp_mat, sp_mat_copy) - else: - if not (normed and check_int_type(mat)): - assert_allclose(laplacian, mat) - if sp_mat.format == 'coo': - _assert_allclose_sparse(sp_laplacian, sp_mat) - - assert_allclose(laplacian, sp_laplacian.toarray()) - - for tested in [laplacian, sp_laplacian.toarray()]: - if not normed: - assert_allclose(tested.sum(axis=0), np.zeros(n_nodes)) - assert_allclose(tested.T, tested) - assert_allclose(tested, explicit_laplacian) - - -def test_symmetric_graph_laplacian(): - symmetric_mats = ( - 'np.arange(10) * np.arange(10)[:, np.newaxis]', - 'np.ones((7, 7))', - 'np.eye(19)', - 'sparse.diags([1, 1], [-1, 1], shape=(4, 4))', - 'sparse.diags([1, 1], [-1, 1], shape=(4, 4)).toarray()', - 'sparse.diags([1, 1], [-1, 1], shape=(4, 4)).todense()', - 'np.vander(np.arange(4)) + np.vander(np.arange(4)).T' - ) - for mat in symmetric_mats: - for normed in True, False: - for copy in True, False: - _check_symmetric_graph_laplacian(mat, normed, copy) - - -def _assert_allclose_sparse(a, b, **kwargs): - # helper function that can deal with sparse matrices - if sparse.issparse(a): - a = a.toarray() - if sparse.issparse(b): - b = b.toarray() - assert_allclose(a, b, **kwargs) - - -def _check_laplacian_dtype_none( - A, desired_L, desired_d, normed, use_out_degree, copy, dtype, arr_type -): - mat = arr_type(A, dtype=dtype) - L, d = csgraph.laplacian( - mat, - normed=normed, - return_diag=True, - use_out_degree=use_out_degree, - copy=copy, - dtype=None, - ) - if normed and check_int_type(mat): - assert L.dtype == np.float64 - assert d.dtype == np.float64 - _assert_allclose_sparse(L, desired_L, atol=1e-12) - _assert_allclose_sparse(d, desired_d, atol=1e-12) - else: - assert L.dtype == dtype - assert d.dtype == dtype - desired_L = np.asarray(desired_L).astype(dtype) - desired_d = np.asarray(desired_d).astype(dtype) - _assert_allclose_sparse(L, desired_L, atol=1e-12) - _assert_allclose_sparse(d, desired_d, atol=1e-12) - - if not copy: - if not (normed and check_int_type(mat)): - if type(mat) is np.ndarray: - assert_allclose(L, mat) - elif mat.format == "coo": - _assert_allclose_sparse(L, mat) - - -def _check_laplacian_dtype( - A, desired_L, desired_d, normed, use_out_degree, copy, dtype, arr_type -): - mat = arr_type(A, dtype=dtype) - L, d = csgraph.laplacian( - mat, - normed=normed, - return_diag=True, - use_out_degree=use_out_degree, - copy=copy, - dtype=dtype, - ) - assert L.dtype == dtype - assert d.dtype == dtype - desired_L = np.asarray(desired_L).astype(dtype) - desired_d = np.asarray(desired_d).astype(dtype) - _assert_allclose_sparse(L, desired_L, atol=1e-12) - _assert_allclose_sparse(d, desired_d, atol=1e-12) - - if not copy: - if not (normed and check_int_type(mat)): - if type(mat) is np.ndarray: - assert_allclose(L, mat) - elif mat.format == 'coo': - _assert_allclose_sparse(L, mat) - - -INT_DTYPES = (np.intc, np_long, np.longlong) -REAL_DTYPES = (np.float32, np.float64, np.longdouble) -COMPLEX_DTYPES = (np.complex64, np.complex128, np.clongdouble) -DTYPES = INT_DTYPES + REAL_DTYPES + COMPLEX_DTYPES - - -@pytest.mark.parametrize("dtype", DTYPES) -@pytest.mark.parametrize("arr_type", [np.array, - sparse.csr_matrix, - sparse.coo_matrix, - sparse.csr_array, - sparse.coo_array]) -@pytest.mark.parametrize("copy", [True, False]) -@pytest.mark.parametrize("normed", [True, False]) -@pytest.mark.parametrize("use_out_degree", [True, False]) -def test_asymmetric_laplacian(use_out_degree, normed, - copy, dtype, arr_type): - # adjacency matrix - A = [[0, 1, 0], - [4, 2, 0], - [0, 0, 0]] - A = arr_type(np.array(A), dtype=dtype) - A_copy = A.copy() - - if not normed and use_out_degree: - # Laplacian matrix using out-degree - L = [[1, -1, 0], - [-4, 4, 0], - [0, 0, 0]] - d = [1, 4, 0] - - if normed and use_out_degree: - # normalized Laplacian matrix using out-degree - L = [[1, -0.5, 0], - [-2, 1, 0], - [0, 0, 0]] - d = [1, 2, 1] - - if not normed and not use_out_degree: - # Laplacian matrix using in-degree - L = [[4, -1, 0], - [-4, 1, 0], - [0, 0, 0]] - d = [4, 1, 0] - - if normed and not use_out_degree: - # normalized Laplacian matrix using in-degree - L = [[1, -0.5, 0], - [-2, 1, 0], - [0, 0, 0]] - d = [2, 1, 1] - - _check_laplacian_dtype_none( - A, - L, - d, - normed=normed, - use_out_degree=use_out_degree, - copy=copy, - dtype=dtype, - arr_type=arr_type, - ) - - _check_laplacian_dtype( - A_copy, - L, - d, - normed=normed, - use_out_degree=use_out_degree, - copy=copy, - dtype=dtype, - arr_type=arr_type, - ) - - -@pytest.mark.parametrize("fmt", ['csr', 'csc', 'coo', 'lil', - 'dok', 'dia', 'bsr']) -@pytest.mark.parametrize("normed", [True, False]) -@pytest.mark.parametrize("copy", [True, False]) -def test_sparse_formats(fmt, normed, copy): - mat = sparse.diags([1, 1], [-1, 1], shape=(4, 4), format=fmt) - _check_symmetric_graph_laplacian(mat, normed, copy) - - -@pytest.mark.parametrize( - "arr_type", [np.asarray, - sparse.csr_matrix, - sparse.coo_matrix, - sparse.csr_array, - sparse.coo_array] -) -@pytest.mark.parametrize("form", ["array", "function", "lo"]) -def test_laplacian_symmetrized(arr_type, form): - # adjacency matrix - n = 3 - mat = arr_type(np.arange(n * n).reshape(n, n)) - L_in, d_in = csgraph.laplacian( - mat, - return_diag=True, - form=form, - ) - L_out, d_out = csgraph.laplacian( - mat, - return_diag=True, - use_out_degree=True, - form=form, - ) - Ls, ds = csgraph.laplacian( - mat, - return_diag=True, - symmetrized=True, - form=form, - ) - Ls_normed, ds_normed = csgraph.laplacian( - mat, - return_diag=True, - symmetrized=True, - normed=True, - form=form, - ) - mat += mat.T - Lss, dss = csgraph.laplacian(mat, return_diag=True, form=form) - Lss_normed, dss_normed = csgraph.laplacian( - mat, - return_diag=True, - normed=True, - form=form, - ) - - assert_allclose(ds, d_in + d_out) - assert_allclose(ds, dss) - assert_allclose(ds_normed, dss_normed) - - d = {} - for L in ["L_in", "L_out", "Ls", "Ls_normed", "Lss", "Lss_normed"]: - if form == "array": - d[L] = eval(L) - else: - d[L] = eval(L)(np.eye(n, dtype=mat.dtype)) - - _assert_allclose_sparse(d["Ls"], d["L_in"] + d["L_out"].T) - _assert_allclose_sparse(d["Ls"], d["Lss"]) - _assert_allclose_sparse(d["Ls_normed"], d["Lss_normed"]) - - -@pytest.mark.parametrize( - "arr_type", [np.asarray, - sparse.csr_matrix, - sparse.coo_matrix, - sparse.csr_array, - sparse.coo_array] -) -@pytest.mark.parametrize("dtype", DTYPES) -@pytest.mark.parametrize("normed", [True, False]) -@pytest.mark.parametrize("symmetrized", [True, False]) -@pytest.mark.parametrize("use_out_degree", [True, False]) -@pytest.mark.parametrize("form", ["function", "lo"]) -def test_format(dtype, arr_type, normed, symmetrized, use_out_degree, form): - n = 3 - mat = [[0, 1, 0], [4, 2, 0], [0, 0, 0]] - mat = arr_type(np.array(mat), dtype=dtype) - Lo, do = csgraph.laplacian( - mat, - return_diag=True, - normed=normed, - symmetrized=symmetrized, - use_out_degree=use_out_degree, - dtype=dtype, - ) - La, da = csgraph.laplacian( - mat, - return_diag=True, - normed=normed, - symmetrized=symmetrized, - use_out_degree=use_out_degree, - dtype=dtype, - form="array", - ) - assert_allclose(do, da) - _assert_allclose_sparse(Lo, La) - - L, d = csgraph.laplacian( - mat, - return_diag=True, - normed=normed, - symmetrized=symmetrized, - use_out_degree=use_out_degree, - dtype=dtype, - form=form, - ) - assert_allclose(d, do) - assert d.dtype == dtype - Lm = L(np.eye(n, dtype=mat.dtype)).astype(dtype) - _assert_allclose_sparse(Lm, Lo, rtol=2e-7, atol=2e-7) - x = np.arange(6).reshape(3, 2) - if not (normed and dtype in INT_DTYPES): - assert_allclose(L(x), Lo @ x) - else: - # Normalized Lo is casted to integer, but L() is not - pass - - -def test_format_error_message(): - with pytest.raises(ValueError, match="Invalid form: 'toto'"): - _ = csgraph.laplacian(np.eye(1), form='toto') diff --git a/tests/csgraph/test_matching.py b/tests/csgraph/test_matching.py deleted file mode 100644 index 87e2920fe9..0000000000 --- a/tests/csgraph/test_matching.py +++ /dev/null @@ -1,294 +0,0 @@ -from itertools import product - -import numpy as np -from numpy.testing import assert_array_equal, assert_equal -import pytest - -from scipy.sparse import csr_matrix, coo_matrix, diags -from scipy.sparse.csgraph import ( - maximum_bipartite_matching, min_weight_full_bipartite_matching -) - - -def test_maximum_bipartite_matching_raises_on_dense_input(): - with pytest.raises(TypeError): - graph = np.array([[0, 1], [0, 0]]) - maximum_bipartite_matching(graph) - - -def test_maximum_bipartite_matching_empty_graph(): - graph = csr_matrix((0, 0)) - x = maximum_bipartite_matching(graph, perm_type='row') - y = maximum_bipartite_matching(graph, perm_type='column') - expected_matching = np.array([]) - assert_array_equal(expected_matching, x) - assert_array_equal(expected_matching, y) - - -def test_maximum_bipartite_matching_empty_left_partition(): - graph = csr_matrix((2, 0)) - x = maximum_bipartite_matching(graph, perm_type='row') - y = maximum_bipartite_matching(graph, perm_type='column') - assert_array_equal(np.array([]), x) - assert_array_equal(np.array([-1, -1]), y) - - -def test_maximum_bipartite_matching_empty_right_partition(): - graph = csr_matrix((0, 3)) - x = maximum_bipartite_matching(graph, perm_type='row') - y = maximum_bipartite_matching(graph, perm_type='column') - assert_array_equal(np.array([-1, -1, -1]), x) - assert_array_equal(np.array([]), y) - - -def test_maximum_bipartite_matching_graph_with_no_edges(): - graph = csr_matrix((2, 2)) - x = maximum_bipartite_matching(graph, perm_type='row') - y = maximum_bipartite_matching(graph, perm_type='column') - assert_array_equal(np.array([-1, -1]), x) - assert_array_equal(np.array([-1, -1]), y) - - -def test_maximum_bipartite_matching_graph_that_causes_augmentation(): - # In this graph, column 1 is initially assigned to row 1, but it should be - # reassigned to make room for row 2. - graph = csr_matrix([[1, 1], [1, 0]]) - x = maximum_bipartite_matching(graph, perm_type='column') - y = maximum_bipartite_matching(graph, perm_type='row') - expected_matching = np.array([1, 0]) - assert_array_equal(expected_matching, x) - assert_array_equal(expected_matching, y) - - -def test_maximum_bipartite_matching_graph_with_more_rows_than_columns(): - graph = csr_matrix([[1, 1], [1, 0], [0, 1]]) - x = maximum_bipartite_matching(graph, perm_type='column') - y = maximum_bipartite_matching(graph, perm_type='row') - assert_array_equal(np.array([0, -1, 1]), x) - assert_array_equal(np.array([0, 2]), y) - - -def test_maximum_bipartite_matching_graph_with_more_columns_than_rows(): - graph = csr_matrix([[1, 1, 0], [0, 0, 1]]) - x = maximum_bipartite_matching(graph, perm_type='column') - y = maximum_bipartite_matching(graph, perm_type='row') - assert_array_equal(np.array([0, 2]), x) - assert_array_equal(np.array([0, -1, 1]), y) - - -def test_maximum_bipartite_matching_explicit_zeros_count_as_edges(): - data = [0, 0] - indices = [1, 0] - indptr = [0, 1, 2] - graph = csr_matrix((data, indices, indptr), shape=(2, 2)) - x = maximum_bipartite_matching(graph, perm_type='row') - y = maximum_bipartite_matching(graph, perm_type='column') - expected_matching = np.array([1, 0]) - assert_array_equal(expected_matching, x) - assert_array_equal(expected_matching, y) - - -def test_maximum_bipartite_matching_feasibility_of_result(): - # This is a regression test for GitHub issue #11458 - data = np.ones(50, dtype=int) - indices = [11, 12, 19, 22, 23, 5, 22, 3, 8, 10, 5, 6, 11, 12, 13, 5, 13, - 14, 20, 22, 3, 15, 3, 13, 14, 11, 12, 19, 22, 23, 5, 22, 3, 8, - 10, 5, 6, 11, 12, 13, 5, 13, 14, 20, 22, 3, 15, 3, 13, 14] - indptr = [0, 5, 7, 10, 10, 15, 20, 22, 22, 23, 25, 30, 32, 35, 35, 40, 45, - 47, 47, 48, 50] - graph = csr_matrix((data, indices, indptr), shape=(20, 25)) - x = maximum_bipartite_matching(graph, perm_type='row') - y = maximum_bipartite_matching(graph, perm_type='column') - assert (x != -1).sum() == 13 - assert (y != -1).sum() == 13 - # Ensure that each element of the matching is in fact an edge in the graph. - for u, v in zip(range(graph.shape[0]), y): - if v != -1: - assert graph[u, v] - for u, v in zip(x, range(graph.shape[1])): - if u != -1: - assert graph[u, v] - - -def test_matching_large_random_graph_with_one_edge_incident_to_each_vertex(): - np.random.seed(42) - A = diags(np.ones(25), offsets=0, format='csr') - rand_perm = np.random.permutation(25) - rand_perm2 = np.random.permutation(25) - - Rrow = np.arange(25) - Rcol = rand_perm - Rdata = np.ones(25, dtype=int) - Rmat = coo_matrix((Rdata, (Rrow, Rcol))).tocsr() - - Crow = rand_perm2 - Ccol = np.arange(25) - Cdata = np.ones(25, dtype=int) - Cmat = coo_matrix((Cdata, (Crow, Ccol))).tocsr() - # Randomly permute identity matrix - B = Rmat * A * Cmat - - # Row permute - perm = maximum_bipartite_matching(B, perm_type='row') - Rrow = np.arange(25) - Rcol = perm - Rdata = np.ones(25, dtype=int) - Rmat = coo_matrix((Rdata, (Rrow, Rcol))).tocsr() - C1 = Rmat * B - - # Column permute - perm2 = maximum_bipartite_matching(B, perm_type='column') - Crow = perm2 - Ccol = np.arange(25) - Cdata = np.ones(25, dtype=int) - Cmat = coo_matrix((Cdata, (Crow, Ccol))).tocsr() - C2 = B * Cmat - - # Should get identity matrix back - assert_equal(any(C1.diagonal() == 0), False) - assert_equal(any(C2.diagonal() == 0), False) - - -@pytest.mark.parametrize('num_rows,num_cols', [(0, 0), (2, 0), (0, 3)]) -def test_min_weight_full_matching_trivial_graph(num_rows, num_cols): - biadjacency_matrix = csr_matrix((num_cols, num_rows)) - row_ind, col_ind = min_weight_full_bipartite_matching(biadjacency_matrix) - assert len(row_ind) == 0 - assert len(col_ind) == 0 - - -@pytest.mark.parametrize('biadjacency_matrix', - [ - [[1, 1, 1], [1, 0, 0], [1, 0, 0]], - [[1, 1, 1], [0, 0, 1], [0, 0, 1]], - [[1, 0, 0, 1], [1, 1, 0, 1], [0, 0, 0, 0]], - [[1, 0, 0], [2, 0, 0]], - [[0, 1, 0], [0, 2, 0]], - [[1, 0], [2, 0], [5, 0]] - ]) -def test_min_weight_full_matching_infeasible_problems(biadjacency_matrix): - with pytest.raises(ValueError): - min_weight_full_bipartite_matching(csr_matrix(biadjacency_matrix)) - - -def test_min_weight_full_matching_large_infeasible(): - # Regression test for GitHub issue #17269 - a = np.asarray([ - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001], - [0.0, 0.11687445, 0.0, 0.0, 0.01319788, 0.07509257, 0.0, - 0.0, 0.0, 0.74228317, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.81087935, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.8408466, 0.0, 0.0, 0.0, 0.0, 0.01194389, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.82994211, 0.0, 0.0, 0.0, 0.11468516, 0.0, 0.0, 0.0, - 0.11173505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0], - [0.18796507, 0.0, 0.04002318, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75883335, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.71545464, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02748488, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.78470564, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14829198, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.10870609, 0.0, 0.0, 0.0, 0.8918677, 0.0, 0.0, 0.0, 0.06306644, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.63844085, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7442354, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09850549, 0.0, 0.0, 0.18638258, - 0.2769244, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.73182464, 0.0, 0.0, 0.46443561, - 0.38589284, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.29510278, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09666032, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] - ]) - with pytest.raises(ValueError, match='no full matching exists'): - min_weight_full_bipartite_matching(csr_matrix(a)) - - -def test_explicit_zero_causes_warning(): - with pytest.warns(UserWarning): - biadjacency_matrix = csr_matrix(((2, 0, 3), (0, 1, 1), (0, 2, 3))) - min_weight_full_bipartite_matching(biadjacency_matrix) - - -# General test for linear sum assignment solvers to make it possible to rely -# on the same tests for scipy.optimize.linear_sum_assignment. -def linear_sum_assignment_assertions( - solver, array_type, sign, test_case -): - cost_matrix, expected_cost = test_case - maximize = sign == -1 - cost_matrix = sign * array_type(cost_matrix) - expected_cost = sign * np.array(expected_cost) - - row_ind, col_ind = solver(cost_matrix, maximize=maximize) - assert_array_equal(row_ind, np.sort(row_ind)) - assert_array_equal(expected_cost, - np.array(cost_matrix[row_ind, col_ind]).flatten()) - - cost_matrix = cost_matrix.T - row_ind, col_ind = solver(cost_matrix, maximize=maximize) - assert_array_equal(row_ind, np.sort(row_ind)) - assert_array_equal(np.sort(expected_cost), - np.sort(np.array( - cost_matrix[row_ind, col_ind])).flatten()) - - -linear_sum_assignment_test_cases = product( - [-1, 1], - [ - # Square - ([[400, 150, 400], - [400, 450, 600], - [300, 225, 300]], - [150, 400, 300]), - - # Rectangular variant - ([[400, 150, 400, 1], - [400, 450, 600, 2], - [300, 225, 300, 3]], - [150, 2, 300]), - - ([[10, 10, 8], - [9, 8, 1], - [9, 7, 4]], - [10, 1, 7]), - - # Square - ([[10, 10, 8, 11], - [9, 8, 1, 1], - [9, 7, 4, 10]], - [10, 1, 4]), - - # Rectangular variant - ([[10, float("inf"), float("inf")], - [float("inf"), float("inf"), 1], - [float("inf"), 7, float("inf")]], - [10, 1, 7]) - ]) - - -@pytest.mark.parametrize('sign,test_case', linear_sum_assignment_test_cases) -def test_min_weight_full_matching_small_inputs(sign, test_case): - linear_sum_assignment_assertions( - min_weight_full_bipartite_matching, csr_matrix, sign, test_case) diff --git a/tests/csgraph/test_pydata_sparse.py b/tests/csgraph/test_pydata_sparse.py deleted file mode 100644 index 025aeb67c1..0000000000 --- a/tests/csgraph/test_pydata_sparse.py +++ /dev/null @@ -1,194 +0,0 @@ -import pytest - -import numpy as np -import scipy.sparse as sp -import scipy.sparse.csgraph as spgraph -from scipy._lib import _pep440 - -from numpy.testing import assert_equal - -try: - import sparse -except Exception: - sparse = None - -pytestmark = pytest.mark.skipif(sparse is None, - reason="pydata/sparse not installed") - - -msg = "pydata/sparse (0.15.1) does not implement necessary operations" - - -sparse_params = (pytest.param("COO"), - pytest.param("DOK", marks=[pytest.mark.xfail(reason=msg)])) - - -def check_sparse_version(min_ver): - if sparse is None: - return pytest.mark.skip(reason="sparse is not installed") - return pytest.mark.skipif( - _pep440.parse(sparse.__version__) < _pep440.Version(min_ver), - reason=f"sparse version >= {min_ver} required" - ) - - -@pytest.fixture(params=sparse_params) -def sparse_cls(request): - return getattr(sparse, request.param) - - -@pytest.fixture -def graphs(sparse_cls): - graph = [ - [0, 1, 1, 0, 0], - [0, 0, 1, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 1], - [0, 0, 0, 0, 0], - ] - A_dense = np.array(graph) - A_sparse = sparse_cls(A_dense) - return A_dense, A_sparse - - -@pytest.mark.parametrize( - "func", - [ - spgraph.shortest_path, - spgraph.dijkstra, - spgraph.floyd_warshall, - spgraph.bellman_ford, - spgraph.johnson, - spgraph.reverse_cuthill_mckee, - spgraph.maximum_bipartite_matching, - spgraph.structural_rank, - ] -) -def test_csgraph_equiv(func, graphs): - A_dense, A_sparse = graphs - actual = func(A_sparse) - desired = func(sp.csc_matrix(A_dense)) - assert_equal(actual, desired) - - -def test_connected_components(graphs): - A_dense, A_sparse = graphs - func = spgraph.connected_components - - actual_comp, actual_labels = func(A_sparse) - desired_comp, desired_labels, = func(sp.csc_matrix(A_dense)) - - assert actual_comp == desired_comp - assert_equal(actual_labels, desired_labels) - - -def test_laplacian(graphs): - A_dense, A_sparse = graphs - sparse_cls = type(A_sparse) - func = spgraph.laplacian - - actual = func(A_sparse) - desired = func(sp.csc_matrix(A_dense)) - - assert isinstance(actual, sparse_cls) - - assert_equal(actual.todense(), desired.todense()) - - -@pytest.mark.parametrize( - "func", [spgraph.breadth_first_order, spgraph.depth_first_order] -) -def test_order_search(graphs, func): - A_dense, A_sparse = graphs - - actual = func(A_sparse, 0) - desired = func(sp.csc_matrix(A_dense), 0) - - assert_equal(actual, desired) - - -@pytest.mark.parametrize( - "func", [spgraph.breadth_first_tree, spgraph.depth_first_tree] -) -def test_tree_search(graphs, func): - A_dense, A_sparse = graphs - sparse_cls = type(A_sparse) - - actual = func(A_sparse, 0) - desired = func(sp.csc_matrix(A_dense), 0) - - assert isinstance(actual, sparse_cls) - - assert_equal(actual.todense(), desired.todense()) - - -def test_minimum_spanning_tree(graphs): - A_dense, A_sparse = graphs - sparse_cls = type(A_sparse) - func = spgraph.minimum_spanning_tree - - actual = func(A_sparse) - desired = func(sp.csc_matrix(A_dense)) - - assert isinstance(actual, sparse_cls) - - assert_equal(actual.todense(), desired.todense()) - - -def test_maximum_flow(graphs): - A_dense, A_sparse = graphs - sparse_cls = type(A_sparse) - func = spgraph.maximum_flow - - actual = func(A_sparse, 0, 2) - desired = func(sp.csr_matrix(A_dense), 0, 2) - - assert actual.flow_value == desired.flow_value - assert isinstance(actual.flow, sparse_cls) - - assert_equal(actual.flow.todense(), desired.flow.todense()) - - -def test_min_weight_full_bipartite_matching(graphs): - A_dense, A_sparse = graphs - func = spgraph.min_weight_full_bipartite_matching - - actual = func(A_sparse[0:2, 1:3]) - desired = func(sp.csc_matrix(A_dense)[0:2, 1:3]) - - assert_equal(actual, desired) - - -@check_sparse_version("0.15.4") -@pytest.mark.parametrize( - "func", - [ - spgraph.shortest_path, - spgraph.dijkstra, - spgraph.floyd_warshall, - spgraph.bellman_ford, - spgraph.johnson, - spgraph.minimum_spanning_tree, - ] -) -@pytest.mark.parametrize( - "fill_value, comp_func", - [(np.inf, np.isposinf), (np.nan, np.isnan)], -) -def test_nonzero_fill_value(graphs, func, fill_value, comp_func): - A_dense, A_sparse = graphs - A_sparse = A_sparse.astype(float) - A_sparse.fill_value = fill_value - sparse_cls = type(A_sparse) - - actual = func(A_sparse) - desired = func(sp.csc_matrix(A_dense)) - - if func == spgraph.minimum_spanning_tree: - assert isinstance(actual, sparse_cls) - assert comp_func(actual.fill_value) - actual = actual.todense() - actual[comp_func(actual)] = 0.0 - assert_equal(actual, desired.todense()) - else: - assert_equal(actual, desired) diff --git a/tests/csgraph/test_reordering.py b/tests/csgraph/test_reordering.py deleted file mode 100644 index cb4c002fa3..0000000000 --- a/tests/csgraph/test_reordering.py +++ /dev/null @@ -1,70 +0,0 @@ -import numpy as np -from numpy.testing import assert_equal -from scipy.sparse.csgraph import reverse_cuthill_mckee, structural_rank -from scipy.sparse import csc_matrix, csr_matrix, coo_matrix - - -def test_graph_reverse_cuthill_mckee(): - A = np.array([[1, 0, 0, 0, 1, 0, 0, 0], - [0, 1, 1, 0, 0, 1, 0, 1], - [0, 1, 1, 0, 1, 0, 0, 0], - [0, 0, 0, 1, 0, 0, 1, 0], - [1, 0, 1, 0, 1, 0, 0, 0], - [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_matrix(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') - perm = reverse_cuthill_mckee(graph, True) - assert_equal(perm, correct_perm) - - -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, - 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, - 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, - 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, - 5, 7, 10, 13, 15]) - graph = coo_matrix((data, (rows,cols))).tocsr() - perm = reverse_cuthill_mckee(graph) - correct_perm = np.array([12, 14, 4, 6, 10, 8, 2, 15, - 0, 13, 7, 5, 9, 11, 1, 3]) - assert_equal(perm, correct_perm) - - -def test_graph_structural_rank(): - # Test square matrix #1 - A = csc_matrix([[1, 1, 0], - [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_matrix((data,(rows,cols)), shape=(8,8)) - assert_equal(structural_rank(B), 6) - - #Test non-square matrix - C = csc_matrix([[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/tests/csgraph/test_shortest_path.py b/tests/csgraph/test_shortest_path.py deleted file mode 100644 index 45600352e8..0000000000 --- a/tests/csgraph/test_shortest_path.py +++ /dev/null @@ -1,484 +0,0 @@ -from io import StringIO -import warnings -import numpy as np -from numpy.testing import assert_array_almost_equal, assert_array_equal, assert_allclose -from pytest import raises as assert_raises -from scipy.sparse.csgraph import (shortest_path, dijkstra, johnson, - bellman_ford, construct_dist_matrix, yen, - NegativeCycleError) -import scipy.sparse -from scipy.io import mmread -import pytest - -directed_G = np.array([[0, 3, 3, 0, 0], - [0, 0, 0, 2, 4], - [0, 0, 0, 0, 0], - [1, 0, 0, 0, 0], - [2, 0, 0, 2, 0]], dtype=float) - -undirected_G = np.array([[0, 3, 3, 1, 2], - [3, 0, 0, 2, 4], - [3, 0, 0, 0, 0], - [1, 2, 0, 0, 2], - [2, 4, 0, 2, 0]], dtype=float) - -unweighted_G = (directed_G > 0).astype(float) - -directed_SP = [[0, 3, 3, 5, 7], - [3, 0, 6, 2, 4], - [np.inf, np.inf, 0, np.inf, np.inf], - [1, 4, 4, 0, 8], - [2, 5, 5, 2, 0]] - -directed_2SP_0_to_3 = [[-9999, 0, -9999, 1, -9999], - [-9999, 0, -9999, 4, 1]] - -directed_sparse_zero_G = scipy.sparse.csr_matrix( - ( - [0, 1, 2, 3, 1], - ([0, 1, 2, 3, 4], [1, 2, 0, 4, 3]), - ), - shape=(5, 5), -) - -directed_sparse_zero_SP = [[0, 0, 1, np.inf, np.inf], - [3, 0, 1, np.inf, np.inf], - [2, 2, 0, np.inf, np.inf], - [np.inf, np.inf, np.inf, 0, 3], - [np.inf, np.inf, np.inf, 1, 0]] - -undirected_sparse_zero_G = scipy.sparse.csr_matrix( - ( - [0, 0, 1, 1, 2, 2, 1, 1], - ([0, 1, 1, 2, 2, 0, 3, 4], [1, 0, 2, 1, 0, 2, 4, 3]) - ), - shape=(5, 5), -) - -undirected_sparse_zero_SP = [[0, 0, 1, np.inf, np.inf], - [0, 0, 1, np.inf, np.inf], - [1, 1, 0, np.inf, np.inf], - [np.inf, np.inf, np.inf, 0, 1], - [np.inf, np.inf, np.inf, 1, 0]] - -directed_pred = np.array([[-9999, 0, 0, 1, 1], - [3, -9999, 0, 1, 1], - [-9999, -9999, -9999, -9999, -9999], - [3, 0, 0, -9999, 1], - [4, 0, 0, 4, -9999]], dtype=float) - -undirected_SP = np.array([[0, 3, 3, 1, 2], - [3, 0, 6, 2, 4], - [3, 6, 0, 4, 5], - [1, 2, 4, 0, 2], - [2, 4, 5, 2, 0]], dtype=float) - -undirected_SP_limit_2 = np.array([[0, np.inf, np.inf, 1, 2], - [np.inf, 0, np.inf, 2, np.inf], - [np.inf, np.inf, 0, np.inf, np.inf], - [1, 2, np.inf, 0, 2], - [2, np.inf, np.inf, 2, 0]], dtype=float) - -undirected_SP_limit_0 = np.ones((5, 5), dtype=float) - np.eye(5) -undirected_SP_limit_0[undirected_SP_limit_0 > 0] = np.inf - -undirected_pred = np.array([[-9999, 0, 0, 0, 0], - [1, -9999, 0, 1, 1], - [2, 0, -9999, 0, 0], - [3, 3, 0, -9999, 3], - [4, 4, 0, 4, -9999]], dtype=float) - -directed_negative_weighted_G = np.array([[0, 0, 0], - [-1, 0, 0], - [0, -1, 0]], dtype=float) - -directed_negative_weighted_SP = np.array([[0, np.inf, np.inf], - [-1, 0, np.inf], - [-2, -1, 0]], dtype=float) - -methods = ['auto', 'FW', 'D', 'BF', 'J'] - - -def test_dijkstra_limit(): - limits = [0, 2, np.inf] - results = [undirected_SP_limit_0, - undirected_SP_limit_2, - undirected_SP] - - def check(limit, result): - SP = dijkstra(undirected_G, directed=False, limit=limit) - assert_array_almost_equal(SP, result) - - for limit, result in zip(limits, results): - check(limit, result) - - -def test_directed(): - def check(method): - SP = shortest_path(directed_G, method=method, directed=True, - overwrite=False) - assert_array_almost_equal(SP, directed_SP) - - for method in methods: - check(method) - - -def test_undirected(): - def check(method, directed_in): - if directed_in: - SP1 = shortest_path(directed_G, method=method, directed=False, - overwrite=False) - assert_array_almost_equal(SP1, undirected_SP) - else: - SP2 = shortest_path(undirected_G, method=method, directed=True, - overwrite=False) - assert_array_almost_equal(SP2, undirected_SP) - - for method in methods: - for directed_in in (True, False): - check(method, directed_in) - - -def test_directed_sparse_zero(): - # test directed sparse graph with zero-weight edge and two connected components - def check(method): - SP = shortest_path(directed_sparse_zero_G, method=method, directed=True, - overwrite=False) - assert_array_almost_equal(SP, directed_sparse_zero_SP) - - for method in methods: - check(method) - - -def test_undirected_sparse_zero(): - def check(method, directed_in): - if directed_in: - SP1 = shortest_path(directed_sparse_zero_G, method=method, directed=False, - overwrite=False) - assert_array_almost_equal(SP1, undirected_sparse_zero_SP) - else: - SP2 = shortest_path(undirected_sparse_zero_G, method=method, directed=True, - overwrite=False) - assert_array_almost_equal(SP2, undirected_sparse_zero_SP) - - for method in methods: - for directed_in in (True, False): - check(method, directed_in) - - -@pytest.mark.parametrize('directed, SP_ans', - ((True, directed_SP), - (False, undirected_SP))) -@pytest.mark.parametrize('indices', ([0, 2, 4], [0, 4], [3, 4], [0, 0])) -def test_dijkstra_indices_min_only(directed, SP_ans, indices): - SP_ans = np.array(SP_ans) - indices = np.array(indices, dtype=np.int64) - min_ind_ans = indices[np.argmin(SP_ans[indices, :], axis=0)] - min_d_ans = np.zeros(SP_ans.shape[0], SP_ans.dtype) - for k in range(SP_ans.shape[0]): - min_d_ans[k] = SP_ans[min_ind_ans[k], k] - min_ind_ans[np.isinf(min_d_ans)] = -9999 - - SP, pred, sources = dijkstra(directed_G, - directed=directed, - indices=indices, - min_only=True, - return_predecessors=True) - assert_array_almost_equal(SP, min_d_ans) - assert_array_equal(min_ind_ans, sources) - SP = dijkstra(directed_G, - directed=directed, - indices=indices, - min_only=True, - return_predecessors=False) - assert_array_almost_equal(SP, min_d_ans) - - -@pytest.mark.parametrize('n', (10, 100, 1000)) -def test_dijkstra_min_only_random(n): - np.random.seed(1234) - data = scipy.sparse.rand(n, n, density=0.5, format='lil', - random_state=42, dtype=np.float64) - data.setdiag(np.zeros(n, dtype=np.bool_)) - # choose some random vertices - v = np.arange(n) - np.random.shuffle(v) - indices = v[:int(n*.1)] - ds, pred, sources = dijkstra(data, - directed=True, - indices=indices, - min_only=True, - return_predecessors=True) - for k in range(n): - p = pred[k] - s = sources[k] - while p != -9999: - assert sources[p] == s - p = pred[p] - - -def test_dijkstra_random(): - # reproduces the hang observed in gh-17782 - n = 10 - indices = [0, 4, 4, 5, 7, 9, 0, 6, 2, 3, 7, 9, 1, 2, 9, 2, 5, 6] - indptr = [0, 0, 2, 5, 6, 7, 8, 12, 15, 18, 18] - data = [0.33629, 0.40458, 0.47493, 0.42757, 0.11497, 0.91653, 0.69084, - 0.64979, 0.62555, 0.743, 0.01724, 0.99945, 0.31095, 0.15557, - 0.02439, 0.65814, 0.23478, 0.24072] - graph = scipy.sparse.csr_matrix((data, indices, indptr), shape=(n, n)) - dijkstra(graph, directed=True, return_predecessors=True) - - -def test_gh_17782_segfault(): - text = """%%MatrixMarket matrix coordinate real general - 84 84 22 - 2 1 4.699999809265137e+00 - 6 14 1.199999973177910e-01 - 9 6 1.199999973177910e-01 - 10 16 2.012000083923340e+01 - 11 10 1.422000026702881e+01 - 12 1 9.645999908447266e+01 - 13 18 2.012000083923340e+01 - 14 13 4.679999828338623e+00 - 15 11 1.199999973177910e-01 - 16 12 1.199999973177910e-01 - 18 15 1.199999973177910e-01 - 32 2 2.299999952316284e+00 - 33 20 6.000000000000000e+00 - 33 32 5.000000000000000e+00 - 36 9 3.720000028610229e+00 - 36 37 3.720000028610229e+00 - 36 38 3.720000028610229e+00 - 37 44 8.159999847412109e+00 - 38 32 7.903999328613281e+01 - 43 20 2.400000000000000e+01 - 43 33 4.000000000000000e+00 - 44 43 6.028000259399414e+01 - """ - data = mmread(StringIO(text)) - dijkstra(data, directed=True, return_predecessors=True) - - -def test_shortest_path_indices(): - indices = np.arange(4) - - def check(func, indshape): - outshape = indshape + (5,) - SP = func(directed_G, directed=False, - indices=indices.reshape(indshape)) - assert_array_almost_equal(SP, undirected_SP[indices].reshape(outshape)) - - for indshape in [(4,), (4, 1), (2, 2)]: - for func in (dijkstra, bellman_ford, johnson, shortest_path): - check(func, indshape) - - assert_raises(ValueError, shortest_path, directed_G, method='FW', - indices=indices) - - -def test_predecessors(): - SP_res = {True: directed_SP, - False: undirected_SP} - pred_res = {True: directed_pred, - False: undirected_pred} - - def check(method, directed): - SP, pred = shortest_path(directed_G, method, directed=directed, - overwrite=False, - return_predecessors=True) - assert_array_almost_equal(SP, SP_res[directed]) - assert_array_almost_equal(pred, pred_res[directed]) - - for method in methods: - for directed in (True, False): - check(method, directed) - - -def test_construct_shortest_path(): - def check(method, directed): - SP1, pred = shortest_path(directed_G, - directed=directed, - overwrite=False, - return_predecessors=True) - SP2 = construct_dist_matrix(directed_G, pred, directed=directed) - assert_array_almost_equal(SP1, SP2) - - for method in methods: - for directed in (True, False): - check(method, directed) - - -def test_unweighted_path(): - def check(method, directed): - SP1 = shortest_path(directed_G, - directed=directed, - overwrite=False, - unweighted=True) - SP2 = shortest_path(unweighted_G, - directed=directed, - overwrite=False, - unweighted=False) - assert_array_almost_equal(SP1, SP2) - - for method in methods: - for directed in (True, False): - check(method, directed) - - -def test_negative_cycles(): - # create a small graph with a negative cycle - graph = np.ones([5, 5]) - graph.flat[::6] = 0 - graph[1, 2] = -2 - - def check(method, directed): - assert_raises(NegativeCycleError, shortest_path, graph, method, - directed) - - for directed in (True, False): - for method in ['FW', 'J', 'BF']: - check(method, directed) - - assert_raises(NegativeCycleError, yen, graph, 0, 1, 1, - directed=directed) - - -@pytest.mark.parametrize("method", ['FW', 'J', 'BF']) -def test_negative_weights(method): - SP = shortest_path(directed_negative_weighted_G, method, directed=True) - assert_allclose(SP, directed_negative_weighted_SP, atol=1e-10) - - -def test_masked_input(): - np.ma.masked_equal(directed_G, 0) - - def check(method): - SP = shortest_path(directed_G, method=method, directed=True, - overwrite=False) - assert_array_almost_equal(SP, directed_SP) - - for method in methods: - check(method) - - -def test_overwrite(): - G = np.array([[0, 3, 3, 1, 2], - [3, 0, 0, 2, 4], - [3, 0, 0, 0, 0], - [1, 2, 0, 0, 2], - [2, 4, 0, 2, 0]], dtype=float) - foo = G.copy() - shortest_path(foo, overwrite=False) - assert_array_equal(foo, G) - - -@pytest.mark.parametrize('method', methods) -def test_buffer(method): - # Smoke test that sparse matrices with read-only buffers (e.g., those from - # joblib workers) do not cause:: - # - # ValueError: buffer source array is read-only - # - G = scipy.sparse.csr_matrix([[1.]]) - G.data.flags['WRITEABLE'] = False - shortest_path(G, method=method) - - -def test_NaN_warnings(): - with warnings.catch_warnings(record=True) as record: - shortest_path(np.array([[0, 1], [np.nan, 0]])) - for r in record: - assert r.category is not RuntimeWarning - - -def test_sparse_matrices(): - # Test that using lil,csr and csc sparse matrix do not cause error - G_dense = np.array([[0, 3, 0, 0, 0], - [0, 0, -1, 0, 0], - [0, 0, 0, 2, 0], - [0, 0, 0, 0, 4], - [0, 0, 0, 0, 0]], dtype=float) - SP = shortest_path(G_dense) - G_csr = scipy.sparse.csr_matrix(G_dense) - G_csc = scipy.sparse.csc_matrix(G_dense) - G_lil = scipy.sparse.lil_matrix(G_dense) - assert_array_almost_equal(SP, shortest_path(G_csr)) - assert_array_almost_equal(SP, shortest_path(G_csc)) - assert_array_almost_equal(SP, shortest_path(G_lil)) - - -def test_yen_directed(): - distances, predecessors = yen( - directed_G, - source=0, - sink=3, - K=2, - return_predecessors=True - ) - assert_allclose(distances, [5., 9.]) - assert_allclose(predecessors, directed_2SP_0_to_3) - - -def test_yen_undirected(): - distances = yen( - undirected_G, - source=0, - sink=3, - K=4, - ) - assert_allclose(distances, [1., 4., 5., 8.]) - -def test_yen_unweighted(): - # Ask for more paths than there are, verify only the available paths are returned - distances, predecessors = yen( - directed_G, - source=0, - sink=3, - K=4, - unweighted=True, - return_predecessors=True, - ) - assert_allclose(distances, [2., 3.]) - assert_allclose(predecessors, directed_2SP_0_to_3) - -def test_yen_no_paths(): - distances = yen( - directed_G, - source=2, - sink=3, - K=1, - ) - assert distances.size == 0 - -def test_yen_negative_weights(): - distances = yen( - directed_negative_weighted_G, - source=2, - sink=0, - K=1, - ) - assert_allclose(distances, [-2.]) - - -@pytest.mark.parametrize("min_only", (True, False)) -@pytest.mark.parametrize("directed", (True, False)) -@pytest.mark.parametrize("return_predecessors", (True, False)) -@pytest.mark.parametrize("index_dtype", (np.int32, np.int64)) -@pytest.mark.parametrize("indices", (None, [1])) -def test_20904(min_only, directed, return_predecessors, index_dtype, indices): - """Test two failures from gh-20904: int32 and indices-as-None.""" - adj_mat = scipy.sparse.eye(4, format="csr") - adj_mat = scipy.sparse.csr_array( - ( - adj_mat.data, - adj_mat.indices.astype(index_dtype), - adj_mat.indptr.astype(index_dtype), - ), - ) - dijkstra( - adj_mat, - directed, - indices=indices, - min_only=min_only, - return_predecessors=return_predecessors, - ) diff --git a/tests/csgraph/test_spanning_tree.py b/tests/csgraph/test_spanning_tree.py deleted file mode 100644 index 90ef6d1b1b..0000000000 --- a/tests/csgraph/test_spanning_tree.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Test the minimum spanning tree function""" -import numpy as np -from numpy.testing import assert_ -import numpy.testing as npt -from scipy.sparse import csr_matrix -from scipy.sparse.csgraph import minimum_spanning_tree - - -def test_minimum_spanning_tree(): - - # Create a graph with two connected components. - graph = [[0,1,0,0,0], - [1,0,0,0,0], - [0,0,0,8,5], - [0,0,8,0,1], - [0,0,5,1,0]] - graph = np.asarray(graph) - - # Create the expected spanning tree. - expected = [[0,1,0,0,0], - [0,0,0,0,0], - [0,0,0,0,5], - [0,0,0,0,1], - [0,0,0,0,0]] - expected = np.asarray(expected) - - # Ensure minimum spanning tree code gives this expected output. - csgraph = csr_matrix(graph) - mintree = minimum_spanning_tree(csgraph) - mintree_array = mintree.toarray() - npt.assert_array_equal(mintree_array, expected, - 'Incorrect spanning tree found.') - - # Ensure that the original graph was not modified. - npt.assert_array_equal(csgraph.toarray(), graph, - 'Original graph was modified.') - - # Now let the algorithm modify the csgraph in place. - mintree = minimum_spanning_tree(csgraph, overwrite=True) - npt.assert_array_equal(mintree.toarray(), expected, - 'Graph was not properly modified to contain MST.') - - np.random.seed(1234) - for N in (5, 10, 15, 20): - - # Create a random graph. - graph = 3 + np.random.random((N, N)) - csgraph = csr_matrix(graph) - - # The spanning tree has at most N - 1 edges. - mintree = minimum_spanning_tree(csgraph) - assert_(mintree.nnz < N) - - # Set the sub diagonal to 1 to create a known spanning tree. - idx = np.arange(N-1) - graph[idx,idx+1] = 1 - csgraph = csr_matrix(graph) - mintree = minimum_spanning_tree(csgraph) - - # We expect to see this pattern in the spanning tree and otherwise - # have this zero. - expected = np.zeros((N, N)) - expected[idx, idx+1] = 1 - - npt.assert_array_equal(mintree.toarray(), expected, - 'Incorrect spanning tree found.') diff --git a/tests/csgraph/test_traversal.py b/tests/csgraph/test_traversal.py deleted file mode 100644 index 414e2d1486..0000000000 --- a/tests/csgraph/test_traversal.py +++ /dev/null @@ -1,81 +0,0 @@ -import numpy as np -import pytest -from numpy.testing import assert_array_almost_equal -from scipy.sparse import csr_array -from scipy.sparse.csgraph import (breadth_first_tree, depth_first_tree, - csgraph_to_dense, csgraph_from_dense) - - -def test_graph_breadth_first(): - csgraph = np.array([[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]]) - csgraph = csgraph_from_dense(csgraph, null_value=0) - - bfirst = np.array([[0, 1, 2, 0, 0], - [0, 0, 0, 0, 3], - [0, 0, 0, 7, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0]]) - - for directed in [True, False]: - bfirst_test = breadth_first_tree(csgraph, 0, directed) - assert_array_almost_equal(csgraph_to_dense(bfirst_test), - bfirst) - - -def test_graph_depth_first(): - csgraph = np.array([[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]]) - csgraph = csgraph_from_dense(csgraph, null_value=0) - - dfirst = np.array([[0, 1, 0, 0, 0], - [0, 0, 0, 0, 3], - [0, 0, 0, 0, 0], - [0, 0, 7, 0, 0], - [0, 0, 0, 1, 0]]) - - for directed in [True, False]: - dfirst_test = depth_first_tree(csgraph, 0, directed) - assert_array_almost_equal(csgraph_to_dense(dfirst_test), - dfirst) - - -def test_graph_breadth_first_trivial_graph(): - csgraph = np.array([[0]]) - csgraph = csgraph_from_dense(csgraph, null_value=0) - - bfirst = np.array([[0]]) - - for directed in [True, False]: - bfirst_test = breadth_first_tree(csgraph, 0, directed) - assert_array_almost_equal(csgraph_to_dense(bfirst_test), - bfirst) - - -def test_graph_depth_first_trivial_graph(): - csgraph = np.array([[0]]) - csgraph = csgraph_from_dense(csgraph, null_value=0) - - bfirst = np.array([[0]]) - - for directed in [True, False]: - bfirst_test = depth_first_tree(csgraph, 0, directed) - assert_array_almost_equal(csgraph_to_dense(bfirst_test), - bfirst) - - -@pytest.mark.parametrize('directed', [True, False]) -@pytest.mark.parametrize('tree_func', [breadth_first_tree, depth_first_tree]) -def test_int64_indices(tree_func, directed): - # See https://github.com/scipy/scipy/issues/18716 - g = csr_array(([1], np.array([[0], [1]], dtype=np.int64)), shape=(2, 2)) - assert g.indices.dtype == np.int64 - tree = tree_func(g, 0, directed=directed) - assert_array_almost_equal(csgraph_to_dense(tree), [[0, 1], [0, 0]]) -