Eigen库是一个非常常用的线性代数库。Eigen库中的Map类是一个非常有用却又很容易被忽略的类,它不同于C++ STL中的map。
Eigen::Map 是一个非常有用的类模板,它的主要作用是将已存在的内存块当作 Eigen 矩阵或向量来使用,而无需进行数据的复制操作。这种方式使得你可以直接操作已有的数据,避免了额外的内存开销和数据复制带来的性能损耗。
// Map类模板的定义如下
template<typename PlainObjectType, int MapOptions, typename StrideType> classMap;
参数 |
解释 |
PlainObjectType |
映射后的eigen数据类型 如常见的Eigen::VectorXd,Eigen::MatrixXd等等 |
MapOptions |
指针所指对象的内存对齐方式,默认值为 Aligned |
StrideType |
跨度类型,默认情况下map在数组的内存中是连续取得映射元素,可以通过该参数设置按照一定的跨度映射元素 |
1. 为什么用Eigen::Map
性能优化:避免数据拷贝。在进行矩阵运算时,如果每次都进行数据的拷贝,会带来较大的性能开销。使用Map可以将外部数据陕封到Eigen的内存空间中,直接对原始数据进行操作,从而提高性能。
便捷的数据访问:通过Map,可以直接像操作Eigen内部的矩阵和向量一样操作外部数据结构,这样可以使代码更加简洁易懂。
2. 如何用Eigen::Map
2.1. std::vector转eigen数据类型
/// std::vector映射到 Eigen::Matrix23d
/// 使用std::vector时通过.data()来获取数vector中的数组数据
#include<vector>
intmain()
{
std::vector<double>data = {1,2,3,4,5,6};
/// 在Eigen::Map中确定维度
Eigen::Map<Eigen::Matrix<double,2,3>> map(data.data());
Eigen::Map<Eigen::Matrix<double,6,1>> map1(data.data());
//现在你可以像操作矩阵一样操作map,例如:
std::cout <<"Matrix:/n"<<map<<std::endl;return 0;}
std::cout <<"Matrix1:/n"<<map1<<std::endl;return 0;}
/// 修改某一个对象其他也一同变化
/// 指向相同内存
map(1,1) = 100;
std::cout <<"Matrix3:/n"<<map<<std::endl;return 0;}
std::cout <<"Matrix4:/n"<<map1<<std::endl;return 0;}
/// 在构造时指定维度
Eigen::Map<Eigen::VectorXd> vd(data.data(),6); //构造成一个长度为6的列向量
std::cout << "------ vd ------" << std::endl << vd << std::endl;
Eigen::Map<Eigen::MatrixXd> xd(data.data(),3,2); //构造成一个3x2的矩阵
std::cout << "------ xd ------" << std::endl << xd << std::endl;
}
/// output
///Matrix:
/// 1 2 3
/// 4 5 6
///Matrix1:
/// 1
/// 2
/// 3
/// 4
/// 5
/// 6
///Matrix:
/// 1 2 3
/// 4 100 6
///Matrix1:
/// 1
/// 2
/// 3
/// 4
/// 100
/// 6
///------ vd ------
///1
///2
///3
///4
///100
///6
------ xd ------
///1 4
///2 100
///3 6
2.2. array转eigen数据类型
/// 数组转矩阵
#include<Eigen/Dense>
intmain()
{
doublearray[6] = {1,2,3,4,5,6};
Eigen::Map<Eigen::Matrix<double,2,3>>map(array);
// 现在你可以像操作矩阵一样操作map,例如:
std::cout<<"Matrix:/n"<< map<<<std::endl;
return
}
/// output
/// Matrix:
/// 1 2 3
/// 4 5 6
3. 注意事项
生命周期管理:确保在使用Map时,所引用的数据结构在作用域内是有效的。如果数据结构被释放或超出作用域,使用Map进行访问将导致未定义行为。
数据对齐:某些硬件平台可能要求数据按照特定的方式对齐,以获得最佳性能。在使用Map时,确保数据的地址和大小满足这些要求。
类型一致性:确保映射的数据类型与模板参数匹配,否则可能会导致运时错误。
通过合理使用Eigen中的Map类,可以有效地提高SLAM算法中矩阵运算的效率和代码的可维护性。