Background: I'm working on a project that historically has relied on sparse matrices for a lot of the math, and developing a plugin to outsource some of the heavy lifting to theano. Since theano's sparse support is limited, we're building a dense version first -- but hopefully that explains why we're interested in the approach below.
The task: apply some operator to only the nonzero values of a matrix.
The following subroutine works most of the time:
import theano.sparse.basic as TSB
def _applyOpToNonzerosOfDense(self,op,expr):
sparseExpr = TSB.clean(TSB.csr_from_dense(expr))
newData = op(TSB.csm_data(sparseExpr)).flatten()
newSparse = TS.CSR(newData, \
TSB.csm_indices(sparseExpr), \
TSB.csm_indptr(sparseExpr), \
TSB.csm_shape(sparseExpr))
ret = TSB.dense_from_sparse(newSparse)
return ret
The problem comes when expr
is not a canonical matrix tensor, but a row tensor (so, expr
is 1xN and expr.broadcastable
is (True, False)
). When that happens, we need to be able to retain or restore the broadcast status in the returned tensor.
Some things I've tried that don't work:
dense_from_sparse
doesn't support broadcastable settings- Theano 0.9 doesn't support assignment to
ret.broadcastable
ret.dimshuffle( ('x',1) )
fails with "You cannot drop a non-broadcastable dimension."
ret
has (ought to have) exactly the same shape as expr
, so I wasn't expecting this to be hard. How do I get my broadcast settings back?