Search code examples
matlabmatrixsparse-matrix

Using spfun with two identically ordered sparse matrices


I got two sparse matrices A and B, which have identical sparsity pattern (all nonzeros are at exactly the same locations):

i = randi(1000,[50,1]);
j = randi(1000,[50,1]);
a = rand(50,1);
b = rand(50,1);

A = sparse(i,j,a,1000,1000);
B = sparse(i,j,b,1000,1000);

I would like to calculate efficiently exp(A-B) only for the nonzeros, and save it back into A. I tried to use spfun for that task:

f = @(x,y) exp(x-y);
A = spfun(f,A,B);

but I got an error in spfun saying: "Too many input arguments." Can anyone suggest an efficient way to calculate it? It should be calculated many times.

Thanks!

Edit: mikkola suggested A = spfun(@f,A-B) which solves the problem, but the question remains how to do it with a function of two variables that can't be solved using the same trick. For example:

g = @(x,y) x.*cos(y);
A = spfun(@g,A,B);

Solution

  • You can't use

    A = spfun(@exp, A-B);
    

    because for entries where A an B are equal you will get 0 instead of 1.

    To solve that, you can compute the vector of exponentials at the nonzero components, and then build a sparse matrix from that:

    A = sparse(i,j,exp(nonzeros(A)-nonzeros(B))); %// if you have i, j stored
    

    or

    A(find(A)) = exp(nonzeros(A)-nonzeros(B));