Reputation: 131
Suppose I have a high dimensional vector v which is dense and another high dimensional vector x which is sparse and I want to do an operation which looks like
v = v + x
Ideally since one needs to update only a few entries in v this operation should be fast but it is still taking a good amount of time even when I have declared x to be sparse. I have tried with v being in full as well as v being in sparse form and both are fairly slow.
I have also tried to extract the indices from the sparse vector x by calling a find and then updating the original vector in a for loop. This is faster than the above operations, but is there a way to achieve the same with much less code.
Thanks
Upvotes: 3
Views: 275
Reputation: 8401
Quoting from the Matlab documentation (emphasis mine):
Binary operators yield sparse results if both operands are sparse, and full results if both are full. For mixed operands, the result is full unless the operation preserves sparsity. If S is sparse and F is full, then S+F, S*F, and F\S are full, while S.*F and S&F are sparse. In some cases, the result might be sparse even though the matrix has few zero elements.
Therefore, if you wish to keep x
sparse, I think using logical indexing to update v
with the nonzero values of x
is best. Here is a sample function that shows either logical indexing or explicitly full
-ing x
is best (at least on my R2015a install):
function [] = blur()
n = 5E6;
v = rand(n,1);
x = sprand(n,1,0.001);
xf = full(x);
vs = sparse(v);
disp(['Full-Sparse: ',num2str(timeit(@() v + x) ,'%9.5f')]);
disp(['Full-Full: ',num2str(timeit(@() v + xf) ,'%9.5f')]);
disp(['Sparse-Sparse: ',num2str(timeit(@() vs + x) ,'%9.5f')]);
disp(['Logical Index: ',num2str(timeit(@() update(v,x)),'%9.5f')]);
end
function [] = update(v,x)
mask = x ~= 0;
v(mask) = v(mask) + x(mask);
end
Upvotes: 6