【问题标题】:Eigen vertical stacking rows into Matrix特征垂直堆叠行成矩阵
【发布时间】:2019-10-27 07:38:52
【问题描述】:

我想创建一个大小为2N x 9 的矩阵,其中N 是垂直堆叠2N1x9 矩阵的动态值。

这是我尝试做的。

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;
}

但是,我收到以下运行时错误。

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.

我尝试通过断言语法进行解析,但我不确定这些内部变量名称在我的代码中指的是什么(对于 Eigen 来说是新的)。

感谢您的帮助。

【问题讨论】:

    标签: c++ eigen eigen3


    【解决方案1】:

    TLDR:这样写:

    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;
    }
    

    您的错误原因是(正如 Avi 解释的那样)operator&lt;&lt; 旨在一次填充整个矩阵。事实上,调用operator&lt;&lt;(Array &amp;A, Array const &amp;b) 会将b 分配给A 的左上角并返回一个代理对象,该对象包含对A 的引用并跟踪A 的多少条目已经分配给(存储在m_rowm_currentBlockRowsm_col)并重载operator,,它将下一个表达式分配给a的相应位置并相应地增加位置。最后,当代理对象被破坏时(通常发生在“;”处),析构函数会检查A 的所有条目是否已被填充(如果没有,则引发失败的断言)。

    如果您更喜欢使用&lt;&lt; , 语法,您也可以编写:

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

    启用优化后,应该生成与上述简单实现相同的代码(因此请选择更易于阅读的代码)。


    N.B.:从技术上讲,您可以(ab)在循环中使用 CommaInitializer,方法是在循环外构造它,将其分配给一个变量,然后只在循环内使用 , 运算符。我将故意不提供有关如何执行此操作的更多详细信息...

    【讨论】:

    • 我喜欢使用middleRows 的想法。恭喜获得 10K。
    【解决方案2】:

    operator &lt;&lt; 的重载会立即填充整个矩阵。如果尺寸不匹配,您会遇到运行时错误。

    这样看。假设代码按您的意愿工作(operator &lt;&lt; 插入了一行?一次两行?)。连续两次拨打operator &lt;&lt; 是如何工作的?现在是否每个矩阵都必须跟踪operator &lt;&lt; 被调用了多少次?或者反过来,如果插入了部分行,应该如何处理?

    【讨论】:

    • 谢谢,那么你想在什么情况下使用这个操作符呢? SO上的其他帖子建议它用于堆叠,
    • @Carpetfizz 请参阅this 了解一些简单的使用示例。
    • 为什么它在这里工作? *.com/a/21496281/896112
    • 这里,Gael 正在一次性完全初始化矩阵。在您的代码中,您有对A &lt;&lt; ax, ay;N 调用。 Gael 执行C &lt;&lt; A, B; 一次,其中A 加上B 的尺寸彼此相邻等于C 的尺寸。
    • 感谢 Avi 的澄清,有道理。
    最近更新 更多