假设我有一个高维的向量v,它是密集的,另一个高维的向量x是稀疏的,我想做一个操作,如下所示
V=v+x
理想情况下,因为人们只需要更新v中的几个条目,所以这个操作应该很快,但即使我已经声明x是稀疏的,它仍然需要大量的时间。我试过用v表示完全形式,也用v表示稀疏形式,两者都相当慢。
我还尝试从稀疏向量x中提取索引,方法是调用find,然后在for循环中更新原始向量。这比上面的操作更快,但有没有一种方法可以用更少的代码实现同样的效果。
谢谢
发布于 2016-03-08 19:23:02
引用自Matlab documentation (emphasis mine):
如果两个操作数都是稀疏的,则
二元运算符会生成稀疏结果;如果两个操作数都是满的,则会产生完整的结果。对于混合操作数,除非操作保留稀疏性,否则结果为满。如果S是稀疏的并且F是满的,则S+F、S*F和F\S是满的,而S*F和S&F是稀疏的。在某些情况下,即使矩阵有很少的零元素,结果也可能是稀疏的。
因此,如果您希望保持x
稀疏,我认为使用逻辑索引用x
的非零值更新v
是最好的。下面是一个示例函数,它显示了逻辑索引或显式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
https://stackoverflow.com/questions/35875823
复制相似问题