将 MatrixXd 的行传递给要修改的函数而不在 Eigen 中创建副本
Passing rows of a MatrixXd to a function to be modified without creating copies in Eigen
这个问题是关于 C++ 和 Eigen 的。
我有一个函数可以将一些向量计算为 Eigen::VectorXd
并将它们存储到作为参数传递的向量中。函数的 return 值是函数中完成的迭代次数。下面是函数的伪代码:
size_t integrate(Eigen::VectorXd& v) {
size_t numIterations = 0;
// do some iterative calculations and increment numIterations
// vNew is generated from the new calculations
v = vNew;
return numIterations;
}
我想使用这个功能的方式如下:
Eigen::MatrixXd q = Eigen::MatrixXd::Zero(numRows, numCols);
for(size_t i = 0; i < numSteps; i++) {
integrate(q.row(i));
}
然而,这不会在 Visual Studio 中编译。我遇到 C++ initial value of reference to non-const must be an lvalue
编译器错误。我的意图是避免不必要的复制,并在 for 循环的每次迭代中将计算结果(一个向量)放入矩阵中。我明白 row()
不是 return 和 VectorXd
。我尝试了其他一些方法,但 none 有效。在 Eigen 中填充预分配 MatrixXd
行的有效方法是什么?
注意:我知道我可以通过 ref 将矩阵连同 i
的当前值传递给函数,然后在 integrate()
中执行 q.row(i) = vNew;
。然而,它看起来很丑陋而且对我来说没有必要。 integrate()
真的不需要了解 MatrixXd
.
谢谢。
您可以使用 Eigen::Ref
对象将可写引用传递给矩阵块。在您的情况下,由于(主要列)矩阵的行将具有内部步幅,因此您需要明确允许:
size_t integrate(Eigen::Ref<Eigen::VectorXd, 0, Eigen::InnerStride<> > v) {
v.setRandom(); // use `v` as if it was a VectorXd
return 0;
}
为了更好的性能,您应该考虑以行主要形式存储 q
,或者将单独的列传递给 integrate
:
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> q; q.setZero(numRows, numCols);
// ...
integrate(q.row(i));
或:
Eigen::MatrixXd q; q.setZero(numRows, numCols); // you'll need to switch how many rows and cols are to be allocated
// ...
integrate(q.col(i));
在任何一种情况下,integrate
都可以采用简单的 Eigen::Ref<Eigen::VectorXd>
(又名 Eigen::Ref<Eigen::VectorXd, 0, Eigen::InnerStride<1> >
):
size_t integrate(Eigen::Ref<Eigen::VectorXd> v) {
// ...
这个问题是关于 C++ 和 Eigen 的。
我有一个函数可以将一些向量计算为 Eigen::VectorXd
并将它们存储到作为参数传递的向量中。函数的 return 值是函数中完成的迭代次数。下面是函数的伪代码:
size_t integrate(Eigen::VectorXd& v) {
size_t numIterations = 0;
// do some iterative calculations and increment numIterations
// vNew is generated from the new calculations
v = vNew;
return numIterations;
}
我想使用这个功能的方式如下:
Eigen::MatrixXd q = Eigen::MatrixXd::Zero(numRows, numCols);
for(size_t i = 0; i < numSteps; i++) {
integrate(q.row(i));
}
然而,这不会在 Visual Studio 中编译。我遇到 C++ initial value of reference to non-const must be an lvalue
编译器错误。我的意图是避免不必要的复制,并在 for 循环的每次迭代中将计算结果(一个向量)放入矩阵中。我明白 row()
不是 return 和 VectorXd
。我尝试了其他一些方法,但 none 有效。在 Eigen 中填充预分配 MatrixXd
行的有效方法是什么?
注意:我知道我可以通过 ref 将矩阵连同 i
的当前值传递给函数,然后在 integrate()
中执行 q.row(i) = vNew;
。然而,它看起来很丑陋而且对我来说没有必要。 integrate()
真的不需要了解 MatrixXd
.
谢谢。
您可以使用 Eigen::Ref
对象将可写引用传递给矩阵块。在您的情况下,由于(主要列)矩阵的行将具有内部步幅,因此您需要明确允许:
size_t integrate(Eigen::Ref<Eigen::VectorXd, 0, Eigen::InnerStride<> > v) {
v.setRandom(); // use `v` as if it was a VectorXd
return 0;
}
为了更好的性能,您应该考虑以行主要形式存储 q
,或者将单独的列传递给 integrate
:
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> q; q.setZero(numRows, numCols);
// ...
integrate(q.row(i));
或:
Eigen::MatrixXd q; q.setZero(numRows, numCols); // you'll need to switch how many rows and cols are to be allocated
// ...
integrate(q.col(i));
在任何一种情况下,integrate
都可以采用简单的 Eigen::Ref<Eigen::VectorXd>
(又名 Eigen::Ref<Eigen::VectorXd, 0, Eigen::InnerStride<1> >
):
size_t integrate(Eigen::Ref<Eigen::VectorXd> v) {
// ...