代码之家  ›  专栏  ›  技术社区  ›  Adrian

初始化动态矩阵时的本征误差

  •  1
  • Adrian  · 技术社区  · 6 年前

    我试图从包含一些简单的笛卡尔点结构的向量中填充一个本征矩阵(双精度行,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 回复  |  直到 6 年前
        1
  •  1
  •   paler123    6 年前

    据我所知,您正在尝试初始化 X 矩阵,每行中的值包含来自早期向量的一个点的坐标。你不能那样做,看 here :

    Eigen提供了逗号初始值设定项语法,允许用户轻松设置矩阵、向量或数组的所有系数。只需列出系数,从左上角开始,从左到右,从上到下移动。需要事先指定对象的大小。如果你列出的系数太少或太多,Eigen会抱怨。

    上面清楚地表明,您的右手侧需要与左手侧的尺寸匹配。在这种情况下,您可能需要逐个元素复制向量元素。类似:

    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;
    }
    
        2
  •  1
  •   chtz    6 年前

    如果你喜欢使用 << 初始化时,您可以一次执行一行(正如@paler123所说,您需要分配 X 在将值存储到其中之前):

    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 直接——在这种情况下,您必须确保存储订单同意,并且 如果仍在使用,则不会修改 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.