简介
Eigen是一个C++开源线性代数库,Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。在使用时,只需引入Eigen的头文件,不需链接库文件(没有库文件)。
数组、矩阵和向量的表示
typedef Matrix MyMatrixType; //矩阵
typedef Array MyArrayType; //行列式
//Scalar为数据类型,如,float,double,bool,int...
//RowATCompileTime为行数
//ColsAtCompileTime为列数
//Options为数据存储方式,分为按列存储(ColMajor)和按行存储(RowMajor),默认为按列存储
Eigen支持定义动态矩阵和静态矩阵:
Matrix // Dynamic number of columns (heap allocation)
Matrix // Dynamic number of rows (heap allocation)
Matrix // Fully dynamic, row major (heap allocation)
Matrix // Fully fixed (usually allocated on stack)
在大多数情况下,矩阵和数组都有简单的表示方式:
Matrix <=> MatrixXf
Matrix <=> VectorXd
Matrix <=> RowVectorXi
Matrix <=> Matrix3f
Matrix <=> Vector4f
Array <=> ArrayXXf
Array <=> ArrayXd
Array <=> RowArrayXi
Array <=> Array33f
Array <=> Array4f
访问和赋值:
与 C++ 数组的操作不同的是,Eigen::Matrix 是不能通过 [] 来访问赋值数据的,而是需要通过 ()。矩阵之间也可以通过 = 来进行赋值(拷贝)。
MatrixXd mat,mat1,mat2;
int x;
x = mat(a, b); // 获取到矩阵 mat 的 a 行 b 列的元素并赋值给 x
mat(b, a) = x; // 将 x 赋值给矩阵 mat 的 b 行 a 列
mat1 = mat2; // 将矩阵 mat2 赋值(拷贝)给矩阵 mat1
//通过 = 进行矩阵之间的拷贝时,如果左右两侧矩阵尺寸不一样并且左侧矩阵为动态矩阵,那么会将左侧矩阵的尺寸修改为与右侧一致。
在 Eigen 中还重载了 << 可以用来赋值矩阵,也可以用来 cout 输出矩阵。
MatrixXf m(4, 4); // 定义一个 4x4 的 float 类型的动态矩阵
m << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;// 赋值
std::cout << m; // 输出 m
Eigen矩阵还可以进行分块操作,通过成员函数block()获取某一部分矩阵。
mat = mat1.block(i, j, p, q); // 从矩阵 mat1 的 i 行 j 列开始获取一个 p 行 q 列的子矩阵
mat = mat1.block(i, j); // 从矩阵 mat1 的 i 行 j 列开始获取一个 p 行 q 列的子矩阵(动态矩阵)
Eigen矩阵可以使用成员函数row()、col()来获取某一行或某一列。
mat = mat1.row(i); // 获取 mat1 的第 i 行
mat = mat1.col(j); // 获取 mat1 的第 j 列
Eigen矩阵还可以使用成员函数fill()进行统一赋值。
mat.fill(n); // 将 mat 的所有元素均赋值为 n
矩阵运算
Eigen 重载了 +、−(减)、∗、/、−(负)、+=、−=、∗=、/=。
mat = mat1 + mat2; // +
mat = mat1 - mat2; // -(减)
mat = mat1 * mat2; // *
mat = mat1 * n; // *
mat = mat1 / n; // /
mat = -mat1; // -(负)
mat += mat1; // +=
mat -= mat1; // -=
mat *= mat1; // *=
mat *= n; // *=
mat /= n; // /=
对于 Matrix 的转置矩阵、共轭矩阵、伴随矩阵、对角矩阵可以通过成员函数transpose()、conjugate()、adjoint()、diagonal() 来获得,如果想要在原矩阵上进行转换,则需要通过成员函数transposeInPlace()、conjugateInPlace()、adjointInPlace()、diagonalInPlace() 。
mat = mat1.transpose(); // 获取 mat1 的转置矩阵
mat = mat1.conjugate(); // 获取 mat1 的共轭矩阵
mat = mat1.adjoint(); // 获取 mat1 的伴随矩阵
mat = mat1.diagonal(); // 获取 mat1 的对角矩阵
mat1.transposeInPlace();// mat1 转换为对应的转置矩阵
mat1.conjugateInPlace();// mat1 转换为对应的共轭矩阵
mat1.adjointInPlace(); // mat1 转换为对应的伴随矩阵
mat1.diagonalInPlace(); // mat1 转换为对应的对角矩阵
mat1.transpose().colwise().reverse(); // mat1 Rot90
动态矩阵可以通过成员函数 resize() 来进行修改大小,静态矩阵是不可以 resize() 的,并且动态矩阵 resize() 后元素不能保证不变。
mat.resize(rows, cols); // 将动态矩阵 mat 大小尺寸修改为 rows x cols