初始化动态矩阵时的特征错误

时间:2019-02-11 08:13:48

标签: c++ eigen

我正在尝试从包含笛卡尔点简单结构的向量填充本征矩阵(动态行,2列双精度数),但是,在使用运算符<<时遇到错误。

最小失败示例(使用MSVC 2017):

#include <Eigen/Dense>
#include <vector>

struct point {
    double x, y;
};

int main() {

    std::vector<point> points = {
        point{0.0, 0.0},
        point{0.5, 0.0},
        point{0.0, 1.0},
        point{0.5, 1.0},
    };

    typedef Eigen::Matrix<double, Eigen::Dynamic, 2> CoordMatrix;
    CoordMatrix X;

    for (auto& p : points)
        X << p.x, p.y;

    return 0;
}

运行此命令时,在X << point.x, point.y;行中出现错误,提示:“没有运算符<<与这些操作数匹配”(在调试模式下尝试传递X << 0.0, 0.0;时也会抛出此错误)。

2 个答案:

答案 0 :(得分:1)

据我了解,您正在尝试使用每行中包含来自较早向量的点之一的坐标的值来初始化X矩阵。您不能那样做,请参见here

  

Eigen提供了一种逗号初始化程序语法,该语法使用户可以轻松设置矩阵,向量或数组的所有系数。只需列出系数,从左上角开始,从左到右,从上到下移动。需要预先指定对象的大小。如果列出的系数太少或太多,Eigen就会抱怨。

以上内容清楚地表明,您的右侧需要将尺寸与左侧匹配。在您的情况下,您可能需要逐个复制vector元素。像这样:

CoordMatrix X(points.size(), 2); // reserving rigth storage for the matrix
for (auto i = 0u; i < points.size(); ++i) {
  X(i, 0) = points[i].x;
  X(i, 1) = points[i].y;
}

答案 1 :(得分:1)

如果您想使用<<初始化,则可以一次执行一行(并且正如@ paler123所说,您需要先分配X,然后再将值存储到其中):< / p>

typedef Eigen::Matrix<double, Eigen::Dynamic, 2> CoordMatrix;
CoordMatrix X(points.size(), 2); // allocate space for matrix
Eigen::Index r=0; // or use `r` as counter in the loop
for (auto& p : points)
    X.row(r++) << p.x, p.y; // fill matrix one row per iteration

您还可以将points的内存直接映射到Eigen::Map -在这种情况下,必须确保存储顺序一致并且如果您修改points仍然使用X,但是X将不需要额外的内存(指针和Index除外)。

typedef Eigen::Matrix<double, Eigen::Dynamic, 2, Eigen::RowMajor> CoordMatrix;
auto X = CoordMatrix::Map(&points[0].x, points.size(), 2); // no copy happens
// X gets invalid if `points` are destructed or re-allocated.