最近在看SLAM14讲的时候顺便看了一下Eigen库的相关使用,之前一直知道Eigen库但是一直没详细的看Eigen库的实际用法,因此,就记录了一下Eigen库的使用。
Eigen库是不需要编译的,但是我还是编译了一下,没觉得有什么区别。
可以自己直接去官网下载后,用CMake编译相当简单
Eigen库编译
Eigen中的所有向量和矩阵都是Eigen::Matrix,它是一个模板类。它的前三个参数为数据类型、行、列
1.声明一个 2 ∗ 3 2*3 2∗3的float
矩阵
Eigen::Matrix<float, 2, 3> matrix_23;
2.Eigen提供了许多内置类型
//Vector3d实质上是Eigen::Matrix
Eigen::Vector3d v_3d;
//Matrix3d实质上是Eigen::Matrix
Eigen::Matrix3d matrix_33
//定义动态大小的矩阵
Eigen::MatrixXd matrix_x;
3.动态矩阵的声明
//定义动态大小的矩阵
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> matrix_dynamic;
Eigen::MatrixXd matrix_x;//定义动态大小的矩阵
1.用()访问矩阵中的元素
和图像中访问像素基本一样
matrix_23 << 1, 2, 3, 4, 5, 6;//初始化
std::cout << "matrix 2x3 from 1 to 6: \n" << matrix_23 << std::endl;
std::cout << "print matrix 2x3: " << std::endl;
for (int i = 0; i < 2; i++)//用()访问矩阵中的元素
{
for (int j = 0; j < 3; j++)
{
std::cout << matrix_23(i, j) << "\t";
std::cout << std::endl;
}
}
2.矩阵和向量相乘
matrix_23 << 1, 2, 3, 4, 5, 6;
v_3d << 3, 2, 1;
vd_3d << 4, 5, 6;
Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
std::cout << "[1,2,3;4,5,6]*[3,2,1]= " << result.transpose() << std::endl;
Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d;
std::cout << "[1,2,3;4,5,6]*[4,5,6]= " << result2.transpose() << std::endl;
3.矩阵的各种运算
matrix_33 = Eigen::Matrix3d::Random();//随机数矩阵
std::cout << "random matrix: \n" << matrix_33 << std::endl;
std::cout << "transpose: \n" << matrix_33.transpose() << std::endl;//转置
std::cout << "sum: " << matrix_33.sum() << std::endl;//各元素和
std::cout << "trace: " << matrix_33.trace() << std::endl;//迹
std::cout << "times 10: \n" << 10 * matrix_33 << std::endl;//数乘
std::cout << "inverse: \n" << matrix_33.inverse() << std::endl;//逆
std::cout << "det: " << matrix_33.determinant() << std::endl;//行列式
4.矩阵的特征值求解
//特征值
//实对称矩阵可以保证对角化成功
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver(matrix_33.transpose() * matrix_33);
std::cout << "Eigen values = \n" << eigen_solver.eigenvalues() << std::endl;
std::cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << std::endl;
5.解方程
//解方程
//求解matrix_NN * x = v_Nd方程
//N的大小在前面的宏定义,由随机数生成
Eigen::Matrix<double, MATRIX_SIZE, MATRIX_SIZE> matrix_NN = Eigen::MatrixXd::Random(MATRIX_SIZE, MATRIX_SIZE);
matrix_NN = matrix_NN * matrix_NN.transpose();//保证半正定
Eigen::Matrix<double, MATRIX_SIZE, 1> v_Nd = Eigen::MatrixXd::Random(MATRIX_SIZE, 1);
//直接求逆
Eigen::Matrix<double, MATRIX_SIZE, 1> x = matrix_NN.inverse() * v_Nd;
std::cout << "x = " << x.transpose() << std::endl;
//通常用矩阵分解来求解,例如QR分解
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
std::cout << "x = " << x.transpose() << std::endl;
//对于正定矩阵,还可以用cholesky分解来解方程
x = matrix_NN.ldlt().solve(v_Nd);
std::cout << "x = " << x.transpose() << std::endl;