在Matlab中将稀疏向量添加到密集向量中

use*_*053 3 matlab sparse-matrix

假设我有一个高维矢量v,它是密集的,另一个高维矢量x是稀疏的,我想做一个看起来像

v = v + x

理想情况下,因为需要仅更新v中的几个条目,所以此操作应该很快但是即使我声明x是稀疏的,它仍然需要很长时间.我试过v完全以及v是稀疏形式,两者都相当慢.

我还尝试通过调用find然后在for循环中更新原始向量来从稀疏向量x中提取索引.这比上面的操作更快,但是有一种方法可以用更少的代码实现相同的操作.

谢谢

Tro*_*kin 6

引用Matlab文档(强调我的):

如果两个操作数都是稀疏的,则二元运算符产生稀疏结果,如果两个操作数都是满的,则产生完整结果.对于混合操作数,除非操作保留稀疏性,否则结果将为完整.如果S稀疏且F满,则S + F,S*F和F\S满,而S.*F和S&F稀疏.在某些情况下,即使矩阵的零元素很少,结果也可能是稀疏的.

因此,如果您希望保持x稀疏,我认为使用逻辑索引来更新v非零值x是最好的.这里是显示无论是逻辑索引或明确的样本函数full-ing x是最好的(至少在我R2015a安装):

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
Run Code Online (Sandbox Code Playgroud)