Eigen::Map的理解

一 Eigen::Map 核心概念回顾
先明确核心定位:Eigen::Map是Eigen库提供的内存映射工具,
能把一段连续的原始内存(C数组 malloc内存 缓冲区等)直接包装成Eigen的向量/矩阵对象,
无需拷贝数据,让Eigen的便捷接口操作原始内存。
目标Eigen类型:要映射成的类型(如VectorXd Matrix3d Vector3f等)
可选参数:内存布局(默认列优先,Eigen::RowMajor行优先):
维度参数:动态大小类型(如VectorXd/MatrixXd) 需要指定行数/列数,
固定大小类型(如Vector3d/Matrix3d)无需指定。
二 常量场景示例
场景1:映射一维数组(向量)

点击查看代码
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
int main()
 {
 //原始C数组(双精度)
     double arr[]={1.0,2.0,3.0,4.0,5.0};
     //1.映射为动态大小向量(VectorXd)
     Eigen::Map<Eigen::VectorXd> vec_map1(arr,5);//5是向量长度

     std::cout<<"动态大小向量:\n"<<vec_map1<<"\n\n";

     //2.映射为固定大小向量(Vector3d,仅取3个元素)
     Eigen::Map<Eigen::Vector3d> vec_map2(arr);
     std::cout<<"固定大小向量(前3个元素):\n"<<vec_map2<<"\n\n";

     //3.修改映射对象->原始数组也会被修改(零拷贝核心特性)
     vec_map1(0)=10.0;
     vec_map2(1)=20.0;
     std::cout<<"修改后原始数组:";
     for (double v:arr)std::cout<<v<<" ";//输出 10 20 3 4 5
     return 0;
 }
运行结果

image
场景2:映射二维数组(矩阵)
注意Eigen默认是列优先存储,若原数组是行优先,需显式指定:

点击查看代码
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
int main()
{
 //原始二维数组(行优先存储:1 2 3;4 5 6)
 double mat_arr[]={1,2,3,4,5,6};
 // 1.映射为列优先矩阵(Eigen默认)
 // 2行3列,mat_map1(0,0)=1,mat_map1(1,0)=4,mat_map1(0,1)=2...
 Eigen::Map<Eigen::MatrixXd> mat_map1(mat_arr,2,3);
 std::cout<<"列优先矩阵:\n"<<mat_map1<<"\n\n";
}
运行结果

image
在内存里,它的存储顺序是[1,2,3,4,5,6],一个挨着一个。
Eigen是怎么读这个数组的
当你用Eigen::Map<Eigen::MatrixXd> mat_map1(mat_arr,2,3);时,Eigen做了几件事:
它默认是列优先(ColMajor)存储。
它会把你给的一维数组,按先填满第一列,再填第二列,最后第三列的方式,拼成一个2行3列的矩阵。
所以,它从数组[1,2,3,4,5,6]里读取的顺序是
第一列:取前两个元素 → 1, 2
第二列:取接下来两个元素 → 3, 4
第三列:取最后两个元素 → 5, 6

点击查看代码
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>

int main()
{
 //原始二维数组(行优先存储:1 2 3;4 5 6)
 double mat_arr[]={1,2,3,4,5,6};
 // 1.映射为列优先矩阵(Eigen默认)
 // 2行3列,mat_map1(0,0)=1,mat_map1(1,0)=4,mat_map1(0,1)=2...
 Eigen::Map<Eigen::MatrixXd> mat_map1(mat_arr,2,3);
 std::cout<<"列优先矩阵:\n"<<mat_map1<<"\n\n";
 //2.映射为行优先矩阵(指定RowMajor)
 Eigen::Map<Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>>
    mat_map2(mat_arr,2,3);
 std::cout<<"行优先矩阵:\n"<<mat_map2<<"\n\n";

 return 0;
}
运行结果:

image

场景3.只读映射(const版本)
用于仅读取,不修改原始内存的场景,提高代码安全性

点击查看代码
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
int main()
{
 const double arr[]={1.0,2.0,3.0};//原始数组是const
 //只读映射:Map<const 向量类型>
 Eigen::Map<const Eigen::Vector3d> const_vec_map(arr);
 std::cout<<"只读向量: \n"<<const_vec_map<<"\n";
 // const_vec_map(0)=10;   //编译报错!禁止修改
 return 0;
}

运行结果

image

场景4.映射内存片段(偏移/子数组) 从数组的指定位值开始映射

点击查看代码
#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>
int main()
{
  double arr[]={1,2,3,4,5,6,7,8,9};
  //从索引2开始(第3个元素),映射长度为4的向量
  Eigen::Map<Eigen::VectorXd> sub_vec(arr+2,4);
  std::cout <<"子向量 (arr[2]~arr[5]):\n "<< sub_vec << std::endl;// 3 4 5 6

  //修改子向量->原始数组对应位置也变
  sub_vec(1)=40.0;
  std::cout<<"修改后原始数组:";
  for (double v:arr) std::cout<<v<<" ";
  return 0;

}
运行结果

image

posted @ 2026-01-20 10:32  阳光天气  阅读(0)  评论(0)    收藏  举报