add padding function to imgScalePadding()
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,339 +0,0 @@
|
||||
import pytest
|
||||
import numpy as np
|
||||
import numpy.testing as npt
|
||||
import scipy.sparse
|
||||
import scipy.sparse.linalg as spla
|
||||
|
||||
sparray_types = ('bsr', 'coo', 'csc', 'csr', 'dia', 'dok', 'lil')
|
||||
|
||||
sparray_classes = [
|
||||
getattr(scipy.sparse, f'{T}_array') for T in sparray_types
|
||||
]
|
||||
|
||||
A = np.array([
|
||||
[0, 1, 2, 0],
|
||||
[2, 0, 0, 3],
|
||||
[1, 4, 0, 0]
|
||||
])
|
||||
|
||||
B = np.array([
|
||||
[0, 1],
|
||||
[2, 0]
|
||||
])
|
||||
|
||||
X = np.array([
|
||||
[1, 0, 0, 1],
|
||||
[2, 1, 2, 0],
|
||||
[0, 2, 1, 0],
|
||||
[0, 0, 1, 2]
|
||||
], dtype=float)
|
||||
|
||||
|
||||
sparrays = [sparray(A) for sparray in sparray_classes]
|
||||
square_sparrays = [sparray(B) for sparray in sparray_classes]
|
||||
eig_sparrays = [sparray(X) for sparray in sparray_classes]
|
||||
|
||||
parametrize_sparrays = pytest.mark.parametrize(
|
||||
"A", sparrays, ids=sparray_types
|
||||
)
|
||||
parametrize_square_sparrays = pytest.mark.parametrize(
|
||||
"B", square_sparrays, ids=sparray_types
|
||||
)
|
||||
parametrize_eig_sparrays = pytest.mark.parametrize(
|
||||
"X", eig_sparrays, ids=sparray_types
|
||||
)
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_sum(A):
|
||||
assert not isinstance(A.sum(axis=0), np.matrix), \
|
||||
"Expected array, got matrix"
|
||||
assert A.sum(axis=0).shape == (4,)
|
||||
assert A.sum(axis=1).shape == (3,)
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_mean(A):
|
||||
assert not isinstance(A.mean(axis=1), np.matrix), \
|
||||
"Expected array, got matrix"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_todense(A):
|
||||
assert not isinstance(A.todense(), np.matrix), \
|
||||
"Expected array, got matrix"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_indexing(A):
|
||||
if A.__class__.__name__[:3] in ('dia', 'coo', 'bsr'):
|
||||
return
|
||||
|
||||
with pytest.raises(NotImplementedError):
|
||||
A[1, :]
|
||||
|
||||
with pytest.raises(NotImplementedError):
|
||||
A[:, 1]
|
||||
|
||||
with pytest.raises(NotImplementedError):
|
||||
A[1, [1, 2]]
|
||||
|
||||
with pytest.raises(NotImplementedError):
|
||||
A[[1, 2], 1]
|
||||
|
||||
assert A[[0]]._is_array, "Expected sparse array, got sparse matrix"
|
||||
assert A[1, [[1, 2]]]._is_array, "Expected ndarray, got sparse array"
|
||||
assert A[[[1, 2]], 1]._is_array, "Expected ndarray, got sparse array"
|
||||
assert A[:, [1, 2]]._is_array, "Expected sparse array, got something else"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_dense_addition(A):
|
||||
X = np.random.random(A.shape)
|
||||
assert not isinstance(A + X, np.matrix), "Expected array, got matrix"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_sparse_addition(A):
|
||||
assert (A + A)._is_array, "Expected array, got matrix"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_elementwise_mul(A):
|
||||
assert np.all((A * A).todense() == A.power(2).todense())
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_elementwise_rmul(A):
|
||||
with pytest.raises(TypeError):
|
||||
None * A
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
np.eye(3) * scipy.sparse.csr_array(np.arange(6).reshape(2, 3))
|
||||
|
||||
assert np.all((2 * A) == (A.todense() * 2))
|
||||
|
||||
assert np.all((A.todense() * A) == (A.todense() ** 2))
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_matmul(A):
|
||||
assert np.all((A @ A.T).todense() == A.dot(A.T).todense())
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_pow(B):
|
||||
assert (B**0)._is_array, "Expected array, got matrix"
|
||||
assert (B**2)._is_array, "Expected array, got matrix"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_sparse_divide(A):
|
||||
assert isinstance(A / A, np.ndarray)
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_dense_divide(A):
|
||||
assert (A / 2)._is_array, "Expected array, got matrix"
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_no_A_attr(A):
|
||||
with pytest.warns(np.VisibleDeprecationWarning):
|
||||
A.A
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_no_H_attr(A):
|
||||
with pytest.warns(np.VisibleDeprecationWarning):
|
||||
A.H
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_getrow_getcol(A):
|
||||
assert A.getcol(0)._is_array
|
||||
assert A.getrow(0)._is_array
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_docstr(A):
|
||||
if A.__doc__ is None:
|
||||
return
|
||||
|
||||
docstr = A.__doc__.lower()
|
||||
for phrase in ('matrix', 'matrices'):
|
||||
assert phrase not in docstr
|
||||
|
||||
|
||||
# -- linalg --
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_as_linearoperator(A):
|
||||
L = spla.aslinearoperator(A)
|
||||
npt.assert_allclose(L * [1, 2, 3, 4], A @ [1, 2, 3, 4])
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_inv(B):
|
||||
if B.__class__.__name__[:3] != 'csc':
|
||||
return
|
||||
|
||||
C = spla.inv(B)
|
||||
|
||||
assert C._is_array
|
||||
npt.assert_allclose(C.todense(), np.linalg.inv(B.todense()))
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_expm(B):
|
||||
if B.__class__.__name__[:3] != 'csc':
|
||||
return
|
||||
|
||||
Bmat = scipy.sparse.csc_matrix(B)
|
||||
|
||||
C = spla.expm(B)
|
||||
|
||||
assert C._is_array
|
||||
npt.assert_allclose(
|
||||
C.todense(),
|
||||
spla.expm(Bmat).todense()
|
||||
)
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_expm_multiply(B):
|
||||
if B.__class__.__name__[:3] != 'csc':
|
||||
return
|
||||
|
||||
npt.assert_allclose(
|
||||
spla.expm_multiply(B, np.array([1, 2])),
|
||||
spla.expm(B) @ [1, 2]
|
||||
)
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_norm(A):
|
||||
C = spla.norm(A)
|
||||
npt.assert_allclose(C, np.linalg.norm(A.todense()))
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_onenormest(B):
|
||||
C = spla.onenormest(B)
|
||||
npt.assert_allclose(C, np.linalg.norm(B.todense(), 1))
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_spsolve(B):
|
||||
if B.__class__.__name__[:3] not in ('csc', 'csr'):
|
||||
return
|
||||
|
||||
npt.assert_allclose(
|
||||
spla.spsolve(B, [1, 2]),
|
||||
np.linalg.solve(B.todense(), [1, 2])
|
||||
)
|
||||
|
||||
|
||||
def test_spsolve_triangular():
|
||||
X = scipy.sparse.csr_array([
|
||||
[1, 0, 0, 0],
|
||||
[2, 1, 0, 0],
|
||||
[3, 2, 1, 0],
|
||||
[4, 3, 2, 1],
|
||||
])
|
||||
spla.spsolve_triangular(X, [1, 2, 3, 4])
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
def test_factorized(B):
|
||||
if B.__class__.__name__[:3] != 'csc':
|
||||
return
|
||||
|
||||
LU = spla.factorized(B)
|
||||
npt.assert_allclose(
|
||||
LU(np.array([1, 2])),
|
||||
np.linalg.solve(B.todense(), [1, 2])
|
||||
)
|
||||
|
||||
|
||||
@parametrize_square_sparrays
|
||||
@pytest.mark.parametrize(
|
||||
"solver",
|
||||
["bicg", "bicgstab", "cg", "cgs", "gmres", "lgmres", "minres", "qmr",
|
||||
"gcrotmk", "tfqmr"]
|
||||
)
|
||||
def test_solvers(B, solver):
|
||||
if solver == "minres":
|
||||
kwargs = {}
|
||||
else:
|
||||
kwargs = {'atol': 1e-5}
|
||||
|
||||
x, info = getattr(spla, solver)(B, np.array([1, 2]), **kwargs)
|
||||
assert info >= 0 # no errors, even if perhaps did not converge fully
|
||||
npt.assert_allclose(x, [1, 1], atol=1e-1)
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
@pytest.mark.parametrize(
|
||||
"solver",
|
||||
["lsqr", "lsmr"]
|
||||
)
|
||||
def test_lstsqr(A, solver):
|
||||
x, *_ = getattr(spla, solver)(A, [1, 2, 3])
|
||||
npt.assert_allclose(A @ x, [1, 2, 3])
|
||||
|
||||
|
||||
@parametrize_eig_sparrays
|
||||
def test_eigs(X):
|
||||
e, v = spla.eigs(X, k=1)
|
||||
npt.assert_allclose(
|
||||
X @ v,
|
||||
e[0] * v
|
||||
)
|
||||
|
||||
|
||||
@parametrize_eig_sparrays
|
||||
def test_eigsh(X):
|
||||
X = X + X.T
|
||||
e, v = spla.eigsh(X, k=1)
|
||||
npt.assert_allclose(
|
||||
X @ v,
|
||||
e[0] * v
|
||||
)
|
||||
|
||||
|
||||
@parametrize_eig_sparrays
|
||||
def test_svds(X):
|
||||
u, s, vh = spla.svds(X, k=3)
|
||||
u2, s2, vh2 = np.linalg.svd(X.todense())
|
||||
s = np.sort(s)
|
||||
s2 = np.sort(s2[:3])
|
||||
npt.assert_allclose(s, s2, atol=1e-3)
|
||||
|
||||
|
||||
def test_splu():
|
||||
X = scipy.sparse.csc_array([
|
||||
[1, 0, 0, 0],
|
||||
[2, 1, 0, 0],
|
||||
[3, 2, 1, 0],
|
||||
[4, 3, 2, 1],
|
||||
])
|
||||
LU = spla.splu(X)
|
||||
npt.assert_allclose(LU.solve(np.array([1, 2, 3, 4])), [1, 0, 0, 0])
|
||||
|
||||
|
||||
def test_spilu():
|
||||
X = scipy.sparse.csc_array([
|
||||
[1, 0, 0, 0],
|
||||
[2, 1, 0, 0],
|
||||
[3, 2, 1, 0],
|
||||
[4, 3, 2, 1],
|
||||
])
|
||||
LU = spla.spilu(X)
|
||||
npt.assert_allclose(LU.solve(np.array([1, 2, 3, 4])), [1, 0, 0, 0])
|
||||
|
||||
|
||||
@parametrize_sparrays
|
||||
def test_power_operator(A):
|
||||
# https://github.com/scipy/scipy/issues/15948
|
||||
npt.assert_equal((A**2).todense(), (A.todense())**2)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,582 +0,0 @@
|
||||
"""test sparse matrix construction functions"""
|
||||
|
||||
import numpy as np
|
||||
from numpy import array
|
||||
from numpy.testing import (assert_equal, assert_,
|
||||
assert_array_equal, assert_array_almost_equal_nulp)
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
from scipy._lib._testutils import check_free_memory
|
||||
from scipy._lib._util import check_random_state
|
||||
|
||||
from scipy.sparse import (csr_matrix, coo_matrix,
|
||||
_construct as construct)
|
||||
from scipy.sparse._construct import rand as sprand
|
||||
from scipy.sparse._sputils import matrix
|
||||
|
||||
sparse_formats = ['csr','csc','coo','bsr','dia','lil','dok']
|
||||
|
||||
#TODO check whether format=XXX is respected
|
||||
|
||||
|
||||
def _sprandn(m, n, density=0.01, format="coo", dtype=None, random_state=None):
|
||||
# Helper function for testing.
|
||||
random_state = check_random_state(random_state)
|
||||
data_rvs = random_state.standard_normal
|
||||
return construct.random(m, n, density, format, dtype,
|
||||
random_state, data_rvs)
|
||||
|
||||
|
||||
class TestConstructUtils:
|
||||
def test_spdiags(self):
|
||||
diags1 = array([[1, 2, 3, 4, 5]])
|
||||
diags2 = array([[1, 2, 3, 4, 5],
|
||||
[6, 7, 8, 9,10]])
|
||||
diags3 = array([[1, 2, 3, 4, 5],
|
||||
[6, 7, 8, 9,10],
|
||||
[11,12,13,14,15]])
|
||||
|
||||
cases = []
|
||||
cases.append((diags1, 0, 1, 1, [[1]]))
|
||||
cases.append((diags1, [0], 1, 1, [[1]]))
|
||||
cases.append((diags1, [0], 2, 1, [[1],[0]]))
|
||||
cases.append((diags1, [0], 1, 2, [[1,0]]))
|
||||
cases.append((diags1, [1], 1, 2, [[0,2]]))
|
||||
cases.append((diags1,[-1], 1, 2, [[0,0]]))
|
||||
cases.append((diags1, [0], 2, 2, [[1,0],[0,2]]))
|
||||
cases.append((diags1,[-1], 2, 2, [[0,0],[1,0]]))
|
||||
cases.append((diags1, [3], 2, 2, [[0,0],[0,0]]))
|
||||
cases.append((diags1, [0], 3, 4, [[1,0,0,0],[0,2,0,0],[0,0,3,0]]))
|
||||
cases.append((diags1, [1], 3, 4, [[0,2,0,0],[0,0,3,0],[0,0,0,4]]))
|
||||
cases.append((diags1, [2], 3, 5, [[0,0,3,0,0],[0,0,0,4,0],[0,0,0,0,5]]))
|
||||
|
||||
cases.append((diags2, [0,2], 3, 3, [[1,0,8],[0,2,0],[0,0,3]]))
|
||||
cases.append((diags2, [-1,0], 3, 4, [[6,0,0,0],[1,7,0,0],[0,2,8,0]]))
|
||||
cases.append((diags2, [2,-3], 6, 6, [[0,0,3,0,0,0],
|
||||
[0,0,0,4,0,0],
|
||||
[0,0,0,0,5,0],
|
||||
[6,0,0,0,0,0],
|
||||
[0,7,0,0,0,0],
|
||||
[0,0,8,0,0,0]]))
|
||||
|
||||
cases.append((diags3, [-1,0,1], 6, 6, [[6,12, 0, 0, 0, 0],
|
||||
[1, 7,13, 0, 0, 0],
|
||||
[0, 2, 8,14, 0, 0],
|
||||
[0, 0, 3, 9,15, 0],
|
||||
[0, 0, 0, 4,10, 0],
|
||||
[0, 0, 0, 0, 5, 0]]))
|
||||
cases.append((diags3, [-4,2,-1], 6, 5, [[0, 0, 8, 0, 0],
|
||||
[11, 0, 0, 9, 0],
|
||||
[0,12, 0, 0,10],
|
||||
[0, 0,13, 0, 0],
|
||||
[1, 0, 0,14, 0],
|
||||
[0, 2, 0, 0,15]]))
|
||||
cases.append((diags3, [-1, 1, 2], len(diags3[0]), len(diags3[0]),
|
||||
[[0, 7, 13, 0, 0],
|
||||
[1, 0, 8, 14, 0],
|
||||
[0, 2, 0, 9, 15],
|
||||
[0, 0, 3, 0, 10],
|
||||
[0, 0, 0, 4, 0]]))
|
||||
|
||||
for d, o, m, n, result in cases:
|
||||
if len(d[0]) == m and m == n:
|
||||
assert_equal(construct.spdiags(d, o).toarray(), result)
|
||||
assert_equal(construct.spdiags(d, o, m, n).toarray(), result)
|
||||
assert_equal(construct.spdiags(d, o, (m, n)).toarray(), result)
|
||||
|
||||
def test_diags(self):
|
||||
a = array([1, 2, 3, 4, 5])
|
||||
b = array([6, 7, 8, 9, 10])
|
||||
c = array([11, 12, 13, 14, 15])
|
||||
|
||||
cases = []
|
||||
cases.append((a[:1], 0, (1, 1), [[1]]))
|
||||
cases.append(([a[:1]], [0], (1, 1), [[1]]))
|
||||
cases.append(([a[:1]], [0], (2, 1), [[1],[0]]))
|
||||
cases.append(([a[:1]], [0], (1, 2), [[1,0]]))
|
||||
cases.append(([a[:1]], [1], (1, 2), [[0,1]]))
|
||||
cases.append(([a[:2]], [0], (2, 2), [[1,0],[0,2]]))
|
||||
cases.append(([a[:1]],[-1], (2, 2), [[0,0],[1,0]]))
|
||||
cases.append(([a[:3]], [0], (3, 4), [[1,0,0,0],[0,2,0,0],[0,0,3,0]]))
|
||||
cases.append(([a[:3]], [1], (3, 4), [[0,1,0,0],[0,0,2,0],[0,0,0,3]]))
|
||||
cases.append(([a[:1]], [-2], (3, 5), [[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,0]]))
|
||||
cases.append(([a[:2]], [-1], (3, 5), [[0,0,0,0,0],[1,0,0,0,0],[0,2,0,0,0]]))
|
||||
cases.append(([a[:3]], [0], (3, 5), [[1,0,0,0,0],[0,2,0,0,0],[0,0,3,0,0]]))
|
||||
cases.append(([a[:3]], [1], (3, 5), [[0,1,0,0,0],[0,0,2,0,0],[0,0,0,3,0]]))
|
||||
cases.append(([a[:3]], [2], (3, 5), [[0,0,1,0,0],[0,0,0,2,0],[0,0,0,0,3]]))
|
||||
cases.append(([a[:2]], [3], (3, 5), [[0,0,0,1,0],[0,0,0,0,2],[0,0,0,0,0]]))
|
||||
cases.append(([a[:1]], [4], (3, 5), [[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0]]))
|
||||
cases.append(([a[:1]], [-4], (5, 3), [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[1,0,0]]))
|
||||
cases.append(([a[:2]], [-3], (5, 3), [[0,0,0],[0,0,0],[0,0,0],[1,0,0],[0,2,0]]))
|
||||
cases.append(([a[:3]], [-2], (5, 3), [[0,0,0],[0,0,0],[1,0,0],[0,2,0],[0,0,3]]))
|
||||
cases.append(([a[:3]], [-1], (5, 3), [[0,0,0],[1,0,0],[0,2,0],[0,0,3],[0,0,0]]))
|
||||
cases.append(([a[:3]], [0], (5, 3), [[1,0,0],[0,2,0],[0,0,3],[0,0,0],[0,0,0]]))
|
||||
cases.append(([a[:2]], [1], (5, 3), [[0,1,0],[0,0,2],[0,0,0],[0,0,0],[0,0,0]]))
|
||||
cases.append(([a[:1]], [2], (5, 3), [[0,0,1],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]))
|
||||
|
||||
cases.append(([a[:3],b[:1]], [0,2], (3, 3), [[1,0,6],[0,2,0],[0,0,3]]))
|
||||
cases.append(([a[:2],b[:3]], [-1,0], (3, 4), [[6,0,0,0],[1,7,0,0],[0,2,8,0]]))
|
||||
cases.append(([a[:4],b[:3]], [2,-3], (6, 6), [[0,0,1,0,0,0],
|
||||
[0,0,0,2,0,0],
|
||||
[0,0,0,0,3,0],
|
||||
[6,0,0,0,0,4],
|
||||
[0,7,0,0,0,0],
|
||||
[0,0,8,0,0,0]]))
|
||||
|
||||
cases.append(([a[:4],b,c[:4]], [-1,0,1], (5, 5), [[6,11, 0, 0, 0],
|
||||
[1, 7,12, 0, 0],
|
||||
[0, 2, 8,13, 0],
|
||||
[0, 0, 3, 9,14],
|
||||
[0, 0, 0, 4,10]]))
|
||||
cases.append(([a[:2],b[:3],c], [-4,2,-1], (6, 5), [[0, 0, 6, 0, 0],
|
||||
[11, 0, 0, 7, 0],
|
||||
[0,12, 0, 0, 8],
|
||||
[0, 0,13, 0, 0],
|
||||
[1, 0, 0,14, 0],
|
||||
[0, 2, 0, 0,15]]))
|
||||
|
||||
# too long arrays are OK
|
||||
cases.append(([a], [0], (1, 1), [[1]]))
|
||||
cases.append(([a[:3],b], [0,2], (3, 3), [[1, 0, 6], [0, 2, 0], [0, 0, 3]]))
|
||||
cases.append((np.array([[1, 2, 3], [4, 5, 6]]), [0,-1], (3, 3), [[1, 0, 0], [4, 2, 0], [0, 5, 3]]))
|
||||
|
||||
# scalar case: broadcasting
|
||||
cases.append(([1,-2,1], [1,0,-1], (3, 3), [[-2, 1, 0],
|
||||
[1, -2, 1],
|
||||
[0, 1, -2]]))
|
||||
|
||||
for d, o, shape, result in cases:
|
||||
err_msg = "%r %r %r %r" % (d, o, shape, result)
|
||||
assert_equal(construct.diags(d, o, shape=shape).toarray(),
|
||||
result, err_msg=err_msg)
|
||||
|
||||
if shape[0] == shape[1] and hasattr(d[0], '__len__') and len(d[0]) <= max(shape):
|
||||
# should be able to find the shape automatically
|
||||
assert_equal(construct.diags(d, o).toarray(), result,
|
||||
err_msg=err_msg)
|
||||
|
||||
def test_diags_default(self):
|
||||
a = array([1, 2, 3, 4, 5])
|
||||
assert_equal(construct.diags(a).toarray(), np.diag(a))
|
||||
|
||||
def test_diags_default_bad(self):
|
||||
a = array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6]])
|
||||
assert_raises(ValueError, construct.diags, a)
|
||||
|
||||
def test_diags_bad(self):
|
||||
a = array([1, 2, 3, 4, 5])
|
||||
b = array([6, 7, 8, 9, 10])
|
||||
c = array([11, 12, 13, 14, 15])
|
||||
|
||||
cases = []
|
||||
cases.append(([a[:0]], 0, (1, 1)))
|
||||
cases.append(([a[:4],b,c[:3]], [-1,0,1], (5, 5)))
|
||||
cases.append(([a[:2],c,b[:3]], [-4,2,-1], (6, 5)))
|
||||
cases.append(([a[:2],c,b[:3]], [-4,2,-1], None))
|
||||
cases.append(([], [-4,2,-1], None))
|
||||
cases.append(([1], [-5], (4, 4)))
|
||||
cases.append(([a], 0, None))
|
||||
|
||||
for d, o, shape in cases:
|
||||
assert_raises(ValueError, construct.diags, d, o, shape)
|
||||
|
||||
assert_raises(TypeError, construct.diags, [[None]], [0])
|
||||
|
||||
def test_diags_vs_diag(self):
|
||||
# Check that
|
||||
#
|
||||
# diags([a, b, ...], [i, j, ...]) == diag(a, i) + diag(b, j) + ...
|
||||
#
|
||||
|
||||
np.random.seed(1234)
|
||||
|
||||
for n_diags in [1, 2, 3, 4, 5, 10]:
|
||||
n = 1 + n_diags//2 + np.random.randint(0, 10)
|
||||
|
||||
offsets = np.arange(-n+1, n-1)
|
||||
np.random.shuffle(offsets)
|
||||
offsets = offsets[:n_diags]
|
||||
|
||||
diagonals = [np.random.rand(n - abs(q)) for q in offsets]
|
||||
|
||||
mat = construct.diags(diagonals, offsets)
|
||||
dense_mat = sum([np.diag(x, j) for x, j in zip(diagonals, offsets)])
|
||||
|
||||
assert_array_almost_equal_nulp(mat.toarray(), dense_mat)
|
||||
|
||||
if len(offsets) == 1:
|
||||
mat = construct.diags(diagonals[0], offsets[0])
|
||||
dense_mat = np.diag(diagonals[0], offsets[0])
|
||||
assert_array_almost_equal_nulp(mat.toarray(), dense_mat)
|
||||
|
||||
def test_diags_dtype(self):
|
||||
x = construct.diags([2.2], [0], shape=(2, 2), dtype=int)
|
||||
assert_equal(x.dtype, int)
|
||||
assert_equal(x.toarray(), [[2, 0], [0, 2]])
|
||||
|
||||
def test_diags_one_diagonal(self):
|
||||
d = list(range(5))
|
||||
for k in range(-5, 6):
|
||||
assert_equal(construct.diags(d, k).toarray(),
|
||||
construct.diags([d], [k]).toarray())
|
||||
|
||||
def test_diags_empty(self):
|
||||
x = construct.diags([])
|
||||
assert_equal(x.shape, (0, 0))
|
||||
|
||||
def test_identity(self):
|
||||
assert_equal(construct.identity(1).toarray(), [[1]])
|
||||
assert_equal(construct.identity(2).toarray(), [[1,0],[0,1]])
|
||||
|
||||
I = construct.identity(3, dtype='int8', format='dia')
|
||||
assert_equal(I.dtype, np.dtype('int8'))
|
||||
assert_equal(I.format, 'dia')
|
||||
|
||||
for fmt in sparse_formats:
|
||||
I = construct.identity(3, format=fmt)
|
||||
assert_equal(I.format, fmt)
|
||||
assert_equal(I.toarray(), [[1,0,0],[0,1,0],[0,0,1]])
|
||||
|
||||
def test_eye(self):
|
||||
assert_equal(construct.eye(1,1).toarray(), [[1]])
|
||||
assert_equal(construct.eye(2,3).toarray(), [[1,0,0],[0,1,0]])
|
||||
assert_equal(construct.eye(3,2).toarray(), [[1,0],[0,1],[0,0]])
|
||||
assert_equal(construct.eye(3,3).toarray(), [[1,0,0],[0,1,0],[0,0,1]])
|
||||
|
||||
assert_equal(construct.eye(3,3,dtype='int16').dtype, np.dtype('int16'))
|
||||
|
||||
for m in [3, 5]:
|
||||
for n in [3, 5]:
|
||||
for k in range(-5,6):
|
||||
assert_equal(construct.eye(m, n, k=k).toarray(), np.eye(m, n, k=k))
|
||||
if m == n:
|
||||
assert_equal(construct.eye(m, k=k).toarray(), np.eye(m, n, k=k))
|
||||
|
||||
def test_eye_one(self):
|
||||
assert_equal(construct.eye(1).toarray(), [[1]])
|
||||
assert_equal(construct.eye(2).toarray(), [[1,0],[0,1]])
|
||||
|
||||
I = construct.eye(3, dtype='int8', format='dia')
|
||||
assert_equal(I.dtype, np.dtype('int8'))
|
||||
assert_equal(I.format, 'dia')
|
||||
|
||||
for fmt in sparse_formats:
|
||||
I = construct.eye(3, format=fmt)
|
||||
assert_equal(I.format, fmt)
|
||||
assert_equal(I.toarray(), [[1,0,0],[0,1,0],[0,0,1]])
|
||||
|
||||
def test_kron(self):
|
||||
cases = []
|
||||
|
||||
cases.append(array([[0]]))
|
||||
cases.append(array([[-1]]))
|
||||
cases.append(array([[4]]))
|
||||
cases.append(array([[10]]))
|
||||
cases.append(array([[0],[0]]))
|
||||
cases.append(array([[0,0]]))
|
||||
cases.append(array([[1,2],[3,4]]))
|
||||
cases.append(array([[0,2],[5,0]]))
|
||||
cases.append(array([[0,2,-6],[8,0,14]]))
|
||||
cases.append(array([[5,4],[0,0],[6,0]]))
|
||||
cases.append(array([[5,4,4],[1,0,0],[6,0,8]]))
|
||||
cases.append(array([[0,1,0,2,0,5,8]]))
|
||||
cases.append(array([[0.5,0.125,0,3.25],[0,2.5,0,0]]))
|
||||
|
||||
for a in cases:
|
||||
for b in cases:
|
||||
expected = np.kron(a, b)
|
||||
for fmt in sparse_formats:
|
||||
result = construct.kron(csr_matrix(a), csr_matrix(b), format=fmt)
|
||||
assert_equal(result.format, fmt)
|
||||
assert_array_equal(result.toarray(), expected)
|
||||
|
||||
def test_kron_large(self):
|
||||
n = 2**16
|
||||
a = construct.eye(1, n, n-1)
|
||||
b = construct.eye(n, 1, 1-n)
|
||||
|
||||
construct.kron(a, a)
|
||||
construct.kron(b, b)
|
||||
|
||||
def test_kronsum(self):
|
||||
cases = []
|
||||
|
||||
cases.append(array([[0]]))
|
||||
cases.append(array([[-1]]))
|
||||
cases.append(array([[4]]))
|
||||
cases.append(array([[10]]))
|
||||
cases.append(array([[1,2],[3,4]]))
|
||||
cases.append(array([[0,2],[5,0]]))
|
||||
cases.append(array([[0,2,-6],[8,0,14],[0,3,0]]))
|
||||
cases.append(array([[1,0,0],[0,5,-1],[4,-2,8]]))
|
||||
|
||||
for a in cases:
|
||||
for b in cases:
|
||||
result = construct.kronsum(
|
||||
csr_matrix(a), csr_matrix(b)).toarray()
|
||||
expected = np.kron(np.eye(len(b)), a) + \
|
||||
np.kron(b, np.eye(len(a)))
|
||||
assert_array_equal(result,expected)
|
||||
|
||||
def test_vstack(self):
|
||||
|
||||
A = coo_matrix([[1,2],[3,4]])
|
||||
B = coo_matrix([[5,6]])
|
||||
|
||||
expected = array([[1, 2],
|
||||
[3, 4],
|
||||
[5, 6]])
|
||||
assert_equal(construct.vstack([A, B]).toarray(), expected)
|
||||
assert_equal(construct.vstack([A, B], dtype=np.float32).dtype,
|
||||
np.float32)
|
||||
|
||||
assert_equal(construct.vstack([A.tocsr(), B.tocsr()]).toarray(),
|
||||
expected)
|
||||
result = construct.vstack([A.tocsr(), B.tocsr()], dtype=np.float32)
|
||||
assert_equal(result.dtype, np.float32)
|
||||
assert_equal(result.indices.dtype, np.int32)
|
||||
assert_equal(result.indptr.dtype, np.int32)
|
||||
|
||||
assert_equal(construct.vstack([A.tocsc(), B.tocsc()]).toarray(),
|
||||
expected)
|
||||
result = construct.vstack([A.tocsc(), B.tocsc()], dtype=np.float32)
|
||||
assert_equal(result.dtype, np.float32)
|
||||
assert_equal(result.indices.dtype, np.int32)
|
||||
assert_equal(result.indptr.dtype, np.int32)
|
||||
|
||||
def test_hstack(self):
|
||||
|
||||
A = coo_matrix([[1,2],[3,4]])
|
||||
B = coo_matrix([[5],[6]])
|
||||
|
||||
expected = array([[1, 2, 5],
|
||||
[3, 4, 6]])
|
||||
assert_equal(construct.hstack([A, B]).toarray(), expected)
|
||||
assert_equal(construct.hstack([A, B], dtype=np.float32).dtype,
|
||||
np.float32)
|
||||
assert_equal(construct.hstack([A.tocsc(), B.tocsc()]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.hstack([A.tocsc(), B.tocsc()],
|
||||
dtype=np.float32).dtype,
|
||||
np.float32)
|
||||
assert_equal(construct.hstack([A.tocsr(), B.tocsr()]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.hstack([A.tocsr(), B.tocsr()],
|
||||
dtype=np.float32).dtype,
|
||||
np.float32)
|
||||
|
||||
def test_bmat(self):
|
||||
|
||||
A = coo_matrix([[1, 2], [3, 4]])
|
||||
B = coo_matrix([[5],[6]])
|
||||
C = coo_matrix([[7]])
|
||||
D = coo_matrix((0, 0))
|
||||
|
||||
expected = array([[1, 2, 5],
|
||||
[3, 4, 6],
|
||||
[0, 0, 7]])
|
||||
assert_equal(construct.bmat([[A, B], [None, C]]).toarray(), expected)
|
||||
E = csr_matrix((1, 2), dtype=np.int32)
|
||||
assert_equal(construct.bmat([[A.tocsr(), B.tocsr()],
|
||||
[E, C.tocsr()]]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.bmat([[A.tocsc(), B.tocsc()],
|
||||
[E.tocsc(), C.tocsc()]]).toarray(),
|
||||
expected)
|
||||
|
||||
expected = array([[1, 2, 0],
|
||||
[3, 4, 0],
|
||||
[0, 0, 7]])
|
||||
assert_equal(construct.bmat([[A, None], [None, C]]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.bmat([[A.tocsr(), E.T.tocsr()],
|
||||
[E, C.tocsr()]]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.bmat([[A.tocsc(), E.T.tocsc()],
|
||||
[E.tocsc(), C.tocsc()]]).toarray(),
|
||||
expected)
|
||||
|
||||
Z = csr_matrix((1, 1), dtype=np.int32)
|
||||
expected = array([[0, 5],
|
||||
[0, 6],
|
||||
[7, 0]])
|
||||
assert_equal(construct.bmat([[None, B], [C, None]]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.bmat([[E.T.tocsr(), B.tocsr()],
|
||||
[C.tocsr(), Z]]).toarray(),
|
||||
expected)
|
||||
assert_equal(construct.bmat([[E.T.tocsc(), B.tocsc()],
|
||||
[C.tocsc(), Z.tocsc()]]).toarray(),
|
||||
expected)
|
||||
|
||||
expected = matrix(np.empty((0, 0)))
|
||||
assert_equal(construct.bmat([[None, None]]).toarray(), expected)
|
||||
assert_equal(construct.bmat([[None, D], [D, None]]).toarray(),
|
||||
expected)
|
||||
|
||||
# test bug reported in gh-5976
|
||||
expected = array([[7]])
|
||||
assert_equal(construct.bmat([[None, D], [C, None]]).toarray(),
|
||||
expected)
|
||||
|
||||
# test failure cases
|
||||
with assert_raises(ValueError) as excinfo:
|
||||
construct.bmat([[A], [B]])
|
||||
excinfo.match(r'Got blocks\[1,0\]\.shape\[1\] == 1, expected 2')
|
||||
|
||||
with assert_raises(ValueError) as excinfo:
|
||||
construct.bmat([[A.tocsr()], [B.tocsr()]])
|
||||
excinfo.match(r'incompatible dimensions for axis 1')
|
||||
|
||||
with assert_raises(ValueError) as excinfo:
|
||||
construct.bmat([[A.tocsc()], [B.tocsc()]])
|
||||
excinfo.match(r'Mismatching dimensions along axis 1: ({1, 2}|{2, 1})')
|
||||
|
||||
with assert_raises(ValueError) as excinfo:
|
||||
construct.bmat([[A, C]])
|
||||
excinfo.match(r'Got blocks\[0,1\]\.shape\[0\] == 1, expected 2')
|
||||
|
||||
with assert_raises(ValueError) as excinfo:
|
||||
construct.bmat([[A.tocsr(), C.tocsr()]])
|
||||
excinfo.match(r'Mismatching dimensions along axis 0: ({1, 2}|{2, 1})')
|
||||
|
||||
with assert_raises(ValueError) as excinfo:
|
||||
construct.bmat([[A.tocsc(), C.tocsc()]])
|
||||
excinfo.match(r'incompatible dimensions for axis 0')
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.xfail_on_32bit("Can't create large array for test")
|
||||
def test_concatenate_int32_overflow(self):
|
||||
""" test for indptr overflow when concatenating matrices """
|
||||
check_free_memory(30000)
|
||||
|
||||
n = 33000
|
||||
A = csr_matrix(np.ones((n, n), dtype=bool))
|
||||
B = A.copy()
|
||||
C = construct._compressed_sparse_stack((A,B), 0)
|
||||
|
||||
assert_(np.all(np.equal(np.diff(C.indptr), n)))
|
||||
assert_equal(C.indices.dtype, np.int64)
|
||||
assert_equal(C.indptr.dtype, np.int64)
|
||||
|
||||
def test_block_diag_basic(self):
|
||||
""" basic test for block_diag """
|
||||
A = coo_matrix([[1,2],[3,4]])
|
||||
B = coo_matrix([[5],[6]])
|
||||
C = coo_matrix([[7]])
|
||||
|
||||
expected = array([[1, 2, 0, 0],
|
||||
[3, 4, 0, 0],
|
||||
[0, 0, 5, 0],
|
||||
[0, 0, 6, 0],
|
||||
[0, 0, 0, 7]])
|
||||
|
||||
assert_equal(construct.block_diag((A, B, C)).toarray(), expected)
|
||||
|
||||
def test_block_diag_scalar_1d_args(self):
|
||||
""" block_diag with scalar and 1d arguments """
|
||||
# one 1d matrix and a scalar
|
||||
assert_array_equal(construct.block_diag([[2,3], 4]).toarray(),
|
||||
[[2, 3, 0], [0, 0, 4]])
|
||||
|
||||
def test_block_diag_1(self):
|
||||
""" block_diag with one matrix """
|
||||
assert_equal(construct.block_diag([[1, 0]]).toarray(),
|
||||
array([[1, 0]]))
|
||||
assert_equal(construct.block_diag([[[1, 0]]]).toarray(),
|
||||
array([[1, 0]]))
|
||||
assert_equal(construct.block_diag([[[1], [0]]]).toarray(),
|
||||
array([[1], [0]]))
|
||||
# just on scalar
|
||||
assert_equal(construct.block_diag([1]).toarray(),
|
||||
array([[1]]))
|
||||
|
||||
def test_block_diag_sparse_matrices(self):
|
||||
""" block_diag with sparse matrices """
|
||||
|
||||
sparse_col_matrices = [coo_matrix(([[1, 2, 3]]), shape=(1, 3)),
|
||||
coo_matrix(([[4, 5]]), shape=(1, 2))]
|
||||
block_sparse_cols_matrices = construct.block_diag(sparse_col_matrices)
|
||||
assert_equal(block_sparse_cols_matrices.toarray(),
|
||||
array([[1, 2, 3, 0, 0], [0, 0, 0, 4, 5]]))
|
||||
|
||||
sparse_row_matrices = [coo_matrix(([[1], [2], [3]]), shape=(3, 1)),
|
||||
coo_matrix(([[4], [5]]), shape=(2, 1))]
|
||||
block_sparse_row_matrices = construct.block_diag(sparse_row_matrices)
|
||||
assert_equal(block_sparse_row_matrices.toarray(),
|
||||
array([[1, 0], [2, 0], [3, 0], [0, 4], [0, 5]]))
|
||||
|
||||
def test_random_sampling(self):
|
||||
# Simple sanity checks for sparse random sampling.
|
||||
for f in sprand, _sprandn:
|
||||
for t in [np.float32, np.float64, np.longdouble,
|
||||
np.int32, np.int64, np.complex64, np.complex128]:
|
||||
x = f(5, 10, density=0.1, dtype=t)
|
||||
assert_equal(x.dtype, t)
|
||||
assert_equal(x.shape, (5, 10))
|
||||
assert_equal(x.nnz, 5)
|
||||
|
||||
x1 = f(5, 10, density=0.1, random_state=4321)
|
||||
assert_equal(x1.dtype, np.double)
|
||||
|
||||
x2 = f(5, 10, density=0.1,
|
||||
random_state=np.random.RandomState(4321))
|
||||
|
||||
assert_array_equal(x1.data, x2.data)
|
||||
assert_array_equal(x1.row, x2.row)
|
||||
assert_array_equal(x1.col, x2.col)
|
||||
|
||||
for density in [0.0, 0.1, 0.5, 1.0]:
|
||||
x = f(5, 10, density=density)
|
||||
assert_equal(x.nnz, int(density * np.prod(x.shape)))
|
||||
|
||||
for fmt in ['coo', 'csc', 'csr', 'lil']:
|
||||
x = f(5, 10, format=fmt)
|
||||
assert_equal(x.format, fmt)
|
||||
|
||||
assert_raises(ValueError, lambda: f(5, 10, 1.1))
|
||||
assert_raises(ValueError, lambda: f(5, 10, -0.1))
|
||||
|
||||
def test_rand(self):
|
||||
# Simple distributional checks for sparse.rand.
|
||||
random_states = [None, 4321, np.random.RandomState()]
|
||||
try:
|
||||
gen = np.random.default_rng()
|
||||
random_states.append(gen)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
for random_state in random_states:
|
||||
x = sprand(10, 20, density=0.5, dtype=np.float64,
|
||||
random_state=random_state)
|
||||
assert_(np.all(np.less_equal(0, x.data)))
|
||||
assert_(np.all(np.less_equal(x.data, 1)))
|
||||
|
||||
def test_randn(self):
|
||||
# Simple distributional checks for sparse.randn.
|
||||
# Statistically, some of these should be negative
|
||||
# and some should be greater than 1.
|
||||
random_states = [None, 4321, np.random.RandomState()]
|
||||
try:
|
||||
gen = np.random.default_rng()
|
||||
random_states.append(gen)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
for random_state in random_states:
|
||||
x = _sprandn(10, 20, density=0.5, dtype=np.float64,
|
||||
random_state=random_state)
|
||||
assert_(np.any(np.less(x.data, 0)))
|
||||
assert_(np.any(np.less(1, x.data)))
|
||||
|
||||
def test_random_accept_str_dtype(self):
|
||||
# anything that np.dtype can convert to a dtype should be accepted
|
||||
# for the dtype
|
||||
construct.random(10, 10, dtype='d')
|
||||
|
||||
def test_random_sparse_matrix_returns_correct_number_of_non_zero_elements(self):
|
||||
# A 10 x 10 matrix, with density of 12.65%, should have 13 nonzero elements.
|
||||
# 10 x 10 x 0.1265 = 12.65, which should be rounded up to 13, not 12.
|
||||
sparse_matrix = construct.random(10, 10, density=0.1265)
|
||||
assert_equal(sparse_matrix.count_nonzero(),13)
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
import numpy as np
|
||||
from numpy.testing import assert_array_almost_equal, assert_
|
||||
from scipy.sparse import csr_matrix, csc_matrix, lil_matrix
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_csc_getrow():
|
||||
N = 10
|
||||
np.random.seed(0)
|
||||
X = np.random.random((N, N))
|
||||
X[X > 0.7] = 0
|
||||
Xcsc = csc_matrix(X)
|
||||
|
||||
for i in range(N):
|
||||
arr_row = X[i:i + 1, :]
|
||||
csc_row = Xcsc.getrow(i)
|
||||
|
||||
assert_array_almost_equal(arr_row, csc_row.toarray())
|
||||
assert_(type(csc_row) is csr_matrix)
|
||||
|
||||
|
||||
def test_csc_getcol():
|
||||
N = 10
|
||||
np.random.seed(0)
|
||||
X = np.random.random((N, N))
|
||||
X[X > 0.7] = 0
|
||||
Xcsc = csc_matrix(X)
|
||||
|
||||
for i in range(N):
|
||||
arr_col = X[:, i:i + 1]
|
||||
csc_col = Xcsc.getcol(i)
|
||||
|
||||
assert_array_almost_equal(arr_col, csc_col.toarray())
|
||||
assert_(type(csc_col) is csc_matrix)
|
||||
|
||||
@pytest.mark.parametrize("matrix_input, axis, expected_shape",
|
||||
[(csc_matrix([[1, 0],
|
||||
[0, 0],
|
||||
[0, 2]]),
|
||||
0, (0, 2)),
|
||||
(csc_matrix([[1, 0],
|
||||
[0, 0],
|
||||
[0, 2]]),
|
||||
1, (3, 0)),
|
||||
(csc_matrix([[1, 0],
|
||||
[0, 0],
|
||||
[0, 2]]),
|
||||
'both', (0, 0)),
|
||||
(csc_matrix([[0, 1, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 2, 3, 0, 1]]),
|
||||
0, (0, 6))])
|
||||
def test_csc_empty_slices(matrix_input, axis, expected_shape):
|
||||
# see gh-11127 for related discussion
|
||||
slice_1 = matrix_input.A.shape[0] - 1
|
||||
slice_2 = slice_1
|
||||
slice_3 = slice_2 - 1
|
||||
|
||||
if axis == 0:
|
||||
actual_shape_1 = matrix_input[slice_1:slice_2, :].A.shape
|
||||
actual_shape_2 = matrix_input[slice_1:slice_3, :].A.shape
|
||||
elif axis == 1:
|
||||
actual_shape_1 = matrix_input[:, slice_1:slice_2].A.shape
|
||||
actual_shape_2 = matrix_input[:, slice_1:slice_3].A.shape
|
||||
elif axis == 'both':
|
||||
actual_shape_1 = matrix_input[slice_1:slice_2, slice_1:slice_2].A.shape
|
||||
actual_shape_2 = matrix_input[slice_1:slice_3, slice_1:slice_3].A.shape
|
||||
|
||||
assert actual_shape_1 == expected_shape
|
||||
assert actual_shape_1 == actual_shape_2
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ax', (-2, -1, 0, 1, None))
|
||||
def test_argmax_overflow(ax):
|
||||
# See gh-13646: Windows integer overflow for large sparse matrices.
|
||||
dim = (100000, 100000)
|
||||
A = lil_matrix(dim)
|
||||
A[-2, -2] = 42
|
||||
A[-3, -3] = 0.1234
|
||||
A = csc_matrix(A)
|
||||
idx = A.argmax(axis=ax)
|
||||
|
||||
if ax is None:
|
||||
# idx is a single flattened index
|
||||
# that we need to convert to a 2d index pair;
|
||||
# can't do this with np.unravel_index because
|
||||
# the dimensions are too large
|
||||
ii = idx % dim[0]
|
||||
jj = idx // dim[0]
|
||||
else:
|
||||
# idx is an array of size of A.shape[ax];
|
||||
# check the max index to make sure no overflows
|
||||
# we encountered
|
||||
assert np.count_nonzero(idx) == A.nnz
|
||||
ii, jj = np.max(idx), np.argmax(idx)
|
||||
|
||||
assert A[ii, jj] == A[-2, -2]
|
||||
@@ -1,169 +0,0 @@
|
||||
import numpy as np
|
||||
from numpy.testing import assert_array_almost_equal, assert_
|
||||
from scipy.sparse import csr_matrix, hstack
|
||||
import pytest
|
||||
|
||||
|
||||
def _check_csr_rowslice(i, sl, X, Xcsr):
|
||||
np_slice = X[i, sl]
|
||||
csr_slice = Xcsr[i, sl]
|
||||
assert_array_almost_equal(np_slice, csr_slice.toarray()[0])
|
||||
assert_(type(csr_slice) is csr_matrix)
|
||||
|
||||
|
||||
def test_csr_rowslice():
|
||||
N = 10
|
||||
np.random.seed(0)
|
||||
X = np.random.random((N, N))
|
||||
X[X > 0.7] = 0
|
||||
Xcsr = csr_matrix(X)
|
||||
|
||||
slices = [slice(None, None, None),
|
||||
slice(None, None, -1),
|
||||
slice(1, -2, 2),
|
||||
slice(-2, 1, -2)]
|
||||
|
||||
for i in range(N):
|
||||
for sl in slices:
|
||||
_check_csr_rowslice(i, sl, X, Xcsr)
|
||||
|
||||
|
||||
def test_csr_getrow():
|
||||
N = 10
|
||||
np.random.seed(0)
|
||||
X = np.random.random((N, N))
|
||||
X[X > 0.7] = 0
|
||||
Xcsr = csr_matrix(X)
|
||||
|
||||
for i in range(N):
|
||||
arr_row = X[i:i + 1, :]
|
||||
csr_row = Xcsr.getrow(i)
|
||||
|
||||
assert_array_almost_equal(arr_row, csr_row.toarray())
|
||||
assert_(type(csr_row) is csr_matrix)
|
||||
|
||||
|
||||
def test_csr_getcol():
|
||||
N = 10
|
||||
np.random.seed(0)
|
||||
X = np.random.random((N, N))
|
||||
X[X > 0.7] = 0
|
||||
Xcsr = csr_matrix(X)
|
||||
|
||||
for i in range(N):
|
||||
arr_col = X[:, i:i + 1]
|
||||
csr_col = Xcsr.getcol(i)
|
||||
|
||||
assert_array_almost_equal(arr_col, csr_col.toarray())
|
||||
assert_(type(csr_col) is csr_matrix)
|
||||
|
||||
@pytest.mark.parametrize("matrix_input, axis, expected_shape",
|
||||
[(csr_matrix([[1, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 2, 3, 0]]),
|
||||
0, (0, 4)),
|
||||
(csr_matrix([[1, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 2, 3, 0]]),
|
||||
1, (3, 0)),
|
||||
(csr_matrix([[1, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 2, 3, 0]]),
|
||||
'both', (0, 0)),
|
||||
(csr_matrix([[0, 1, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 2, 3, 0]]),
|
||||
0, (0, 5))])
|
||||
def test_csr_empty_slices(matrix_input, axis, expected_shape):
|
||||
# see gh-11127 for related discussion
|
||||
slice_1 = matrix_input.A.shape[0] - 1
|
||||
slice_2 = slice_1
|
||||
slice_3 = slice_2 - 1
|
||||
|
||||
if axis == 0:
|
||||
actual_shape_1 = matrix_input[slice_1:slice_2, :].A.shape
|
||||
actual_shape_2 = matrix_input[slice_1:slice_3, :].A.shape
|
||||
elif axis == 1:
|
||||
actual_shape_1 = matrix_input[:, slice_1:slice_2].A.shape
|
||||
actual_shape_2 = matrix_input[:, slice_1:slice_3].A.shape
|
||||
elif axis == 'both':
|
||||
actual_shape_1 = matrix_input[slice_1:slice_2, slice_1:slice_2].A.shape
|
||||
actual_shape_2 = matrix_input[slice_1:slice_3, slice_1:slice_3].A.shape
|
||||
|
||||
assert actual_shape_1 == expected_shape
|
||||
assert actual_shape_1 == actual_shape_2
|
||||
|
||||
|
||||
def test_csr_bool_indexing():
|
||||
data = csr_matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
|
||||
list_indices1 = [False, True, False]
|
||||
array_indices1 = np.array(list_indices1)
|
||||
list_indices2 = [[False, True, False], [False, True, False], [False, True, False]]
|
||||
array_indices2 = np.array(list_indices2)
|
||||
list_indices3 = ([False, True, False], [False, True, False])
|
||||
array_indices3 = (np.array(list_indices3[0]), np.array(list_indices3[1]))
|
||||
slice_list1 = data[list_indices1].toarray()
|
||||
slice_array1 = data[array_indices1].toarray()
|
||||
slice_list2 = data[list_indices2]
|
||||
slice_array2 = data[array_indices2]
|
||||
slice_list3 = data[list_indices3]
|
||||
slice_array3 = data[array_indices3]
|
||||
assert (slice_list1 == slice_array1).all()
|
||||
assert (slice_list2 == slice_array2).all()
|
||||
assert (slice_list3 == slice_array3).all()
|
||||
|
||||
|
||||
def test_csr_hstack_int64():
|
||||
"""
|
||||
Tests if hstack properly promotes to indices and indptr arrays to np.int64
|
||||
when using np.int32 during concatenation would result in either array
|
||||
overflowing.
|
||||
"""
|
||||
max_int32 = np.iinfo(np.int32).max
|
||||
|
||||
# First case: indices would overflow with int32
|
||||
data = [1.0]
|
||||
row = [0]
|
||||
|
||||
max_indices_1 = max_int32 - 1
|
||||
max_indices_2 = 3
|
||||
|
||||
# Individual indices arrays are representable with int32
|
||||
col_1 = [max_indices_1 - 1]
|
||||
col_2 = [max_indices_2 - 1]
|
||||
|
||||
X_1 = csr_matrix((data, (row, col_1)))
|
||||
X_2 = csr_matrix((data, (row, col_2)))
|
||||
|
||||
assert max(max_indices_1 - 1, max_indices_2 - 1) < max_int32
|
||||
assert X_1.indices.dtype == X_1.indptr.dtype == np.int32
|
||||
assert X_2.indices.dtype == X_2.indptr.dtype == np.int32
|
||||
|
||||
# ... but when concatenating their CSR matrices, the resulting indices
|
||||
# array can't be represented with int32 and must be promoted to int64.
|
||||
X_hs = hstack([X_1, X_2], format="csr")
|
||||
|
||||
assert X_hs.indices.max() == max_indices_1 + max_indices_2 - 1
|
||||
assert max_indices_1 + max_indices_2 - 1 > max_int32
|
||||
assert X_hs.indices.dtype == X_hs.indptr.dtype == np.int64
|
||||
|
||||
# Even if the matrices are empty, we must account for their size
|
||||
# contribution so that we may safely set the final elements.
|
||||
X_1_empty = csr_matrix(X_1.shape)
|
||||
X_2_empty = csr_matrix(X_2.shape)
|
||||
X_hs_empty = hstack([X_1_empty, X_2_empty], format="csr")
|
||||
|
||||
assert X_hs_empty.shape == X_hs.shape
|
||||
assert X_hs_empty.indices.dtype == np.int64
|
||||
|
||||
# Should be just small enough to stay in int32 after stack. Note that
|
||||
# we theoretically could support indices.max() == max_int32, but due to an
|
||||
# edge-case in the underlying sparsetools code
|
||||
# (namely the `coo_tocsr` routine),
|
||||
# we require that max(X_hs_32.shape) < max_int32 as well.
|
||||
# Hence we can only support max_int32 - 1.
|
||||
col_3 = [max_int32 - max_indices_1 - 1]
|
||||
X_3 = csr_matrix((data, (row, col_3)))
|
||||
X_hs_32 = hstack([X_1, X_3], format="csr")
|
||||
assert X_hs_32.indices.dtype == np.int32
|
||||
assert X_hs_32.indices.max() == max_int32 - 1
|
||||
@@ -1,42 +0,0 @@
|
||||
"""test sparse matrix construction functions"""
|
||||
|
||||
from numpy.testing import assert_equal
|
||||
from scipy.sparse import csr_matrix
|
||||
|
||||
import numpy as np
|
||||
from scipy.sparse import _extract
|
||||
|
||||
|
||||
class TestExtract:
|
||||
def setup_method(self):
|
||||
self.cases = [
|
||||
csr_matrix([[1,2]]),
|
||||
csr_matrix([[1,0]]),
|
||||
csr_matrix([[0,0]]),
|
||||
csr_matrix([[1],[2]]),
|
||||
csr_matrix([[1],[0]]),
|
||||
csr_matrix([[0],[0]]),
|
||||
csr_matrix([[1,2],[3,4]]),
|
||||
csr_matrix([[0,1],[0,0]]),
|
||||
csr_matrix([[0,0],[1,0]]),
|
||||
csr_matrix([[0,0],[0,0]]),
|
||||
csr_matrix([[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]]),
|
||||
csr_matrix([[1,2,0,0,3],[4,5,0,6,7],[0,0,8,9,0]]).T,
|
||||
]
|
||||
|
||||
def find(self):
|
||||
for A in self.cases:
|
||||
I,J,V = _extract.find(A)
|
||||
assert_equal(A.toarray(), csr_matrix(((I,J),V), shape=A.shape))
|
||||
|
||||
def test_tril(self):
|
||||
for A in self.cases:
|
||||
B = A.toarray()
|
||||
for k in [-3,-2,-1,0,1,2,3]:
|
||||
assert_equal(_extract.tril(A,k=k).toarray(), np.tril(B,k=k))
|
||||
|
||||
def test_triu(self):
|
||||
for A in self.cases:
|
||||
B = A.toarray()
|
||||
for k in [-3,-2,-1,0,1,2,3]:
|
||||
assert_equal(_extract.triu(A,k=k).toarray(), np.triu(B,k=k))
|
||||
@@ -1,86 +0,0 @@
|
||||
import os
|
||||
import numpy as np
|
||||
import tempfile
|
||||
|
||||
from pytest import raises as assert_raises
|
||||
from numpy.testing import assert_equal, assert_
|
||||
|
||||
from scipy.sparse import (csc_matrix, csr_matrix, bsr_matrix, dia_matrix,
|
||||
coo_matrix, save_npz, load_npz, dok_matrix)
|
||||
|
||||
|
||||
DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
|
||||
|
||||
|
||||
def _save_and_load(matrix):
|
||||
fd, tmpfile = tempfile.mkstemp(suffix='.npz')
|
||||
os.close(fd)
|
||||
try:
|
||||
save_npz(tmpfile, matrix)
|
||||
loaded_matrix = load_npz(tmpfile)
|
||||
finally:
|
||||
os.remove(tmpfile)
|
||||
return loaded_matrix
|
||||
|
||||
def _check_save_and_load(dense_matrix):
|
||||
for matrix_class in [csc_matrix, csr_matrix, bsr_matrix, dia_matrix, coo_matrix]:
|
||||
matrix = matrix_class(dense_matrix)
|
||||
loaded_matrix = _save_and_load(matrix)
|
||||
assert_(type(loaded_matrix) is matrix_class)
|
||||
assert_(loaded_matrix.shape == dense_matrix.shape)
|
||||
assert_(loaded_matrix.dtype == dense_matrix.dtype)
|
||||
assert_equal(loaded_matrix.toarray(), dense_matrix)
|
||||
|
||||
def test_save_and_load_random():
|
||||
N = 10
|
||||
np.random.seed(0)
|
||||
dense_matrix = np.random.random((N, N))
|
||||
dense_matrix[dense_matrix > 0.7] = 0
|
||||
_check_save_and_load(dense_matrix)
|
||||
|
||||
def test_save_and_load_empty():
|
||||
dense_matrix = np.zeros((4,6))
|
||||
_check_save_and_load(dense_matrix)
|
||||
|
||||
def test_save_and_load_one_entry():
|
||||
dense_matrix = np.zeros((4,6))
|
||||
dense_matrix[1,2] = 1
|
||||
_check_save_and_load(dense_matrix)
|
||||
|
||||
|
||||
def test_malicious_load():
|
||||
class Executor:
|
||||
def __reduce__(self):
|
||||
return (assert_, (False, 'unexpected code execution'))
|
||||
|
||||
fd, tmpfile = tempfile.mkstemp(suffix='.npz')
|
||||
os.close(fd)
|
||||
try:
|
||||
np.savez(tmpfile, format=Executor())
|
||||
|
||||
# Should raise a ValueError, not execute code
|
||||
assert_raises(ValueError, load_npz, tmpfile)
|
||||
finally:
|
||||
os.remove(tmpfile)
|
||||
|
||||
|
||||
def test_py23_compatibility():
|
||||
# Try loading files saved on Python 2 and Python 3. They are not
|
||||
# the same, since files saved with SciPy versions < 1.0.0 may
|
||||
# contain unicode.
|
||||
|
||||
a = load_npz(os.path.join(DATA_DIR, 'csc_py2.npz'))
|
||||
b = load_npz(os.path.join(DATA_DIR, 'csc_py3.npz'))
|
||||
c = csc_matrix([[0]])
|
||||
|
||||
assert_equal(a.toarray(), c.toarray())
|
||||
assert_equal(b.toarray(), c.toarray())
|
||||
|
||||
def test_implemented_error():
|
||||
# Attempts to save an unsupported type and checks that an
|
||||
# NotImplementedError is raised.
|
||||
|
||||
x = dok_matrix((2,3))
|
||||
x[0,1] = 1
|
||||
|
||||
assert_raises(NotImplementedError, save_npz, 'x.npz', x)
|
||||
@@ -1,337 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
import gc
|
||||
import threading
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal, assert_, assert_allclose
|
||||
from scipy.sparse import (_sparsetools, coo_matrix, csr_matrix, csc_matrix,
|
||||
bsr_matrix, dia_matrix)
|
||||
from scipy.sparse._sputils import supported_dtypes
|
||||
from scipy._lib._testutils import check_free_memory
|
||||
|
||||
import pytest
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
|
||||
def int_to_int8(n):
|
||||
"""
|
||||
Wrap an integer to the interval [-128, 127].
|
||||
"""
|
||||
return (n + 128) % 256 - 128
|
||||
|
||||
|
||||
def test_exception():
|
||||
assert_raises(MemoryError, _sparsetools.test_throw_error)
|
||||
|
||||
|
||||
def test_threads():
|
||||
# Smoke test for parallel threaded execution; doesn't actually
|
||||
# check that code runs in parallel, but just that it produces
|
||||
# expected results.
|
||||
nthreads = 10
|
||||
niter = 100
|
||||
|
||||
n = 20
|
||||
a = csr_matrix(np.ones([n, n]))
|
||||
bres = []
|
||||
|
||||
class Worker(threading.Thread):
|
||||
def run(self):
|
||||
b = a.copy()
|
||||
for j in range(niter):
|
||||
_sparsetools.csr_plus_csr(n, n,
|
||||
a.indptr, a.indices, a.data,
|
||||
a.indptr, a.indices, a.data,
|
||||
b.indptr, b.indices, b.data)
|
||||
bres.append(b)
|
||||
|
||||
threads = [Worker() for _ in range(nthreads)]
|
||||
for thread in threads:
|
||||
thread.start()
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
for b in bres:
|
||||
assert_(np.all(b.toarray() == 2))
|
||||
|
||||
|
||||
def test_regression_std_vector_dtypes():
|
||||
# Regression test for gh-3780, checking the std::vector typemaps
|
||||
# in sparsetools.cxx are complete.
|
||||
for dtype in supported_dtypes:
|
||||
ad = np.array([[1, 2], [3, 4]]).astype(dtype)
|
||||
a = csr_matrix(ad, dtype=dtype)
|
||||
|
||||
# getcol is one function using std::vector typemaps, and should not fail
|
||||
assert_equal(a.getcol(0).toarray(), ad[:, :1])
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.xfail_on_32bit("Can't create large array for test")
|
||||
def test_nnz_overflow():
|
||||
# Regression test for gh-7230 / gh-7871, checking that coo_toarray
|
||||
# with nnz > int32max doesn't overflow.
|
||||
nnz = np.iinfo(np.int32).max + 1
|
||||
# Ensure ~20 GB of RAM is free to run this test.
|
||||
check_free_memory((4 + 4 + 1) * nnz / 1e6 + 0.5)
|
||||
|
||||
# Use nnz duplicate entries to keep the dense version small.
|
||||
row = np.zeros(nnz, dtype=np.int32)
|
||||
col = np.zeros(nnz, dtype=np.int32)
|
||||
data = np.zeros(nnz, dtype=np.int8)
|
||||
data[-1] = 4
|
||||
s = coo_matrix((data, (row, col)), shape=(1, 1), copy=False)
|
||||
# Sums nnz duplicates to produce a 1x1 array containing 4.
|
||||
d = s.toarray()
|
||||
|
||||
assert_allclose(d, [[4]])
|
||||
|
||||
|
||||
@pytest.mark.skipif(not (sys.platform.startswith('linux') and np.dtype(np.intp).itemsize >= 8),
|
||||
reason="test requires 64-bit Linux")
|
||||
class TestInt32Overflow:
|
||||
"""
|
||||
Some of the sparsetools routines use dense 2D matrices whose
|
||||
total size is not bounded by the nnz of the sparse matrix. These
|
||||
routines used to suffer from int32 wraparounds; here, we try to
|
||||
check that the wraparounds don't occur any more.
|
||||
"""
|
||||
# choose n large enough
|
||||
n = 50000
|
||||
|
||||
def setup_method(self):
|
||||
assert self.n**2 > np.iinfo(np.int32).max
|
||||
|
||||
# check there's enough memory even if everything is run at the
|
||||
# same time
|
||||
try:
|
||||
parallel_count = int(os.environ.get('PYTEST_XDIST_WORKER_COUNT', '1'))
|
||||
except ValueError:
|
||||
parallel_count = np.inf
|
||||
|
||||
check_free_memory(3000 * parallel_count)
|
||||
|
||||
def teardown_method(self):
|
||||
gc.collect()
|
||||
|
||||
def test_coo_todense(self):
|
||||
# Check *_todense routines (cf. gh-2179)
|
||||
#
|
||||
# All of them in the end call coo_matrix.todense
|
||||
|
||||
n = self.n
|
||||
|
||||
i = np.array([0, n-1])
|
||||
j = np.array([0, n-1])
|
||||
data = np.array([1, 2], dtype=np.int8)
|
||||
m = coo_matrix((data, (i, j)))
|
||||
|
||||
r = m.todense()
|
||||
assert_equal(r[0,0], 1)
|
||||
assert_equal(r[-1,-1], 2)
|
||||
del r
|
||||
gc.collect()
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_matvecs(self):
|
||||
# Check *_matvecs routines
|
||||
n = self.n
|
||||
|
||||
i = np.array([0, n-1])
|
||||
j = np.array([0, n-1])
|
||||
data = np.array([1, 2], dtype=np.int8)
|
||||
m = coo_matrix((data, (i, j)))
|
||||
|
||||
b = np.ones((n, n), dtype=np.int8)
|
||||
for sptype in (csr_matrix, csc_matrix, bsr_matrix):
|
||||
m2 = sptype(m)
|
||||
r = m2.dot(b)
|
||||
assert_equal(r[0,0], 1)
|
||||
assert_equal(r[-1,-1], 2)
|
||||
del r
|
||||
gc.collect()
|
||||
|
||||
del b
|
||||
gc.collect()
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_dia_matvec(self):
|
||||
# Check: huge dia_matrix _matvec
|
||||
n = self.n
|
||||
data = np.ones((n, n), dtype=np.int8)
|
||||
offsets = np.arange(n)
|
||||
m = dia_matrix((data, offsets), shape=(n, n))
|
||||
v = np.ones(m.shape[1], dtype=np.int8)
|
||||
r = m.dot(v)
|
||||
assert_equal(r[0], int_to_int8(n))
|
||||
del data, offsets, m, v, r
|
||||
gc.collect()
|
||||
|
||||
_bsr_ops = [pytest.param("matmat", marks=pytest.mark.xslow),
|
||||
pytest.param("matvecs", marks=pytest.mark.xslow),
|
||||
"matvec",
|
||||
"diagonal",
|
||||
"sort_indices",
|
||||
pytest.param("transpose", marks=pytest.mark.xslow)]
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize("op", _bsr_ops)
|
||||
def test_bsr_1_block(self, op):
|
||||
# Check: huge bsr_matrix (1-block)
|
||||
#
|
||||
# The point here is that indices inside a block may overflow.
|
||||
|
||||
def get_matrix():
|
||||
n = self.n
|
||||
data = np.ones((1, n, n), dtype=np.int8)
|
||||
indptr = np.array([0, 1], dtype=np.int32)
|
||||
indices = np.array([0], dtype=np.int32)
|
||||
m = bsr_matrix((data, indices, indptr), blocksize=(n, n), copy=False)
|
||||
del data, indptr, indices
|
||||
return m
|
||||
|
||||
gc.collect()
|
||||
try:
|
||||
getattr(self, "_check_bsr_" + op)(get_matrix)
|
||||
finally:
|
||||
gc.collect()
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize("op", _bsr_ops)
|
||||
def test_bsr_n_block(self, op):
|
||||
# Check: huge bsr_matrix (n-block)
|
||||
#
|
||||
# The point here is that while indices within a block don't
|
||||
# overflow, accumulators across many block may.
|
||||
|
||||
def get_matrix():
|
||||
n = self.n
|
||||
data = np.ones((n, n, 1), dtype=np.int8)
|
||||
indptr = np.array([0, n], dtype=np.int32)
|
||||
indices = np.arange(n, dtype=np.int32)
|
||||
m = bsr_matrix((data, indices, indptr), blocksize=(n, 1), copy=False)
|
||||
del data, indptr, indices
|
||||
return m
|
||||
|
||||
gc.collect()
|
||||
try:
|
||||
getattr(self, "_check_bsr_" + op)(get_matrix)
|
||||
finally:
|
||||
gc.collect()
|
||||
|
||||
def _check_bsr_matvecs(self, m):
|
||||
m = m()
|
||||
n = self.n
|
||||
|
||||
# _matvecs
|
||||
r = m.dot(np.ones((n, 2), dtype=np.int8))
|
||||
assert_equal(r[0, 0], int_to_int8(n))
|
||||
|
||||
def _check_bsr_matvec(self, m):
|
||||
m = m()
|
||||
n = self.n
|
||||
|
||||
# _matvec
|
||||
r = m.dot(np.ones((n,), dtype=np.int8))
|
||||
assert_equal(r[0], int_to_int8(n))
|
||||
|
||||
def _check_bsr_diagonal(self, m):
|
||||
m = m()
|
||||
n = self.n
|
||||
|
||||
# _diagonal
|
||||
r = m.diagonal()
|
||||
assert_equal(r, np.ones(n))
|
||||
|
||||
def _check_bsr_sort_indices(self, m):
|
||||
# _sort_indices
|
||||
m = m()
|
||||
m.sort_indices()
|
||||
|
||||
def _check_bsr_transpose(self, m):
|
||||
# _transpose
|
||||
m = m()
|
||||
m.transpose()
|
||||
|
||||
def _check_bsr_matmat(self, m):
|
||||
m = m()
|
||||
n = self.n
|
||||
|
||||
# _bsr_matmat
|
||||
m2 = bsr_matrix(np.ones((n, 2), dtype=np.int8), blocksize=(m.blocksize[1], 2))
|
||||
m.dot(m2) # shouldn't SIGSEGV
|
||||
del m2
|
||||
|
||||
# _bsr_matmat
|
||||
m2 = bsr_matrix(np.ones((2, n), dtype=np.int8), blocksize=(2, m.blocksize[0]))
|
||||
m2.dot(m) # shouldn't SIGSEGV
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="64-bit indices in sparse matrices not available")
|
||||
def test_csr_matmat_int64_overflow():
|
||||
n = 3037000500
|
||||
assert n**2 > np.iinfo(np.int64).max
|
||||
|
||||
# the test would take crazy amounts of memory
|
||||
check_free_memory(n * (8*2 + 1) * 3 / 1e6)
|
||||
|
||||
# int64 overflow
|
||||
data = np.ones((n,), dtype=np.int8)
|
||||
indptr = np.arange(n+1, dtype=np.int64)
|
||||
indices = np.zeros(n, dtype=np.int64)
|
||||
a = csr_matrix((data, indices, indptr))
|
||||
b = a.T
|
||||
|
||||
assert_raises(RuntimeError, a.dot, b)
|
||||
|
||||
|
||||
def test_upcast():
|
||||
a0 = csr_matrix([[np.pi, np.pi*1j], [3, 4]], dtype=complex)
|
||||
b0 = np.array([256+1j, 2**32], dtype=complex)
|
||||
|
||||
for a_dtype in supported_dtypes:
|
||||
for b_dtype in supported_dtypes:
|
||||
msg = "(%r, %r)" % (a_dtype, b_dtype)
|
||||
|
||||
if np.issubdtype(a_dtype, np.complexfloating):
|
||||
a = a0.copy().astype(a_dtype)
|
||||
else:
|
||||
a = a0.real.copy().astype(a_dtype)
|
||||
|
||||
if np.issubdtype(b_dtype, np.complexfloating):
|
||||
b = b0.copy().astype(b_dtype)
|
||||
else:
|
||||
with np.errstate(invalid="ignore"):
|
||||
# Casting a large value (2**32) to int8 causes a warning in
|
||||
# numpy >1.23
|
||||
b = b0.real.copy().astype(b_dtype)
|
||||
|
||||
if not (a_dtype == np.bool_ and b_dtype == np.bool_):
|
||||
c = np.zeros((2,), dtype=np.bool_)
|
||||
assert_raises(ValueError, _sparsetools.csr_matvec,
|
||||
2, 2, a.indptr, a.indices, a.data, b, c)
|
||||
|
||||
if ((np.issubdtype(a_dtype, np.complexfloating) and
|
||||
not np.issubdtype(b_dtype, np.complexfloating)) or
|
||||
(not np.issubdtype(a_dtype, np.complexfloating) and
|
||||
np.issubdtype(b_dtype, np.complexfloating))):
|
||||
c = np.zeros((2,), dtype=np.float64)
|
||||
assert_raises(ValueError, _sparsetools.csr_matvec,
|
||||
2, 2, a.indptr, a.indices, a.data, b, c)
|
||||
|
||||
c = np.zeros((2,), dtype=np.result_type(a_dtype, b_dtype))
|
||||
_sparsetools.csr_matvec(2, 2, a.indptr, a.indices, a.data, b, c)
|
||||
assert_allclose(c, np.dot(a.toarray(), b), err_msg=msg)
|
||||
|
||||
|
||||
def test_endianness():
|
||||
d = np.ones((3,4))
|
||||
offsets = [-1,0,1]
|
||||
|
||||
a = dia_matrix((d.astype('<f8'), offsets), (4, 4))
|
||||
b = dia_matrix((d.astype('>f8'), offsets), (4, 4))
|
||||
v = np.arange(4)
|
||||
|
||||
assert_allclose(a.dot(v), [1, 3, 6, 5])
|
||||
assert_allclose(b.dot(v), [1, 3, 6, 5])
|
||||
@@ -1,97 +0,0 @@
|
||||
from numpy import array, kron, diag
|
||||
from numpy.testing import assert_, assert_equal
|
||||
|
||||
from scipy.sparse import _spfuncs as spfuncs
|
||||
from scipy.sparse import csr_matrix, csc_matrix, bsr_matrix
|
||||
from scipy.sparse._sparsetools import (csr_scale_rows, csr_scale_columns,
|
||||
bsr_scale_rows, bsr_scale_columns)
|
||||
|
||||
|
||||
class TestSparseFunctions:
|
||||
def test_scale_rows_and_cols(self):
|
||||
D = array([[1, 0, 0, 2, 3],
|
||||
[0, 4, 0, 5, 0],
|
||||
[0, 0, 6, 7, 0]])
|
||||
|
||||
#TODO expose through function
|
||||
S = csr_matrix(D)
|
||||
v = array([1,2,3])
|
||||
csr_scale_rows(3,5,S.indptr,S.indices,S.data,v)
|
||||
assert_equal(S.toarray(), diag(v)@D)
|
||||
|
||||
S = csr_matrix(D)
|
||||
v = array([1,2,3,4,5])
|
||||
csr_scale_columns(3,5,S.indptr,S.indices,S.data,v)
|
||||
assert_equal(S.toarray(), D@diag(v))
|
||||
|
||||
# blocks
|
||||
E = kron(D,[[1,2],[3,4]])
|
||||
S = bsr_matrix(E,blocksize=(2,2))
|
||||
v = array([1,2,3,4,5,6])
|
||||
bsr_scale_rows(3,5,2,2,S.indptr,S.indices,S.data,v)
|
||||
assert_equal(S.toarray(), diag(v)@E)
|
||||
|
||||
S = bsr_matrix(E,blocksize=(2,2))
|
||||
v = array([1,2,3,4,5,6,7,8,9,10])
|
||||
bsr_scale_columns(3,5,2,2,S.indptr,S.indices,S.data,v)
|
||||
assert_equal(S.toarray(), E@diag(v))
|
||||
|
||||
E = kron(D,[[1,2,3],[4,5,6]])
|
||||
S = bsr_matrix(E,blocksize=(2,3))
|
||||
v = array([1,2,3,4,5,6])
|
||||
bsr_scale_rows(3,5,2,3,S.indptr,S.indices,S.data,v)
|
||||
assert_equal(S.toarray(), diag(v)@E)
|
||||
|
||||
S = bsr_matrix(E,blocksize=(2,3))
|
||||
v = array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
|
||||
bsr_scale_columns(3,5,2,3,S.indptr,S.indices,S.data,v)
|
||||
assert_equal(S.toarray(), E@diag(v))
|
||||
|
||||
def test_estimate_blocksize(self):
|
||||
mats = []
|
||||
mats.append([[0,1],[1,0]])
|
||||
mats.append([[1,1,0],[0,0,1],[1,0,1]])
|
||||
mats.append([[0],[0],[1]])
|
||||
mats = [array(x) for x in mats]
|
||||
|
||||
blks = []
|
||||
blks.append([[1]])
|
||||
blks.append([[1,1],[1,1]])
|
||||
blks.append([[1,1],[0,1]])
|
||||
blks.append([[1,1,0],[1,0,1],[1,1,1]])
|
||||
blks = [array(x) for x in blks]
|
||||
|
||||
for A in mats:
|
||||
for B in blks:
|
||||
X = kron(A,B)
|
||||
r,c = spfuncs.estimate_blocksize(X)
|
||||
assert_(r >= B.shape[0])
|
||||
assert_(c >= B.shape[1])
|
||||
|
||||
def test_count_blocks(self):
|
||||
def gold(A,bs):
|
||||
R,C = bs
|
||||
I,J = A.nonzero()
|
||||
return len(set(zip(I//R,J//C)))
|
||||
|
||||
mats = []
|
||||
mats.append([[0]])
|
||||
mats.append([[1]])
|
||||
mats.append([[1,0]])
|
||||
mats.append([[1,1]])
|
||||
mats.append([[0,1],[1,0]])
|
||||
mats.append([[1,1,0],[0,0,1],[1,0,1]])
|
||||
mats.append([[0],[0],[1]])
|
||||
|
||||
for A in mats:
|
||||
for B in mats:
|
||||
X = kron(A,B)
|
||||
Y = csr_matrix(X)
|
||||
for R in range(1,6):
|
||||
for C in range(1,6):
|
||||
assert_equal(spfuncs.count_blocks(Y, (R, C)), gold(X, (R, C)))
|
||||
|
||||
X = kron([[1,1,0],[0,0,1],[1,0,1]],[[1,1]])
|
||||
Y = csc_matrix(X)
|
||||
assert_equal(spfuncs.count_blocks(X, (1, 2)), gold(X, (1, 2)))
|
||||
assert_equal(spfuncs.count_blocks(Y, (1, 2)), gold(X, (1, 2)))
|
||||
@@ -1,188 +0,0 @@
|
||||
"""unit tests for sparse utility functions"""
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal
|
||||
from pytest import raises as assert_raises
|
||||
from scipy.sparse import _sputils as sputils
|
||||
from scipy.sparse._sputils import matrix
|
||||
|
||||
|
||||
class TestSparseUtils:
|
||||
|
||||
def test_upcast(self):
|
||||
assert_equal(sputils.upcast('intc'), np.intc)
|
||||
assert_equal(sputils.upcast('int32', 'float32'), np.float64)
|
||||
assert_equal(sputils.upcast('bool', complex, float), np.complex128)
|
||||
assert_equal(sputils.upcast('i', 'd'), np.float64)
|
||||
|
||||
def test_getdtype(self):
|
||||
A = np.array([1], dtype='int8')
|
||||
|
||||
assert_equal(sputils.getdtype(None, default=float), float)
|
||||
assert_equal(sputils.getdtype(None, a=A), np.int8)
|
||||
|
||||
with assert_raises(
|
||||
ValueError,
|
||||
match="object dtype is not supported by sparse matrices",
|
||||
):
|
||||
sputils.getdtype("O")
|
||||
|
||||
def test_isscalarlike(self):
|
||||
assert_equal(sputils.isscalarlike(3.0), True)
|
||||
assert_equal(sputils.isscalarlike(-4), True)
|
||||
assert_equal(sputils.isscalarlike(2.5), True)
|
||||
assert_equal(sputils.isscalarlike(1 + 3j), True)
|
||||
assert_equal(sputils.isscalarlike(np.array(3)), True)
|
||||
assert_equal(sputils.isscalarlike("16"), True)
|
||||
|
||||
assert_equal(sputils.isscalarlike(np.array([3])), False)
|
||||
assert_equal(sputils.isscalarlike([[3]]), False)
|
||||
assert_equal(sputils.isscalarlike((1,)), False)
|
||||
assert_equal(sputils.isscalarlike((1, 2)), False)
|
||||
|
||||
def test_isintlike(self):
|
||||
assert_equal(sputils.isintlike(-4), True)
|
||||
assert_equal(sputils.isintlike(np.array(3)), True)
|
||||
assert_equal(sputils.isintlike(np.array([3])), False)
|
||||
with assert_raises(
|
||||
ValueError,
|
||||
match="Inexact indices into sparse matrices are not allowed"
|
||||
):
|
||||
sputils.isintlike(3.0)
|
||||
|
||||
assert_equal(sputils.isintlike(2.5), False)
|
||||
assert_equal(sputils.isintlike(1 + 3j), False)
|
||||
assert_equal(sputils.isintlike((1,)), False)
|
||||
assert_equal(sputils.isintlike((1, 2)), False)
|
||||
|
||||
def test_isshape(self):
|
||||
assert_equal(sputils.isshape((1, 2)), True)
|
||||
assert_equal(sputils.isshape((5, 2)), True)
|
||||
|
||||
assert_equal(sputils.isshape((1.5, 2)), False)
|
||||
assert_equal(sputils.isshape((2, 2, 2)), False)
|
||||
assert_equal(sputils.isshape(([2], 2)), False)
|
||||
assert_equal(sputils.isshape((-1, 2), nonneg=False),True)
|
||||
assert_equal(sputils.isshape((2, -1), nonneg=False),True)
|
||||
assert_equal(sputils.isshape((-1, 2), nonneg=True),False)
|
||||
assert_equal(sputils.isshape((2, -1), nonneg=True),False)
|
||||
|
||||
def test_issequence(self):
|
||||
assert_equal(sputils.issequence((1,)), True)
|
||||
assert_equal(sputils.issequence((1, 2, 3)), True)
|
||||
assert_equal(sputils.issequence([1]), True)
|
||||
assert_equal(sputils.issequence([1, 2, 3]), True)
|
||||
assert_equal(sputils.issequence(np.array([1, 2, 3])), True)
|
||||
|
||||
assert_equal(sputils.issequence(np.array([[1], [2], [3]])), False)
|
||||
assert_equal(sputils.issequence(3), False)
|
||||
|
||||
def test_ismatrix(self):
|
||||
assert_equal(sputils.ismatrix(((),)), True)
|
||||
assert_equal(sputils.ismatrix([[1], [2]]), True)
|
||||
assert_equal(sputils.ismatrix(np.arange(3)[None]), True)
|
||||
|
||||
assert_equal(sputils.ismatrix([1, 2]), False)
|
||||
assert_equal(sputils.ismatrix(np.arange(3)), False)
|
||||
assert_equal(sputils.ismatrix([[[1]]]), False)
|
||||
assert_equal(sputils.ismatrix(3), False)
|
||||
|
||||
def test_isdense(self):
|
||||
assert_equal(sputils.isdense(np.array([1])), True)
|
||||
assert_equal(sputils.isdense(matrix([1])), True)
|
||||
|
||||
def test_validateaxis(self):
|
||||
assert_raises(TypeError, sputils.validateaxis, (0, 1))
|
||||
assert_raises(TypeError, sputils.validateaxis, 1.5)
|
||||
assert_raises(ValueError, sputils.validateaxis, 3)
|
||||
|
||||
# These function calls should not raise errors
|
||||
for axis in (-2, -1, 0, 1, None):
|
||||
sputils.validateaxis(axis)
|
||||
|
||||
def test_get_index_dtype(self):
|
||||
imax = np.int64(np.iinfo(np.int32).max)
|
||||
too_big = imax + 1
|
||||
|
||||
# Check that uint32's with no values too large doesn't return
|
||||
# int64
|
||||
a1 = np.ones(90, dtype='uint32')
|
||||
a2 = np.ones(90, dtype='uint32')
|
||||
assert_equal(
|
||||
np.dtype(sputils.get_index_dtype((a1, a2), check_contents=True)),
|
||||
np.dtype('int32')
|
||||
)
|
||||
|
||||
# Check that if we can not convert but all values are less than or
|
||||
# equal to max that we can just convert to int32
|
||||
a1[-1] = imax
|
||||
assert_equal(
|
||||
np.dtype(sputils.get_index_dtype((a1, a2), check_contents=True)),
|
||||
np.dtype('int32')
|
||||
)
|
||||
|
||||
# Check that if it can not convert directly and the contents are
|
||||
# too large that we return int64
|
||||
a1[-1] = too_big
|
||||
assert_equal(
|
||||
np.dtype(sputils.get_index_dtype((a1, a2), check_contents=True)),
|
||||
np.dtype('int64')
|
||||
)
|
||||
|
||||
# test that if can not convert and didn't specify to check_contents
|
||||
# we return int64
|
||||
a1 = np.ones(89, dtype='uint32')
|
||||
a2 = np.ones(89, dtype='uint32')
|
||||
assert_equal(
|
||||
np.dtype(sputils.get_index_dtype((a1, a2))),
|
||||
np.dtype('int64')
|
||||
)
|
||||
|
||||
# Check that even if we have arrays that can be converted directly
|
||||
# that if we specify a maxval directly it takes precedence
|
||||
a1 = np.ones(12, dtype='uint32')
|
||||
a2 = np.ones(12, dtype='uint32')
|
||||
assert_equal(
|
||||
np.dtype(sputils.get_index_dtype(
|
||||
(a1, a2), maxval=too_big, check_contents=True
|
||||
)),
|
||||
np.dtype('int64')
|
||||
)
|
||||
|
||||
# Check that an array with a too max size and maxval set
|
||||
# still returns int64
|
||||
a1[-1] = too_big
|
||||
assert_equal(
|
||||
np.dtype(sputils.get_index_dtype((a1, a2), maxval=too_big)),
|
||||
np.dtype('int64')
|
||||
)
|
||||
|
||||
def test_check_shape_overflow(self):
|
||||
new_shape = sputils.check_shape([(10, -1)], (65535, 131070))
|
||||
assert_equal(new_shape, (10, 858967245))
|
||||
|
||||
def test_matrix(self):
|
||||
a = [[1, 2, 3]]
|
||||
b = np.array(a)
|
||||
|
||||
assert isinstance(sputils.matrix(a), np.matrix)
|
||||
assert isinstance(sputils.matrix(b), np.matrix)
|
||||
|
||||
c = sputils.matrix(b)
|
||||
c[:, :] = 123
|
||||
assert_equal(b, a)
|
||||
|
||||
c = sputils.matrix(b, copy=False)
|
||||
c[:, :] = 123
|
||||
assert_equal(b, [[123, 123, 123]])
|
||||
|
||||
def test_asmatrix(self):
|
||||
a = [[1, 2, 3]]
|
||||
b = np.array(a)
|
||||
|
||||
assert isinstance(sputils.asmatrix(a), np.matrix)
|
||||
assert isinstance(sputils.asmatrix(b), np.matrix)
|
||||
|
||||
c = sputils.asmatrix(b)
|
||||
c[:, :] = 123
|
||||
assert_equal(b, [[123, 123, 123]])
|
||||
Reference in New Issue
Block a user