Eigen vertical stacking rows into Matrix

蹲街弑〆低调 提交于 2021-01-28 05:47:15

问题


I would like to create a matrix of size 2N x 9 where N is a dynamic value by vertical stacking 2N 1x9 matrices.

Here's what I tried doing.

using CoefficientMatrix = Eigen::Matrix<T, Eigen::Dynamic, 9>;
using CoefficientRow = Eigen::Matrix<T, 1, 9>;

CoefficientMatrix A(2*N, 9);

for (int i = 0; i < N; i++) {
    CoefficientRow ax;
    CoefficientRow ay;
    // fill in ax and ay
    A << ax, ay;
}

But, I get the following runtime error.

Assertion failed: (((m_row+m_currentBlockRows) == m_xpr.rows() || m_xpr.cols() == 0) && m_col == m_xpr.cols() && "Too few coefficients passed to comma initializer (operator<<)"), function finished, file /usr/local/include/eigen3/Eigen/src/Core/CommaInitializer.h, line 120.

I tried parsing through the assertion syntax but I'm not sure what those internal variable names are referring to in terms of my code (new to Eigen).

Thanks for any assistance.


回答1:


TLDR: Write something like this:

CoefficientMatrix A(2*N, 9);

for (int i = 0; i < N; i++) {
    CoefficientRow ax;
    CoefficientRow ay;
    // fill in ax and ay
    A.row(2*i)   = ax;
    A.row(2*i+1) = ay;
}

The reason of your error is (as Avi explained) that the operator<< is intended to fill an entire matrix at once. In fact, calling operator<<(Array &A, Array const &b) assigns b to the top-left corner of A and returns a proxy-object which holds a reference to A and keeps track of how much entries of A already got assigned to (stored in m_row, m_currentBlockRows, m_col) and overloads operator, which assigns the next expression to the corresponding position of a and increases the position accordingly. Finally, when that proxy object gets destructed (which usually happens "at the ;") the destructor checks if all entries of A have been filled (and raises a failed assertion, if not).

If you prefer to use the << , syntax you could also write:

    A.middleRows<2>(2*i) << ax, ay;

With optimizations enabled that should generate the same code as the simple implementation above (so choose whichever is easier to read for you).


N.B.: You could technically (ab)use the CommaInitializer in a loop, by constructing it outside the loop, assigning it to a variable and then only use the , operator inside the loop. I'll intentionally won't give more details on how to do that ...




回答2:


The overload for operator << fills the entire matrix at once. If the dimensions don't match, you get the runtime error you encountered.

Look at it this way. Assume that the code works as you wanted (operator << inserted a single row? two rows at a time?). How do two consecutive calls to operator << work? Does every matrix now have to track how many times operator << was called? Or conversely, if a partial row was inserted, how should that be handled?



来源:https://stackoverflow.com/questions/58577439/eigen-vertical-stacking-rows-into-matrix

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!