本征C++;就地矩阵乘法 [英] Eigen C++; In-place matrix multiplication
问题描述
使用 Eigen C++ 矩阵库,如何有效地将 n x n 矩阵 A 乘以 n x m 矩阵 B并将结果存储在 A 中?也就是说,我怎样才能避免生成一个临时的 n x m 矩阵并存储结果直接在B?
Using the Eigen C++ Matrix library, how can one efficiently multiply an n x n matrix A with a n x m matrix B and store the result in A? That is, how can I avoid generating a temporary n x m matrix and instead store the result directly in B?
对于 m 非常大的应用程序(例如 100000)比 n(例如 3),这绝对有意义,因为它避免了超大数组的应用.
For applications where m is very much larger (e.g. 100000) than n (e.g. 3), this definitely makes sense since it avoids the application of very a large array.
以下代码,我无法开始工作:
The following code, I cannot get to work:
B.noalias() = A * B;
我认为,内部必须发生的是以下.B 的每一列都应该单独处理.考虑中的列 column_i
必须复制到备份列 column_tmp
.那么,
I would think, that what would have to happen internally is
the following. Each column of B should be treated separately.
The column under consideration column_i
must be copied to a backup
column column_tmp
. Then,
B(row_i, column_i) = A.row(row_i) * column_tmp; // dot-product
对于所有 column_i
= 0 到 m.Eigen 有没有办法做到这一点高效并从优化中获利?
for all column_i
= 0 to m. Is there a way in Eigen to do this
efficiently and profit from its optimizations?
推荐答案
告诉 Eigen 您希望产品就地"发生的最明确方式可能是:
The most explicit way of telling Eigen that you want the product to happen "in place" could be:
B.transpose() *= A.transpose();
// or B.applyOnTheLeft(A);
也就是说,不能保证这不会在任何临时发生,您必须为此相信内部特征成本逻辑(特征设计者可能更了解:) ...或检查通过调试器自己解决,经过适当的分析后表明这是一个真正的问题,而不仅仅是过早的优化).
that said, there's no guarantee this won't incur in any temporary, you'll have to trust internal Eigen cost logic for that (Eigen designers probably know better :) ... or check it yourself via a debugger, after proper profiling suggested this to be a real problem and not just premature optimization).
在我的 Eigen 副本 (3.2.7) 上,上面直接在 Transpose
表达式上调用了 MatrixBase::applyThisOnTheRight
,这反过来又可悲地简化为 B=A*B
内部;与 applyOnTheLeft
的情况相同,所以在这种情况下你很不走运.
On my Eigen copy (3.2.7), the above invokes MatrixBase::applyThisOnTheRight
directly on the Transpose
expression, that in turn sadly reduces to B=A*B
internally; the same happens as of applyOnTheLeft
, so you're out of luck in this case.
如果你真的需要避免 any nxm 临时的,你可以手动矢量执行乘积,比如:
If you really need to avoid any nxm temporary, you can perform the product manually vector-wise, something like:
for(auto i=0;i<B.cols();++i)
B.col(i) = A * B.col(i);
假设 B.rows()
<<B.cols()
,这将消耗更少的额外内存,但你可能会错过一些重要的优化;确实,我想暂时还是可以在这里做出最好的权衡.
this will consume much less extra memory assuming B.rows()
<<B.cols()
,
but you may miss some important optimizations here; indeed, I guess having a temporary could still give the best trade-off here.
这篇关于本征C++;就地矩阵乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!