Why multiply a sparse matrix(0.5) with a dense vector is slower than the normal multiply?
matlab
Solution
No. That is simply NOT a sparse matrix. You misunderstand when sparse matrices are useful. Those of us who do use them heavily would say that a matrix is not really sparse unless it has a density of less than 1%. Even that density is not very sparse!
A sparse matrix has extra bookkeeping when you use it, because now MATLAB essentially needs to worry about where the non-zeros are. So if you make a matrix that is essentially a dense matrix, and pretend that it is sparse, you are defeating the value of the tool.
Lets make a comparison or two. First, a completely dense matrix. I'll use Steve Eddins timeit tool from the file exchange. This does a very good job of estimating time taken, and does not require an explicit loop.
A = rand(1000);
As = sparse(A);
b = rand(1000,1);
whos A As
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
As 1000x1000 16008008 double sparse
See that the fully dense matrix takes up considerably less space than the sparse form.
timeit(@() A*b)
ans =
0.00039474
timeit(@() As*b)
ans =
0.0023663
The overhead of the sparse matrix in a simple multiply is way too large.
As = sprand(1000,1000,.5);
A = full(As);
b = rand(1000,1);
whos A As
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
As 1000x1000 6303448 double sparse
Here the two matrices barely show a size reduction for the sparse version. So calling it sparse is a waste of time in terms of space consumed. As well, as you found, the time consumed for multiplies is still not a gain.
timeit(@() A*b)
ans =
0.00027594
timeit(@() As*b)
ans =
0.0005011
However, what happens when the matrix is closer to what I suggested in terms of sparsity?
As = sprand(1000,1000,.01);
A = full(As);
b = rand(1000,1);
whos A As
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
As 1000x1000 167176 double sparse
timeit(@() A*b)
ans =
0.00023629
timeit(@() As*b)
ans =
5.3167e-05
Ok, so this now is saving some serious space. And some serious time too.
But really, the time for a multiply is NOT why we use sparse matrices. It is the time required to solve a linear system of equations that makes us use sparse matrices. This can be a MASSIVE savings, where the problem will be essentially unsolvable using full matrices. A common problem for me might involve a 40000x40000 matrix, with perhaps a density of 0.02%. I would spend days waiting for the full version to finish, but only seconds for a sparse solve in that case.
For example, consider gridfit, a function of mine that is on the file exchange. It creates surfaces from scattered data. In this example, the tool will need to solve a linear system of equations with 40000 unknowns.
timeit(@() gridfit(rand(100,1),rand(100,1),rand(100,1),linspace(0,1,200),linspace(0,1,200)))
ans =
0.83624
So for everything, including setting up that system of equations, it took less than 1 second.
The (in this case, non-square) linear system that it solves is VERY sparse.
whos A
Name Size Bytes Class Attributes
A 80100x40000 4126408 double sparse
How sparse is it?
nnz(A)
ans =
237900
nnz(A)/40000
ans =
5.9475
So on average, only 5.9475 non-zeros per row, with 40000 columns. And we don't have the time it would take for me to do a full linear solve with that system. At least I don't have any desire to try it.
Problem
I generated a matrix with sparsity 0.5, and I want to know its speed multiplying a dense vector compared to the multiplying in the normal way. ``` function sparseTest() A = sprand(1000, 1000, 0.5); test(A); test(full(A)); end function test(A) tic; b = rand(size(A, 2), 1); for i = 1:10000 c = A * b; end toc; end ``` The result is ``` Elapsed time is 10.968797 seconds. Elapsed time is 10.194440 seconds. ``` what confuses me is that since there is only half non-zero numbers, I think the sparse multiplying should somehow be faster.