如何为不断增长的 Eigen::MatrixXd 预分配内存
Posted
技术标签:
【中文标题】如何为不断增长的 Eigen::MatrixXd 预分配内存【英文标题】:How to pre-allocate memory for a growing Eigen::MatrixXd 【发布时间】:2015-11-06 02:20:20 【问题描述】:我有一个Eigen::MatrixXd
形式的不断增长的数据库。我的矩阵开始为空并逐一添加行,直到达到最大预定义(在编译时已知)行数。
目前我是这样发展的(来自 Eigen 文档以及这里和其他地方的许多帖子):
MatrixXd new_database(database.rows()+1, database.cols());
new_database << database, new_row;
database = new_database;
但这似乎比它需要的效率低得多,因为每次添加新行时它都会进行大量无用的内存重新分配和数据复制......似乎我应该能够预先分配一堆MAX_ROWS*N_COLS
大小的内存并让矩阵在其中增长,但是我找不到与 Eigen 相同的 std::vector
的 capacity
。
注意:我可能需要在矩阵实际满之前随时使用它。所以我确实需要区分它的size
和它的capacity
。
我该怎么做?
编辑 1:我看到有一个 MaxSizeAtCompileTime
,但我发现文档相当不清楚,没有示例。任何人都知道这是否可行,如何使用此参数以及如何与resize
和conservativeResize
交互?
编辑 2:C++: Eigen conservativeResize too expensive? 提供了另一种有趣的方法,同时提出了关于非连续数据的问题......有人对这个问题有一些很好的见解吗?
【问题讨论】:
为什么不使用 std::vector? 因为我在做矩阵乘法。我曾想过使用Eigen::Vector
的std::vector
,但我认为将Eigen::Matrix
与Eigen::Vector
相乘会比在for 循环中使用Eigen::Vector
的多个点积来优化和更有效然后用结果填充一个新的Eigen::Vector
...
文档提到了一个保留矩阵值的保守调整大小函数。至少它可以使您免于像您一直在做的那样对调整大小进行编码。不确定它是否有更好的性能。
这是保存的代码行,是的!据我了解,当大小增加时,conservativeResize 遵循完全相同的低效内存重新分配和数据复制过程......
【参考方案1】:
在我忘记之前我想提的第一件事是,您可能需要考虑使用行主矩阵进行存储。
对您的问题最简单(可能也是最好)的解决方案是使用block operations 访问最上面的行。
#include <Eigen/Core>
#include <iostream>
using namespace Eigen;
int main(void)
const int rows = 5;
const int cols = 6;
MatrixXd database(rows, cols);
database.setConstant(-1.0);
std::cout << database << "\n\n";
for (int i = 0; i < rows; i++)
database.row(i) = VectorXd::Constant(cols, i);
// Use block operations instead of the full matrix
std::cout << database.topRows(i+1) << "\n\n";
std::cout << database << "\n\n";
return 0;
您可以执行任何您需要的操作,而不仅仅是打印矩阵。
【讨论】:
要完成答案,为了避免每次都重复.topRows()
,您可以使用c++ auto
包装它,或者在c++98 中声明:Eigen::Ref<Eigen::MatrixXd> db = database.topRows(i+1)
,并使用db as一个普通的Eigen::Matrix
。以上是关于如何为不断增长的 Eigen::MatrixXd 预分配内存的主要内容,如果未能解决你的问题,请参考以下文章
如何调整 Eigen::MatrixXd 的 std::vector 的大小