【问题标题】:Convert every column of an Eigen::Matrix to an std::vector?将 Eigen::Matrix 的每一列转换为 std::vector?
【发布时间】:2021-12-13 07:37:14
【问题描述】:

假设我有以下 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&lt;float&gt; 我尝试了这个解决方案的改编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 模板:static_assert 由于要求而失败 'Map<:matrix>, 0, Eigen::Stride>:: IsVectorAtCompileTime' "YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX"

什么是正确和最有效的解决方案?

【问题讨论】:

  • 我已经分别在我的答案版本 1 和版本 2 中展示了如何将任何单个列以及所有列提取到 std::vector 中。看看吧。

标签: c++ vector eigen


【解决方案1】:

下面的程序展示了如何从 Eigen::Matrix 中提取第一列到 std::vector&lt;float&gt; 中。

版本 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

同样你可以提取其他列。

请注意,如果您想提取所有列,则可以创建/使用std::vector&lt;std::vector&lt;float&gt;&gt;,您可以在其中存储所有行和列,如下所示:

版本 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

【讨论】:

  • 感谢它有效,但我认为@oroshimaru 的解决方案更清洁
【解决方案2】:

我认为最优雅的解决方案是使用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); }

【讨论】:

    猜你喜欢
    • 2019-07-08
    • 1970-01-01
    • 2014-11-23
    • 2021-11-16
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    相关资源
    最近更新 更多