Efficient matrix multiplication for large sparse matrices stored as sparse column vectors
Show older comments
I'm working on a project where I need to manipulate very large sparse matrices. To keep the memory cost down, I store these tensors as a sparse column vector, along with their actual dimensions. For example, a random (M x N) sparse matrix matrixA would instead be stored as a struct A as follows:
matrixA = sprand(M,N,0.01);
[rows, cols, val] = find(matrixA);
ind = sub2ind(size(matrixA), rows, cols);
A.size = size(matrixA);
A.var = sparse(ind, ones(size(ind)), val, prod(A.size),1); % create (N,1) sparse matrix
Note that this is just an example to show the struct A is related to matrixA, in practice I would never actually construct matrixA in the first place.
I need to multiply two such matrices, A and B, with sizes (M,N) and (N,P) and store the result in the same way as above. One way of doing this would be as follows:
A = reshape(A.var,A.size); % redefine A as an actual sparse matrix with size A.size
B = reshape(B.var,B.size); % redfine B as an actual sparse matrix with size B.size
result = A * B;
C.size = size(result);
C.var = reshape(result, [prod(C.size),1]);
The problem with this method however, is that I loose the advantage of the lower memory consumption that I obtained by storing my matrices as sparse column vectors instead normal sparse matrices (which have a very large number of columns in my case). Alternatively, I could attempt to use some for-loops to do the multiplication element-wise, but this will certainly be very slow.
What is a better way of doing this? I'm looking for a solution that is more memory-efficient than the first method, while still being reasonably fast.
Note that I have little flexibility in the way these matrices are stored, since other parts of my code rely heavily on this.
5 Comments
David Goodmanson
on 10 Sep 2020
Edited: David Goodmanson
on 10 Sep 2020
Hi Alexis
I ran your example for a few moderately large cases of M and N, with A as you defined it (a structure). The memory taken up by matrixA and A are virtually the same. This is also true for a matrix identical to A, only defined as a sparse matrix and not as a structure. Given how Matlab stores sparse matrices, that's how the results should have turned out. Could you provide an example where this is not true?
AS
on 10 Sep 2020
James Tursa
on 10 Sep 2020
What are all of the operations you intend doing with this sparse matrix? Because you would need to write your own functions from scratch for every single operation (plus, minus, mtimes, transpose, etc.). Mex routines might help with this, but I'm not sure it is going to be worth it.
AS
on 10 Sep 2020
You could also try the ndSparse class,
It shouldn't have any issue with complex arrays. A minor issue that you might have is that ndSparse uses pre-R2016 syntax, so it doesn't support implicit expansion or reduction operations along more than one dimension at a time, like in sum(X,[1,2]).
Accepted Answer
More Answers (0)
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!