将 Eigen::Matrix 的每一列转换为 std::vector?
Convert every column of an Eigen::Matrix to an std::vector?
假设我有以下 Eigen::Matrix:
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
现在如何将每一列转换为 std::vector<float>
我试过改编这个解决方案 typecasting Eigen::VectorXd to std::vector:
std::vector<float> vec;
vec.resize(mat.rows());
for(int col=0; col<mat.cols(); col++){
Eigen::MatrixXf::Map(&vec[0], mat.rows());
}
但这会引发以下错误:
n template: static_assert failed due to requirement 'Map<Eigen::Matrix<float, -1, -1, 0, -1, -1>, 0, Eigen::Stride<0, 0>>::IsVectorAtCompileTime' "YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX"
什么是正确且最有效的解决方案?
下面的程序显示了如何将 Eigen::Matrix 中的第一列提取到 std::vector<float>
中。
版本 1:一次只提取一列
int main()
{
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
std::vector<float> column1(mat.rows());
for(int j = 0; j < mat.rows(); ++j)
{
column1.at(j) = mat(j, 0);//this will put all the elements in the first column of Eigen::Matrix into the column3 vector
}
for(float elem: column1)
{
std::cout<<elem<<std::endl;
}
//similarly you can create columns corresponding to other columns of the Matrix. Note that you can also
//create std::vector<std::vector<float>> for storing all the rows and columns as shown in version 2 of my answer
return 0;
}
版本1的输出如下:
1.1
2.2
3.1
同样,您可以提取其他列。
请注意,如果您想提取所有列,那么您可以 create/use 一个 std::vector<std::vector<float>>
,您可以在其中存储所有行和列,如下所示:
版本 2:将所有列提取到 2D std::vector
int main()
{
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
std::vector<std::vector<float>> vec_2d(mat.rows(), std::vector<float>(mat.cols(), 0));
for(int col = 0; col < mat.cols(); ++col)
{
for(int row = 0; row < mat.rows(); ++row)
{
vec_2d.at(row).at(col) = mat(row, col);
}
}
//lets print out i.e., confirm if our vec_2d contains the columns correctly
for(int col = 0; col < mat.cols(); ++col)
{ std::cout<<"This is the "<<col+1<< " column"<<std::endl;
for(int row = 0; row < mat.rows(); ++row)
{
std::cout<<vec_2d.at(row).at(col)<<std::endl;
}
}
return 0;
}
版本2的输出如下:
This is the 1 column
1.1
2.2
3.1
This is the 2 column
2
2
2
This is the 3 column
3
3
3
This is the 4 column
50
50
50
我认为最优雅的解决方案是使用 Eigen::Map
。在你的情况下你会这样做:
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
std::vector<float> vec;
vec.resize(mat.rows());
for(int col=0; col<mat.cols(); col++){
Eigen::Map<Eigen::MatrixXf>(vec.data(), mat.rows(), 1 ) = mat.col(col); }
假设我有以下 Eigen::Matrix:
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
现在如何将每一列转换为 std::vector<float>
我试过改编这个解决方案 typecasting Eigen::VectorXd to std::vector:
std::vector<float> vec;
vec.resize(mat.rows());
for(int col=0; col<mat.cols(); col++){
Eigen::MatrixXf::Map(&vec[0], mat.rows());
}
但这会引发以下错误:
n template: static_assert failed due to requirement 'Map<Eigen::Matrix<float, -1, -1, 0, -1, -1>, 0, Eigen::Stride<0, 0>>::IsVectorAtCompileTime' "YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX"
什么是正确且最有效的解决方案?
下面的程序显示了如何将 Eigen::Matrix 中的第一列提取到 std::vector<float>
中。
版本 1:一次只提取一列
int main()
{
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
std::vector<float> column1(mat.rows());
for(int j = 0; j < mat.rows(); ++j)
{
column1.at(j) = mat(j, 0);//this will put all the elements in the first column of Eigen::Matrix into the column3 vector
}
for(float elem: column1)
{
std::cout<<elem<<std::endl;
}
//similarly you can create columns corresponding to other columns of the Matrix. Note that you can also
//create std::vector<std::vector<float>> for storing all the rows and columns as shown in version 2 of my answer
return 0;
}
版本1的输出如下:
1.1
2.2
3.1
同样,您可以提取其他列。
请注意,如果您想提取所有列,那么您可以 create/use 一个 std::vector<std::vector<float>>
,您可以在其中存储所有行和列,如下所示:
版本 2:将所有列提取到 2D std::vector
int main()
{
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
std::vector<std::vector<float>> vec_2d(mat.rows(), std::vector<float>(mat.cols(), 0));
for(int col = 0; col < mat.cols(); ++col)
{
for(int row = 0; row < mat.rows(); ++row)
{
vec_2d.at(row).at(col) = mat(row, col);
}
}
//lets print out i.e., confirm if our vec_2d contains the columns correctly
for(int col = 0; col < mat.cols(); ++col)
{ std::cout<<"This is the "<<col+1<< " column"<<std::endl;
for(int row = 0; row < mat.rows(); ++row)
{
std::cout<<vec_2d.at(row).at(col)<<std::endl;
}
}
return 0;
}
版本2的输出如下:
This is the 1 column
1.1
2.2
3.1
This is the 2 column
2
2
2
This is the 3 column
3
3
3
This is the 4 column
50
50
50
我认为最优雅的解决方案是使用 Eigen::Map
。在你的情况下你会这样做:
Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;
std::vector<float> vec;
vec.resize(mat.rows());
for(int col=0; col<mat.cols(); col++){
Eigen::Map<Eigen::MatrixXf>(vec.data(), mat.rows(), 1 ) = mat.col(col); }