dspyz
dspyz

Reputation: 5490

Take the product of all nonzero elements in each column of a sparse matrix

Is there a well-vectorized way to take the product of all the nonzero elements in each column of a sparse matrix in octave (or matlab) (returning a row-vector of products)?

Upvotes: 2

Views: 1863

Answers (2)

dspyz
dspyz

Reputation: 5490

I found an alternative approach to solving this, but it may be slower and not quite as precise in the worst-case:

Simply take the log of all the nonzero elements and then sum the columns. Then take the exp of the resulting vector:

function [r] = prodnz(m)
    nzinds = find(m != 0);
    vals = full(m(nzinds));
    vals = log(vals);
    m(nzinds) = vals;
    s = full(sum(m));
    r = exp(s);
endfunction

Upvotes: 0

Jonas
Jonas

Reputation: 74940

I'd combine find with accumarray:

%# create a random sparse array
s = sprand(4,4,0.6);

%# find the nonzero values
[rowIdx,colIdx,values] = find(s);

%# calculate product
product = accumarray(colIdx,values,[],@prod)

Some alternatives (that might be less efficient; you may want to profile them)

%# simply set the zero-elements to 1, then apply prod
%# may lead to memory issues
s(s==0) = 1;
product = prod(s,1);

.

%# do "manual" accumarray
[rowIdx,colIdx,values] = find(s);

product = zeros(1,size(s,2));
uCols = unique(colIdx);

for col = uCols(:)'
    product(col) = prod(values(colIdx==col));
end

Upvotes: 4

Related Questions