Note that you want scipy >= 0.7.0. 0.6 has a very bug and inconsistent
implementation of sparse matrices.
We describe the details of the compressed sparse matrix types.
``scipy.sparse.csc_matrix``
should be used if the columns are sparse.
``scipy.sparse.csr_matrix``
should be used if the rows are sparse.
``scipy.sparse.lil_matrix``
is faster if we are modifying the array. After initial inserts,
we can then convert to the appropriate sparse matrix format.
There are four member variables that comprise a compressed matrix ``sp``:
``sp.shape``
gives the shape of the matrix.
``sp.data``
gives the values of the non-zero entries. For CSC, these should
be in order from (I think, not sure) reading down in columns,
starting at the leftmost column until we reach the rightmost
column.
``sp.indices``
gives the location of the non-zero entry. For CSC, this is the
row location.
``sp.indptr``
gives the other location of the non-zero entry. For CSC, there are
as many values of indptr as there are columns + 1 in the matrix.
``sp.indptr[k] = x`` and ``indptr[k+1] = y`` means that column
k contains sp.data[x:y], i.e. the xth through the y-1th non-zero values.
See the example below for details.
.. code-block:: python
>>> import scipy.sparse
>>> sp = scipy.sparse.csc_matrix((5, 10))
>>> sp[4, 0] = 20
/u/lisa/local/byhost/test_maggie46.iro.umontreal.ca/lib64/python2.5/site-packages/scipy/sparse/compressed.py:494: SparseEfficiencyWarning: changing the sparsity structure of a csc_matrix is expensive. lil_matrix is more efficient.
raiseNotImplementedError("this function should only be called on results of type sparse.Sparse or tensor.Tensor, not,",x)
raiseNotImplementedError("this function should only be called on *results* (of type sparse.Sparse or tensor.Tensor), not,",x)
returnisinstance(x.type,tensor.Tensor)
def_is_sparse(x):
...
...
@@ -371,7 +374,12 @@ class DenseFromSparse(gof.op.Op):
[tensor.Tensor(dtype=x.type.dtype,
broadcastable=(False,False)).make_result()])
defperform(self,node,(x,),(out,)):
out[0]=x.toarray()
if_is_dense(x):
print>>sys.stderr,"WARNING: You just called DenseFromSparse on a dense matrix:",x
out[0]=x
else:
out[0]=x.toarray()
assert_is_dense(out[0])
defgrad(self,(x,),(gz,)):
ifself.sparse_grad:
return[sp_ones_like(x)*gz]
...
...
@@ -686,10 +694,11 @@ class StructuredDot(gof.Op):
result=a.dot(b)
# sparse dot generates sparse matrix, unless output has single dimension
ifsparse.issparse(result):
result=result.toarray()
assertisinstance(result,numpy.ndarray)
# scipy 0.7.0 automatically casts to dense, so the following is not necessary:
# # sparse dot generates sparse matrix, unless output has single dimension
# if sparse.issparse(result):
# result = result.toarray()
assert_is_dense(result)
# dot of an NxM sparse matrix, with a Mx1 dense matrix, returns vector not matrix
ifresult.ndim==1:
...
...
@@ -701,7 +710,7 @@ class StructuredDot(gof.Op):
ifresult.shape!=(a.shape[0],b.shape[1]):
ifb.shape[0]==1:
raiseException("a.shape=%s, b.shape=%s, result.shape=%s ??? This is probably because scipy.csc_matrix dot has a bug with singleton dimensions (i.e. b.shape[0]=1), for scipy 0.6. Use scipy 0.7"%(a.shape,b.shape,result.shape))
raiseException("a.shape=%s, b.shape=%s, result.shape=%s ??? This is probably because scipy.csc_matrix dot has a bug with singleton dimensions (i.e. b.shape[0]=1), for scipy 0.6. Use scipy 0.7. NB you have scipy version %s"%(a.shape,b.shape,result.shape,scipy.__version__))
else:
raiseException("a.shape=%s, b.shape=%s, result.shape=%s ??? I have no idea why")
...
...
@@ -747,7 +756,10 @@ class StructuredDotCSC(gof.Op):
a=sparse.csc_matrix((a_val,a_ind,a_ptr),
(a_nrows,b.shape[0]),
copy=False)
out[0]=numpy.asarray(a.dot(b).todense())
# TODO: todense() is automatic in 0.7.0, just remove the following line: