本征C++;就地矩阵乘法 [英] Eigen C++; In-place matrix multiplication

查看:112
本文介绍了本征C++;就地矩阵乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆