2013-04-07 120 views

回答

4

我与accumarray结合find

%# 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) 

一些替代品(可能是低效率的,你可能要分析他们)

%# 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 
+0

谢谢,我不知道有关accumarray。你知道是否有任何方法不涉及函数传递? – dspyz 2013-04-07 01:31:27

+0

@dspyz:你说“函数传递”是什么意思? – Jonas 2013-04-07 01:57:54

+0

@dspyz假设当你说“避免函数传递”时,你指的是'accumarray'的'@ prod'参数 - 这是'accumarray'如何知道应用到数组的哪个函数。这是典型的,预期的语法。你为什么要避免它? – tmpearce 2013-04-07 02:28:27

0

我找到了一种替代的方法来解决这一点,但它可能是速度较慢,不太在最坏的情况下精确:

简单地采取所有非零元素的日志,然后求和列。然后取出结果向量的exp:

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