Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #208 from larsmans/sparse-ufuncs

ENH implement unary functions on CSR/CSC matrices that don't change the sparsity
  • Loading branch information...
commit 6dc28b2e9a18690f0e6f424e6405dd7e2ea3c235 2 parents 3039101 + 1227008
@rgommers rgommers authored
View
12 doc/release/0.11.0-notes.rst
@@ -61,6 +61,18 @@ added to easily construct diagonal and block-diagonal sparse matrices
respectively.
+New operations on sparse matrices
+---------------------------------
+
+``scipy.sparse.csc_matrix`` and ``csr_matrix`` now support the operations
+``sin``, ``tan``, ``arcsin``, ``arctan``, ``sinh``, ``tanh``, ``arcsinh``,
+``arctanh``, ``rint``, ``sign``, ``expm1``, ``log1p``, ``deg2rad``, ``rad2deg``,
+``floor``, ``ceil`` and ``trunc``.
+
+Previously, these operations had to be performed by operating on the matrices'
+``data`` attribute.
+
+
LSMR iterative solver
---------------------
View
24 scipy/sparse/data.py
@@ -8,9 +8,12 @@
__all__ = []
+import numpy as np
+
from base import spmatrix
from sputils import isscalarlike
+
#TODO implement all relevant operations
#use .data.__methods__() instead of /=, *=, etc.
class _data_matrix(spmatrix):
@@ -66,3 +69,24 @@ def copy(self):
def _mul_scalar(self, other):
return self._with_data(self.data * other)
+
+
+# Add the numpy unary ufuncs for which func(0) = 0 to _data_matrix.
+for npfunc in [np.sin, np.tan, np.arcsin, np.arctan, np.sinh, np.tanh,
+ np.arcsinh, np.arctanh, np.rint, np.sign, np.expm1, np.log1p,
+ np.deg2rad, np.rad2deg, np.floor, np.ceil, np.trunc]:
+ name = npfunc.__name__
+
+ def _create_method(op):
+ def method(self):
+ result = op(self.data)
+ x = self._with_data(result, copy=True)
+ return x
+
+ method.__doc__ = ("Element-wise %s.\n\n"
+ "See numpy.%s for more information." % (name, name))
+ method.__name__ = name
+
+ return method
+
+ setattr(_data_matrix, name, _create_method(npfunc))
View
24 scipy/sparse/tests/test_base.py
@@ -1091,6 +1091,18 @@ def test_eliminate_zeros(self):
assert_array_equal(asp.data,[1, 2, 3])
assert_array_equal(asp.todense(),bsp.todense())
+ def test_ufuncs(self):
+ X = csr_matrix(np.arange(20).reshape(4, 5) / 20.)
+ for f in ["sin", "tan", "arcsin", "arctan", "sinh", "tanh",
+ "arcsinh", "arctanh", "rint", "sign", "expm1", "log1p",
+ "deg2rad", "rad2deg", "floor", "ceil", "trunc"]:
+ assert_equal(hasattr(csr_matrix, f), True)
+ X2 = getattr(X, f)()
+ assert_equal(X.shape, X2.shape)
+ assert_array_equal(X.indices, X2.indices)
+ assert_array_equal(X.indptr, X2.indptr)
+ assert_array_equal(X2.toarray(), getattr(np, f)(X.toarray()))
+
def test_unsorted_arithmetic(self):
data = arange( 5 )
indices = array( [7, 2, 1, 5, 4] )
@@ -1179,6 +1191,18 @@ def test_sort_indices(self):
assert_array_equal(asp.indices,[1, 2, 7, 4, 5])
assert_array_equal(asp.todense(),bsp.todense())
+ def test_ufuncs(self):
+ X = csc_matrix(np.arange(21).reshape(7, 3) / 21.)
+ for f in ["sin", "tan", "arcsin", "arctan", "sinh", "tanh",
+ "arcsinh", "arctanh", "rint", "sign", "expm1", "log1p",
+ "deg2rad", "rad2deg", "floor", "ceil", "trunc"]:
+ assert_equal(hasattr(csr_matrix, f), True)
+ X2 = getattr(X, f)()
+ assert_equal(X.shape, X2.shape)
+ assert_array_equal(X.indices, X2.indices)
+ assert_array_equal(X.indptr, X2.indptr)
+ assert_array_equal(X2.toarray(), getattr(np, f)(X.toarray()))
+
def test_unsorted_arithmetic(self):
data = arange( 5 )
indices = array( [7, 2, 1, 5, 4] )
Please sign in to comment.
Something went wrong with that request. Please try again.