I am working on an algorithm that uses diagonal and first off-diagonal blocks of a large (will be e06 x e06) block diagonal sparse matrix.
Right now I create a dict that stores the blocks in such a way that I can access the blocks in a matrix like fashion. For example B[0,0](5x5) gives the first block of matrix A
(20x20), assuming 5x5 blocks and that matrix A
is of type sparse.lil
.
This works fine but takes horribly long too run. It is inefficient because it copies the data, as this reference revealed to my astonishment: GetItem Method
Is there a way to only store a view on a sparse matrix in a dict? I would like to change the content and still be able to use the same identifiers. It is fine if it takes a little longer as it should only be done once. The blocks will have many different dimensions and shapes.
As far as I know, all of the various sparse matricies in scipy.sparse
return copies rather than a view of some sort. (Some of the others may be significantly faster at doing so than lil_matrix
, though!)
One way of doing what you want is to just work with slice objects. For example:
import scipy.sparse
class SparseBlocks(object):
def __init__(self, data, chunksize=5):
self.data = data
self.chunksize = chunksize
def _convert_slices(self, slices):
newslices = []
for axslice in slices:
if isinstance(axslice, slice):
start, stop = axslice.start, axslice.stop
if axslice.start is not None:
start *= self.chunksize
if axslice.stop is not None:
stop *= self.chunksize
axslice = slice(start, stop, None)
elif axslice is not None:
axslice = slice(axslice, axslice+self.chunksize)
newslices.append(axslice)
return tuple(newslices)
def __getitem__(self, item):
item = self._convert_slices(item)
return self.data.__getitem__(item)
def __setitem__(self, item, value):
item = self._convert_slices(item)
return self.data.__setitem__(item, value)
data = scipy.sparse.lil_matrix((20,20))
s = SparseBlocks(data)
s[0,0] = 1
print s.data
Now, whenever we modify s[whatever]
it will modify s.data
of the appropriate chunk. In other words, s[0,0]
will return or set s.data[:5, :5]
, and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With