提交 48ef7fd4 authored 作者: Iban Harlouchet's avatar Iban Harlouchet

numpydoc for theano/sparse/basic.py

上级 0a7415d7
"""Classes for handling sparse matrices. """
Classes for handling sparse matrices.
To read about different sparse formats, see To read about different sparse formats, see
http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps
""" """
from __future__ import print_function from __future__ import print_function
...@@ -26,7 +28,10 @@ from theano.sparse.type import SparseType, _is_sparse ...@@ -26,7 +28,10 @@ from theano.sparse.type import SparseType, _is_sparse
sparse_formats = ['csc', 'csr'] sparse_formats = ['csc', 'csr']
""" Types of sparse matrices to use for testing """ """
Types of sparse matrices to use for testing.
"""
_mtypes = [scipy.sparse.csc_matrix, scipy.sparse.csr_matrix] _mtypes = [scipy.sparse.csc_matrix, scipy.sparse.csr_matrix]
# _mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix, # _mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix,
# sparse.lil_matrix, sparse.coo_matrix] # sparse.lil_matrix, sparse.coo_matrix]
...@@ -38,9 +43,13 @@ _mtype_to_str = {scipy.sparse.csc_matrix: "csc", ...@@ -38,9 +43,13 @@ _mtype_to_str = {scipy.sparse.csc_matrix: "csc",
def _is_sparse_variable(x): def _is_sparse_variable(x):
""" """
@rtype: boolean
@return: True iff x is a L{SparseVariable} (and not a L{tensor.TensorType}, Returns
for instance) -------
boolean
True iff x is a L{SparseVariable} (and not a L{tensor.TensorType},
for instance).
""" """
if not isinstance(x, gof.Variable): if not isinstance(x, gof.Variable):
raise NotImplementedError("this function should only be called on " raise NotImplementedError("this function should only be called on "
...@@ -52,9 +61,13 @@ def _is_sparse_variable(x): ...@@ -52,9 +61,13 @@ def _is_sparse_variable(x):
def _is_dense_variable(x): def _is_dense_variable(x):
""" """
@rtype: boolean
@return: True if x is a L{tensor.TensorType} (and not a Returns
L{SparseVariable}, for instance) -------
boolean
True if x is a L{tensor.TensorType} (and not a L{SparseVariable},
for instance).
""" """
if not isinstance(x, gof.Variable): if not isinstance(x, gof.Variable):
raise NotImplementedError("this function should only be called on " raise NotImplementedError("this function should only be called on "
...@@ -65,9 +78,13 @@ def _is_dense_variable(x): ...@@ -65,9 +78,13 @@ def _is_dense_variable(x):
def _is_dense(x): def _is_dense(x):
""" """
@rtype: boolean
@return: True unless x is a L{scipy.sparse.spmatrix} (and not a Returns
L{numpy.ndarray}) -------
boolean
True unless x is a L{scipy.sparse.spmatrix} (and not a
L{numpy.ndarray}).
""" """
if not isinstance(x, (scipy.sparse.spmatrix, numpy.ndarray)): if not isinstance(x, (scipy.sparse.spmatrix, numpy.ndarray)):
raise NotImplementedError("this function should only be called on " raise NotImplementedError("this function should only be called on "
...@@ -92,13 +109,21 @@ def _kmap_hash(a): ...@@ -92,13 +109,21 @@ def _kmap_hash(a):
# Wrapper type # Wrapper type
def as_sparse_variable(x, name=None): def as_sparse_variable(x, name=None):
"""Wrapper around SparseVariable constructor to construct """
Wrapper around SparseVariable constructor to construct
a Variable with a sparse matrix with the same dtype and a Variable with a sparse matrix with the same dtype and
format. format.
:param x: A sparse matrix. Parameters
----------
x
A sparse matrix.
Returns
-------
object
SparseVariable version of `x`.
:return: SparseVariable version of `x`.
""" """
# TODO # TODO
...@@ -124,13 +149,19 @@ as_sparse = as_sparse_variable ...@@ -124,13 +149,19 @@ as_sparse = as_sparse_variable
def as_sparse_or_tensor_variable(x, name=None): def as_sparse_or_tensor_variable(x, name=None):
"""Same as `as_sparse_variable` but If we can't make a """
Same as `as_sparse_variable` but if we can't make a
sparse variable, we try to make a tensor variable. sparse variable, we try to make a tensor variable.
format.
:param x: A sparse matrix. Parameters
----------
x
A sparse matrix.
Returns
-------
SparseVariable or TensorVariable version of `x`
:return: SparseVariable or TensorVariable version of `x`.
""" """
try: try:
...@@ -140,17 +171,27 @@ def as_sparse_or_tensor_variable(x, name=None): ...@@ -140,17 +171,27 @@ def as_sparse_or_tensor_variable(x, name=None):
def verify_grad_sparse(op, pt, structured=False, *args, **kwargs): def verify_grad_sparse(op, pt, structured=False, *args, **kwargs):
"""Wrapper for theano.test.unittest_tools.py:verify_grad wich """
Wrapper for theano.test.unittest_tools.py:verify_grad wich
converts sparse variables back and forth. converts sparse variables back and forth.
:param op: Op to check. Parameters
:param pt: List of inputs to realize the tests. ----------
:param structured: True to tests with a structured grad, op
False otherwise. Op to check.
:param args: Other `verify_grad` parameters if any. pt
:param kwargs: Other `verify_grad` keywords if any. List of inputs to realize the tests.
structured
True to tests with a structured grad, False otherwise.
args
Other `verify_grad` parameters if any.
kwargs
Other `verify_grad` keywords if any.
Returns
-------
None
:return: None
""" """
def conv_none(x): def conv_none(x):
...@@ -222,14 +263,19 @@ def constant(x, name=None): ...@@ -222,14 +263,19 @@ def constant(x, name=None):
def sp_ones_like(x): def sp_ones_like(x):
"""Construct a sparse matrix of ones """
with the same sparsity pattern. Construct a sparse matrix of ones with the same sparsity pattern.
Parameters
----------
x
Sparse matrix to take the sparsity pattern.
:param x: Sparse matrix to take Returns
the sparsity pattern. -------
matrix
The same as `x` with data changed for ones.
:return: The same as `x` with data
changed for ones.
""" """
# TODO: don't restrict to CSM formats # TODO: don't restrict to CSM formats
data, indices, indptr, shape = csm_properties(x) data, indices, indptr, shape = csm_properties(x)
...@@ -237,13 +283,19 @@ def sp_ones_like(x): ...@@ -237,13 +283,19 @@ def sp_ones_like(x):
def sp_zeros_like(x): def sp_zeros_like(x):
"""Construct a sparse matrix of zeros. """
Construct a sparse matrix of zeros.
:param x: Sparse matrix to take Parameters
the shape. ----------
x
Sparse matrix to take the shape.
Returns
-------
matrix
The same as `x` with zero entries for all element.
:return: The same as `x` with zero entries
for all element.
""" """
# TODO: don't restrict to CSM formats # TODO: don't restrict to CSM formats
...@@ -468,8 +520,11 @@ class CSMProperties(gof.Op): ...@@ -468,8 +520,11 @@ class CSMProperties(gof.Op):
view_map = {0: [0], 1: [0], 2: [0]} view_map = {0: [0], 1: [0], 2: [0]}
kmap = None kmap = None
"""Indexing to speficied what part of the data parameter """
should be use to construct the sparse matrix.""" Indexing to speficied what part of the data parameter
should be use to construct the sparse matrix.
"""
def __init__(self, kmap=None): def __init__(self, kmap=None):
self.kmap = kmap self.kmap = kmap
...@@ -533,39 +588,50 @@ Extract all of .data, .indices, .indptr and .shape field. ...@@ -533,39 +588,50 @@ Extract all of .data, .indices, .indptr and .shape field.
For specific field, `csm_data`, `csm_indices`, `csm_indptr` For specific field, `csm_data`, `csm_indices`, `csm_indptr`
and `csm_shape` are provided. and `csm_shape` are provided.
:param csm: Sparse matrix in CSR or CSC format. Parameters
----------
csm
Sparse matrix in CSR or CSC format.
Returns
(data, indices, indptr, shape), the properties of `csm`.
:return: (data, indices, indptr, shape), the properties of `csm`. Notes
-----
The grad implemented is regular, i.e. not structured.
`infer_shape` method is not available for this op.
:note: The grad implemented is regular, i.e. not structured.
`infer_shape` method is not available for this op.
""" """
def csm_data(csm): def csm_data(csm):
""" """
return the data field of the sparse variable. Return the data field of the sparse variable.
""" """
return csm_properties(csm)[0] return csm_properties(csm)[0]
def csm_indices(csm): def csm_indices(csm):
""" """
return the indices field of the sparse variable. Return the indices field of the sparse variable.
""" """
return csm_properties(csm)[1] return csm_properties(csm)[1]
def csm_indptr(csm): def csm_indptr(csm):
""" """
return the indptr field of the sparse variable. Return the indptr field of the sparse variable.
""" """
return csm_properties(csm)[2] return csm_properties(csm)[2]
def csm_shape(csm): def csm_shape(csm):
""" """
return the shape field of the sparse variable. Return the shape field of the sparse variable.
""" """
return csm_properties(csm)[3] return csm_properties(csm)[3]
...@@ -573,11 +639,17 @@ def csm_shape(csm): ...@@ -573,11 +639,17 @@ def csm_shape(csm):
class CSM(gof.Op): class CSM(gof.Op):
# See doc in instance of this Op or function after this class definition. # See doc in instance of this Op or function after this class definition.
kmap = None kmap = None
"""Indexing to speficied what part of the data parameter """
should be use to construct the sparse matrix.""" Indexing to speficied what part of the data parameter
should be used to construct the sparse matrix.
"""
_hashval = None _hashval = None
"""Pre-computed hash value, defined by __init__""" """
Pre-computed hash value, defined by __init__.
"""
def __init__(self, format, kmap=None): def __init__(self, format, kmap=None):
if format not in ('csr', 'csc'): if format not in ('csr', 'csc'):
...@@ -698,49 +770,63 @@ class CSM(gof.Op): ...@@ -698,49 +770,63 @@ class CSM(gof.Op):
CSC = CSM('csc') CSC = CSM('csc')
"""Construct a CSC matrix from the internal """
representation. Construct a CSC matrix from the internal representation.
:param data: One dimensional tensor representing Parameters
the data of the sparse matrix to construct. ----------
:param indices: One dimensional tensor of integers data
representing the indices of the sparse One dimensional tensor representing the data of the sparse matrix to
construct.
indices
One dimensional tensor of integers representing the indices of the sparse
matrix to construct. matrix to construct.
:param indptr: One dimensional tensor of integers indptr
representing the indice pointer for One dimensional tensor of integers representing the indice pointer for
the sparse matrix to construct. the sparse matrix to construct.
:param shape: One dimensional tensor of integers shape
representing the shape of the sparse One dimensional tensor of integers representing the shape of the sparse
matrix to construct. matrix to construct.
:return: A sparse matrix having the properties Returns
specified by the inputs. -------
matrix
A sparse matrix having the properties specified by the inputs.
Notes
-----
The grad method returns a dense vector, so it provides a regular grad.
:note: The grad method returns a dense vector, so it provides
a regular grad.
""" """
CSR = CSM('csr') CSR = CSM('csr')
"""Construct a CSR matrix from the internal """
representation. Construct a CSR matrix from the internal representation.
:param data: One dimensional tensor representing Parameters
the data of the sparse matrix to construct. ----------
:param indices: One dimensional tensor of integers data
representing the indices of the sparse One dimensional tensor representing the data of the sparse matrix to
construct.
indices
One dimensional tensor of integers representing the indices of the sparse
matrix to construct. matrix to construct.
:param indptr: One dimensional tensor of integers indptr
representing the indice pointer for One dimensional tensor of integers representing the indice pointer for
the sparse matrix to construct. the sparse matrix to construct.
:param shape: One dimensional tensor of integers shape
representing the shape of the sparse One dimensional tensor of integers representing the shape of the sparse
matrix to construct. matrix to construct.
:return: A sparse matrix having the properties Returns
specified by the inputs. -------
matrix
A sparse matrix having the properties specified by the inputs.
Notes
-----
The grad method returns a dense vector, so it provides a regular grad.
:note: The grad method returns a dense vector, so it provides
a regular grad.
""" """
...@@ -876,17 +962,25 @@ zcast = Cast('complex128') ...@@ -876,17 +962,25 @@ zcast = Cast('complex128')
def cast(variable, dtype): def cast(variable, dtype):
"""Cast sparse variable to the desired dtype. """
Cast sparse variable to the desired dtype.
:param variable: Sparse matrix. Parameters
:param dtype: the dtype wanted. ----------
variable
Sparse matrix.
dtype
The dtype wanted.
:return: Same as `x` but having `dtype` as dtype. Returns
-------
Same as `x` but having `dtype` as dtype.
:note: The grad implemented is regular, i.e. not Notes
structured. -----
""" The grad implemented is regular, i.e. not structured.
"""
return Cast(dtype)(variable) return Cast(dtype)(variable)
# #
...@@ -949,17 +1043,25 @@ class DenseFromSparse(gof.op.Op): ...@@ -949,17 +1043,25 @@ class DenseFromSparse(gof.op.Op):
return [shapes[0]] return [shapes[0]]
dense_from_sparse = DenseFromSparse() dense_from_sparse = DenseFromSparse()
"""Convert a sparse matrix to a dense one. """
Convert a sparse matrix to a dense one.
:param x: A sparse matrix. Parameters
----------
x
A sparse matrix.
:return: A dense matrix, the same as `x`. Returns
-------
matrix
A dense matrix, the same as `x`.
Notes
-----
The grad implementation can be controlled through the constructor via the
`structured` parameter. `True` will provide a structured grad while `False`
will provide a regular grad. By default, the grad is structured.
:note: The grad implementation can be controlled
through the constructor via the `structured`
parameter. `True` will provide a structured
grad while `False` will provide a regular
grad. By default, the grad is structured.
""" """
...@@ -1009,15 +1111,35 @@ class SparseFromDense(gof.op.Op): ...@@ -1009,15 +1111,35 @@ class SparseFromDense(gof.op.Op):
return [shapes[0]] return [shapes[0]]
csr_from_dense = SparseFromDense('csr') csr_from_dense = SparseFromDense('csr')
"""Convert a dense matrix to a sparse csr matrix. """
:param x: A dense matrix. Convert a dense matrix to a sparse csr matrix.
:return: The same as `x` in a sparse csr matrix format.
Parameters
----------
x
A dense matrix.
Returns
-------
matrix
The same as `x` in a sparse csr matrix format.
""" """
csc_from_dense = SparseFromDense('csc') csc_from_dense = SparseFromDense('csc')
"""Convert a dense matrix to a sparse csc matrix. """
:param x: A dense matrix. Convert a dense matrix to a sparse csc matrix.
:return: The same as `x` in a sparse csc matrix format.
Parameters
----------
x
A dense matrix.
Returns
-------
matrix
The same as `x` in a sparse csc matrix format.
""" """
...@@ -1053,13 +1175,21 @@ class GetItemList(gof.op.Op): ...@@ -1053,13 +1175,21 @@ class GetItemList(gof.op.Op):
grad_undefined(self, 1, indices, "No gradient for this input")] grad_undefined(self, 1, indices, "No gradient for this input")]
get_item_list = GetItemList() get_item_list = GetItemList()
"""Select row of sparse matrix, """
returning them as a new sparse matrix. Select row of sparse matrix, returning them as a new sparse matrix.
:param x: Sparse matrix. Parameters
:param index: List of rows. ----------
x
Sparse matrix.
index
List of rows.
Returns
-------
matrix
The corresponding rows in `x`.
:return: The corresponding rows in `x`.
""" """
...@@ -1127,8 +1257,11 @@ class GetItem2Lists(gof.op.Op): ...@@ -1127,8 +1257,11 @@ class GetItem2Lists(gof.op.Op):
ind1 = inp[1] ind1 = inp[1]
ind2 = inp[2] ind2 = inp[2]
out[0] = numpy.asarray(x[ind1, ind2]).flatten() out[0] = numpy.asarray(x[ind1, ind2]).flatten()
"""Here scipy returns the corresponding elements in a matrix which isn't what we are aiming for. """
Using asarray and flatten, out[0] becomes an array. Here scipy returns the corresponding elements in a matrix which isn't
what we are aiming for. Using asarray and flatten, out[0] becomes an
array.
""" """
def grad(self, inputs, g_outputs): def grad(self, inputs, g_outputs):
x, ind1, ind2 = inputs x, ind1, ind2 = inputs
...@@ -1138,14 +1271,22 @@ class GetItem2Lists(gof.op.Op): ...@@ -1138,14 +1271,22 @@ class GetItem2Lists(gof.op.Op):
grad_undefined(self, 1, ind2, "No gradient for this input")] grad_undefined(self, 1, ind2, "No gradient for this input")]
get_item_2lists = GetItem2Lists() get_item_2lists = GetItem2Lists()
"""Select elements of sparse matrix, returning them in a vector. """
Select elements of sparse matrix, returning them in a vector.
:param x: Sparse matrix. Parameters
----------
x
Sparse matrix.
index
List of two lists, first list indicating the row of each element and second
list indicating its column.
:param index: List of two lists, first list indicating the row of Returns
each element and second list indicating its column. -------
vector
The corresponding elements in `x`.
:return: The corresponding elements in `x`.
""" """
...@@ -1280,31 +1421,38 @@ class GetItem2d(gof.op.Op): ...@@ -1280,31 +1421,38 @@ class GetItem2d(gof.op.Op):
out[0] = x[start1:stop1:step1, start2:stop2:step2] out[0] = x[start1:stop1:step1, start2:stop2:step2]
get_item_2d = GetItem2d() get_item_2d = GetItem2d()
"""Implement a subtensor of sparse variable, returning a """
sparse matrix. Implement a subtensor of sparse variable, returning a sparse matrix.
If you want to take only one element of a sparse matrix see If you want to take only one element of a sparse matrix see
`GetItemScalar` that returns a tensor scalar. `GetItemScalar` that returns a tensor scalar.
.. note:: Parameters
----------
x
Sparse matrix.
index
Tuple of slice object.
Subtensor selection always returns a matrix, so indexing Returns
with [a:b, c:d] is forced. If one index is a scalar, for -------
instance, x[a:b, c] or x[a, b:c], an error will be raised. Use The corresponding slice in `x`.
instead x[a:b, c:c+1] or x[a:a+1, b:c].
Notes
-----
Subtensor selection always returns a matrix, so indexing with [a:b, c:d]
is forced. If one index is a scalar, for instance, x[a:b, c] or x[a, b:c],
an error will be raised. Use instead x[a:b, c:c+1] or x[a:a+1, b:c].
The above indexing methods are not supported because the return value The above indexing methods are not supported because the return value
would be a sparse matrix rather than a sparse vector, which is a would be a sparse matrix rather than a sparse vector, which is a
deviation from numpy indexing rule. This decision is made largely deviation from numpy indexing rule. This decision is made largely
to preserve consistency between numpy and theano. This may be revised to preserve consistency between numpy and theano. This may be revised
when sparse vectors are supported. when sparse vectors are supported.
:param x: Sparse matrix. The grad is not implemented for this op.
:param index: Tuple of slice object.
:return: The corresponding slice in `x`.
:note: The grad is not implemented for this op.
""" """
...@@ -1347,18 +1495,29 @@ class GetItemScalar(gof.op.Op): ...@@ -1347,18 +1495,29 @@ class GetItemScalar(gof.op.Op):
out[0] = theano._asarray(x[ind1, ind2], x.dtype) out[0] = theano._asarray(x[ind1, ind2], x.dtype)
get_item_scalar = GetItemScalar() get_item_scalar = GetItemScalar()
"""Implement a subtensor of a sparse variable that takes """
two scalars as index and returns a scalar. Implement a subtensor of a sparse variable that takes two scalars as index and
returns a scalar.
If you want to take a slice of a sparse matrix see `GetItem2d` that returns a
sparse matrix.
If you want to take a slice of a sparse matrix see Parameters
`GetItem2d` that returns a sparse matrix. ----------
x
Sparse matrix.
index
Tuple of scalars.
:param x: Sparse matrix. Returns
:param index: Tuple of scalars. -------
scalar
The corresponding item in `x`.
:return: The corresponding item in `x`. Notes
-----
The grad is not implemented for this op.
:note: The grad is not implemented for this op.
""" """
...@@ -1397,17 +1556,26 @@ class Transpose(gof.op.Op): ...@@ -1397,17 +1556,26 @@ class Transpose(gof.op.Op):
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [shapes[0][::-1]] return [shapes[0][::-1]]
transpose = Transpose() transpose = Transpose()
"""Return the transpose of the sparse matrix. """
Return the transpose of the sparse matrix.
:param x: Sparse matrix. Parameters
----------
x
Sparse matrix.
:return: `x` transposed. Returns
-------
matrix
`x` transposed.
Notes
-----
The returned matrix will not be in the same format. `csc` matrix will be changed
in `csr` matrix and `csr` matrix in `csc` matrix.
The grad is regular, i.e. not structured.
:note: The returned matrix will not be in the
same format. `csc` matrix will be changed
in `csr` matrix and `csr` matrix in `csc`
matrix.
:note: The grad is regular, i.e. not structured.
""" """
...@@ -1439,13 +1607,23 @@ class Neg(gof.op.Op): ...@@ -1439,13 +1607,23 @@ class Neg(gof.op.Op):
def infer_shape(self, node, shapes): def infer_shape(self, node, shapes):
return [shapes[0]] return [shapes[0]]
neg = Neg() neg = Neg()
"""Return the negation of the sparse matrix. """
Return the negation of the sparse matrix.
Parameters
----------
x
Sparse matrix.
:param x: Sparse matrix. Returns
-------
matrix
-`x`.
:return: -`x`. Notes
-----
The grad is regular, i.e. not structured.
:note: The grad is regular, i.e. not structured.
""" """
...@@ -1543,18 +1721,26 @@ class RowScaleCSC(gof.op.Op): ...@@ -1543,18 +1721,26 @@ class RowScaleCSC(gof.op.Op):
def col_scale(x, s): def col_scale(x, s):
"""Scale each columns of a sparse matrix by the corresponding """
element of a dense vector Scale each columns of a sparse matrix by the corresponding element of a
dense vector.
Parameters
----------
x
A sparse matrix.
s
A dense vector with length equal to the number of columns of `x`.
:param x: A sparse matrix. Returns
:param s: A dense vector with length equal to the number -------
of columns of `x`. A sparse matrix in the same format as `x` which each column had been
multiply by the corresponding element of `s`.
:return: A sparse matrix in the same format as `x` which Notes
each column had been multiply by the corresponding -----
element of `s`. The grad implemented is structured.
:note: The grad implemented is structured.
""" """
if x.format == 'csc': if x.format == 'csc':
...@@ -1566,18 +1752,27 @@ def col_scale(x, s): ...@@ -1566,18 +1752,27 @@ def col_scale(x, s):
def row_scale(x, s): def row_scale(x, s):
"""Scale each row of a sparse matrix by the corresponding element of """
a dense vector Scale each row of a sparse matrix by the corresponding element of
a dense vector.
:param x: A sparse matrix.
:param s: A dense vector with length equal to the number Parameters
of rows of `x`. ----------
x
:return: A sparse matrix in the same format as `x` which A sparse matrix.
each row had been multiply by the corresponding s
element of `s`. A dense vector with length equal to the number of rows of `x`.
Returns
-------
matrix
A sparse matrix in the same format as `x` whose each row has been
multiplied by the corresponding element of `s`.
Notes
-----
The grad implemented is structured.
:note: The grad implemented is structured.
""" """
return col_scale(x.T, s).T return col_scale(x.T, s).T
...@@ -1664,24 +1859,35 @@ class SpSum(gof.op.Op): ...@@ -1664,24 +1859,35 @@ class SpSum(gof.op.Op):
def sp_sum(x, axis=None, sparse_grad=False): def sp_sum(x, axis=None, sparse_grad=False):
"""Calculate the sum of a sparse matrix along the specified """
axis. Calculate the sum of a sparse matrix along the specified axis.
It operates a reduction along the specified axis. When It operates a reduction along the specified axis. When `axis` is `None`,
`axis` is `None`, it is applied along all axes. it is applied along all axes.
:param x: Sparse matrix. Parameters
:param axis: Axis along which the sum is applied. Integer or `None`. ----------
:param sparse_grad: `True` to have a structured grad. Boolean. x
Sparse matrix.
:return: The sum of `x` in a dense format. axis
Axis along which the sum is applied. Integer or `None`.
sparse_grad : bool
`True` to have a structured grad.
Returns
-------
object
The sum of `x` in a dense format.
Notes
-----
The grad implementation is controlled with the `sparse_grad` parameter.
`True` will provide a structured grad and `False` will provide a regular
grad. For both choices, the grad returns a sparse matrix having the same
format as `x`.
This op does not return a sparse matrix, but a dense tensor matrix.
:note: The grad implementation is controlled with the `sparse_grad`
parameter. `True` will provide a structured grad and `False`
will provide a regular grad. For both choices, the grad
returns a sparse matrix having the same format as `x`.
:note: This op does not return a sparse matrix, but a dense tensor
matrix.
""" """
return SpSum(axis, sparse_grad)(x) return SpSum(axis, sparse_grad)(x)
...@@ -1714,16 +1920,24 @@ class Diag(gof.op.Op): ...@@ -1714,16 +1920,24 @@ class Diag(gof.op.Op):
return [(tensor.minimum(*shapes[0]), )] return [(tensor.minimum(*shapes[0]), )]
diag = Diag() diag = Diag()
"""Extract the diagonal of a square sparse matrix as a dense vector. """
Extract the diagonal of a square sparse matrix as a dense vector.
:param x: A square sparse matrix in csc format. Parameters
----------
x
A square sparse matrix in csc format.
:return: A dense vector representing the diagonal elements. Returns
-------
vector
A dense vector representing the diagonal elements.
.. note:: Notes
-----
The grad implemented is regular, i.e. not structured, since the output is a
dense vector.
The grad implemented is regular, i.e. not structured, since the
output is a dense vector.
""" """
...@@ -1760,14 +1974,24 @@ class SquareDiagonal(gof.op.Op): ...@@ -1760,14 +1974,24 @@ class SquareDiagonal(gof.op.Op):
return [(shapes[0][0], shapes[0][0])] return [(shapes[0][0], shapes[0][0])]
square_diagonal = SquareDiagonal() square_diagonal = SquareDiagonal()
"""Return a square sparse (csc) matrix whose diagonal """
is given by the dense vector argument. Return a square sparse (csc) matrix whose diagonal is given by the dense vector
argument.
Parameters
----------
x
Dense vector for the diagonal.
:param x: Dense vector for the diagonal. Returns
-------
matrix
A sparse matrix having `x` as diagonal.
:return: A sparse matrix having `x` as diagonal. Notes
-----
The grad implemented is regular, i.e. not structured.
:note: The grad implemented is regular, i.e. not structured.
""" """
...@@ -1805,36 +2029,55 @@ class EnsureSortedIndices(gof.op.Op): ...@@ -1805,36 +2029,55 @@ class EnsureSortedIndices(gof.op.Op):
else: else:
return self.__class__.__name__ + "{no_inplace}" return self.__class__.__name__ + "{no_inplace}"
ensure_sorted_indices = EnsureSortedIndices(inplace=False) ensure_sorted_indices = EnsureSortedIndices(inplace=False)
"""Re-sort indices of a sparse matrix. """
Re-sort indices of a sparse matrix.
CSR column indices are not necessarily sorted. Likewise CSR column indices are not necessarily sorted. Likewise
for CSC row indices. Use `ensure_sorted_indices` when sorted for CSC row indices. Use `ensure_sorted_indices` when sorted
indices are required (e.g. when passing data to other indices are required (e.g. when passing data to other
libraries). libraries).
:param x: A sparse matrix. Parameters
----------
x
A sparse matrix.
:return: The same as `x` with indices sorted. Returns
-------
matrix
The same as `x` with indices sorted.
Notes
-----
The grad implemented is regular, i.e. not structured.
:note: The grad implemented is regular, i.e. not structured.
""" """
def clean(x): def clean(x):
"""Remove explicit zeros from a sparse matrix, and """
re-sort indices. Remove explicit zeros from a sparse matrix, and re-sort indices.
CSR column indices are not necessarily sorted. Likewise CSR column indices are not necessarily sorted. Likewise
for CSC row indices. Use `clean` when sorted for CSC row indices. Use `clean` when sorted
indices are required (e.g. when passing data to other indices are required (e.g. when passing data to other
libraries) and to ensure there are no zeros in the data. libraries) and to ensure there are no zeros in the data.
:param x: A sparse matrix. Parameters
----------
x
A sparse matrix.
Returns
-------
matrix
The same as `x` with indices sorted and zeros
removed.
:return: The same as `x` with indices sorted and zeros Notes
removed. -----
The grad implemented is regular, i.e. not structured.
:note: The grad implemented is regular, i.e. not structured.
""" """
return ensure_sorted_indices(remove0(x)) return ensure_sorted_indices(remove0(x))
...@@ -1911,17 +2154,26 @@ class AddSSData(gof.op.Op): ...@@ -1911,17 +2154,26 @@ class AddSSData(gof.op.Op):
return [ins_shapes[0]] return [ins_shapes[0]]
add_s_s_data = AddSSData() add_s_s_data = AddSSData()
"""Add two sparse matrices assuming they have the same sparsity """
pattern. Add two sparse matrices assuming they have the same sparsity pattern.
Parameters
----------
x
Sparse matrix.
y
Sparse matrix.
:param x: Sparse matrix. Returns
:param y: Sparse matrix. -------
matrix
The sum of the two sparse matrices element wise.
:return: The sum of the two sparse matrices element wise. Notes
-----
`x` and `y` are assumed to have the same sparsity pattern.
:note: `x` and `y` are assumed to have the same The grad implemented is structured.
sparsity pattern.
:note: The grad implemented is structured.
""" """
...@@ -2003,35 +2255,58 @@ class StructuredAddSV(gof.op.Op): ...@@ -2003,35 +2255,58 @@ class StructuredAddSV(gof.op.Op):
return [ins_shapes[0]] return [ins_shapes[0]]
structured_add_s_v = StructuredAddSV() structured_add_s_v = StructuredAddSV()
"""Structured addition of a sparse matrix and a dense vector. """
Structured addition of a sparse matrix and a dense vector.
The elements of the vector are only added to the corresponding The elements of the vector are only added to the corresponding
non-zero elements of the sparse matrix. Therefore, this operation non-zero elements of the sparse matrix. Therefore, this operation
outputs another sparse matrix. outputs another sparse matrix.
:param x: Sparse matrix. Parameters
:param y: Tensor type vector. ----------
x
:return: A sparse matrix containing the addition of the vector to Sparse matrix.
y
Tensor type vector.
Returns
-------
matrix
A sparse matrix containing the addition of the vector to
the data of the sparse matrix. the data of the sparse matrix.
:note: The grad implemented is structured since the op is structured. Notes
-----
The grad implemented is structured since the op is structured.
""" """
def add(x, y): def add(x, y):
"""Add two matrices, at least one of which is sparse. """
Add two matrices, at least one of which is sparse.
This method will provide the right op according This method will provide the right op according
to the inputs. to the inputs.
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
:return: `x` + `y` Returns
-------
matrix
`x` + `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
The grad will be structured only when one of the variable will be a dense
matrix.
:note: At least one of `x` and `y` must be a sparse matrix.
:note: The grad will be structured only when one of the
variable will be a dense matrix.
""" """
if hasattr(x, 'getnnz'): if hasattr(x, 'getnnz'):
...@@ -2058,21 +2333,32 @@ def add(x, y): ...@@ -2058,21 +2333,32 @@ def add(x, y):
def sub(x, y): def sub(x, y):
"""Substact two matrices, at least one of which is sparse. """
Subtract two matrices, at least one of which is sparse.
This method will provide the right op according This method will provide the right op according
to the inputs. to the inputs.
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
:return: `x` - `y` Returns
-------
matrix
`x` - `y`
:note: At least one of `x` and `y` must be a sparse matrix. Notes
:note: The grad will be structured only when one of the variable -----
will be a dense matrix. At least one of `x` and `y` must be a sparse matrix.
"""
The grad will be structured only when one of the variable will be a dense
matrix.
"""
return x + (-y) return x + (-y)
...@@ -2249,31 +2535,51 @@ class MulSV(gof.op.Op): ...@@ -2249,31 +2535,51 @@ class MulSV(gof.op.Op):
return [ins_shapes[0]] return [ins_shapes[0]]
mul_s_v = MulSV() mul_s_v = MulSV()
"""Multiplication of sparse matrix by a broadcasted dense vector element wise. """
Multiplication of sparse matrix by a broadcasted dense vector element wise.
Parameters
----------
x
Sparse matrix to multiply.
y
Tensor broadcastable vector.
:param x: Sparse matrix to multiply. Returns
:param y: Tensor broadcastable vector. -------
matrix
The product x * y element wise.
:Return: The product x * y element wise. Notes
-----
The grad implemented is regular, i.e. not structured.
:note: The grad implemented is regular, i.e. not structured.
""" """
def mul(x, y): def mul(x, y):
"""Multiply elementwise two matrices, at least one """
of which is sparse. Multiply elementwise two matrices, at least one of which is sparse.
This method will provide the right op according This method will provide the right op according to the inputs.
to the inputs.
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
:return: `x` + `y` Returns
-------
matrix
`x` + `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
The grad is regular, i.e. not structured.
:note: At least one of `x` and `y` must be a sparse matrix.
:note: The grad is regular, i.e. not structured.
""" """
x = as_sparse_or_tensor_variable(x) x = as_sparse_or_tensor_variable(x)
...@@ -2305,14 +2611,22 @@ def mul(x, y): ...@@ -2305,14 +2611,22 @@ def mul(x, y):
class __ComparisonOpSS(gof.op.Op): class __ComparisonOpSS(gof.op.Op):
""" """
Used as a superclass for all comparisons between Used as a superclass for all comparisons between two sparses matrices.
two sparses matrices
Parameters
----------
x
First compared sparse matrix.
y
Second compared sparse matrix
:param x:first compared sparse matrix Returns
:param y:second compared sparse matrix -------
object
Comparison(x,y)
:return: Comparison(x,y)
""" """
__props__ = () __props__ = ()
# Function to override # Function to override
...@@ -2343,14 +2657,22 @@ class __ComparisonOpSS(gof.op.Op): ...@@ -2343,14 +2657,22 @@ class __ComparisonOpSS(gof.op.Op):
class __ComparisonOpSD(gof.op.Op): class __ComparisonOpSD(gof.op.Op):
""" """
Used as a superclass for all comparisons between Used as a superclass for all comparisons between sparse and dense matrix.
sparse and dense matrix
:param x:sparse matrix Parameters
:param y:dense matrix ----------
x
Sparse matrix.
y
Dense matrix.
Returns
-------
object
Comparison(x,y)
:return: Comparison(x,y)
""" """
__props__ = () __props__ = ()
# Function to override # Function to override
...@@ -2380,14 +2702,27 @@ class __ComparisonOpSD(gof.op.Op): ...@@ -2380,14 +2702,27 @@ class __ComparisonOpSD(gof.op.Op):
def __ComparisonSwitch(SS, SD, DS): 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 Parameters
----------
SS
Function to apply between two sparses matrices.
SD
Function to apply between a sparse and a dense matrix.
DS
Function to apply between a dense and a sparse matrix.
Returns
-------
function
Switch function taking two matrices as input.
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
DS swap input as a dense matrix cannot be a left operand.
:note: At least one of `x` and `y` must be a sparse matrix.
:note: DS swap input as a dense matrix cannot be a left operand.
""" """
def helper(x, y): def helper(x, y):
...@@ -2508,66 +2843,125 @@ greater_equal_s_d = GreaterEqualSD() ...@@ -2508,66 +2843,125 @@ greater_equal_s_d = GreaterEqualSD()
eq = __ComparisonSwitch(equal_s_s, equal_s_d, equal_s_d) eq = __ComparisonSwitch(equal_s_s, equal_s_d, equal_s_d)
""" """
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
Returns
-------
matrix
`x` == `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
:return: `x` == `y`
:note: At least one of `x` and `y` must be a sparse matrix.
""" """
neq = __ComparisonSwitch(not_equal_s_s, not_equal_s_d, not_equal_s_d) neq = __ComparisonSwitch(not_equal_s_s, not_equal_s_d, not_equal_s_d)
""" """
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
:return: `x` != `y` A matrix variable.
y
A matrix variable.
Returns
-------
matrix
`x` != `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
:note: At least one of `x` and `y` must be a sparse matrix.
""" """
lt = __ComparisonSwitch(less_than_s_s, less_than_s_d, greater_than_s_d) lt = __ComparisonSwitch(less_than_s_s, less_than_s_d, greater_than_s_d)
""" """
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
Returns
-------
matrix
`x` < `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
:return: `x` < `y`
:note: At least one of `x` and `y` must be a sparse matrix.
""" """
gt = __ComparisonSwitch(greater_than_s_s, greater_than_s_d, less_than_s_d) gt = __ComparisonSwitch(greater_than_s_s, greater_than_s_d, less_than_s_d)
""" """
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
:return: `x` > `y` A matrix variable.
y
A matrix variable.
Returns
-------
matrix
`x` > `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
:note: At least one of `x` and `y` must be a sparse matrix.
""" """
le = __ComparisonSwitch(less_equal_s_s, less_equal_s_d, greater_equal_s_d) le = __ComparisonSwitch(less_equal_s_s, less_equal_s_d, greater_equal_s_d)
""" """
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
Returns
-------
`x` <= `y`
:return: `x` <= `y` Notes
-----
At least one of `x` and `y` must be a sparse matrix.
:note: At least one of `x` and `y` must be a sparse matrix.
""" """
ge = __ComparisonSwitch(greater_equal_s_s, greater_equal_s_d, ge = __ComparisonSwitch(greater_equal_s_s, greater_equal_s_d,
less_equal_s_d) less_equal_s_d)
""" """
:param x: A matrix variable. Parameters
:param y: A matrix variable. ----------
x
A matrix variable.
y
A matrix variable.
Returns
-------
matrix
`x` >= `y`
Notes
-----
At least one of `x` and `y` must be a sparse matrix.
:return: `x` >= `y`
:note: At least one of `x` and `y` must be a sparse matrix.
""" """
...@@ -2644,19 +3038,31 @@ class HStack(gof.op.Op): ...@@ -2644,19 +3038,31 @@ class HStack(gof.op.Op):
def hstack(blocks, format=None, dtype=None): def hstack(blocks, format=None, dtype=None):
"""Stack sparse matrices horizontally (column wise). """
Stack sparse matrices horizontally (column wise).
This wrap the method hstack from scipy. This wrap the method hstack from scipy.
:param blocks: List of sparse array of compatible shape. Parameters
:param format: String representing the output format. Default ----------
is csc. blocks
:param dtype: Output dtype. List of sparse array of compatible shape.
format
String representing the output format. Default is csc.
dtype
Output dtype.
Returns
-------
array
The concatenation of the sparse array column wise.
:return: The concatenation of the sparse array column wise. Notes
-----
The number of line of the sparse matrix must agree.
The grad implemented is regular, i.e. not structured.
:note: The number of line of the sparse matrix must agree.
:note: The grad implemented is regular, i.e. not structured.
""" """
blocks = [as_sparse_variable(i) for i in blocks] blocks = [as_sparse_variable(i) for i in blocks]
...@@ -2710,19 +3116,31 @@ class VStack(HStack): ...@@ -2710,19 +3116,31 @@ class VStack(HStack):
def vstack(blocks, format=None, dtype=None): def vstack(blocks, format=None, dtype=None):
"""Stack sparse matrices vertically (row wise). """
Stack sparse matrices vertically (row wise).
This wrap the method vstack from scipy. This wrap the method vstack from scipy.
:param blocks: List of sparse array of compatible shape. Parameters
:param format: String representing the output format. Default ----------
is csc. blocks
:param dtype: Output dtype. List of sparse array of compatible shape.
format
String representing the output format. Default is csc.
dtype
Output dtype.
Returns
-------
array
The concatenation of the sparse array row wise.
:return: The concatenation of the sparse array row wise. Notes
-----
The number of column of the sparse matrix must agree.
The grad implemented is regular, i.e. not structured.
:note: The number of column of the sparse matrix must agree.
:note: The grad implemented is regular, i.e. not structured.
""" """
blocks = [as_sparse_variable(i) for i in blocks] blocks = [as_sparse_variable(i) for i in blocks]
...@@ -2769,13 +3187,23 @@ class Remove0(gof.Op): ...@@ -2769,13 +3187,23 @@ class Remove0(gof.Op):
def infer_shape(self, node, i0_shapes): def infer_shape(self, node, i0_shapes):
return i0_shapes return i0_shapes
remove0 = Remove0() remove0 = Remove0()
"""Remove explicit zeros from a sparse matrix. """
Remove explicit zeros from a sparse matrix.
Parameters
----------
x
Sparse matrix.
Returns
-------
matrix
Exactly `x` but with a data attribute exempt of zeros.
:param x: Sparse matrix. Notes
-----
The grad implemented is regular, i.e. not structured.
:return: Exactly `x` but with a data attribute
exempt of zeros.
:note: The grad implemented is regular, i.e. not structured.
""" """
...@@ -2806,53 +3234,63 @@ def structured_monoid(tensor_op): ...@@ -2806,53 +3234,63 @@ def structured_monoid(tensor_op):
@structured_monoid(tensor.nnet.sigmoid) @structured_monoid(tensor.nnet.sigmoid)
def structured_sigmoid(x): def structured_sigmoid(x):
"""structured elemwise sigmoid. """
Structured elemwise sigmoid.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.exp) @structured_monoid(tensor.exp)
def structured_exp(x): def structured_exp(x):
"""structured elemwise exponential. """
Structured elemwise exponential.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.log) @structured_monoid(tensor.log)
def structured_log(x): def structured_log(x):
"""structured elemwise logarithm. """
Structured elemwise logarithm.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.pow) @structured_monoid(tensor.pow)
def structured_pow(x, y): def structured_pow(x, y):
"""structured elemwise power of sparse matrix """
x by scalar y. Structured elemwise power of sparse matrix x by scalar y.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.minimum) @structured_monoid(tensor.minimum)
def structured_minimum(x, y): def structured_minimum(x, y):
"""structured elemwise minimum of sparse matrix """
x by scalar y. Structured elemwise minimum of sparse matrix x by scalar y.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.maximum) @structured_monoid(tensor.maximum)
def structured_maximum(x, y): def structured_maximum(x, y):
"""structured elemwise maximum of sparse matrix """
x by scalar y. Structured elemwise maximum of sparse matrix x by scalar y.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.add) @structured_monoid(tensor.add)
def structured_add(x): def structured_add(x):
"""structured addition of sparse matrix """
x and scalar y. Structured addition of sparse matrix x and scalar y.
""" """
# see decorator for function body # see decorator for function body
...@@ -2860,64 +3298,82 @@ def structured_add(x): ...@@ -2860,64 +3298,82 @@ def structured_add(x):
# Sparse operation (map 0 to 0) # Sparse operation (map 0 to 0)
@structured_monoid(tensor.sin) @structured_monoid(tensor.sin)
def sin(x): def sin(x):
"""Elemwise sinus of `x`. """
Elemwise sinus of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.tan) @structured_monoid(tensor.tan)
def tan(x): def tan(x):
"""Elemwise tan of `x`. """
Elemwise tan of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.arcsin) @structured_monoid(tensor.arcsin)
def arcsin(x): def arcsin(x):
"""Elemwise arcsinus of `x`. """
Elemwise arcsinus of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.arctan) @structured_monoid(tensor.arctan)
def arctan(x): def arctan(x):
"""Elemwise arctan of `x`. """
Elemwise arctan of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.sinh) @structured_monoid(tensor.sinh)
def sinh(x): def sinh(x):
"""Elemwise sinh of `x`. """
Elemwise sinh of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.arcsinh) @structured_monoid(tensor.arcsinh)
def arcsinh(x): def arcsinh(x):
"""Elemwise arcsinh of `x`. """
Elemwise arcsinh of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.tanh) @structured_monoid(tensor.tanh)
def tanh(x): def tanh(x):
"""Elemwise tanh of `x`. """
Elemwise tanh of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.arctanh) @structured_monoid(tensor.arctanh)
def arctanh(x): def arctanh(x):
"""Elemwise arctanh of `x`. """
Elemwise arctanh of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.round_half_to_even) @structured_monoid(tensor.round_half_to_even)
def rint(x): def rint(x):
"""Elemwise round half to even of `x`.
""" """
Elemwise round half to even of `x`.
"""
# see decorator for function body # see decorator for function body
# Give it a simple name instead of the complex one that would automatically # Give it a simple name instead of the complex one that would automatically
...@@ -2927,77 +3383,99 @@ rint.__name__ = 'rint' ...@@ -2927,77 +3383,99 @@ rint.__name__ = 'rint'
@structured_monoid(tensor.sgn) @structured_monoid(tensor.sgn)
def sgn(x): def sgn(x):
"""Elemwise signe of `x`. """
Elemwise signe of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.ceil) @structured_monoid(tensor.ceil)
def ceil(x): def ceil(x):
"""Elemwise ceiling of `x`. """
Elemwise ceiling of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.floor) @structured_monoid(tensor.floor)
def floor(x): def floor(x):
"""Elemwise floor of `x`. """
Elemwise floor of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.log1p) @structured_monoid(tensor.log1p)
def log1p(x): def log1p(x):
"""Elemwise log(1 + `x`). """
Elemwise log(1 + `x`).
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.expm1) @structured_monoid(tensor.expm1)
def expm1(x): def expm1(x):
"""Elemwise e^`x` - 1. """
Elemwise e^`x` - 1.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.deg2rad) @structured_monoid(tensor.deg2rad)
def deg2rad(x): def deg2rad(x):
"""Elemwise degree to radian. """
Elemwise degree to radian.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.rad2deg) @structured_monoid(tensor.rad2deg)
def rad2deg(x): def rad2deg(x):
"""Elemwise radian to degree. """
Elemwise radian to degree.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.trunc) @structured_monoid(tensor.trunc)
def trunc(x): def trunc(x):
"""Elemwise truncature. """
Elemwise truncature.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.sqr) @structured_monoid(tensor.sqr)
def sqr(x): def sqr(x):
"""Elemwise `x` * `x`. """
Elemwise `x` * `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.sqrt) @structured_monoid(tensor.sqrt)
def sqrt(x): def sqrt(x):
"""Elemwise square root of `x`. """
Elemwise square root of `x`.
""" """
# see decorator for function body # see decorator for function body
@structured_monoid(tensor.conj) @structured_monoid(tensor.conj)
def conj(x): def conj(x):
"""Elemwise complex conjugate of `x`. """
Elemwise complex conjugate of `x`.
""" """
# see decorator for function body # see decorator for function body
...@@ -3097,15 +3575,24 @@ def true_dot(x, y, grad_preserves_dense=True): ...@@ -3097,15 +3575,24 @@ def true_dot(x, y, grad_preserves_dense=True):
one or all operands are sparse. Supported formats are CSC and CSR. one or all operands are sparse. Supported formats are CSC and CSR.
The output of the operation is sparse. The output of the operation is sparse.
:param x: Sparse matrix. Parameters
:param y: Sparse matrix or 2d tensor variable. ----------
:param grad_preserves_dense: if True (default), makes the grad of x
dense inputs dense. Otherwise the grad is always sparse. Sparse matrix.
y
Sparse matrix or 2d tensor variable.
grad_preserves_dense : bool
If True (default), makes the grad of dense inputs dense.
Otherwise the grad is always sparse.
:return: The dot product `x`.`y` in a sparse format. Returns
-------
The dot product `x`.`y` in a sparse format.
Notex
-----
The grad implemented is regular, i.e. not structured.
:note:
- The grad implemented is regular, i.e. not structured.
""" """
# TODO # TODO
# Maybe the triple-transposition formulation # Maybe the triple-transposition formulation
...@@ -3214,19 +3701,30 @@ _structured_dot = StructuredDot() ...@@ -3214,19 +3701,30 @@ _structured_dot = StructuredDot()
def structured_dot(x, y): def structured_dot(x, y):
"""Structured Dot is like dot, except that only the """
Structured Dot is like dot, except that only the
gradient wrt non-zero elements of the sparse matrix gradient wrt non-zero elements of the sparse matrix
`a` are calculated and propagated. `a` are calculated and propagated.
The output is presumed to be a dense matrix, and is represented by a The output is presumed to be a dense matrix, and is represented by a
TensorType instance. TensorType instance.
:param a: A sparse matrix. Parameters
:param b: A sparse or dense matrix. ----------
a
A sparse matrix.
b
A sparse or dense matrix.
Returns
-------
matrix
The dot product of `a` and `b`.
:return: The dot product of `a` and `b`. Notes
-----
The grad implemented is structured.
:note: The grad implemented is structured.
""" """
# @todo: Maybe the triple-transposition formulation (when x is dense) # @todo: Maybe the triple-transposition formulation (when x is dense)
...@@ -3581,7 +4079,8 @@ class SamplingDot(gof.op.Op): ...@@ -3581,7 +4079,8 @@ class SamplingDot(gof.op.Op):
return [ins_shapes[2]] return [ins_shapes[2]]
sampling_dot = SamplingDot() sampling_dot = SamplingDot()
"""Operand for calculating the dot product dot(`x`, `y`.T) = `z` when you """
Operand for calculating the dot product dot(`x`, `y`.T) = `z` when you
only want to calculate a subset of `z`. only want to calculate a subset of `z`.
It is equivalent to `p` o (`x` . `y`.T) where o is the element-wise It is equivalent to `p` o (`x` . `y`.T) where o is the element-wise
...@@ -3591,21 +4090,30 @@ and 0 when it shouldn't. Note that SamplingDot has a different interface ...@@ -3591,21 +4090,30 @@ and 0 when it shouldn't. Note that SamplingDot has a different interface
than `dot` because SamplingDot requires `x` to be a `m`x`k` matrix while than `dot` because SamplingDot requires `x` to be a `m`x`k` matrix while
`y` is a `n`x`k` matrix instead of the usual `k`x`n` matrix. `y` is a `n`x`k` matrix instead of the usual `k`x`n` matrix.
.. note:: Notes
-----
It will work if the pattern is not binary value, but if the It will work if the pattern is not binary value, but if the
pattern doesn't have a high sparsity proportion it will be slower pattern doesn't have a high sparsity proportion it will be slower
then a more optimized dot followed by a normal elemwise then a more optimized dot followed by a normal elemwise
multiplication. multiplication.
:param x: Tensor matrix. The grad implemented is regular, i.e. not structured.
:param y: Tensor matrix.
:param p: Sparse matrix in csr format. Parameters
----------
:return: A dense matrix containing the dot product of `x` by `y`.T only x
Tensor matrix.
y
Tensor matrix.
p
Sparse matrix in csr format.
Returns
-------
matrix
A dense matrix containing the dot product of `x` by `y`.T only
where `p` is 1. where `p` is 1.
:note: The grad implemented is regular, i.e. not structured.
""" """
...@@ -3707,21 +4215,32 @@ _dot = Dot() ...@@ -3707,21 +4215,32 @@ _dot = Dot()
def dot(x, y): def dot(x, y):
"""Operation for efficiently calculating the dot product when """
Operation for efficiently calculating the dot product when
one or all operands is sparse. Supported format are CSC and CSR. one or all operands is sparse. Supported format are CSC and CSR.
The output of the operation is dense. The output of the operation is dense.
:param x: sparse or dense matrix variable. Parameters
:param y: sparse or dense matrix variable. ----------
x
Sparse or dense matrix variable.
y
Sparse or dense matrix variable.
Returns
-------
The dot product `x`.`y` in a dense format.
Notes
-----
The grad implemented is regular, i.e. not structured.
At least one of `x` or `y` must be a sparse matrix.
:return: The dot product `x`.`y` in a dense format. When the operation has the form dot(csr_matrix, dense)
the gradient of this operation can be performed inplace
by UsmmCscDense. This leads to significant speed-ups.
:note: The grad implemented is regular, i.e. not structured.
:note: At least one of `x` or `y` must be a sparse matrix.
:note: At least one of `x` or `y` must be a sparse matrix.
:note: When the operation has the form dot(csr_matrix, dense)
the gradient of this operation can be performed inplace
by UsmmCscDense. This leads to significant speed-ups.
""" """
if hasattr(x, 'getnnz'): if hasattr(x, 'getnnz'):
...@@ -3796,17 +4315,29 @@ class Usmm(gof.op.Op): ...@@ -3796,17 +4315,29 @@ class Usmm(gof.op.Op):
out[0] = rval out[0] = rval
usmm = Usmm() usmm = Usmm()
"""Performs the expression `alpha` * `x` `y` + `z`. """
Performs the expression `alpha` * `x` `y` + `z`.
:param x: Matrix variable.
:param y: Matrix variable. Parameters
:param z: Dense matrix. ----------
:param alpha: A tensor scalar. x
Matrix variable.
:return: The dense matrix resulting from `alpha` * `x` `y` + `z`. y
Matrix variable.
z
Dense matrix.
alpha
A tensor scalar.
Returns
-------
The dense matrix resulting from `alpha` * `x` `y` + `z`.
Notes
-----
The grad is not implemented for this op.
At least one of `x` or `y` must be a sparse matrix.
:note: The grad is not implemented for this op.
:note: At least one of `x` or `y` must be a sparse matrix.
""" """
...@@ -3816,11 +4347,16 @@ class ConstructSparseFromList(gof.Op): ...@@ -3816,11 +4347,16 @@ class ConstructSparseFromList(gof.Op):
def make_node(self, x, values, ilist): def make_node(self, x, values, ilist):
""" """
:param x: a dense matrix that specify the output shape.
:param values: a dense matrix with the values to use for output. Parameters
:param ilist: a dense vector with the same length as the number of rows ----------
of values. It specify where in the output to put x
the corresponding rows. A dense matrix that specify the output shape.
values
A dense matrix with the values to use for output.
ilist
A dense vector with the same length as the number of rows of values.
It specify where in the output to put the corresponding rows.
This create a sparse matrix with the same shape as `x`. Its This create a sparse matrix with the same shape as `x`. Its
values are the rows of `values` moved. Pseudo-code:: values are the rows of `values` moved. Pseudo-code::
...@@ -3894,7 +4430,11 @@ class ConstructSparseFromList(gof.Op): ...@@ -3894,7 +4430,11 @@ class ConstructSparseFromList(gof.Op):
return [gx, gy] + [DisconnectedType()()] * len(idx_list) return [gx, gy] + [DisconnectedType()()] * len(idx_list)
construct_sparse_from_list = ConstructSparseFromList() construct_sparse_from_list = ConstructSparseFromList()
"""Constructs a sparse matrix out of a list of 2-D matrix rows """
Constructs a sparse matrix out of a list of 2-D matrix rows.
Notes
-----
The grad implemented is regular, i.e. not structured.
:note: The grad implemented is regular, i.e. not structured.
""" """
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论