2017-03-10 128 views
2

我可以访问大量的矩阵库,但对于这个项目,我使用Eigen,因为它的编译时间定义和包含SVD。现在Eigen中有效的矩阵转置矩阵乘法

,我做以下操作:

Eigen::Matrix<double,M,N> A;  // populated in the code 

Eigen::Matrix<double,N,N> B = A.transpose() * A; 

据我所知,这使得A的副本,并形成转置,这是由一个又成倍增加。这个操作是在相对较小的矩阵(M = 20-30,N = 3)上执行的,但是每秒要执行数百万次,这意味着它必须尽可能快。

,我读了使用下面的更快:

B.noalias() = A.transpose() * A; 

我可以写我自己的子程序接受一个作为输入和填充B,但我在想,如果有一个使用一个有效的,现有的实现最少的周期。

+0

考虑看看这个:http://scicomp.stackexchange.com/questions/25283/beating-typical-blas-libraries-matrix-multiplication-performance –

+0

这有帮助吗? http://stackoverflow.com/questions/39606224/does-eigen-have-self-transpose-multiply-optimization-like-h-transposeh – kennytm

回答

1

首先,由于Eigen依赖于模板表达式,所以A.transpose()不会评估为临时值。

其次,在:

Matrix<double,N,N> B = A.transpose() * A; 

征知道B不能出现在表达式的右手边(因为这里的编译器调用B的构造函数),因此,没有临时创建的所有。

Matrix<double,N,N> B;    // declare first 
B.noalias() = A.transpose() * A; // eval later 

最后,对于这样的小矩阵,我不认为使用B.selfadjointView().rankUpdate(A)将帮助(如kennytm评论建议):这是等价的。

在otherhand,与N = 3,这可能是值得尝试的懒惰实现:

B = A.transpose().lazyProduct(A)

只是要确定。 Eigen的内置启发式方法可以选择最佳的产品实现方式,但由于启发式方法必须简单且快速进行评估,因此它可能不是100%正确的。

+0

谢谢。懒惰的项目提示是如何。现在,我最终做了一些完全不同的事情,因为我在发现后发现Eigen不能在GPU上运行cuda。尽管我喜欢图书馆。另外,完全不建立A是最有效的,这就是我所做的。 –