密集和稀疏向量的总和

时间:2015-05-10 12:32:54

标签: matlab sparse-matrix

我需要在Matlab中总结一个密集和稀疏的向量,以及实现它的天真方式,即:

w = rand(1e7,1);
d = sprand(1e7,1,.001);
tic
for k = 1 : 100
    w = w + d;
end
toc

需要大约3.5秒,这比我期待Matlab在引擎盖后面实现它的方式慢大约20倍:

for k = 1 : 100
    ind = find(d);
    w(ind) = w(ind) + d(ind);
end

(当然这个更快版本的时间取决于稀疏性)。

那么,为什么Matlab没有这样做?快速的方式'?我到目前为止使用Matlab的经验表明它在利用稀疏性方面相当不错。

更重要的是,还有其他稀疏的'操作我应该怀疑效率不高?

1 个答案:

答案 0 :(得分:1)

我肯定不知道答案,但我会猜测你发生了什么。我不了解Fortran,但从C ++的角度来看,你所展示的内容是有道理的,我们只需要解构那个陈述。

其中a = b + c已满且a,b稀疏的c的伪代码转换看起来像a.operator= ( b.operator+ (c) )

Matlab中的完整矩阵容器很可能应该有专门的算术运算符来处理稀疏输入,即full full::operator+ ( const sparse& )之类的东西。这里需要注意的主要问题是混合完全/稀疏算术运算的结果必须是满的。因此,即使没有更新的值,我们也需要创建一个新的完整容器来存储结果。 [ 注意:返回的完整容器是一个临时容器,因此作业a.operator= ( ... )可能会避免使用完整的附加副本,例如使用full& full::operator= ( full&& )。的

不幸的是,由于Matlab中没有算术复合操作(即operator +=),因此无法返回新的完整容器。这就是为什么Matlab无法利用在您的示例中ab相同的事实(尝试用x = w + d计算循环时间,没有运行时差异),这就是IMO的开销。 [ 注意:即使没有明确的分配,例如b+c;,也会分配通用答案变量ans。的

有趣的是,full full::operator+ ( const sparse& )full sparse::operator+ ( const full& )之间似乎存在显着差异,即a = b + ca = c + b之间;我无法详细说明原因,但后者似乎更快。

无论如何,我的简短回答是#34;因为Matlab没有算术复合算子",这是不幸的。如果你知道你将要做很多这些操作,那么实现 ad hoc 优化版本(如你提议的那个)并不是很难。希望这有帮助!