【问题标题】:Take the product of all nonzero elements in each column of a sparse matrix取稀疏矩阵每一列中所有非零元素的乘积
【发布时间】:2013-04-07 01:19:00
【问题描述】:

是否有一种很好的矢量化方法来获取八度(或 matlab)中稀疏矩阵每一列中所有非零元素的乘积(返回乘积的行向量)?

【问题讨论】:

    标签: matlab octave vectorization sparse-matrix multiplication


    【解决方案1】:

    我会将findaccumarray 结合起来:

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

    【讨论】:

    • 谢谢,我不知道 accumarray。不知道有没有不涉及函数传递的方法?
    • @dspyz:“函数传递”是什么意思?
    • @dspyz 假设当您说“避免函数传递”时,您指的是accumarray@prod 参数——这就是accumarray 知道将哪个函数应用于数组的方式。这是典型的预期语法。为什么要避免它?
    • 只是因为它限制了效率。理想情况下,我正在寻找一种只调用编译代码的方法。这与您只使用 sum 而不是 accumarray(... @sum) 的原因相同
    • @dspyz:我添加了两个额外的解决方案。它们可能(或不)更有效。
    【解决方案2】:

    我找到了解决此问题的另一种方法,但在最坏的情况下它可能会更慢且不够精确:

    只需记录所有非零元素的对数,然后对各列求和。然后取结果向量的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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 2017-04-16
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多