Eigen矩阵运算开源库完全使用指南

匿名 (未验证) 提交于 2019-12-03 00:27:02
Eigen库是一个开源的矩阵运算库,其利用C++模板编程的思想,构造所有矩阵通过传递模板参数形式完成。由于模板类不支持库链接方式编译,而且模板类要求全部写在头文件中,从而导致导致Eigen库只能通过开源的方式供大家使用,并且只需要包含Eigen头文件就能直接使用。
Eigen库中矩阵为其基本数据类型,向量也是一种特殊的矩阵。其所有矩阵数据类型都是由一个模板类Matrix生成。
Matrix 类有6个模板参数,现在我们了解前三个足够。剩下的三个参数都有默认值.
Matrix 的三个强制的模板参数:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
完整模板参数:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options = 0, int MaxRowsAtCompileTime = RowsAtCompileTime, int MaxColsAtCompileTime = ColsAtCompileTime>

  • Scalar 就是矩阵元素标量类型。
Eigen中提供了许多typedefs ,例如Matrix4f 是4*4的float型矩阵
typedef Matrix<float, 4, 4> Matrix4f;
在Eigen中,vectors 只是一种特殊形式的矩阵,有一行或者一列。在大多数情况下一列比较多,这样的向量也叫做列向量,也简称向量。其他情况叫做行向量。
例如typedef Vector3f 是一个(列)向量,它的定义如下:
typedef Matrix<float, 3, 1> Vector3f;
同样我们也提供了行向量的定义:
typedef Matrix<int, 1, 2> RowVector2i;

动态矩阵和静态矩阵:动态矩阵是指其大小在运行时确定,静态矩阵是指其大小在编译时确定。
MatrixXd:表示任意大小的元素类型为double的矩阵变量,其大小只有在运行时被赋值之后才能知道。
Matrix3d:表示元素类型为double大小为3*3的矩阵变量,其大小在编译时就知道。
在Eigen中行优先的矩阵会在其名字中包含有row,否则就是列优先。
Eigen中的向量只是一个特殊的矩阵,其维度为1而已。
矩阵类型:Eigen中的矩阵类型一般都是用类似MatrixXXX来表示,可以根据该名字来判断其数据类型,比如”d”表示double类型,”f”表示float类型,”i”表示整数,”c”表示复数;Matrix2f,表示的是一个2*2维的,其每个元素都是float类型。

项目中使用Eigen库

find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})

#include <Eigen/Dense>
数据类型定义在Eigen命名空间下

矩阵构造

1)默认构造:不会进行动态内存分配,也不会初始化矩阵元素
Matrix3f a;MatrixXf b;
2)指定行数列数构造:分配元素数组,不初始化元素
MatrixXf a(10,15);VectorXf b(30);
3)向量简单初始构造
对于比较小的、固定长度的向量提供直接构造元素方式。
Vector2d a(5.0, 6.0);Vector3d b(5.0, 6.0, 7.0);Vector4d c(5.0, 6.0, 7.0, 8.0);
4)逗号初始化
Eigen::Matrix3f m;m << 1, 2, 3, 4, 5, 6, 7, 8, 9;
矩阵和向量都可以通过逗号分隔方法进行初始化。
注意这种初始化方法只能对确定大小矩阵进行,包括指定行列数的动态矩阵,即下面这种是会出现段错误的:
Eigen::MatrixXd m;
m <<1,2,3,
4,5,6,
7,8,9;
而下面这种可以
Eigen::MatrixXd m(3,3);
m <<1,2,3,
4,5,6,
7,8,9;
5)常用矩阵
MatrixXf::Zero(3,4); // 将矩阵3行4列初始化为0
MatrixXf::Ones(3,3); // 将矩阵3行3列初始化为1
Vector3f::Ones(); // 将3行的纵向量初始化为1
MatrixXi::Identity(3,3); //单位阵
Matrix3d::Random();//随机矩阵
注意对动态矩阵初始化的时候,必须指定行数和列数。
6)矩阵特定初始化
m1.setIdentity(3,3);


矩阵元素的访问

1、矩阵访问按照先行索引、后列索引方式进行,索引下标从0开始(与Matlab不同);
2、矩阵元素的访问可以通过”()”操作符完成。例如m(2, 3)既是获取矩阵m的第2行第3列元素;
3、针对向量还提供”[]”操作符,注意矩阵则不可如此使用。

矩阵常用成员函数

当前矩阵的行数、列数、大小可以通过rows()、cols()和size()来获取,对于动态矩阵可以通过resize()函数来动态修改矩阵的大小。注意:(1)、固定大小的矩阵是不能使用resize()来修改矩阵的大小;(2)、resize()函数会析构掉原来的数据,因此调用resize()函数之后将不能保证元素的值不改变;(3)、使用”=”操作符操作动态矩阵时,如果左右两边的矩阵大小不等,则左边的动态矩阵的大小会被修改为右边的大小。
需要特别注意,遍历Eigen矩阵时最好通过rows和cols来限制访问范围,在Eigen中size()其实返回的是rows()*cols()的值,这就意味着如果Eigen矩阵的rows为0的时候,size()就会为0。


矩阵赋值运算符注意事项

赋值是将一个矩阵拷贝进另外一个矩阵,使用操作符=。Eigen 会自动跳转左面元素的大小,从而使得它和右侧元素匹配。例如:
MatrixXf a(2,2);std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl;MatrixXf b(3,3);a = b;std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;
如果你不需要这种自动调整大小,你可以将他关闭。


实用操作总结

给一个已经存在的矩阵后面增加一行:

MatrixXf s(3,4);
s<<1,2,3,4,
5,6,7,8,
9,10,11,12;
s = (MatrixXf(4,4)<<s,1,1,1,1).finished();

矩阵部分操作(感兴趣部分操作)

官网参考:
Eigen矩阵可以实现按列或按行操作:也叫partial reductions
主要利用colwise()和rowwise()实现对矩阵逐列或逐行操作,很重要的一个应用就是得到一个矩阵的行最大值或列最大值:


如果同时想要获得对应最值在矩阵中的索引,可以用:
Eigen::MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
Eigen::VectorXi maxIndices;
Eigen::VectorXf maxVals;
MatrixXf::Index maxIndex[2];//存储对应索引
VectorXf maxVal(2);//存储最大值
for(int i=0;i<2;++i)
maxVal(i) = mat.row(i).maxCoeff( &maxIndex[i] );//行最大



元素读写



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!