将MatrixXd的行传递给要修改的函数,而无需在本征中创建副本

问题描述 投票:0回答:1

此问题与C ++和本征有关。

我有一个函数,将某些向量计算为Eigen::VectorXd,并将其存储到作为参数传递的向量中。函数的返回值是在函数中完成的迭代次数。下面是该函数的伪代码:

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()不会返回VectorXd。我尝试了其他一些方法,但没有任何效果。在Eigen中填充预分配的MatrixXd行的有效方法是什么?

注意:我知道我可以将ref连同i的当前值一起传递给函数,然后在q.row(i) = vNew;中执行integrate()。但是,对我来说,它看起来很丑陋且不必要。 integrate()真的不必了解MatrixXd

谢谢。

c++ eigen
1个回答
1
投票

您可以使用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>(aka Eigen::Ref<Eigen::VectorXd, 0, Eigen::InnerStride<1> >):

size_t integrate(Eigen::Ref<Eigen::VectorXd> v) {
    // ...
© www.soinside.com 2019 - 2024. All rights reserved.