提交 03afa5bb authored 作者: Tomas Capretto's avatar Tomas Capretto 提交者: Ricardo Vieira

Remove SquareDiagonal Op and replace it with a square_diagonal function

上级 2b15ce1a
...@@ -1445,53 +1445,13 @@ class Diag(Op): ...@@ -1445,53 +1445,13 @@ class Diag(Op):
diag = Diag() diag = Diag()
class SquareDiagonal(Op): def square_diagonal(diag):
"""Produce a square sparse (csc) matrix with a diagonal given by a dense vector. """Produce a square sparse (csc) matrix with a diagonal given by a dense vector."""
n = diag.shape[0]
Notes data = ptb.as_tensor_variable(diag)
----- indices = ptb.arange(n, dtype=np.int32)
The grad implemented is regular, i.e. not structured. indptr = ptb.arange(n + 1, dtype=np.int32)
return CSC(data, indices, indptr, ptb.as_tensor((n, n)))
"""
__props__ = ()
def make_node(self, diag):
"""
Parameters
----------
x
Dense vector for the diagonal.
"""
diag = ptb.as_tensor_variable(diag)
if diag.type.ndim != 1:
raise TypeError("data argument must be a vector", diag.type)
return Apply(self, [diag], [SparseTensorType(dtype=diag.dtype, format="csc")()])
def perform(self, node, inputs, outputs):
(z,) = outputs
diag = inputs[0]
N = len(diag)
data = diag[:N]
indices = list(range(N))
indptr = list(range(N + 1))
tup = (data, indices, indptr)
z[0] = scipy.sparse.csc_matrix(tup, copy=True)
def grad(self, inputs, gout):
(gz,) = gout
return [diag(gz)]
def infer_shape(self, fgraph, nodes, shapes):
return [(shapes[0][0], shapes[0][0])]
square_diagonal = SquareDiagonal()
class EnsureSortedIndices(Op): class EnsureSortedIndices(Op):
......
...@@ -29,7 +29,6 @@ from pytensor.sparse.basic import ( ...@@ -29,7 +29,6 @@ from pytensor.sparse.basic import (
Remove0, Remove0,
SparseFromDense, SparseFromDense,
SparseTensorType, SparseTensorType,
SquareDiagonal,
Transpose, Transpose,
VStack, VStack,
_is_sparse, _is_sparse,
...@@ -966,42 +965,33 @@ class TestDiag(utt.InferShapeTester): ...@@ -966,42 +965,33 @@ class TestDiag(utt.InferShapeTester):
verify_grad_sparse(self.op, data, structured=False) verify_grad_sparse(self.op, data, structured=False)
class TestSquareDiagonal(utt.InferShapeTester): class TestSquareDiagonal:
def setup_method(self):
super().setup_method()
self.op_class = SquareDiagonal
self.op = square_diagonal
def test_op(self): def test_op(self):
for format in sparse.sparse_formats: x = vector(dtype=config.floatX)
for size in range(5, 9): y = square_diagonal(x)
variable = [vector()] f = pytensor.function([x], y)
data = [np.random.random(size).astype(config.floatX)]
size = 11
f = pytensor.function(variable, self.op(*variable)) values = np.random.random(size).astype(config.floatX)
tested = f(*data).toarray() tested = f(values)
expected = np.diag(*data) assert tested.format == "csc"
utt.assert_allclose(expected, tested) utt.assert_allclose(tested.toarray(), np.diag(values))
assert tested.dtype == expected.dtype assert tuple(tested.shape) == (values.size, values.size)
assert tested.shape == expected.shape np.testing.assert_array_equal(
tested.indices, np.arange(values.size, dtype="int32")
def test_infer_shape(self): )
for format in sparse.sparse_formats: np.testing.assert_array_equal(
for size in range(5, 9): tested.indptr, np.arange(values.size + 1, dtype="int32")
variable = [vector()] )
data = [np.random.random(size).astype(config.floatX)]
self._compile_and_check(
variable, [self.op(*variable)], data, self.op_class
)
def test_grad(self): def test_grad(self):
for format in sparse.sparse_formats: values = [np.random.random(13).astype(config.floatX)]
for size in range(5, 9): verify_grad_sparse(square_diagonal, values, structured=False)
data = [np.random.random(size).astype(config.floatX)]
verify_grad_sparse(self.op, data, structured=False) def test_rejects_non_vector_input(self):
with pytest.raises(TypeError, match="data argument must be a vector"):
square_diagonal(matrix(dtype=config.floatX))
class TestEnsureSortedIndices(utt.InferShapeTester): class TestEnsureSortedIndices(utt.InferShapeTester):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论