我可以访问许多矩阵库,但是对于这个项目我使用的是Eigen,因为它的编译时间定义和它包含了SVD。
现在,我正在执行以下操作:
Eigen::Matrix<double,M,N> A; // populated in the code
Eigen::Matrix<double,N,N> B = A.transpose() * A;
据我所知,这会制作A的副本并形成转置,再次乘以A.此操作在相对较小的矩阵(M = 20-30,N = 3)上执行,但每秒数百万次,这意味着它必须尽可能快。
我读到使用以下内容更快:
B.noalias() = A.transpose() * A;
我可以编写自己的子程序,接受A作为输入并填充B,但我想知道是否存在使用最少循环次数的高效现有实现。
答案 0 :(得分:2)
首先,由于Eigen依赖于模板表达式,A.transpose()
不会评估为临时表达式。
其次,在:
Matrix<double,N,N> B = A.transpose() * A;
Eigen知道B
不能出现在表达式的右侧(因为这里编译器调用B的构造函数),因此根本不会创建临时值。这相当于:
Matrix<double,N,N> B; // declare first
B.noalias() = A.transpose() * A; // eval later
最后,对于这样的小矩阵,我不希望使用B.selfadjointView().rankUpdate(A)
会有所帮助(正如kennytm评论中所建议的那样)。
另一方面,当N = 3时,可能值得尝试延迟实现:
B = A.transpose().lazyProduct(A)
只是为了确定。 Eigen有内置的启发式方法来选择最佳的产品实现,但由于启发式方法必须简单快速地进行评估,因此可能并非100%正确。