Skip to content

Commit b0f1a81

Browse files
authored
Add tests for scipy.sparse.csgraph and scipy.sparse.linalg (#683)
* Add tests for scipy.sparse.csgraph and linalg * Separate tests * Add parameters
1 parent 554cc7b commit b0f1a81

File tree

4 files changed

+161
-11
lines changed

4 files changed

+161
-11
lines changed

ci/array-api-skips.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error
2+
array_api_tests/test_special_cases.py::test_unary[sign((x_i is -0 or x_i == +0)) -> 0]

ci/array-api-xfails.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i
303303
array_api_tests/test_special_cases.py::test_unary[signbit(isfinite(x_i) and x_i < 0) -> True]
304304
array_api_tests/test_special_cases.py::test_unary[signbit(x_i is NaN) -> False]
305305
array_api_tests/test_special_cases.py::test_unary[signbit(x_i is NaN) -> True]
306-
array_api_tests/test_special_cases.py::test_unary[sign((x_i is -0 or x_i == +0)) -> 0]
307306
array_api_tests/test_special_cases.py::test_unary[sin((x_i is +infinity or x_i == -infinity)) -> NaN]
308307
array_api_tests/test_special_cases.py::test_unary[sqrt(x_i < 0) -> NaN]
309308
array_api_tests/test_special_cases.py::test_unary[tan((x_i is +infinity or x_i == -infinity)) -> NaN]

sparse/tests/conftest.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,23 @@
22

33
import pytest
44

5+
import numpy as np
6+
57

68
@pytest.fixture(scope="session", params=[sparse.BackendType.Numba, sparse.BackendType.Finch])
79
def backend(request):
810
with sparse.Backend(backend=request.param):
911
yield request.param
12+
13+
14+
@pytest.fixture(scope="module")
15+
def graph():
16+
return np.array(
17+
[
18+
[0, 1, 1, 0, 0],
19+
[0, 0, 1, 0, 1],
20+
[0, 0, 0, 0, 0],
21+
[0, 0, 0, 0, 1],
22+
[0, 1, 0, 1, 0],
23+
]
24+
)

sparse/tests/test_backends.py

Lines changed: 145 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import pytest
44

55
import numpy as np
6-
import scipy.sparse as sp
6+
import scipy as sp
7+
import scipy.sparse as sps
8+
import scipy.sparse.csgraph as spgraph
79
import scipy.sparse.linalg as splin
810
from numpy.testing import assert_almost_equal, assert_equal
911

@@ -32,7 +34,7 @@ def storage():
3234

3335
def test_finch_backend():
3436
np_eye = np.eye(5)
35-
sp_arr = sp.csr_matrix(np_eye)
37+
sp_arr = sps.csr_matrix(np_eye)
3638

3739
with sparse.Backend(backend=sparse.BackendType.Finch):
3840
import finch
@@ -69,19 +71,152 @@ def test_asarray(backend, format, order):
6971

7072

7173
@pytest.mark.parametrize("format, order", [("csc", "F"), ("csr", "C"), ("coo", "F"), ("coo", "C")])
72-
def test_scipy_sparse_dispatch(backend, format, order):
74+
def test_scipy_spsolve(backend, format, order):
7375
x = np.eye(10, order=order) * 2
7476
y = np.ones((10, 1), order=order)
77+
x_pydata = sparse.asarray(x, format=format)
78+
y_pydata = sparse.asarray(y, format="coo")
7579

76-
x_sp = sparse.asarray(x, format=format)
77-
y_sp = sparse.asarray(y, format="coo")
78-
79-
actual = splin.spsolve(x_sp, y_sp)
80+
actual = splin.spsolve(x_pydata, y_pydata)
8081
expected = np.linalg.solve(x, y.ravel())
81-
8282
assert_almost_equal(actual, expected)
8383

84-
actual = splin.inv(x_sp)
85-
expected = np.linalg.inv(x)
8684

85+
@pytest.mark.parametrize("format, order", [("csc", "F"), ("csr", "C"), ("coo", "F"), ("coo", "C")])
86+
def test_scipy_inv(backend, format, order):
87+
x = np.eye(10, order=order) * 2
88+
x_pydata = sparse.asarray(x, format=format)
89+
90+
actual = splin.inv(x_pydata)
91+
expected = np.linalg.inv(x)
8792
assert_almost_equal(actual.todense(), expected)
93+
94+
95+
@pytest.mark.skip(reason="https://github.com/scipy/scipy/pull/20759")
96+
@pytest.mark.parametrize("format, order", [("csc", "F"), ("csr", "C"), ("coo", "F"), ("coo", "C")])
97+
def test_scipy_norm(backend, format, order):
98+
x = np.eye(10, order=order) * 2
99+
x_pydata = sparse.asarray(x, format=format)
100+
101+
actual = splin.norm(x_pydata)
102+
expected = sp.linalg.norm(x)
103+
assert_almost_equal(actual, expected)
104+
105+
106+
@pytest.mark.skip(reason="https://github.com/scipy/scipy/pull/20759")
107+
@pytest.mark.parametrize("format, order", [("csc", "F"), ("csr", "C"), ("coo", "F"), ("coo", "C")])
108+
def test_scipy_lsqr(backend, format, order):
109+
x = np.eye(10, order=order) * 2
110+
y = np.ones((10, 1), order=order)
111+
x_pydata = sparse.asarray(x, format=format)
112+
113+
actual_x, _ = splin.lsqr(x_pydata, y)[:2]
114+
expected_x, _ = sp.linalg.lstsq(x, y)[:2]
115+
assert_almost_equal(actual_x, expected_x.ravel())
116+
117+
118+
@pytest.mark.skip(reason="https://github.com/scipy/scipy/pull/20759")
119+
@pytest.mark.parametrize("format, order", [("csc", "F"), ("csr", "C"), ("coo", "F"), ("coo", "C")])
120+
def test_scipy_eigs(backend, format, order):
121+
x = np.eye(10, order=order) * 2
122+
x_pydata = sparse.asarray(x, format=format)
123+
x_sp = sps.coo_matrix(x)
124+
125+
actual_vals, _ = splin.eigs(x_pydata, k=3)
126+
expected_vals, _ = splin.eigs(x_sp, k=3)
127+
assert_almost_equal(actual_vals, expected_vals)
128+
129+
130+
@pytest.mark.parametrize(
131+
"matrix_fn, format, order",
132+
[(sps.csc_matrix, "csc", "F"), (sps.csr_matrix, "csr", "C"), (sps.coo_matrix, "coo", "F")],
133+
)
134+
def test_scipy_connected_components(backend, graph, matrix_fn, format, order):
135+
graph = matrix_fn(np.array(graph, order=order))
136+
sp_graph = sparse.asarray(graph, format=format)
137+
138+
actual_n_components, actual_labels = spgraph.connected_components(sp_graph)
139+
expected_n_components, expected_labels = spgraph.connected_components(graph)
140+
assert actual_n_components == expected_n_components
141+
assert_equal(actual_labels, expected_labels)
142+
143+
144+
@pytest.mark.parametrize(
145+
"matrix_fn, format, order",
146+
[(sps.csc_matrix, "csc", "F"), (sps.csr_matrix, "csr", "C"), (sps.coo_matrix, "coo", "F")],
147+
)
148+
def test_scipy_laplacian(backend, graph, matrix_fn, format, order):
149+
graph = matrix_fn(np.array(graph, order=order))
150+
sp_graph = sparse.asarray(graph, format=format)
151+
152+
actual_lap = spgraph.laplacian(sp_graph)
153+
expected_lap = spgraph.laplacian(graph)
154+
assert_equal(actual_lap.todense(), expected_lap.toarray())
155+
156+
157+
@pytest.mark.parametrize("matrix_fn, format, order", [(sps.csc_matrix, "csc", "F"), (sps.csr_matrix, "csr", "C")])
158+
def test_scipy_shortest_path(backend, graph, matrix_fn, format, order):
159+
graph = matrix_fn(np.array(graph, order=order))
160+
sp_graph = sparse.asarray(graph, format=format)
161+
162+
actual_dist_matrix, actual_predecessors = spgraph.shortest_path(sp_graph, return_predecessors=True)
163+
expected_dist_matrix, expected_predecessors = spgraph.shortest_path(graph, return_predecessors=True)
164+
assert_equal(actual_dist_matrix, expected_dist_matrix)
165+
assert_equal(actual_predecessors, expected_predecessors)
166+
167+
168+
@pytest.mark.parametrize(
169+
"matrix_fn, format, order",
170+
[(sps.csc_matrix, "csc", "F"), (sps.csr_matrix, "csr", "C"), (sps.coo_matrix, "coo", "F")],
171+
)
172+
def test_scipy_breadth_first_tree(backend, graph, matrix_fn, format, order):
173+
graph = matrix_fn(np.array(graph, order=order))
174+
sp_graph = sparse.asarray(graph, format=format)
175+
176+
actual_bft = spgraph.breadth_first_tree(sp_graph, 0, directed=False)
177+
expected_bft = spgraph.breadth_first_tree(graph, 0, directed=False)
178+
assert_equal(actual_bft.todense(), expected_bft.toarray())
179+
180+
181+
@pytest.mark.parametrize(
182+
"matrix_fn, format, order",
183+
[(sps.csc_matrix, "csc", "F"), (sps.csr_matrix, "csr", "C"), (sps.coo_matrix, "coo", "F")],
184+
)
185+
def test_scipy_dijkstra(backend, graph, matrix_fn, format, order):
186+
graph = matrix_fn(np.array(graph, order=order))
187+
sp_graph = sparse.asarray(graph, format=format)
188+
189+
actual_dist_matrix = spgraph.dijkstra(sp_graph, directed=False)
190+
expected_dist_matrix = spgraph.dijkstra(graph, directed=False)
191+
assert_equal(actual_dist_matrix, expected_dist_matrix)
192+
193+
194+
@pytest.mark.parametrize(
195+
"matrix_fn, format, order",
196+
[(sps.csc_matrix, "csc", "F"), (sps.csr_matrix, "csr", "C"), (sps.coo_matrix, "coo", "F")],
197+
)
198+
def test_scipy_minimum_spanning_tree(backend, graph, matrix_fn, format, order):
199+
graph = matrix_fn(np.array(graph, order=order))
200+
sp_graph = sparse.asarray(graph, format=format)
201+
202+
actual_span_tree = spgraph.minimum_spanning_tree(sp_graph)
203+
expected_span_tree = spgraph.minimum_spanning_tree(graph)
204+
assert_equal(actual_span_tree.todense(), expected_span_tree.toarray())
205+
206+
207+
@pytest.mark.skip(reason="https://github.com/scikit-learn/scikit-learn/pull/29031")
208+
@pytest.mark.parametrize("matrix_fn, format, order", [(sps.csc_matrix, "csc", "F")])
209+
def test_scikit_learn_dispatch(backend, graph, matrix_fn, format, order):
210+
from sklearn.cluster import KMeans
211+
212+
graph = matrix_fn(np.array(graph, order=order))
213+
214+
sp_graph = sparse.asarray(graph, format=format)
215+
216+
neigh = KMeans(n_clusters=2)
217+
actual_labels = neigh.fit_predict(sp_graph)
218+
219+
neigh = KMeans(n_clusters=2)
220+
expected_labels = neigh.fit_predict(graph)
221+
222+
assert_equal(actual_labels, expected_labels)

0 commit comments

Comments
 (0)