提交 dbf6d673 authored 作者: Hengjean's avatar Hengjean

Added le, lt, ge, gt and associated test cases

上级 bd65bb19
......@@ -287,16 +287,16 @@ class _sparse_py_operators:
# comparison operators
def __lt__(self, other):
pass
return lt(self, other)
def __le__(self, other):
pass
return le(self, other)
def __gt__(self, other):
pass
return gt(self, other)
def __ge__(self, other):
pass
return ge(self, other)
# extra pseudo-operator symbols
......@@ -351,7 +351,7 @@ class _sparse_py_operators:
return ret
class SparseVariable(gof.Variable, _sparse_py_operators):
class SparseVariable(_sparse_py_operators, gof.Variable):
dtype = property(lambda self: self.type.dtype)
format = property(lambda self: self.type.format)
......@@ -2163,15 +2163,22 @@ def mul(x, y):
raise NotImplementedError()
class EqualSS(gof.op.Op):
class __ComparisonOpSS(gof.op.Op):
"""
Used as a superclass for all comparisons between
two sparses matrices
:param x:first compared sparse matrix
:param y:second compared sparse matrix
:return: x==y
:return: Comparison(x,y)
"""
#Function to override
def comparison(self, x, y):
return x
def __eq__(self, other):
return (type(self) == type(other))
......@@ -2192,7 +2199,7 @@ class EqualSS(gof.op.Op):
def perform(self, node, (x, y), (out, )):
assert _is_sparse(x) and _is_sparse(y)
assert x.shape == y.shape
out[0] = (x == y).astype('uint8')
out[0] = self.comparison(x, y).astype('uint8')
def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]]
......@@ -2200,18 +2207,23 @@ class EqualSS(gof.op.Op):
def __str__(self):
return self.__class__.__name__
equal_s_s = EqualSS()
class EqualSD(gof.op.Op):
class __ComparisonOpSD(gof.op.Op):
"""
Used as a superclass for all comparisons between
sparse and dense matrix
:param x:sparse matrix
:param y:dense matrix
:return: x==y
:return: Comparison(x,y)
"""
#Function to override
def comparison(self, x, y):
return x
def __eq__(self, other):
return (type(self) == type(other))
......@@ -2231,7 +2243,7 @@ class EqualSD(gof.op.Op):
assert _is_sparse(x)
assert x.shape == y.shape
assert _is_dense(y)
out[0] = (x == y).astype('uint8')
out[0] = self.comparison(x, y).astype('uint8')
def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]]
......@@ -2239,6 +2251,77 @@ class EqualSD(gof.op.Op):
def __str__(self):
return self.__class__.__name__
def __ComparisonSwitch(SS, SD, DS):
"""
:param SS: function to apply between two sparses matrices.
:param SD: function to apply between a sparse and a dense matrix.
:param DS: function to apply between a dense and a sparse matrix.
:return: switch function taking two matrices as input
:note: At least one of `x` and `y` must be a sparse matrix.
"""
def helper(x, y):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
assert scipy_ver >= [0, 14]
if hasattr(x, 'getnnz'):
x = as_sparse_variable(x)
if hasattr(y, 'getnnz'):
y = as_sparse_variable(y)
if not isinstance(x, theano.Variable):
x = theano.tensor.as_tensor_variable(x)
if not isinstance(y, theano.Variable):
y = theano.tensor.as_tensor_variable(y)
x_is_sparse_variable = _is_sparse_variable(x)
y_is_sparse_variable = _is_sparse_variable(y)
assert x_is_sparse_variable or y_is_sparse_variable
if x_is_sparse_variable and y_is_sparse_variable:
return SS(x, y)
elif x_is_sparse_variable and not y_is_sparse_variable:
return SD(x, y)
elif y_is_sparse_variable and not x_is_sparse_variable:
return DS(y, x)
else:
raise NotImplementedError()
return helper
class EqualSS(__ComparisonOpSS):
"""
:param x:first compared sparse matrix
:param y:second compared sparse matrix
:return: x==y
"""
def comparison(self, x, y):
return x == y
equal_s_s = EqualSS()
class EqualSD(__ComparisonOpSD):
"""
:param x:sparse matrix
:param y:dense matrix
:return: x==y
"""
def comparison(self, x, y):
return x == y
equal_s_d = EqualSD()
......@@ -2252,147 +2335,229 @@ def eq(x, y):
:note: At least one of `x` and `y` must be a sparse matrix.
"""
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
fE = __ComparisonSwitch(equal_s_s, equal_s_d, equal_s_d)
return fE(x, y)
assert scipy_ver >= [0, 14]
if hasattr(x, 'getnnz'):
x = as_sparse_variable(x)
if hasattr(y, 'getnnz'):
y = as_sparse_variable(y)
if not isinstance(x, theano.Variable):
x = theano.tensor.as_tensor_variable(x)
if not isinstance(y, theano.Variable):
y = theano.tensor.as_tensor_variable(y)
class NotEqualSS(__ComparisonOpSS):
x_is_sparse_variable = _is_sparse_variable(x)
y_is_sparse_variable = _is_sparse_variable(y)
"""
:param x:first compared sparse matrix
:param y:second compared sparse matrix
assert x_is_sparse_variable or y_is_sparse_variable
if x_is_sparse_variable and y_is_sparse_variable:
return equal_s_s(x, y)
elif x_is_sparse_variable and not y_is_sparse_variable:
return equal_s_d(x, y)
elif y_is_sparse_variable and not x_is_sparse_variable:
return equal_s_d(y, x)
else:
raise NotImplementedError()
:return: x!=y
"""
def comparison(self, x, y):
return x != y
class NotEqualSS(gof.op.Op):
not_equal_s_s = NotEqualSS()
class NotEqualSD(__ComparisonOpSD):
"""
:param x:sparse matrix
:param y:dense matrix
:return: x!=y
"""
def comparison(self, x, y):
return x != y
not_equal_s_d = NotEqualSD()
def neq(x, y):
"""
:param x: A matrix variable.
:param y: A matrix variable.
:return: `x` == `y`
:note: At least one of `x` and `y` must be a sparse matrix.
"""
fNE = __ComparisonSwitch(not_equal_s_s, not_equal_s_d, not_equal_s_d)
return fNE(x, y)
class LessThanSS(__ComparisonOpSS):
"""
:param x:first compared sparse matrix
:param y:second compared sparse matrix
:return: x==y
:return: x<y
"""
def __eq__(self, other):
return (type(self) == type(other))
def comparison(self, x, y):
return x < y
def __hash__(self):
return hash(type(self))
less_than_s_s = LessThanSS()
def make_node(self, x, y):
x = as_sparse_variable(x)
y = as_sparse_variable(y)
if x.type.format != y.type.format:
raise NotImplementedError()
return gof.Apply(self,
[x, y],
[SparseType(dtype='uint8',
format=x.type.format).make_variable()])
class LessThanSD(__ComparisonOpSD):
def perform(self, node, (x, y), (out, )):
assert _is_sparse(x) and _is_sparse(y)
assert x.shape == y.shape
out[0] = (x != y).astype('uint8')
"""
:param x:sparse matrix
:param y:dense matrix
def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]]
:return: x<y
"""
def __str__(self):
return self.__class__.__name__
def comparison(self, x, y):
return x < y
not_equal_s_s = NotEqualSS()
less_than_s_d = LessThanSD()
class NotEqualSD(gof.op.Op):
def lt(x, y):
"""
:param x: A matrix variable.
:param y: A matrix variable.
:return: `x` < `y`
:note: At least one of `x` and `y` must be a sparse matrix.
"""
fL = __ComparisonSwitch(less_than_s_s, less_than_s_d, greater_than_s_d)
return fL(x, y)
class GreaterThanSS(__ComparisonOpSS):
"""
:param x:first compared sparse matrix
:param y:second compared sparse matrix
:return: x>y
"""
def comparison(self, x, y):
return x > y
greater_than_s_s = GreaterThanSS()
class GreaterThanSD(__ComparisonOpSD):
"""
:param x:sparse matrix
:param y:dense matrix
:return: x==y
:return: x>y
"""
def __eq__(self, other):
return (type(self) == type(other))
def comparison(self, x, y):
return x > y
def __hash__(self):
return hash(type(self))
greater_than_s_d = GreaterThanSD()
def make_node(self, x, y):
x, y = as_sparse_variable(x), tensor.as_tensor_variable(y)
assert y.type.ndim == 2
return gof.Apply(self,
[x, y],
[SparseType(dtype='uint8',
format=x.type.format).make_variable()])
def gt(x, y):
"""
:param x: A matrix variable.
:param y: A matrix variable.
def perform(self, node, (x, y), (out, )):
assert _is_sparse(x)
assert x.shape == y.shape
assert _is_dense(y)
out[0] = (x != y).astype('uint8')
:return: `x` > `y`
def infer_shape(self, node, ins_shapes):
return [ins_shapes[0]]
:note: At least one of `x` and `y` must be a sparse matrix.
"""
def __str__(self):
return self.__class__.__name__
fG = __ComparisonSwitch(greater_than_s_s, greater_than_s_d, less_than_s_d)
return fG(x, y)
not_equal_s_d = NotEqualSD()
class LessEqualSS(__ComparisonOpSS):
def neq(x, y):
"""
:param x:first compared sparse matrix
:param y:second compared sparse matrix
:return: x>y
"""
def comparison(self, x, y):
return x <= y
less_equal_s_s = LessEqualSS()
class LessEqualSD(__ComparisonOpSD):
"""
:param x:sparse matrix
:param y:dense matrix
:return: x>y
"""
def comparison(self, x, y):
return x <= y
less_equal_s_d = LessEqualSD()
def le(x, y):
"""
:param x: A matrix variable.
:param y: A matrix variable.
:return: `x` == `y`
:return: `x` >= `y`
:note: At least one of `x` and `y` must be a sparse matrix.
"""
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
fLE = __ComparisonSwitch(less_equal_s_s, less_equal_s_d, greater_equal_s_d)
return fLE(x, y)
assert scipy_ver >= [0, 14]
if hasattr(x, 'getnnz'):
x = as_sparse_variable(x)
if hasattr(y, 'getnnz'):
y = as_sparse_variable(y)
if not isinstance(x, theano.Variable):
x = theano.tensor.as_tensor_variable(x)
if not isinstance(y, theano.Variable):
y = theano.tensor.as_tensor_variable(y)
class GreaterEqualSS(__ComparisonOpSS):
x_is_sparse_variable = _is_sparse_variable(x)
y_is_sparse_variable = _is_sparse_variable(y)
"""
:param x:first compared sparse matrix
:param y:second compared sparse matrix
assert x_is_sparse_variable or y_is_sparse_variable
if x_is_sparse_variable and y_is_sparse_variable:
return not_equal_s_s(x, y)
elif x_is_sparse_variable and not y_is_sparse_variable:
return not_equal_s_d(x, y)
elif y_is_sparse_variable and not x_is_sparse_variable:
return not_equal_s_d(y, x)
else:
raise NotImplementedError()
:return: x>y
"""
def comparison(self, x, y):
return x >= y
greater_equal_s_s = GreaterEqualSS()
class GreaterEqualSD(__ComparisonOpSD):
"""
:param x:sparse matrix
:param y:dense matrix
:return: x>y
"""
def comparison(self, x, y):
return x >= y
greater_equal_s_d = GreaterEqualSD()
def ge(x, y):
"""
:param x: A matrix variable.
:param y: A matrix variable.
:return: `x` >= `y`
:note: At least one of `x` and `y` must be a sparse matrix.
"""
fGE = __ComparisonSwitch(greater_equal_s_s, greater_equal_s_d,
less_equal_s_d)
return fGE(x, y)
class HStack(gof.op.Op):
......
......@@ -40,7 +40,7 @@ from theano.sparse import (
Diag, diag, SquareDiagonal, square_diagonal,
EnsureSortedIndices, ensure_sorted_indices, clean,
ConstructSparseFromList, construct_sparse_from_list,
TrueDot, true_dot, eq, neq)
TrueDot, true_dot, eq, neq, le, ge, gt, lt)
# Probability distributions are currently tested in test_sp2.py
#from theano.sparse import (
......@@ -656,157 +656,290 @@ class test_comparison(unittest.TestCase):
return numpy.asarray(numpy.random.rand(*shape) * (max - min) + min,
dtype=config.floatX)
def test_equalss_csr(self):
def __generalized_ss_test(self, theanop, symbolicType, testOp, scipyType):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
x = sparse.csr_matrix()
y = sparse.csr_matrix()
x = symbolicType()
y = symbolicType()
equality = eq(x, y)
op = theanop(x, y)
f = theano.function([x, y], equality)
f = theano.function([x, y], op)
m1 = sp.csr_matrix(random_lil((10, 40), config.floatX, 3))
m2 = sp.csr_matrix(random_lil((10, 40), config.floatX, 3))
m1 = scipyType(random_lil((10, 40), config.floatX, 3))
m2 = scipyType(random_lil((10, 40), config.floatX, 3))
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 == m2).data))
self.assertTrue(numpy.array_equal(f(m1, m2).data, testOp(m1, m2).data))
def test_equalss_csc(self):
def __generalized_sd_test(self, theanop, symbolicType, testOp, scipyType):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
x = sparse.csc_matrix()
y = sparse.csc_matrix()
x = symbolicType()
y = theano.tensor.matrix()
equality = eq(x, y)
op = theanop(x, y)
f = theano.function([x, y], equality)
f = theano.function([x, y], op)
m1 = sp.csc_matrix(random_lil((10, 40), config.floatX, 3))
m2 = sp.csc_matrix(random_lil((10, 40), config.floatX, 3))
m1 = scipyType(random_lil((10, 40), config.floatX, 3))
m2 = self._rand_ranged(1000, -1000, [10, 40])
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 == m2).data))
self.assertTrue(numpy.array_equal(f(m1, m2).data, testOp(m1, m2).data))
def test_not_equalss_csr(self):
def __generalized_ds_test(self, theanop, symbolicType, testOp, scipyType):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
x = sparse.csr_matrix()
y = sparse.csr_matrix()
x = symbolicType()
y = theano.tensor.matrix()
op = theanop(y, x)
f = theano.function([y, x], op)
m1 = scipyType(random_lil((10, 40), config.floatX, 3))
m2 = self._rand_ranged(1000, -1000, [10, 40])
self.assertTrue(numpy.array_equal(f(m2, m1).data, testOp(m2, m1).data))
def test_equalss_csr(self):
self.__generalized_ss_test(eq, sparse.csr_matrix,
lambda x, y: x == y, sp.csr_matrix)
unequality = neq(x, y)
def test_equalss_csc(self):
f = theano.function([x, y], unequality)
self.__generalized_ss_test(eq, sparse.csc_matrix,
lambda x, y: x == y, sp.csc_matrix)
m1 = sp.csr_matrix(random_lil((10, 40), config.floatX, 3))
m2 = sp.csr_matrix(random_lil((10, 40), config.floatX, 3))
def test_not_equalss_csr(self):
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 != m2).data))
self.__generalized_ss_test(neq, sparse.csr_matrix,
lambda x, y: x != y, sp.csr_matrix)
def test_not_equalss_csc(self):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
self.__generalized_ss_test(neq, sparse.csc_matrix,
lambda x, y: x != y, sp.csc_matrix)
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
def test_less_equalss_csr(self):
x = sparse.csc_matrix()
y = sparse.csc_matrix()
opT = lambda x, y: x <= y
unequality = neq(x, y)
self.__generalized_ss_test(le, sparse.csr_matrix,
opT, sp.csr_matrix)
f = theano.function([x, y], unequality)
def test_less_equalss_csc(self):
m1 = sp.csc_matrix(random_lil((10, 40), config.floatX, 3))
m2 = sp.csc_matrix(random_lil((10, 40), config.floatX, 3))
opT = lambda x, y: x <= y
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 != m2).data))
self.__generalized_ss_test(le, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_equalsd_csr(self):
def test_less_thanss_csr(self):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
opT = lambda x, y: x < y
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
self.__generalized_ss_test(opT, sparse.csr_matrix,
opT, sp.csr_matrix)
x = sparse.csr_matrix()
y = theano.tensor.matrix()
def test_less_thanss_csc(self):
equality = eq(x, y)
opT = lambda x, y: x < y
f = theano.function([x, y], equality)
self.__generalized_ss_test(opT, sparse.csc_matrix,
opT, sp.csc_matrix)
m1 = sp.csr_matrix(random_lil((10, 40), config.floatX, 3))
m2 = self._rand_ranged(1000, -1000, [10, 40])
def test_greater_equalss_csr(self):
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 == m2).data))
opT = lambda x, y: x >= y
def test_equalsd_csc(self):
self.__generalized_ss_test(opT, sparse.csr_matrix,
opT, sp.csr_matrix)
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
def test_greater_equalss_csc(self):
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
opT = lambda x, y: x >= y
x = sparse.csc_matrix()
y = theano.tensor.matrix()
self.__generalized_ss_test(opT, sparse.csc_matrix,
opT, sp.csc_matrix)
equality = eq(x, y)
def test_greater_thanss_csr(self):
f = theano.function([x, y], equality)
opT = lambda x, y: x > y
m1 = sp.csc_matrix(random_lil((10, 40), config.floatX, 3))
m2 = self._rand_ranged(1000, -1000, [10, 40])
self.__generalized_ss_test(opT, sparse.csr_matrix,
opT, sp.csr_matrix)
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 == m2).data))
def test_greater_thanss_csc(self):
def test_not_equalsd_csr(self):
opT = lambda x, y: x > y
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
self.__generalized_ss_test(opT, sparse.csc_matrix,
opT, sp.csc_matrix)
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
def test_equalsd_csr(self):
x = sparse.csr_matrix()
y = theano.tensor.matrix()
self.__generalized_sd_test(eq, sparse.csr_matrix,
lambda x, y: x == y, sp.csr_matrix)
unequality = neq(x, y)
def test_equalsd_csc(self):
f = theano.function([x, y], unequality)
self.__generalized_sd_test(eq, sparse.csc_matrix,
lambda x, y: x == y, sp.csc_matrix)
m1 = sp.csr_matrix(random_lil((10, 40), config.floatX, 3))
m2 = self._rand_ranged(1000, -1000, [10, 40])
def test_not_equalsd_csr(self):
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 != m2).data))
self.__generalized_sd_test(neq, sparse.csr_matrix,
lambda x, y: x != y, sp.csr_matrix)
def test_not_equalsd_csc(self):
scipy_ver = [int(n) for n in scipy.__version__.split('.')[:2]]
self.__generalized_sd_test(neq, sparse.csc_matrix,
lambda x, y: x != y, sp.csc_matrix)
if (bool(scipy_ver < [0, 14])):
raise SkipTest("comparison operators need newer release of scipy")
def test_less_equalsd_csr(self):
x = sparse.csc_matrix()
y = theano.tensor.matrix()
opT = lambda x, y: x <= y
unequality = neq(x, y)
self.__generalized_sd_test(le, sparse.csr_matrix,
opT, sp.csr_matrix)
f = theano.function([x, y], unequality)
def test_less_equalsd_csc(self):
m1 = sp.csc_matrix(random_lil((10, 40), config.floatX, 3))
m2 = self._rand_ranged(1000, -1000, [10, 40])
opT = lambda x, y: x <= y
self.__generalized_sd_test(le, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_less_thansd_csr(self):
opT = lambda x, y: x < y
self.__generalized_sd_test(opT, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_less_thansd_csc(self):
opT = lambda x, y: x < y
self.__generalized_sd_test(opT, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_greater_equalsd_csr(self):
opT = lambda x, y: x >= y
self.__generalized_sd_test(opT, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_greater_equalsd_csc(self):
opT = lambda x, y: x >= y
self.__generalized_sd_test(opT, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_greater_thansd_csr(self):
opT = lambda x, y: x > y
self.__generalized_sd_test(opT, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_greater_thansd_csc(self):
opT = lambda x, y: x > y
self.__generalized_sd_test(opT, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_equalds_csr(self):
self.__generalized_ds_test(eq, sparse.csr_matrix,
lambda x, y: x == y, sp.csr_matrix)
def test_equalds_csc(self):
self.__generalized_ds_test(eq, sparse.csc_matrix,
lambda x, y: x == y, sp.csc_matrix)
def test_not_equalds_csr(self):
self.__generalized_ds_test(neq, sparse.csr_matrix,
lambda x, y: x != y, sp.csr_matrix)
def test_not_equalds_csc(self):
self.__generalized_ds_test(neq, sparse.csc_matrix,
lambda x, y: x != y, sp.csc_matrix)
def test_less_equalds_csr(self):
opT = lambda x, y: x <= y
self.__generalized_ds_test(le, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_less_equalds_csc(self):
opT = lambda x, y: x <= y
self.__generalized_ds_test(le, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_less_thands_csr(self):
opT = lambda x, y: x < y
self.__generalized_ds_test(lt, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_less_thands_csc(self):
opT = lambda x, y: x < y
self.__generalized_ds_test(lt, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_greater_equalds_csr(self):
opT = lambda x, y: x >= y
self.__generalized_ds_test(ge, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_greater_equalds_csc(self):
opT = lambda x, y: x >= y
self.__generalized_ds_test(ge, sparse.csc_matrix,
opT, sp.csc_matrix)
def test_greater_thands_csr(self):
opT = lambda x, y: x > y
self.__generalized_ds_test(gt, sparse.csr_matrix,
opT, sp.csr_matrix)
def test_greater_thands_csc(self):
opT = lambda x, y: x > y
self.assertTrue(numpy.array_equal(f(m1, m2).data, (m1 != m2).data))
self.__generalized_ds_test(gt, sparse.csc_matrix,
opT, sp.csc_matrix)
class T_conversion(unittest.TestCase):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论