有时候脑子会突然卡住,忘记eigen库里的有些细节。所以还是决定来写个笔记把常用的用法总结一下,方便查阅。
1、Installation
g++ -I /path/to/eigen/ program.cpp -o program
- 在CmakeLists中添加
-
find_package(Eigen3 REQUIRED) include_directories(&{EIGEN#_INCLUDE_DIR})
2、Eigen库的模块(参考官方)
Module | Header File | Contents |
Core | #include<Eigen/Core> | Matrix和Array类,基本线性代数 |
Geometry | #include<Eigen/Geometry> | Transform,Translation,Rotation 2D,3D rotation(Quaterion,AngleAxis) |
LU | #include<Eigen/LU> | |
Cholesky | #include<Eigen/Cholesky> | |
Householder | #include<Eigen/Householder> | |
SVD | #include<Eigen/SVD> | |
QR | #include<Eigen/QR> | |
EigenValues | #include<EIgen/Eigenvalues> | |
Sparse | #Include<Eigen/Sparse> | 稀疏矩阵 |
#include<Eigen/Dense> | 包含Core,Geometry,LU,Cholesky,SVD,QR和Eigenvalues | |
#include<Eigen/Eigen> | 包含Dense和Sparse头文件,也就是整个Eigen库 |
3、Eigen库的常用用法
x.size() //向量长度
x.norm() //取模
x.squareNorm() //模的平方
C.rows() //矩阵行数
C.cols() //矩阵列数
C.transpose() //矩阵转置
C.adjoint() //伴随矩阵
C.transposeInPlace() //修改原始矩阵,将转置后结果存储在原矩阵
C.adjointInPlace() //修改原始矩阵
C.sum() //求和
C.cast<float>() //类型转换为float
C.real() //每个元素取实部
C.imag() //每个元素取虚部
C.conjugate() //每个元素取共轭
vector.resize(n) //改变大小,大小改变后会删除原有数据,大小不变时无操作
matrix.resize(new_row,new_col)
matrix.resize(NoChange,new_col)
matrix.resize(new_row,NoChange)
//************分块****************
x.head(n) //返回一个新的vector,包含x的前n个元素。这里的n可以是变量
x.head<n>() //返回前n个元素,并返回一个新的向量。这里n必须是一个编译时常量,因为模板参数必须在编译时确定
x.tail(n) //返回后n个元素
x.tail<n>() //n为编译时常量
x.segment(i,n) //从i+1开始取n个数
x.segment<n>(i) //从i+1开始取n个数
x.block<a,b>(i,j) //选取a×b大小的块,开始位置i+1,j+1
//*********矩阵运算******************
C.trace() //迹
C.inverse() //逆
C.determinant() //行列式
//************For Vector Use***********
v.dot(y) //点乘
v.transpose() * y //点乘
v.cross(y) //叉乘
//******访问某个元素*************
x(i , j) //访问第(i+1,j+1)个元素
1. Array,Matrix,Vector type
①matrix argument
Matrix<typename Scalar, int RowsAtCompileTime , int ColsAtCompileTime>
Matrix前三个参数分别为:数据类型,行数,列数
实际上后面还有三个参数,Options(RowMajor或ColumnMajor),MaxRowsAtCompileTime, MaxColsAtCompileTime.
- 对于Matrix的声明可以有很多组合:(可预先固定也可动态声明)
Matrix<double,6,Dynamic> //动态列,heap allocation
Matrix<double,Dynamic,2> //动态行,heap allocation
Matrix<double, Dynamic, Dynamic, RowMajor>//完全动态,row major,heap allocation
Matrix<double, 13, 3> //完全固定,stack allocation
- Matrices(Eigen库预设):
Matrix<type, N, N> | MatrixNt | Matrix<int, Dynamic, Dynamic> | MatrixXi |
Matrix<type, Dynamic, N> | MatrixXNt | Matrix<int, Dynamic, 3> | MatrixX3i |
Matrix<type, N, Dynamic> | MatrixNXt | Matrix<int, 3, Dynamic> | Matrix3Xi |
Matrix<type, N, 1> | VectorNt | Matrix<int, 3, 1> | Vector3i |
Matrix<type, 1, N> | RowVectorNt | Matrix<int, 1, 3> | RowVetor3i |
②Vector
vector是Matrix的一种特殊情况,只有一行或者一列。
typedef Matrix<float, 3, 1> Vector3f;
typedef Matrix<int, 1, 2> RowVector2i;
③Array
Array是Eigen中的一个模板类,用于表示任意维度的数组数据。与Matrix和Vector不同,Array不限定于二维或一维,可以是多维数组。
④何时用matrix ,何时用array
i. 如果需要进行线性代数运算,如矩阵乘法,矩阵求逆等,用Matrix类;
如果需要逐元素操作,逐元素加法、减法、乘法等,用Array
ii. 可以在需要的时候进行转换,.array()方法和.matrix()方法
iii. 这二者不可以混用,即一个表达式中不能同时存在
iiii. 在Matrix对象上可以用.cwiseProduct()方法进行逐元素乘法
Array<float, Dynamic, Dynamic> | ArrayXXf |
Array<double, Dynamic, 1> | ArrayXd |
Array<int, 1, Dynamic> | RowArrayXi |
Array<float, 3, 3> | Array33f |
Array<float, 4, 1> | Array4f |
2. Block Operation
Block Operation | Dynamic-size block | Fixed-size block |
Block size(p,q),starting at (i,j) | matrix.block(i,j,p,q) | matrix.block<p,q>(i,j) |
第i行 | matrix.row(i) | |
第i列 | matrix.col(j) | |
Top-Left p by q | matrix.topLeftCorner(p,q) | matrix.topLeftCorner<p,q>() |
Bottom-left p by q | matrix.bottomLeftCorner(p,q) | matrix.bottomLeftCorner<p,q>() |
Top-right p by q | matrix.topRightCorner(p,q) | matrix.topRightCorner<p,q>() |
... |
- 代码测试及输出结果
g++ -I /usr/include/eigen3/ eigenTest.cpp -o eigenTest
int main(){
RowVectorXi m(9);
m.setZero();
m << 1, 2, 3,4, 5, 6,7, 8, 9;
std::cout<<m.segment<6>(0)<<std::endl;
return 0;
}
//output: 1 2 3 4 5 6
int main(){
Vector3i m , n;
m << 1,0,2;
n << 1,2,3;
std::cout<<m.dot(n)<<std::endl;
//或者把这个换成m.transpose()*n , n.transpose()*m也是一样
return 0;
}
//output: 7
int main(){
Vector3i m , n;
m << 1,0,2;
n << 1,2,3;
std::cout<<m.cross(n)<<std::endl;
return 0;
}
//output:
//-4
//-1
//2
3. 初始化矩阵Initiation of Matrices
Comma Initializer
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
//1 2 3
//4 5 6
//7 8 9
RowVectorXd vec1(3);
vec1 << 1,2,3;
std::cout << vec1 ;
//1 2 3
//vec1 1 2 3
//vec2 4 5 6 7
RowVectorXd joined(7);
joined << vec1,vec2;
std::cout << joined ;
//使用<<连续输入
//joined: 1 2 3 4 5 6 7
MatrixXf matA(2,2);
matA << 1,2,3,4;
MatrixXf matB(4,4);
matB << matA , matA/10 , matA/10 , matA;
std::cout << matB ;
// 1 2 0.1 0.2
// 3 4 0.3 0.4
// 0.1 0.2 1 2
// 0.3 0.4 3 4
Matrix3f m;
m.row(0) << 1 , 2 , 3;
m.block(1,0,2,2) << 4 , 5 , 7 , 8;
m.col(2).tail(2) << 6,9;
std::cout <<m;
//1 2 3
//4 5 6
//7 8 9
int main (void){
Eigen::Matrix<double, 3, 3> A;
A << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Eigen::Matrix<double, 3, 3> B;
B << 1, 1, 1,
1, 1, 1,
1, 1, 1;
double m = A(3) * B(2);
std::cout << m << std::endl;
return 0;
}
//输出结果: 2
//若 m = A(2) * B(2); 输出结果为7
//使用单个数字索引访问矩阵,默认按照列优先来索引数据
int main (void){
Eigen::Vector3d A(1, 2, 3);
Eigen::Vector3d B(4, 5, 6);
double C = A.dot(B);
double D = A.transpose() * B;
Eigen::Vector3d E = A.cross(B);
std::cout << "C: " << C << std::endl;
std::cout << "D: " << D << std::endl;
std::cout << "E: " << E << std::endl;
return 0;
}
/*
C: 32
D: 32
E: -3
6
-3
*/