提交 3c57118b authored 作者: Nicolas Bouchard's avatar Nicolas Bouchard

Review and add tests for EnsureSortedIndices.

上级 8ead8d0f
......@@ -119,8 +119,19 @@ square_diagonal = SquareDiagonal()
class EnsureSortedIndices(Op):
"""
Remove explicit zeros from a sparse matrix, and resort indices
"""Resort indices of a sparse matrix.
CSR column indices are not necessarily sorted. Likewise
for CSC row indices. Use `ensure_sorted_indices` when sorted
indices are required (e.g. when passing data to other
libraries).
:param x: A sparse matrix.
:return: The same as `x` with indices sorted.
:note:
- The grad implemented is regular, i.e. not structured.
"""
def __init__(self, inplace):
......@@ -128,15 +139,18 @@ class EnsureSortedIndices(Op):
if self.inplace:
self.view_map = {0: [0]}
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return hash(type(self))
def make_node(self, x):
return gof.Apply(self, [x], [x.type()])
def perform(self, node, inputs, output_storage):
x = inputs[0]
z = output_storage[0]
def perform(self, node, (x, ), (z, )):
if self.inplace:
x.sort_indices()
z[0] = x
z[0] = x.sort_indices()
else:
z[0] = x.sorted_indices()
......@@ -151,11 +165,26 @@ class EnsureSortedIndices(Op):
return self.__class__.__name__ + "{inplace}"
else:
return self.__class__.__name__ + "{no_inplace}"
ensure_sorted_indices = EnsureSortedIndices(inplace=False)
def clean(x):
"""Remove explicit zeros from a sparse matrix, and
resort indices.
CSR column indices are not necessarily sorted. Likewise
for CSC row indices. Use `clean` when sorted
indices are required (e.g. when passing data to other
libraries) and to ensure there is no zeros in the data.
:param x: A sparse matrix.
:return: The same as `x` with indices sorted and zeros
removed.
:note:
- The grad implemented is regular, i.e. not structured.
"""
return ensure_sorted_indices(remove0(x))
......
......@@ -446,45 +446,75 @@ class SquareDiagonalTester(utt.InferShapeTester):
structured=False)
def test_ensure_sorted_indices():
x = 2000
y = 2000
sparsity = 1000
for i in range(2):
# testing both csc and csr
if i is 0:
# csc
input_tensor = theano.sparse.csc_dmatrix()
sample = scipy.sparse.csc_matrix(random_lil((x,y),'float64',sparsity))
else:
# csr
input_tensor = theano.sparse.csr_dmatrix()
sample = scipy.sparse.csr_matrix(random_lil((x,y),'float64',sparsity))
sort_op = sp.ensure_sorted_indices(input_tensor)
f = theano.function([input_tensor], sort_op)
sorted_scipy = sample.sorted_indices()
sorted_theano = f(sample)
assert numpy.all(sorted_theano.todense() == sorted_scipy.todense())
def test_square_diagonal_grad():
def d(x):
return sp.sp_sum(sp.square_diagonal(x), sparse_grad=True)
utt.verify_grad(d, [[0.0, 0.1, 0.2, 0.3]],
mode=theano.Mode(linker='py', optimizer='fast_compile'))
def test_diag_grad():
def d(x):
sp_x = theano.sparse.csc_from_dense(x)
diag_x = sp.diag(sp_x)
return diag_x.sum()
diag_mat = numpy.zeros((4,4))
for idx in xrange(4):
diag_mat[idx, idx] += idx * 0.1
utt.verify_grad(d, [diag_mat],
mode=theano.Mode(linker='py', optimizer='fast_compile'))
class EnsureSortedIndicesTester(utt.InferShapeTester):
def setUp(self):
super(EnsureSortedIndicesTester, self).setUp()
self.op_class = sp.EnsureSortedIndices
self.op = sp.ensure_sorted_indices
def test_op(self):
for format in theano.sparse.sparse_formats:
for shape in zip(range(5, 9), range(3, 7)[::-1]):
variable, data = sparse_random_inputs(format, shape=shape)
f = theano.function(variable, self.op(*variable))
tested = f(*data).toarray()
expected = data[0].sorted_indices().toarray()
assert numpy.allclose(tested, expected)
def test_infer_shape(self):
for format in theano.sparse.sparse_formats:
for shape in zip(range(5, 9), range(3, 7)[::-1]):
variable, data = sparse_random_inputs(format, shape=shape)
self._compile_and_check(variable,
[self.op(*variable)],
data,
self.op_class)
def test_grad(self):
for format in theano.sparse.sparse_formats:
for shape in zip(range(5, 9), range(3, 7)[::-1]):
variable, data = sparse_random_inputs(format, shape=shape)
verify_grad_sparse(
self.op,
data,
structured=False)
class CleanTester(utt.InferShapeTester):
def setUp(self):
super(CleanTester, self).setUp()
self.op = sp.clean
def test_op(self):
for format in theano.sparse.sparse_formats:
for shape in zip(range(5, 9), range(3, 7)[::-1]):
variable, data = sparse_random_inputs(format, shape=shape)
data[0][0, 0] = data[0][1, 1] = 0
f = theano.function(variable, self.op(*variable))
tested = f(*data)
expected = data[0]
expected.eliminate_zeros()
assert all(tested.data == expected.data)
assert not all(tested.data == 0)
tested = tested.toarray()
expected = expected.toarray()
assert numpy.allclose(tested, expected)
def test_grad(self):
for format in theano.sparse.sparse_formats:
for shape in zip(range(5, 9), range(3, 7)[::-1]):
variable, data = sparse_random_inputs(format, shape=shape)
verify_grad_sparse(
self.op,
data,
structured=False)
if __name__ == '__main__':
if 0:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论