初始化动态矩阵时的特征错误
Eigen error when initializing dynamic matrix
我正在尝试从包含一些简单的笛卡尔点结构的向量中填充特征矩阵(动态行、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;
行中收到一条错误消息:"No operator <<
matches these operands"(在调试模式下尝试通过 X << 0.0, 0.0;
时也会抛出此错误) .
据我了解,您正在尝试使用每行中的值初始化 X
矩阵,其中包含较早向量中的一个点的坐标。您不能那样做,请参阅 here:
Eigen offers a comma initializer syntax which allows the user to easily set all the coefficients of a matrix, vector or array. Simply list the coefficients, starting at the top-left corner and moving from left to right and from the top to the bottom. The size of the object needs to be specified beforehand. If you list too few or too many coefficients, Eigen will complain.
上面清楚地说明了您的右手边需要与左手边的尺寸相匹配。在您的情况下,您可能需要逐个元素地复制向量。类似于:
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;
}
如果你喜欢使用 <<
初始化,你可以一次一行(正如@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
-- 在这种情况下,您必须确保存储顺序一致并且 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.
我正在尝试从包含一些简单的笛卡尔点结构的向量中填充特征矩阵(动态行、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;
行中收到一条错误消息:"No operator <<
matches these operands"(在调试模式下尝试通过 X << 0.0, 0.0;
时也会抛出此错误) .
据我了解,您正在尝试使用每行中的值初始化 X
矩阵,其中包含较早向量中的一个点的坐标。您不能那样做,请参阅 here:
Eigen offers a comma initializer syntax which allows the user to easily set all the coefficients of a matrix, vector or array. Simply list the coefficients, starting at the top-left corner and moving from left to right and from the top to the bottom. The size of the object needs to be specified beforehand. If you list too few or too many coefficients, Eigen will complain.
上面清楚地说明了您的右手边需要与左手边的尺寸相匹配。在您的情况下,您可能需要逐个元素地复制向量。类似于:
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;
}
如果你喜欢使用 <<
初始化,你可以一次一行(正如@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
-- 在这种情况下,您必须确保存储顺序一致并且 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.